OSDN Git Service

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