]> gcc.gnu.org Git - gcc.git/blob - gcc/config/i386/i386.c
*** empty log message ***
[gcc.git] / gcc / config / i386 / i386.c
1 /* Subroutines for insn-output.c for Intel 80386.
2 Copyright (C) 1988 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #include <stdio.h>
21 #include "config.h"
22 #include "rtl.h"
23 #include "regs.h"
24 #include "hard-reg-set.h"
25 #include "real.h"
26 #include "insn-config.h"
27 #include "conditions.h"
28 #include "insn-flags.h"
29 #include "output.h"
30 #include "insn-attr.h"
31 #include "tree.h"
32 #include "flags.h"
33
34 #ifdef EXTRA_CONSTRAINT
35 /* If EXTRA_CONSTRAINT is defined, then the 'S'
36 constraint in REG_CLASS_FROM_LETTER will no longer work, and various
37 asm statements that need 'S' for class SIREG will break. */
38 error EXTRA_CONSTRAINT conflicts with S constraint letter
39 /* The previous line used to be #error, but some compilers barf
40 even if the conditional was untrue. */
41 #endif
42
43 #define AT_BP(mode) (gen_rtx (MEM, (mode), frame_pointer_rtx))
44
45 extern FILE *asm_out_file;
46 extern char *strcat ();
47
48 char *singlemove_string ();
49 char *output_move_const_single ();
50 char *output_fp_cc0_set ();
51
52 static char *hi_reg_name[] = HI_REGISTER_NAMES;
53 static char *qi_reg_name[] = QI_REGISTER_NAMES;
54 static char *qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES;
55
56 /* Array of the smallest class containing reg number REGNO, indexed by
57 REGNO. Used by REGNO_REG_CLASS in i386.h. */
58
59 enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
60 {
61 /* ax, dx, cx, bx */
62 AREG, DREG, CREG, BREG,
63 /* si, di, bp, sp */
64 SIREG, DIREG, INDEX_REGS, GENERAL_REGS,
65 /* FP registers */
66 FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
67 FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,
68 /* arg pointer */
69 INDEX_REGS
70 };
71
72 /* Test and compare insns in i386.md store the information needed to
73 generate branch and scc insns here. */
74
75 struct rtx_def *i386_compare_op0, *i386_compare_op1;
76 struct rtx_def *(*i386_compare_gen)(), *(*i386_compare_gen_eq)();
77 \f
78 /* Output an insn whose source is a 386 integer register. SRC is the
79 rtx for the register, and TEMPLATE is the op-code template. SRC may
80 be either SImode or DImode.
81
82 The template will be output with operands[0] as SRC, and operands[1]
83 as a pointer to the top of the 386 stack. So a call from floatsidf2
84 would look like this:
85
86 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
87
88 where %z0 corresponds to the caller's operands[1], and is used to
89 emit the proper size suffix.
90
91 ??? Extend this to handle HImode - a 387 can load and store HImode
92 values directly. */
93
94 void
95 output_op_from_reg (src, template)
96 rtx src;
97 char *template;
98 {
99 rtx xops[4];
100
101 xops[0] = src;
102 xops[1] = AT_SP (Pmode);
103 xops[2] = gen_rtx (CONST_INT, VOIDmode, GET_MODE_SIZE (GET_MODE (src)));
104 xops[3] = stack_pointer_rtx;
105
106 if (GET_MODE_SIZE (GET_MODE (src)) > UNITS_PER_WORD)
107 {
108 rtx high = gen_rtx (REG, SImode, REGNO (src) + 1);
109 output_asm_insn (AS1 (push%L0,%0), &high);
110 }
111 output_asm_insn (AS1 (push%L0,%0), &src);
112
113 output_asm_insn (template, xops);
114
115 output_asm_insn (AS2 (add%L3,%2,%3), xops);
116 }
117 \f
118 /* Output an insn to pop an value from the 387 top-of-stack to 386
119 register DEST. The 387 register stack is popped if DIES is true. If
120 the mode of DEST is an integer mode, a `fist' integer store is done,
121 otherwise a `fst' float store is done. */
122
123 void
124 output_to_reg (dest, dies)
125 rtx dest;
126 int dies;
127 {
128 rtx xops[4];
129
130 xops[0] = AT_SP (Pmode);
131 xops[1] = stack_pointer_rtx;
132 xops[2] = gen_rtx (CONST_INT, VOIDmode, GET_MODE_SIZE (GET_MODE (dest)));
133 xops[3] = dest;
134
135 output_asm_insn (AS2 (sub%L1,%2,%1), xops);
136
137 if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_INT)
138 {
139 if (dies)
140 output_asm_insn (AS1 (fistp%z3,%y0), xops);
141 else
142 output_asm_insn (AS1 (fist%z3,%y0), xops);
143 }
144 else if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_FLOAT)
145 {
146 if (dies)
147 output_asm_insn (AS1 (fstp%z3,%y0), xops);
148 else
149 output_asm_insn (AS1 (fst%z3,%y0), xops);
150 }
151 else
152 abort ();
153
154 output_asm_insn (AS1 (pop%L0,%0), &dest);
155
156 if (GET_MODE_SIZE (GET_MODE (dest)) > UNITS_PER_WORD)
157 {
158 dest = gen_rtx (REG, SImode, REGNO (dest) + 1);
159 output_asm_insn (AS1 (pop%L0,%0), &dest);
160 }
161 }
162 \f
163 char *
164 singlemove_string (operands)
165 rtx *operands;
166 {
167 rtx x;
168 if (GET_CODE (operands[0]) == MEM
169 && GET_CODE (x = XEXP (operands[0], 0)) == PRE_DEC)
170 {
171 if (XEXP (x, 0) != stack_pointer_rtx)
172 abort ();
173 return "push%L1 %1";
174 }
175 else if (GET_CODE (operands[1]) == CONST_DOUBLE)
176 {
177 return output_move_const_single (operands);
178 }
179 else if (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == REG)
180 return AS2 (mov%L0,%1,%0);
181 else if (CONSTANT_P (operands[1]))
182 return AS2 (mov%L0,%1,%0);
183 else
184 {
185 output_asm_insn ("push%L1 %1", operands);
186 return "pop%L0 %0";
187 }
188 }
189 \f
190 /* Return a REG that occurs in ADDR with coefficient 1.
191 ADDR can be effectively incremented by incrementing REG. */
192
193 static rtx
194 find_addr_reg (addr)
195 rtx addr;
196 {
197 while (GET_CODE (addr) == PLUS)
198 {
199 if (GET_CODE (XEXP (addr, 0)) == REG)
200 addr = XEXP (addr, 0);
201 else if (GET_CODE (XEXP (addr, 1)) == REG)
202 addr = XEXP (addr, 1);
203 else if (CONSTANT_P (XEXP (addr, 0)))
204 addr = XEXP (addr, 1);
205 else if (CONSTANT_P (XEXP (addr, 1)))
206 addr = XEXP (addr, 0);
207 else
208 abort ();
209 }
210 if (GET_CODE (addr) == REG)
211 return addr;
212 abort ();
213 }
214
215 /* Output an insn to add the constant N to the register X. */
216
217 static void
218 asm_add (n, x)
219 int n;
220 rtx x;
221 {
222 rtx xops[2];
223 xops[1] = x;
224 if (n < 0)
225 {
226 xops[0] = gen_rtx (CONST_INT, VOIDmode, -n);
227 output_asm_insn (AS2 (sub%L0,%0,%1), xops);
228 }
229 else if (n > 0)
230 {
231 xops[0] = gen_rtx (CONST_INT, VOIDmode, n);
232 output_asm_insn (AS2 (add%L0,%0,%1), xops);
233 }
234 }
235
236 /* Output assembler code to perform a doubleword move insn
237 with operands OPERANDS. */
238
239 char *
240 output_move_double (operands)
241 rtx *operands;
242 {
243 enum {REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
244 rtx latehalf[2];
245 rtx addreg0 = 0, addreg1 = 0;
246
247 /* First classify both operands. */
248
249 if (REG_P (operands[0]))
250 optype0 = REGOP;
251 else if (offsettable_memref_p (operands[0]))
252 optype0 = OFFSOP;
253 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
254 optype0 = POPOP;
255 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
256 optype0 = PUSHOP;
257 else if (GET_CODE (operands[0]) == MEM)
258 optype0 = MEMOP;
259 else
260 optype0 = RNDOP;
261
262 if (REG_P (operands[1]))
263 optype1 = REGOP;
264 else if (CONSTANT_P (operands[1]))
265 optype1 = CNSTOP;
266 else if (offsettable_memref_p (operands[1]))
267 optype1 = OFFSOP;
268 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
269 optype1 = POPOP;
270 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
271 optype1 = PUSHOP;
272 else if (GET_CODE (operands[1]) == MEM)
273 optype1 = MEMOP;
274 else
275 optype1 = RNDOP;
276
277 /* Check for the cases that the operand constraints are not
278 supposed to allow to happen. Abort if we get one,
279 because generating code for these cases is painful. */
280
281 if (optype0 == RNDOP || optype1 == RNDOP)
282 abort ();
283
284 /* If one operand is decrementing and one is incrementing
285 decrement the former register explicitly
286 and change that operand into ordinary indexing. */
287
288 if (optype0 == PUSHOP && optype1 == POPOP)
289 {
290 operands[0] = XEXP (XEXP (operands[0], 0), 0);
291 asm_add (-8, operands[0]);
292 operands[0] = gen_rtx (MEM, DImode, operands[0]);
293 optype0 = OFFSOP;
294 }
295 if (optype0 == POPOP && optype1 == PUSHOP)
296 {
297 operands[1] = XEXP (XEXP (operands[1], 0), 0);
298 asm_add (-8, operands[1]);
299 operands[1] = gen_rtx (MEM, DImode, operands[1]);
300 optype1 = OFFSOP;
301 }
302
303 /* If an operand is an unoffsettable memory ref, find a register
304 we can increment temporarily to make it refer to the second word. */
305
306 if (optype0 == MEMOP)
307 addreg0 = find_addr_reg (XEXP (operands[0], 0));
308
309 if (optype1 == MEMOP)
310 addreg1 = find_addr_reg (XEXP (operands[1], 0));
311
312 /* Ok, we can do one word at a time.
313 Normally we do the low-numbered word first,
314 but if either operand is autodecrementing then we
315 do the high-numbered word first.
316
317 In either case, set up in LATEHALF the operands to use
318 for the high-numbered word and in some cases alter the
319 operands in OPERANDS to be suitable for the low-numbered word. */
320
321 if (optype0 == REGOP)
322 latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
323 else if (optype0 == OFFSOP)
324 latehalf[0] = adj_offsettable_operand (operands[0], 4);
325 else
326 latehalf[0] = operands[0];
327
328 if (optype1 == REGOP)
329 latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
330 else if (optype1 == OFFSOP)
331 latehalf[1] = adj_offsettable_operand (operands[1], 4);
332 else if (optype1 == CNSTOP)
333 {
334 if (GET_CODE (operands[1]) == CONST_DOUBLE)
335 split_double (operands[1], &operands[1], &latehalf[1]);
336 else if (CONSTANT_P (operands[1]))
337 {
338 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
339 latehalf[1] = constm1_rtx;
340 else
341 latehalf[1] = const0_rtx;
342 }
343 }
344 else
345 latehalf[1] = operands[1];
346
347 /* If insn is effectively movd N (sp),-(sp) then we will do the
348 high word first. We should use the adjusted operand 1 (which is N+4 (sp))
349 for the low word as well, to compensate for the first decrement of sp. */
350 if (optype0 == PUSHOP
351 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
352 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
353 operands[1] = latehalf[1];
354
355 /* If one or both operands autodecrementing,
356 do the two words, high-numbered first. */
357
358 /* Likewise, the first move would clobber the source of the second one,
359 do them in the other order. This happens only for registers;
360 such overlap can't happen in memory unless the user explicitly
361 sets it up, and that is an undefined circumstance. */
362
363 if (optype0 == PUSHOP || optype1 == PUSHOP
364 || (optype0 == REGOP && optype1 == REGOP
365 && REGNO (operands[0]) == REGNO (latehalf[1])))
366 {
367 /* Make any unoffsettable addresses point at high-numbered word. */
368 if (addreg0)
369 asm_add (4, addreg0);
370 if (addreg1)
371 asm_add (4, addreg1);
372
373 /* Do that word. */
374 output_asm_insn (singlemove_string (latehalf), latehalf);
375
376 /* Undo the adds we just did. */
377 if (addreg0)
378 asm_add (-4, addreg0);
379 if (addreg1)
380 asm_add (-4, addreg1);
381
382 /* Do low-numbered word. */
383 return singlemove_string (operands);
384 }
385
386 /* Normal case: do the two words, low-numbered first. */
387
388 output_asm_insn (singlemove_string (operands), operands);
389
390 /* Make any unoffsettable addresses point at high-numbered word. */
391 if (addreg0)
392 asm_add (4, addreg0);
393 if (addreg1)
394 asm_add (4, addreg1);
395
396 /* Do that word. */
397 output_asm_insn (singlemove_string (latehalf), latehalf);
398
399 /* Undo the adds we just did. */
400 if (addreg0)
401 asm_add (-4, addreg0);
402 if (addreg1)
403 asm_add (-4, addreg1);
404
405 return "";
406 }
407 \f
408 int
409 standard_80387_constant_p (x)
410 rtx x;
411 {
412 union real_extract u;
413 register double d;
414
415 bcopy (&CONST_DOUBLE_LOW (x), &u, sizeof u);
416 d = u.d;
417
418 if (d == 0)
419 return 1;
420
421 if (d == 1)
422 return 2;
423
424 /* Note that on the 80387, other constants, such as pi,
425 are much slower to load as standard constants
426 than to load from doubles in memory! */
427
428 return 0;
429 }
430
431 char *
432 output_move_const_single (operands)
433 rtx *operands;
434 {
435 if (FP_REG_P (operands[0]))
436 {
437 int conval = standard_80387_constant_p (operands[1]);
438
439 if (conval == 1)
440 return "fldz";
441
442 if (conval == 2)
443 return "fld1";
444 }
445 if (GET_CODE (operands[1]) == CONST_DOUBLE)
446 {
447 union { int i[2]; double d;} u1;
448 union { int i; float f;} u2;
449 u1.i[0] = CONST_DOUBLE_LOW (operands[1]);
450 u1.i[1] = CONST_DOUBLE_HIGH (operands[1]);
451 u2.f = u1.d;
452 operands[1] = gen_rtx (CONST_INT, VOIDmode, u2.i);
453 }
454 return singlemove_string (operands);
455 }
456 \f
457 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
458 reference and a constant. */
459
460 int
461 symbolic_operand (op, mode)
462 register rtx op;
463 enum machine_mode mode;
464 {
465 switch (GET_CODE (op))
466 {
467 case SYMBOL_REF:
468 case LABEL_REF:
469 return 1;
470 case CONST:
471 op = XEXP (op, 0);
472 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
473 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
474 && GET_CODE (XEXP (op, 1)) == CONST_INT);
475 default:
476 return 0;
477 }
478 }
479 \f
480 /* Returns 1 if OP contains a symbol reference */
481
482 int
483 symbolic_reference_mentioned_p (op)
484 rtx op;
485 {
486 register char *fmt;
487 register int i;
488
489 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
490 return 1;
491
492 fmt = GET_RTX_FORMAT (GET_CODE (op));
493 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
494 {
495 if (fmt[i] == 'E')
496 {
497 register int j;
498
499 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
500 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
501 return 1;
502 }
503 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
504 return 1;
505 }
506
507 return 0;
508 }
509 \f
510 /* Return a legitimate reference for ORIG (an address) using the
511 register REG. If REG is 0, a new pseudo is generated.
512
513 There are three types of references that must be handled:
514
515 1. Global data references must load the address from the GOT, via
516 the PIC reg. An insn is emitted to do this load, and the reg is
517 returned.
518
519 2. Static data references must compute the address as an offset
520 from the GOT, whose base is in the PIC reg. An insn is emitted to
521 compute the address into a reg, and the reg is returned. Static
522 data objects have SYMBOL_REF_FLAG set to differentiate them from
523 global data objects.
524
525 3. Constant pool addresses must be handled special. They are
526 considered legitimate addresses, but only if not used with regs.
527 When printed, the output routines know to print the reference with the
528 PIC reg, even though the PIC reg doesn't appear in the RTL.
529
530 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
531 reg also appears in the address (except for constant pool references,
532 noted above).
533
534 "switch" statements also require special handling when generating
535 PIC code. See comments by the `casesi' insn in i386.md for details. */
536
537 rtx
538 legitimize_pic_address (orig, reg)
539 rtx orig;
540 rtx reg;
541 {
542 rtx addr = orig;
543 rtx new = orig;
544
545 if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
546 {
547 if (GET_CODE (addr) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (addr))
548 reg = new = orig;
549 else
550 {
551 if (reg == 0)
552 reg = gen_reg_rtx (Pmode);
553
554 if (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
555 new = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig);
556 else
557 new = gen_rtx (MEM, Pmode,
558 gen_rtx (PLUS, Pmode,
559 pic_offset_table_rtx, orig));
560
561 emit_move_insn (reg, new);
562 }
563 current_function_uses_pic_offset_table = 1;
564 return reg;
565 }
566 else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
567 {
568 rtx base;
569
570 if (GET_CODE (addr) == CONST)
571 {
572 addr = XEXP (addr, 0);
573 if (GET_CODE (addr) != PLUS)
574 abort ();
575 }
576
577 if (XEXP (addr, 0) == pic_offset_table_rtx)
578 return orig;
579
580 if (reg == 0)
581 reg = gen_reg_rtx (Pmode);
582
583 base = legitimize_pic_address (XEXP (addr, 0), reg);
584 addr = legitimize_pic_address (XEXP (addr, 1), base == reg ? 0 : reg);
585
586 if (GET_CODE (addr) == CONST_INT)
587 return plus_constant (base, INTVAL (addr));
588
589 if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
590 {
591 base = gen_rtx (PLUS, Pmode, base, XEXP (addr, 0));
592 addr = XEXP (addr, 1);
593 }
594 return gen_rtx (PLUS, Pmode, base, addr);
595 }
596 return new;
597 }
598 \f
599 /* Emit insns to move operands[1] into operands[0]. */
600
601 void
602 emit_pic_move (operands, mode)
603 rtx *operands;
604 enum machine_mode mode;
605 {
606 rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
607
608 if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
609 operands[1] = (rtx) force_reg (SImode, operands[1]);
610 else
611 operands[1] = legitimize_pic_address (operands[1], temp);
612 }
613 \f
614 /* This function generates the assembly code for function entry.
615 FILE is an stdio stream to output the code to.
616 SIZE is an int: how many units of temporary storage to allocate. */
617
618 void
619 function_prologue (file, size)
620 FILE *file;
621 int size;
622 {
623 register int regno;
624 int limit;
625 rtx xops[4];
626 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
627 || current_function_uses_const_pool);
628
629 xops[0] = stack_pointer_rtx;
630 xops[1] = frame_pointer_rtx;
631 xops[2] = gen_rtx (CONST_INT, VOIDmode, size);
632 if (frame_pointer_needed)
633 {
634 output_asm_insn ("push%L1 %1", xops);
635 output_asm_insn (AS2 (mov%L0,%0,%1), xops);
636 }
637
638 if (size)
639 output_asm_insn (AS2 (sub%L0,%2,%0), xops);
640
641 /* Note If use enter it is NOT reversed args.
642 This one is not reversed from intel!!
643 I think enter is slower. Also sdb doesn't like it.
644 But if you want it the code is:
645 {
646 xops[3] = const0_rtx;
647 output_asm_insn ("enter %2,%3", xops);
648 }
649 */
650 limit = (frame_pointer_needed ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
651 for (regno = limit - 1; regno >= 0; regno--)
652 if ((regs_ever_live[regno] && ! call_used_regs[regno])
653 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
654 {
655 xops[0] = gen_rtx (REG, SImode, regno);
656 output_asm_insn ("push%L0 %0", xops);
657 }
658
659 if (pic_reg_used)
660 {
661 xops[0] = pic_offset_table_rtx;
662 xops[1] = (rtx) gen_label_rtx ();
663
664 output_asm_insn (AS1 (call,%P1), xops);
665 ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (xops[1]));
666 output_asm_insn (AS1 (pop%L0,%0), xops);
667 output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops);
668 }
669 }
670
671 /* Return 1 if it is appropriate to emit `ret' instructions in the
672 body of a function. Do this only if the epilogue is simple, needing a
673 couple of insns. Prior to reloading, we can't tell how many registers
674 must be saved, so return 0 then.
675
676 If NON_SAVING_SETJMP is defined and true, then it is not possible
677 for the epilogue to be simple, so return 0. This is a special case
678 since NON_SAVING_SETJMP will not cause regs_ever_live to change until
679 final, but jump_optimize may need to know sooner if a `return' is OK. */
680
681 int
682 simple_386_epilogue ()
683 {
684 int regno;
685 int nregs = 0;
686 int reglimit = (frame_pointer_needed
687 ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
688 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
689 || current_function_uses_const_pool);
690
691 #ifdef NON_SAVING_SETJMP
692 if (NON_SAVING_SETJMP && current_function_calls_setjmp)
693 return 0;
694 #endif
695
696 if (! reload_completed)
697 return 0;
698
699 for (regno = reglimit - 1; regno >= 0; regno--)
700 if ((regs_ever_live[regno] && ! call_used_regs[regno])
701 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
702 nregs++;
703
704 return nregs == 0 || ! frame_pointer_needed;
705 }
706
707 /* This function generates the assembly code for function exit.
708 FILE is an stdio stream to output the code to.
709 SIZE is an int: how many units of temporary storage to deallocate. */
710
711 void
712 function_epilogue (file, size)
713 FILE *file;
714 int size;
715 {
716 register int regno;
717 register int nregs, limit;
718 int offset;
719 rtx xops[3];
720 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
721 || current_function_uses_const_pool);
722
723 /* Compute the number of registers to pop */
724
725 limit = (frame_pointer_needed
726 ? FRAME_POINTER_REGNUM
727 : STACK_POINTER_REGNUM);
728
729 nregs = 0;
730
731 for (regno = limit - 1; regno >= 0; regno--)
732 if ((regs_ever_live[regno] && ! call_used_regs[regno])
733 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
734 nregs++;
735
736 /* sp is often unreliable so we must go off the frame pointer,
737 */
738
739 /* In reality, we may not care if sp is unreliable, because we can
740 restore the register relative to the frame pointer. In theory,
741 since each move is the same speed as a pop, and we don't need the
742 leal, this is faster. For now restore multiple registers the old
743 way. */
744
745 offset = -size - (nregs * UNITS_PER_WORD);
746
747 xops[2] = stack_pointer_rtx;
748
749 if (nregs > 1 || ! frame_pointer_needed)
750 {
751 if (frame_pointer_needed)
752 {
753 xops[0] = adj_offsettable_operand (AT_BP (Pmode), offset);
754 output_asm_insn (AS2 (lea%L2,%0,%2), xops);
755 }
756
757 for (regno = 0; regno < limit; regno++)
758 if ((regs_ever_live[regno] && ! call_used_regs[regno])
759 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
760 {
761 xops[0] = gen_rtx (REG, SImode, regno);
762 output_asm_insn ("pop%L0 %0", xops);
763 }
764 }
765 else
766 for (regno = 0; regno < limit; regno++)
767 if ((regs_ever_live[regno] && ! call_used_regs[regno])
768 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
769 {
770 xops[0] = gen_rtx (REG, SImode, regno);
771 xops[1] = adj_offsettable_operand (AT_BP (Pmode), offset);
772 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
773 offset += 4;
774 }
775
776 if (frame_pointer_needed)
777 {
778 /* On i486, mov & pop is faster than "leave". */
779
780 if (TARGET_486)
781 {
782 xops[0] = frame_pointer_rtx;
783 output_asm_insn (AS2 (mov%L2,%0,%2), xops);
784 output_asm_insn ("pop%L0 %0", xops);
785 }
786 else
787 output_asm_insn ("leave", xops);
788 }
789 else if (size)
790 {
791 /* If there is no frame pointer, we must still release the frame. */
792
793 xops[0] = gen_rtx (CONST_INT, VOIDmode, size);
794 output_asm_insn (AS2 (add%L2,%0,%2), xops);
795 }
796
797 if (current_function_pops_args && current_function_args_size)
798 {
799 xops[1] = gen_rtx (CONST_INT, VOIDmode, current_function_pops_args);
800
801 /* i386 can only pop 32K bytes (maybe 64K? Is it signed?). If
802 asked to pop more, pop return address, do explicit add, and jump
803 indirectly to the caller. */
804
805 if (current_function_pops_args >= 32768)
806 {
807 /* ??? Which register to use here? */
808 xops[0] = gen_rtx (REG, SImode, 2);
809 output_asm_insn ("pop%L0 %0", xops);
810 output_asm_insn (AS2 (add%L2,%1,%2), xops);
811 output_asm_insn ("jmp %*%0", xops);
812 }
813 else
814 output_asm_insn ("ret %1", xops);
815 }
816 else
817 output_asm_insn ("ret", xops);
818 }
819 \f
820 /* Print an integer constant expression in assembler syntax. Addition
821 and subtraction are the only arithmetic that may appear in these
822 expressions. FILE is the stdio stream to write to, X is the rtx, and
823 CODE is the operand print code from the output string. */
824
825 static void
826 output_pic_addr_const (file, x, code)
827 FILE *file;
828 rtx x;
829 int code;
830 {
831 char buf[256];
832
833 switch (GET_CODE (x))
834 {
835 case PC:
836 if (flag_pic)
837 putc ('.', file);
838 else
839 abort ();
840 break;
841
842 case SYMBOL_REF:
843 case LABEL_REF:
844 if (GET_CODE (x) == SYMBOL_REF)
845 assemble_name (file, XSTR (x, 0));
846 else
847 {
848 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
849 CODE_LABEL_NUMBER (XEXP (x, 0)));
850 assemble_name (asm_out_file, buf);
851 }
852
853 if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
854 fprintf (file, "@GOTOFF(%%ebx)");
855 else if (code == 'P')
856 fprintf (file, "@PLT");
857 else if (GET_CODE (x) == LABEL_REF || ! SYMBOL_REF_FLAG (x))
858 fprintf (file, "@GOT");
859 else
860 fprintf (file, "@GOTOFF");
861
862 break;
863
864 case CODE_LABEL:
865 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
866 assemble_name (asm_out_file, buf);
867 break;
868
869 case CONST_INT:
870 fprintf (file, "%d", INTVAL (x));
871 break;
872
873 case CONST:
874 /* This used to output parentheses around the expression,
875 but that does not work on the 386 (either ATT or BSD assembler). */
876 output_pic_addr_const (file, XEXP (x, 0), code);
877 break;
878
879 case CONST_DOUBLE:
880 if (GET_MODE (x) == VOIDmode)
881 {
882 /* We can use %d if the number is <32 bits and positive. */
883 if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
884 fprintf (file, "0x%x%08x",
885 CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
886 else
887 fprintf (file, "%d", CONST_DOUBLE_LOW (x));
888 }
889 else
890 /* We can't handle floating point constants;
891 PRINT_OPERAND must handle them. */
892 output_operand_lossage ("floating constant misused");
893 break;
894
895 case PLUS:
896 /* Some assemblers need integer constants to appear last (eg masm). */
897 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
898 {
899 output_pic_addr_const (file, XEXP (x, 1), code);
900 if (INTVAL (XEXP (x, 0)) >= 0)
901 fprintf (file, "+");
902 output_pic_addr_const (file, XEXP (x, 0), code);
903 }
904 else
905 {
906 output_pic_addr_const (file, XEXP (x, 0), code);
907 if (INTVAL (XEXP (x, 1)) >= 0)
908 fprintf (file, "+");
909 output_pic_addr_const (file, XEXP (x, 1), code);
910 }
911 break;
912
913 case MINUS:
914 output_pic_addr_const (file, XEXP (x, 0), code);
915 fprintf (file, "-");
916 output_pic_addr_const (file, XEXP (x, 1), code);
917 break;
918
919 default:
920 output_operand_lossage ("invalid expression as operand");
921 }
922 }
923 \f
924 /* Print the name of a register based on its machine mode and number.
925 If CODE is 'w', pretend the mode is HImode.
926 If CODE is 'b', pretend the mode is QImode.
927 If CODE is 'k', pretend the mode is SImode.
928 If CODE is 'h', pretend the reg is the `high' byte register.
929 If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op. */
930
931 #define PRINT_REG(X, CODE, FILE) \
932 do { if (REGNO (X) == ARG_POINTER_REGNUM) \
933 abort (); \
934 fprintf (FILE, "%s", RP); \
935 switch ((CODE == 'w' ? 2 \
936 : CODE == 'b' ? 1 \
937 : CODE == 'k' ? 4 \
938 : CODE == 'y' ? 3 \
939 : CODE == 'h' ? 0 \
940 : GET_MODE_SIZE (GET_MODE (X)))) \
941 { \
942 case 3: \
943 if (STACK_TOP_P (X)) \
944 { \
945 fputs ("st(0)", FILE); \
946 break; \
947 } \
948 case 4: \
949 case 8: \
950 if (!FP_REG_P (X)) fputs ("e", FILE); \
951 case 2: \
952 fputs (hi_reg_name[REGNO (X)], FILE); \
953 break; \
954 case 1: \
955 fputs (qi_reg_name[REGNO (X)], FILE); \
956 break; \
957 case 0: \
958 fputs (qi_high_reg_name[REGNO (X)], FILE); \
959 break; \
960 } \
961 } while (0)
962
963 /* Meaning of CODE:
964 f -- float insn (print a CONST_DOUBLE as a float rather than in hex).
965 D,L,W,B,Q,S -- print the opcode suffix for specified size of operand.
966 R -- print the prefix for register names.
967 z -- print the opcode suffix for the size of the current operand.
968 * -- print a star (in certain assembler syntax)
969 w -- print the operand as if it's a "word" (HImode) even if it isn't.
970 c -- don't print special prefixes before constant operands.
971 */
972
973 void
974 print_operand (file, x, code)
975 FILE *file;
976 rtx x;
977 int code;
978 {
979 if (code)
980 {
981 switch (code)
982 {
983 case '*':
984 if (USE_STAR)
985 putc ('*', file);
986 return;
987
988 case 'L':
989 PUT_OP_SIZE (code, 'l', file);
990 return;
991
992 case 'W':
993 PUT_OP_SIZE (code, 'w', file);
994 return;
995
996 case 'B':
997 PUT_OP_SIZE (code, 'b', file);
998 return;
999
1000 case 'Q':
1001 PUT_OP_SIZE (code, 'l', file);
1002 return;
1003
1004 case 'S':
1005 PUT_OP_SIZE (code, 's', file);
1006 return;
1007
1008 case 'z':
1009 /* 387 opcodes don't get size suffixes if the operands are
1010 registers. */
1011
1012 if (STACK_REG_P (x))
1013 return;
1014
1015 /* this is the size of op from size of operand */
1016 switch (GET_MODE_SIZE (GET_MODE (x)))
1017 {
1018 case 1:
1019 PUT_OP_SIZE ('B', 'b', file);
1020 return;
1021
1022 case 2:
1023 PUT_OP_SIZE ('W', 'w', file);
1024 return;
1025
1026 case 4:
1027 if (GET_MODE (x) == SFmode)
1028 {
1029 PUT_OP_SIZE ('S', 's', file);
1030 return;
1031 }
1032 else
1033 PUT_OP_SIZE ('L', 'l', file);
1034 return;
1035
1036 case 8:
1037 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
1038 {
1039 #ifdef GAS_MNEMONICS
1040 PUT_OP_SIZE ('Q', 'q', file);
1041 return;
1042 #else
1043 PUT_OP_SIZE ('Q', 'l', file); /* Fall through */
1044 #endif
1045 }
1046
1047 PUT_OP_SIZE ('Q', 'l', file);
1048 return;
1049 }
1050
1051 case 'b':
1052 case 'w':
1053 case 'k':
1054 case 'h':
1055 case 'y':
1056 case 'P':
1057 break;
1058
1059 default:
1060 abort ();
1061 }
1062 }
1063 if (GET_CODE (x) == REG)
1064 {
1065 PRINT_REG (x, code, file);
1066 }
1067 else if (GET_CODE (x) == MEM)
1068 {
1069 PRINT_PTR (x, file);
1070 if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
1071 {
1072 if (flag_pic)
1073 output_pic_addr_const (file, XEXP (x, 0), code);
1074 else
1075 output_addr_const (file, XEXP (x, 0));
1076 }
1077 else
1078 output_address (XEXP (x, 0));
1079 }
1080 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
1081 {
1082 union { double d; int i[2]; } u;
1083 union { float f; int i; } u1;
1084 u.i[0] = CONST_DOUBLE_LOW (x);
1085 u.i[1] = CONST_DOUBLE_HIGH (x);
1086 u1.f = u.d;
1087 PRINT_IMMED_PREFIX (file);
1088 fprintf (file, "0x%x", u1.i);
1089 }
1090 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
1091 {
1092 union { double d; int i[2]; } u;
1093 u.i[0] = CONST_DOUBLE_LOW (x);
1094 u.i[1] = CONST_DOUBLE_HIGH (x);
1095 fprintf (file, "%.22e", u.d);
1096 }
1097 else
1098 {
1099 if (code != 'P')
1100 {
1101 if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
1102 PRINT_IMMED_PREFIX (file);
1103 else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
1104 || GET_CODE (x) == LABEL_REF)
1105 PRINT_OFFSET_PREFIX (file);
1106 }
1107 if (flag_pic)
1108 output_pic_addr_const (file, x, code);
1109 else
1110 output_addr_const (file, x);
1111 }
1112 }
1113 \f
1114 /* Print a memory operand whose address is ADDR. */
1115
1116 void
1117 print_operand_address (file, addr)
1118 FILE *file;
1119 register rtx addr;
1120 {
1121 register rtx reg1, reg2, breg, ireg;
1122 rtx offset;
1123
1124 switch (GET_CODE (addr))
1125 {
1126 case REG:
1127 ADDR_BEG (file);
1128 fprintf (file, "%se", RP);
1129 fputs (hi_reg_name[REGNO (addr)], file);
1130 ADDR_END (file);
1131 break;
1132
1133 case PLUS:
1134 reg1 = 0;
1135 reg2 = 0;
1136 ireg = 0;
1137 breg = 0;
1138 offset = 0;
1139 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
1140 {
1141 offset = XEXP (addr, 0);
1142 addr = XEXP (addr, 1);
1143 }
1144 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
1145 {
1146 offset = XEXP (addr, 1);
1147 addr = XEXP (addr, 0);
1148 }
1149 if (GET_CODE (addr) != PLUS) ;
1150 else if (GET_CODE (XEXP (addr, 0)) == MULT)
1151 {
1152 reg1 = XEXP (addr, 0);
1153 addr = XEXP (addr, 1);
1154 }
1155 else if (GET_CODE (XEXP (addr, 1)) == MULT)
1156 {
1157 reg1 = XEXP (addr, 1);
1158 addr = XEXP (addr, 0);
1159 }
1160 else if (GET_CODE (XEXP (addr, 0)) == REG)
1161 {
1162 reg1 = XEXP (addr, 0);
1163 addr = XEXP (addr, 1);
1164 }
1165 else if (GET_CODE (XEXP (addr, 1)) == REG)
1166 {
1167 reg1 = XEXP (addr, 1);
1168 addr = XEXP (addr, 0);
1169 }
1170 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
1171 {
1172 if (reg1 == 0) reg1 = addr;
1173 else reg2 = addr;
1174 addr = 0;
1175 }
1176 if (offset != 0)
1177 {
1178 if (addr != 0) abort ();
1179 addr = offset;
1180 }
1181 if ((reg1 && GET_CODE (reg1) == MULT)
1182 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
1183 {
1184 breg = reg2;
1185 ireg = reg1;
1186 }
1187 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
1188 {
1189 breg = reg1;
1190 ireg = reg2;
1191 }
1192
1193 if (ireg != 0 || breg != 0)
1194 {
1195 int scale = 1;
1196
1197 if (addr != 0)
1198 {
1199 if (GET_CODE (addr) == LABEL_REF)
1200 output_asm_label (addr);
1201 else
1202 {
1203 if (flag_pic)
1204 output_pic_addr_const (file, addr, 0);
1205 else
1206 output_addr_const (file, addr);
1207 }
1208 }
1209
1210 if (ireg != 0 && GET_CODE (ireg) == MULT)
1211 {
1212 scale = INTVAL (XEXP (ireg, 1));
1213 ireg = XEXP (ireg, 0);
1214 }
1215
1216 /* The stack pointer can only appear as a base register,
1217 never an index register, so exchange the regs if it is wrong. */
1218
1219 if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM)
1220 {
1221 rtx tmp;
1222
1223 tmp = breg;
1224 breg = ireg;
1225 ireg = tmp;
1226 }
1227
1228 /* output breg+ireg*scale */
1229 PRINT_B_I_S (breg, ireg, scale, file);
1230 break;
1231 }
1232
1233 case MULT:
1234 {
1235 int scale;
1236 if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
1237 {
1238 scale = INTVAL (XEXP (addr, 0));
1239 ireg = XEXP (addr, 1);
1240 }
1241 else
1242 {
1243 scale = INTVAL (XEXP (addr, 1));
1244 ireg = XEXP (addr, 0);
1245 }
1246 output_addr_const (file, const0_rtx);
1247 PRINT_B_I_S ((rtx) 0, ireg, scale, file);
1248 }
1249 break;
1250
1251 default:
1252 if (GET_CODE (addr) == CONST_INT
1253 && INTVAL (addr) < 0x8000
1254 && INTVAL (addr) >= -0x8000)
1255 fprintf (file, "%d", INTVAL (addr));
1256 else
1257 {
1258 if (flag_pic)
1259 output_pic_addr_const (file, addr, 0);
1260 else
1261 output_addr_const (file, addr);
1262 }
1263 }
1264 }
1265 \f
1266 /* Set the cc_status for the results of an insn whose pattern is EXP.
1267 On the 80386, we assume that only test and compare insns, as well
1268 as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, ASHIFT, LSHIFT,
1269 ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
1270 Also, we assume that jumps, moves and sCOND don't affect the condition
1271 codes. All else clobbers the condition codes, by assumption.
1272
1273 We assume that ALL integer add, minus, etc. instructions effect the
1274 condition codes. This MUST be consistent with i386.md.
1275
1276 We don't record any float test or compare - the redundant test &
1277 compare check in final.c does not handle stack-like regs correctly. */
1278
1279 void
1280 notice_update_cc (exp)
1281 rtx exp;
1282 {
1283 if (GET_CODE (exp) == SET)
1284 {
1285 /* Jumps do not alter the cc's. */
1286 if (SET_DEST (exp) == pc_rtx)
1287 return;
1288 /* Moving register or memory into a register:
1289 it doesn't alter the cc's, but it might invalidate
1290 the RTX's which we remember the cc's came from.
1291 (Note that moving a constant 0 or 1 MAY set the cc's). */
1292 if (REG_P (SET_DEST (exp))
1293 && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM
1294 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
1295 {
1296 if (cc_status.value1
1297 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
1298 cc_status.value1 = 0;
1299 if (cc_status.value2
1300 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
1301 cc_status.value2 = 0;
1302 return;
1303 }
1304 /* Moving register into memory doesn't alter the cc's.
1305 It may invalidate the RTX's which we remember the cc's came from. */
1306 if (GET_CODE (SET_DEST (exp)) == MEM
1307 && (REG_P (SET_SRC (exp))
1308 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
1309 {
1310 if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
1311 cc_status.value1 = 0;
1312 if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
1313 cc_status.value2 = 0;
1314 return;
1315 }
1316 /* Function calls clobber the cc's. */
1317 else if (GET_CODE (SET_SRC (exp)) == CALL)
1318 {
1319 CC_STATUS_INIT;
1320 return;
1321 }
1322 /* Tests and compares set the cc's in predictable ways. */
1323 else if (SET_DEST (exp) == cc0_rtx)
1324 {
1325 CC_STATUS_INIT;
1326 cc_status.value1 = SET_SRC (exp);
1327 return;
1328 }
1329 /* Certain instructions effect the condition codes. */
1330 else if (GET_MODE (SET_SRC (exp)) == SImode
1331 || GET_MODE (SET_SRC (exp)) == HImode
1332 || GET_MODE (SET_SRC (exp)) == QImode)
1333 switch (GET_CODE (SET_SRC (exp)))
1334 {
1335 case ASHIFTRT: case LSHIFTRT:
1336 case ASHIFT: case LSHIFT:
1337 /* Shifts on the 386 don't set the condition codes if the
1338 shift count is zero. */
1339 if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
1340 {
1341 CC_STATUS_INIT;
1342 break;
1343 }
1344 /* We assume that the CONST_INT is non-zero (this rtx would
1345 have been deleted if it were zero. */
1346
1347 case PLUS: case MINUS: case NEG:
1348 case AND: case IOR: case XOR:
1349 cc_status.flags = CC_NO_OVERFLOW;
1350 cc_status.value1 = SET_SRC (exp);
1351 cc_status.value2 = SET_DEST (exp);
1352 break;
1353
1354 default:
1355 CC_STATUS_INIT;
1356 }
1357 else
1358 {
1359 CC_STATUS_INIT;
1360 }
1361 }
1362 else if (GET_CODE (exp) == PARALLEL
1363 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
1364 {
1365 if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
1366 return;
1367 if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
1368 {
1369 CC_STATUS_INIT;
1370 if (! stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
1371 cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
1372
1373 cc_status.flags |= CC_IN_80387;
1374 return;
1375 }
1376 CC_STATUS_INIT;
1377 }
1378 else
1379 {
1380 CC_STATUS_INIT;
1381 }
1382 }
1383 \f
1384 /* Split one or more DImode RTL references into pairs of SImode
1385 references. The RTL can be REG, offsettable MEM, integer constant, or
1386 CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to
1387 split and "num" is its length. lo_half and hi_half are output arrays
1388 that parallel "operands". */
1389
1390 void
1391 split_di (operands, num, lo_half, hi_half)
1392 rtx operands[];
1393 int num;
1394 rtx lo_half[], hi_half[];
1395 {
1396 while (num--)
1397 {
1398 if (GET_CODE (operands[num]) == REG)
1399 {
1400 lo_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]));
1401 hi_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]) + 1);
1402 }
1403 else if (CONSTANT_P (operands[num]))
1404 {
1405 split_double (operands[num], &lo_half[num], &hi_half[num]);
1406 }
1407 else if (offsettable_memref_p (operands[num]))
1408 {
1409 lo_half[num] = operands[num];
1410 hi_half[num] = adj_offsettable_operand (operands[num], 4);
1411 }
1412 else
1413 abort();
1414 }
1415 }
1416 \f
1417 /* Return 1 if this is a valid binary operation on a 387.
1418 OP is the expression matched, and MODE is its mode. */
1419
1420 int
1421 binary_387_op (op, mode)
1422 register rtx op;
1423 enum machine_mode mode;
1424 {
1425 if (mode != VOIDmode && mode != GET_MODE (op))
1426 return 0;
1427
1428 switch (GET_CODE (op))
1429 {
1430 case PLUS:
1431 case MINUS:
1432 case MULT:
1433 case DIV:
1434 return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
1435
1436 default:
1437 return 0;
1438 }
1439 }
1440
1441 /* Return 1 if this is a valid conversion operation on a 387.
1442 OP is the expression matched, and MODE is its mode. */
1443
1444 int
1445 convert_387_op (op, mode)
1446 register rtx op;
1447 enum machine_mode mode;
1448 {
1449 if (mode != VOIDmode && mode != GET_MODE (op))
1450 return 0;
1451
1452 switch (GET_CODE (op))
1453 {
1454 case FLOAT:
1455 return GET_MODE (XEXP (op, 0)) == SImode;
1456
1457 case FLOAT_EXTEND:
1458 return mode == DFmode && GET_MODE (XEXP (op, 0)) == SFmode;
1459
1460 default:
1461 return 0;
1462 }
1463 }
1464
1465 /* Return 1 if this is a valid "float from int" operation on a 387.
1466 OP is the expression matched, and MODE is its mode. */
1467
1468 int
1469 float_op (op, mode)
1470 register rtx op;
1471 enum machine_mode mode;
1472 {
1473 if (mode != VOIDmode && mode != GET_MODE (op))
1474 return 0;
1475
1476 return GET_CODE (op) == FLOAT
1477 && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
1478 }
1479
1480 /* Return 1 if this is a valid shift or rotate operation on a 386.
1481 OP is the expression matched, and MODE is its mode. */
1482
1483 int
1484 shift_op (op, mode)
1485 register rtx op;
1486 enum machine_mode mode;
1487 {
1488 rtx operand = XEXP (op, 0);
1489
1490 if (mode != VOIDmode && mode != GET_MODE (op))
1491 return 0;
1492
1493 if (GET_MODE (operand) != GET_MODE (op)
1494 || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
1495 return 0;
1496
1497 return (GET_CODE (op) == ASHIFT
1498 || GET_CODE (op) == ASHIFTRT
1499 || GET_CODE (op) == LSHIFTRT
1500 || GET_CODE (op) == ROTATE
1501 || GET_CODE (op) == ROTATERT);
1502 }
1503 \f
1504 /* Output code to perform a 387 binary operation in INSN, one of PLUS,
1505 MINUS, MULT or DIV. OPERANDS are the insn operands, where operands[3]
1506 is the expression of the binary operation. The output may either be
1507 emitted here, or returned to the caller, like all output_* functions.
1508
1509 There is no guarantee that the operands are the same mode, as they
1510 might be within FLOAT or FLOAT_EXTEND expressions. */
1511
1512 char *
1513 output_387_binary_op (insn, operands)
1514 rtx insn;
1515 rtx *operands;
1516 {
1517 rtx temp;
1518 char *base_op;
1519 static char buf[100];
1520
1521 switch (GET_CODE (operands[3]))
1522 {
1523 case PLUS:
1524 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
1525 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
1526 base_op = "fiadd";
1527 else
1528 base_op = "fadd";
1529 break;
1530
1531 case MINUS:
1532 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
1533 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
1534 base_op = "fisub";
1535 else
1536 base_op = "fsub";
1537 break;
1538
1539 case MULT:
1540 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
1541 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
1542 base_op = "fimul";
1543 else
1544 base_op = "fmul";
1545 break;
1546
1547 case DIV:
1548 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
1549 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
1550 base_op = "fidiv";
1551 else
1552 base_op = "fdiv";
1553 break;
1554
1555 default:
1556 abort ();
1557 }
1558
1559 strcpy (buf, base_op);
1560
1561 switch (GET_CODE (operands[3]))
1562 {
1563 case MULT:
1564 case PLUS:
1565 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
1566 {
1567 temp = operands[2];
1568 operands[2] = operands[1];
1569 operands[1] = temp;
1570 }
1571
1572 if (GET_CODE (operands[2]) == MEM)
1573 return strcat (buf, AS1 (%z2,%2));
1574
1575 if (NON_STACK_REG_P (operands[1]))
1576 {
1577 output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
1578 RET;
1579 }
1580 else if (NON_STACK_REG_P (operands[2]))
1581 {
1582 output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
1583 RET;
1584 }
1585
1586 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
1587 return strcat (buf, AS2 (p,%2,%0));
1588
1589 if (STACK_TOP_P (operands[0]))
1590 return strcat (buf, AS2 (,%y2,%0));
1591 else
1592 return strcat (buf, AS2 (,%2,%0));
1593
1594 case MINUS:
1595 case DIV:
1596 if (GET_CODE (operands[1]) == MEM)
1597 return strcat (buf, AS1 (r%z1,%1));
1598
1599 if (GET_CODE (operands[2]) == MEM)
1600 return strcat (buf, AS1 (%z2,%2));
1601
1602 if (NON_STACK_REG_P (operands[1]))
1603 {
1604 output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1)));
1605 RET;
1606 }
1607 else if (NON_STACK_REG_P (operands[2]))
1608 {
1609 output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
1610 RET;
1611 }
1612
1613 if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
1614 abort ();
1615
1616 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
1617 return strcat (buf, AS2 (rp,%2,%0));
1618
1619 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1620 return strcat (buf, AS2 (p,%1,%0));
1621
1622 if (STACK_TOP_P (operands[0]))
1623 {
1624 if (STACK_TOP_P (operands[1]))
1625 return strcat (buf, AS2 (,%y2,%0));
1626 else
1627 return strcat (buf, AS2 (r,%y1,%0));
1628 }
1629 else if (STACK_TOP_P (operands[1]))
1630 return strcat (buf, AS2 (,%1,%0));
1631 else
1632 return strcat (buf, AS2 (r,%2,%0));
1633
1634 default:
1635 abort ();
1636 }
1637 }
1638 \f
1639 /* Output code for INSN to convert a float to a signed int. OPERANDS
1640 are the insn operands. The output may be SFmode or DFmode and the
1641 input operand may be SImode or DImode. As a special case, make sure
1642 that the 387 stack top dies if the output mode is DImode, because the
1643 hardware requires this. */
1644
1645 char *
1646 output_fix_trunc (insn, operands)
1647 rtx insn;
1648 rtx *operands;
1649 {
1650 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1651 rtx xops[6];
1652
1653 if (! STACK_TOP_P (operands[1]) ||
1654 (GET_MODE (operands[0]) == DImode && ! stack_top_dies))
1655 abort ();
1656
1657 xops[0] = stack_pointer_rtx;
1658 xops[1] = AT_SP (SImode);
1659 xops[2] = adj_offsettable_operand (xops[1], 2);
1660 xops[3] = gen_rtx (CONST_INT, VOIDmode, 4);
1661 xops[4] = gen_rtx (CONST_INT, VOIDmode, 0xc00);
1662 xops[5] = operands[2];
1663
1664 output_asm_insn (AS2 (sub%L0,%3,%0), xops);
1665 output_asm_insn (AS1 (fnstc%W5,%1), xops);
1666 output_asm_insn (AS2 (mov%W5,%1,%5), xops);
1667 output_asm_insn (AS2 (or%W5,%4,%5), xops);
1668 output_asm_insn (AS2 (mov%W5,%5,%2), xops);
1669 output_asm_insn (AS1 (fldc%W5,%2), xops);
1670
1671 if (NON_STACK_REG_P (operands[0]))
1672 output_to_reg (operands[0], stack_top_dies);
1673 else if (GET_CODE (operands[0]) == MEM)
1674 {
1675 /* If frame pointer elimination is being done, the MEM reference
1676 might be an index off of the stack pointer. In that case,
1677 since we have already adjusted %esp above, adjust the operand
1678 address so it points where it should. */
1679
1680 if (! frame_pointer_needed
1681 && reg_mentioned_p (stack_pointer_rtx, operands[0]))
1682 operands[0] = adj_offsettable_operand (operands[0], 4);
1683
1684 if (stack_top_dies)
1685 output_asm_insn (AS1 (fistp%z0,%0), operands);
1686 else
1687 output_asm_insn (AS1 (fist%z0,%0), operands);
1688 }
1689 else
1690 abort ();
1691
1692 output_asm_insn (AS1 (fldc%W5,%1), xops);
1693 output_asm_insn (AS2 (add%L0,%3,%0), xops);
1694
1695 RET;
1696 }
1697 \f
1698 /* Output code for INSN to compare OPERANDS. The two operands might
1699 not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
1700 expression. If the compare is in mode CCFPEQmode, use an opcode that
1701 will not fault if a qNaN is present. */
1702
1703 char *
1704 output_float_compare (insn, operands)
1705 rtx insn;
1706 rtx *operands;
1707 {
1708 int stack_top_dies;
1709 rtx body = XVECEXP (PATTERN (insn), 0, 0);
1710 int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
1711
1712 if (! STACK_TOP_P (operands[0]))
1713 abort ();
1714
1715 stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1716
1717 if (STACK_REG_P (operands[1])
1718 && stack_top_dies
1719 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
1720 && REGNO (operands[1]) != FIRST_STACK_REG)
1721 {
1722 /* If both the top of the 387 stack dies, and the other operand
1723 is also a stack register that dies, then this must be a
1724 `fcompp' float compare */
1725
1726 if (unordered_compare)
1727 output_asm_insn ("fucompp", operands);
1728 else
1729 output_asm_insn ("fcompp", operands);
1730 }
1731 else
1732 {
1733 static char buf[100];
1734
1735 /* Decide if this is the integer or float compare opcode, or the
1736 unordered float compare. */
1737
1738 if (unordered_compare)
1739 strcpy (buf, "fucom");
1740 else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT)
1741 strcpy (buf, "fcom");
1742 else
1743 strcpy (buf, "ficom");
1744
1745 /* Modify the opcode if the 387 stack is to be popped. */
1746
1747 if (stack_top_dies)
1748 strcat (buf, "p");
1749
1750 if (NON_STACK_REG_P (operands[1]))
1751 output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
1752 else
1753 output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
1754 }
1755
1756 /* Now retrieve the condition code. */
1757
1758 return output_fp_cc0_set (insn);
1759 }
1760 \f
1761 /* Output opcodes to transfer the results of FP compare or test INSN
1762 from the FPU to the CPU flags. If TARGET_IEEE_FP, ensure that if the
1763 result of the compare or test is unordered, no comparison operator
1764 succeeds except NE. Return an output template, if any. */
1765
1766 char *
1767 output_fp_cc0_set (insn)
1768 rtx insn;
1769 {
1770 rtx xops[3];
1771 rtx unordered_label;
1772 rtx next;
1773 enum rtx_code code;
1774
1775 xops[0] = gen_rtx (REG, HImode, 0);
1776 output_asm_insn (AS1 (fnsts%W0,%0), xops);
1777
1778 if (! TARGET_IEEE_FP)
1779 return "sahf";
1780
1781 next = next_cc0_user (insn);
1782
1783 if (GET_CODE (next) == JUMP_INSN
1784 && GET_CODE (PATTERN (next)) == SET
1785 && SET_DEST (PATTERN (next)) == pc_rtx
1786 && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
1787 {
1788 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
1789 }
1790 else if (GET_CODE (PATTERN (next)) == SET)
1791 {
1792 code = GET_CODE (SET_SRC (PATTERN (next)));
1793 }
1794 else
1795 abort ();
1796
1797 xops[0] = gen_rtx (REG, QImode, 0);
1798
1799 switch (code)
1800 {
1801 case GT:
1802 xops[1] = gen_rtx (CONST_INT, VOIDmode, 0x45);
1803 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1804 /* je label */
1805 break;
1806
1807 case LT:
1808 xops[1] = gen_rtx (CONST_INT, VOIDmode, 0x45);
1809 xops[2] = gen_rtx (CONST_INT, VOIDmode, 0x01);
1810 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1811 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
1812 /* je label */
1813 break;
1814
1815 case GE:
1816 xops[1] = gen_rtx (CONST_INT, VOIDmode, 0x05);
1817 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1818 /* je label */
1819 break;
1820
1821 case LE:
1822 xops[1] = gen_rtx (CONST_INT, VOIDmode, 0x45);
1823 xops[2] = gen_rtx (CONST_INT, VOIDmode, 0x40);
1824 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1825 output_asm_insn (AS1 (dec%B0,%h0), xops);
1826 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
1827 /* jb label */
1828 break;
1829
1830 case EQ:
1831 xops[1] = gen_rtx (CONST_INT, VOIDmode, 0x45);
1832 xops[2] = gen_rtx (CONST_INT, VOIDmode, 0x40);
1833 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1834 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
1835 /* je label */
1836 break;
1837
1838 case NE:
1839 xops[1] = gen_rtx (CONST_INT, VOIDmode, 0x44);
1840 xops[2] = gen_rtx (CONST_INT, VOIDmode, 0x40);
1841 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1842 output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
1843 /* jne label */
1844 break;
1845
1846 case GTU:
1847 case LTU:
1848 case GEU:
1849 case LEU:
1850 default:
1851 abort ();
1852 }
1853 RET;
1854 }
1855 \f
1856 #ifdef HANDLE_PRAGMA
1857
1858 /* When structure field packing is in effect, this variable is the
1859 number of bits to use as the maximum alignment. When packing is not
1860 in effect, this is zero. */
1861
1862 int maximum_field_alignment = 0;
1863
1864 /* Handle a pragma directive. HANDLE_PRAGMA conspires to parse the
1865 input following #pragma into tokens based on yylex. TOKEN is the
1866 current token, and STRING is its printable form. */
1867
1868 void
1869 handle_pragma_token (string, token)
1870 char *string;
1871 tree token;
1872 {
1873 static enum pragma_state
1874 {
1875 ps_start,
1876 ps_done,
1877 ps_bad,
1878 ps_weak,
1879 ps_name,
1880 ps_equals,
1881 ps_value,
1882 ps_pack,
1883 ps_left,
1884 ps_align,
1885 ps_right
1886 } state = ps_start, type;
1887 static char *name;
1888 static char *value;
1889 static int align;
1890
1891 if (string == 0)
1892 {
1893 if (type == ps_pack)
1894 {
1895 if (state == ps_right)
1896 maximum_field_alignment = align * 8;
1897 else
1898 warning ("ignoring malformed #pragma pack( [ 1 | 2 | 4 ] )");
1899 }
1900 #ifdef WEAK_ASM_OP
1901 else if (type == ps_weak)
1902 {
1903 if (state == ps_name || state == ps_value)
1904 {
1905 fprintf (asm_out_file, "\t%s\t", WEAK_ASM_OP);
1906 ASM_OUTPUT_LABELREF (asm_out_file, name);
1907 fputc ('\n', asm_out_file);
1908 if (state == ps_value)
1909 {
1910 fprintf (asm_out_file, "\t%s\t", SET_ASM_OP);
1911 ASM_OUTPUT_LABELREF (asm_out_file, name);
1912 fputc (',', asm_out_file);
1913 ASM_OUTPUT_LABELREF (asm_out_file, value);
1914 fputc ('\n', asm_out_file);
1915 }
1916 }
1917 else if (! (state == ps_done || state == ps_start))
1918 warning ("ignoring malformed #pragma weak symbol [=value]");
1919 }
1920 #endif /* WEAK_ASM_OP */
1921
1922 type = state = ps_start;
1923 return;
1924 }
1925
1926 switch (state)
1927 {
1928 case ps_start:
1929 if (token && TREE_CODE (token) == IDENTIFIER_NODE)
1930 {
1931 if (strcmp (IDENTIFIER_POINTER (token), "pack") == 0)
1932 type = state = ps_pack;
1933 #ifdef WEAK_ASM_OP
1934 else if (strcmp (IDENTIFIER_POINTER (token), "weak") == 0)
1935 type = state = ps_weak;
1936 #endif
1937 else
1938 type = state = ps_done;
1939 }
1940 else
1941 type = state = ps_done;
1942 break;
1943
1944 #ifdef WEAK_ASM_OP
1945 case ps_weak:
1946 if (token && TREE_CODE (token) == IDENTIFIER_NODE)
1947 {
1948 name = IDENTIFIER_POINTER (token);
1949 state = ps_name;
1950 }
1951 else
1952 state = ps_bad;
1953 break;
1954
1955 case ps_name:
1956 state = (strcmp (string, "=") ? ps_bad : ps_equals);
1957 break;
1958
1959 case ps_equals:
1960 if (token && TREE_CODE (token) == IDENTIFIER_NODE)
1961 {
1962 value = IDENTIFIER_POINTER (token);
1963 state = ps_value;
1964 }
1965 else
1966 state = ps_bad;
1967 break;
1968
1969 case ps_value:
1970 state = ps_bad;
1971 break;
1972 #endif /* WEAK_ASM_OP */
1973
1974 case ps_pack:
1975 if (strcmp (string, "(") == 0)
1976 state = ps_left;
1977 else
1978 state = ps_bad;
1979 break;
1980
1981 case ps_left:
1982 if (token && TREE_CODE (token) == INTEGER_CST
1983 && TREE_INT_CST_HIGH (token) == 0)
1984 switch (TREE_INT_CST_LOW (token))
1985 {
1986 case 1:
1987 case 2:
1988 case 4:
1989 align = TREE_INT_CST_LOW (token);
1990 state = ps_align;
1991 break;
1992
1993 default:
1994 state = ps_bad;
1995 }
1996 else if (! token && strcmp (string, ")") == 0)
1997 {
1998 align = 0;
1999 state = ps_right;
2000 }
2001 else
2002 state = ps_bad;
2003 break;
2004
2005 case ps_align:
2006 if (strcmp (string, ")") == 0)
2007 state = ps_right;
2008 else
2009 state = ps_bad;
2010 break;
2011
2012 case ps_right:
2013 state = ps_bad;
2014 break;
2015
2016 case ps_bad:
2017 case ps_done:
2018 break;
2019
2020 default:
2021 abort ();
2022 }
2023 }
2024 #endif /* HANDLE_PRAGMA */
This page took 0.135406 seconds and 6 git commands to generate.