OSDN Git Service

(hi_reg_name, qi_reg_name, qi_high_reg_name): Not static.
[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 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 char *hi_reg_name[] = HI_REGISTER_NAMES;
53 char *qi_reg_name[] = QI_REGISTER_NAMES;
54 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_INT (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_INT (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_INT (-n);
227       output_asm_insn (AS2 (sub%L0,%0,%1), xops);
228     }
229   else if (n > 0)
230     {
231       xops[0] = GEN_INT (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_INT (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),
585                                      base == reg ? NULL_RTX : reg);
586
587       if (GET_CODE (addr) == CONST_INT)
588         return plus_constant (base, INTVAL (addr));
589
590       if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
591         {
592           base = gen_rtx (PLUS, Pmode, base, XEXP (addr, 0));
593           addr = XEXP (addr, 1);
594         }
595         return gen_rtx (PLUS, Pmode, base, addr);
596     }
597   return new;
598 }
599 \f
600 /* Emit insns to move operands[1] into operands[0].  */
601
602 void
603 emit_pic_move (operands, mode)
604      rtx *operands;
605      enum machine_mode mode;
606 {
607   rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
608
609   if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
610     operands[1] = (rtx) force_reg (SImode, operands[1]);
611   else
612     operands[1] = legitimize_pic_address (operands[1], temp);
613 }
614 \f
615 /* This function generates the assembly code for function entry.
616    FILE is an stdio stream to output the code to.
617    SIZE is an int: how many units of temporary storage to allocate. */
618
619 void
620 function_prologue (file, size)
621      FILE *file;
622      int size;
623 {
624   register int regno;
625   int limit;
626   rtx xops[4];
627   int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
628                                   || current_function_uses_const_pool);
629
630   xops[0] = stack_pointer_rtx;
631   xops[1] = frame_pointer_rtx;
632   xops[2] = GEN_INT (size);
633   if (frame_pointer_needed)
634     {
635       output_asm_insn ("push%L1 %1", xops);
636       output_asm_insn (AS2 (mov%L0,%0,%1), xops);
637     }
638
639   if (size)
640     output_asm_insn (AS2 (sub%L0,%2,%0), xops);
641
642   /* Note If use enter it is NOT reversed args.
643      This one is not reversed from intel!!
644      I think enter is slower.  Also sdb doesn't like it.
645      But if you want it the code is:
646      {
647      xops[3] = const0_rtx;
648      output_asm_insn ("enter %2,%3", xops);
649      }
650      */
651   limit = (frame_pointer_needed ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
652   for (regno = limit - 1; regno >= 0; regno--)
653     if ((regs_ever_live[regno] && ! call_used_regs[regno])
654         || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
655       {
656         xops[0] = gen_rtx (REG, SImode, regno);
657         output_asm_insn ("push%L0 %0", xops);
658       }
659
660   if (pic_reg_used)
661     {
662       xops[0] = pic_offset_table_rtx;
663       xops[1] = (rtx) gen_label_rtx ();
664
665       output_asm_insn (AS1 (call,%P1), xops);
666       ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (xops[1]));
667       output_asm_insn (AS1 (pop%L0,%0), xops);
668       output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops);
669     }
670 }
671
672 /* Return 1 if it is appropriate to emit `ret' instructions in the
673    body of a function.  Do this only if the epilogue is simple, needing a
674    couple of insns.  Prior to reloading, we can't tell how many registers
675    must be saved, so return 0 then.
676
677    If NON_SAVING_SETJMP is defined and true, then it is not possible
678    for the epilogue to be simple, so return 0.  This is a special case
679    since NON_SAVING_SETJMP will not cause regs_ever_live to change until
680    final, but jump_optimize may need to know sooner if a `return' is OK.  */
681
682 int
683 simple_386_epilogue ()
684 {
685   int regno;
686   int nregs = 0;
687   int reglimit = (frame_pointer_needed
688                   ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
689   int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
690                                   || current_function_uses_const_pool);
691
692 #ifdef NON_SAVING_SETJMP
693   if (NON_SAVING_SETJMP && current_function_calls_setjmp)
694     return 0;
695 #endif
696
697   if (! reload_completed)
698     return 0;
699
700   for (regno = reglimit - 1; regno >= 0; regno--)
701     if ((regs_ever_live[regno] && ! call_used_regs[regno])
702         || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
703       nregs++;
704
705   return nregs == 0 || ! frame_pointer_needed;
706 }
707
708 /* This function generates the assembly code for function exit.
709    FILE is an stdio stream to output the code to.
710    SIZE is an int: how many units of temporary storage to deallocate. */
711
712 void
713 function_epilogue (file, size)
714      FILE *file;
715      int size;
716 {
717   register int regno;
718   register int nregs, limit;
719   int offset;
720   rtx xops[3];
721   int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
722                                   || current_function_uses_const_pool);
723
724   /* Compute the number of registers to pop */
725
726   limit = (frame_pointer_needed
727            ? FRAME_POINTER_REGNUM
728            : STACK_POINTER_REGNUM);
729
730   nregs = 0;
731
732   for (regno = limit - 1; regno >= 0; regno--)
733     if ((regs_ever_live[regno] && ! call_used_regs[regno])
734         || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
735       nregs++;
736
737   /* sp is often  unreliable so we must go off the frame pointer,
738    */
739
740   /* In reality, we may not care if sp is unreliable, because we can
741      restore the register relative to the frame pointer.  In theory,
742      since each move is the same speed as a pop, and we don't need the
743      leal, this is faster.  For now restore multiple registers the old
744      way. */
745
746   offset = -size - (nregs * UNITS_PER_WORD);
747
748   xops[2] = stack_pointer_rtx;
749
750   if (nregs > 1 || ! frame_pointer_needed)
751     {
752       if (frame_pointer_needed)
753         {
754           xops[0] = adj_offsettable_operand (AT_BP (Pmode), offset);
755           output_asm_insn (AS2 (lea%L2,%0,%2), xops);
756         }
757
758       for (regno = 0; regno < limit; regno++)
759         if ((regs_ever_live[regno] && ! call_used_regs[regno])
760             || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
761           {
762             xops[0] = gen_rtx (REG, SImode, regno);
763             output_asm_insn ("pop%L0 %0", xops);
764           }
765     }
766   else
767     for (regno = 0; regno < limit; regno++)
768       if ((regs_ever_live[regno] && ! call_used_regs[regno])
769           || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
770         {
771           xops[0] = gen_rtx (REG, SImode, regno);
772           xops[1] = adj_offsettable_operand (AT_BP (Pmode), offset);
773           output_asm_insn (AS2 (mov%L0,%1,%0), xops);
774           offset += 4;
775         }
776
777   if (frame_pointer_needed)
778     {
779       /* On i486, mov & pop is faster than "leave". */
780
781       if (TARGET_486)
782         {
783           xops[0] = frame_pointer_rtx;
784           output_asm_insn (AS2 (mov%L2,%0,%2), xops);
785           output_asm_insn ("pop%L0 %0", xops);
786         }
787       else
788         output_asm_insn ("leave", xops);
789     }
790   else if (size)
791     {
792       /* If there is no frame pointer, we must still release the frame. */
793
794       xops[0] = GEN_INT (size);
795       output_asm_insn (AS2 (add%L2,%0,%2), xops);
796     }
797
798   if (current_function_pops_args && current_function_args_size)
799     {
800       xops[1] = GEN_INT (current_function_pops_args);
801
802       /* i386 can only pop 32K bytes (maybe 64K?  Is it signed?).  If
803          asked to pop more, pop return address, do explicit add, and jump
804          indirectly to the caller. */
805
806       if (current_function_pops_args >= 32768)
807         {
808           /* ??? Which register to use here? */
809           xops[0] = gen_rtx (REG, SImode, 2);
810           output_asm_insn ("pop%L0 %0", xops);
811           output_asm_insn (AS2 (add%L2,%1,%2), xops);
812           output_asm_insn ("jmp %*%0", xops);
813         }
814       else
815           output_asm_insn ("ret %1", xops);
816     }
817   else
818     output_asm_insn ("ret", xops);
819 }
820 \f
821 /* Print an integer constant expression in assembler syntax.  Addition
822    and subtraction are the only arithmetic that may appear in these
823    expressions.  FILE is the stdio stream to write to, X is the rtx, and
824    CODE is the operand print code from the output string.  */
825
826 static void
827 output_pic_addr_const (file, x, code)
828      FILE *file;
829      rtx x;
830      int code;
831 {
832   char buf[256];
833
834   switch (GET_CODE (x))
835     {
836     case PC:
837       if (flag_pic)
838         putc ('.', file);
839       else
840         abort ();
841       break;
842
843     case SYMBOL_REF:
844     case LABEL_REF:
845       if (GET_CODE (x) == SYMBOL_REF)
846         assemble_name (file, XSTR (x, 0));
847       else
848         {
849           ASM_GENERATE_INTERNAL_LABEL (buf, "L",
850                                        CODE_LABEL_NUMBER (XEXP (x, 0)));
851           assemble_name (asm_out_file, buf);
852         }
853
854       if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
855         fprintf (file, "@GOTOFF(%%ebx)");
856       else if (code == 'P')
857         fprintf (file, "@PLT");
858       else if (GET_CODE (x) == LABEL_REF || ! SYMBOL_REF_FLAG (x))
859         fprintf (file, "@GOT");
860       else
861         fprintf (file, "@GOTOFF");
862
863       break;
864
865     case CODE_LABEL:
866       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
867       assemble_name (asm_out_file, buf);
868       break;
869
870     case CONST_INT:
871       fprintf (file, "%d", INTVAL (x));
872       break;
873
874     case CONST:
875       /* This used to output parentheses around the expression,
876          but that does not work on the 386 (either ATT or BSD assembler).  */
877       output_pic_addr_const (file, XEXP (x, 0), code);
878       break;
879
880     case CONST_DOUBLE:
881       if (GET_MODE (x) == VOIDmode)
882         {
883           /* We can use %d if the number is <32 bits and positive.  */
884           if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
885             fprintf (file, "0x%x%08x",
886                      CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
887           else
888             fprintf (file, "%d", CONST_DOUBLE_LOW (x));
889         }
890       else
891         /* We can't handle floating point constants;
892            PRINT_OPERAND must handle them.  */
893         output_operand_lossage ("floating constant misused");
894       break;
895
896     case PLUS:
897       /* Some assemblers need integer constants to appear last (eg masm).  */
898       if (GET_CODE (XEXP (x, 0)) == CONST_INT)
899         {
900           output_pic_addr_const (file, XEXP (x, 1), code);
901           if (INTVAL (XEXP (x, 0)) >= 0)
902             fprintf (file, "+");
903           output_pic_addr_const (file, XEXP (x, 0), code);
904         }
905       else
906         {
907           output_pic_addr_const (file, XEXP (x, 0), code);
908           if (INTVAL (XEXP (x, 1)) >= 0)
909             fprintf (file, "+");
910           output_pic_addr_const (file, XEXP (x, 1), code);
911         }
912       break;
913
914     case MINUS:
915       output_pic_addr_const (file, XEXP (x, 0), code);
916       fprintf (file, "-");
917       output_pic_addr_const (file, XEXP (x, 1), code);
918       break;
919
920     default:
921       output_operand_lossage ("invalid expression as operand");
922     }
923 }
924 \f
925 /* Meaning of CODE:
926    f -- float insn (print a CONST_DOUBLE as a float rather than in hex).
927    D,L,W,B,Q,S -- print the opcode suffix for specified size of operand.
928    R -- print the prefix for register names.
929    z -- print the opcode suffix for the size of the current operand.
930    * -- print a star (in certain assembler syntax)
931    w -- print the operand as if it's a "word" (HImode) even if it isn't.
932    c -- don't print special prefixes before constant operands.
933 */
934
935 void
936 print_operand (file, x, code)
937      FILE *file;
938      rtx x;
939      int code;
940 {
941   if (code)
942     {
943       switch (code)
944         {
945         case '*':
946           if (USE_STAR)
947             putc ('*', file);
948           return;
949
950         case 'L':
951           PUT_OP_SIZE (code, 'l', file);
952           return;
953
954         case 'W':
955           PUT_OP_SIZE (code, 'w', file);
956           return;
957
958         case 'B':
959           PUT_OP_SIZE (code, 'b', file);
960           return;
961
962         case 'Q':
963           PUT_OP_SIZE (code, 'l', file);
964           return;
965
966         case 'S':
967           PUT_OP_SIZE (code, 's', file);
968           return;
969
970         case 'z':
971           /* 387 opcodes don't get size suffixes if the operands are
972              registers. */
973
974           if (STACK_REG_P (x))
975             return;
976
977           /* this is the size of op from size of operand */
978           switch (GET_MODE_SIZE (GET_MODE (x)))
979             {
980             case 1:
981               PUT_OP_SIZE ('B', 'b', file);
982               return;
983
984             case 2:
985               PUT_OP_SIZE ('W', 'w', file);
986               return;
987
988             case 4:
989               if (GET_MODE (x) == SFmode)
990                 {
991                   PUT_OP_SIZE ('S', 's', file);
992                   return;
993                 }
994               else
995                 PUT_OP_SIZE ('L', 'l', file);
996               return;
997
998             case 8:
999               if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
1000                 {
1001 #ifdef GAS_MNEMONICS
1002                   PUT_OP_SIZE ('Q', 'q', file);
1003                   return;
1004 #else
1005                   PUT_OP_SIZE ('Q', 'l', file); /* Fall through */
1006 #endif
1007                 }
1008
1009               PUT_OP_SIZE ('Q', 'l', file);
1010               return;
1011             }
1012
1013         case 'b':
1014         case 'w':
1015         case 'k':
1016         case 'h':
1017         case 'y':
1018         case 'P':
1019           break;
1020
1021         default:
1022           {
1023             char str[50];
1024
1025             sprintf (str, "invalid operand code `%c'", code);
1026             output_operand_lossage (str);
1027           }
1028         }
1029     }
1030   if (GET_CODE (x) == REG)
1031     {
1032       PRINT_REG (x, code, file);
1033     }
1034   else if (GET_CODE (x) == MEM)
1035     {
1036       PRINT_PTR (x, file);
1037       if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
1038         {
1039           if (flag_pic)
1040             output_pic_addr_const (file, XEXP (x, 0), code);
1041           else
1042             output_addr_const (file, XEXP (x, 0));
1043         }
1044       else
1045         output_address (XEXP (x, 0));
1046     }
1047   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
1048     {
1049       union { double d; int i[2]; } u;
1050       union { float f; int i; } u1;
1051       u.i[0] = CONST_DOUBLE_LOW (x);
1052       u.i[1] = CONST_DOUBLE_HIGH (x);
1053       u1.f = u.d;
1054       PRINT_IMMED_PREFIX (file);
1055       fprintf (file, "0x%x", u1.i);
1056     }
1057   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
1058     {
1059       union { double d; int i[2]; } u;
1060       u.i[0] = CONST_DOUBLE_LOW (x);
1061       u.i[1] = CONST_DOUBLE_HIGH (x);
1062       fprintf (file, "%.22e", u.d);
1063     }
1064   else 
1065     {
1066       if (code != 'P')
1067         {
1068           if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
1069             PRINT_IMMED_PREFIX (file);
1070           else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
1071                    || GET_CODE (x) == LABEL_REF)
1072             PRINT_OFFSET_PREFIX (file);
1073         }
1074       if (flag_pic)
1075         output_pic_addr_const (file, x, code);
1076       else
1077         output_addr_const (file, x);
1078     }
1079 }
1080 \f
1081 /* Print a memory operand whose address is ADDR.  */
1082
1083 void
1084 print_operand_address (file, addr)
1085      FILE *file;
1086      register rtx addr;
1087 {
1088   register rtx reg1, reg2, breg, ireg;
1089   rtx offset;
1090
1091   switch (GET_CODE (addr))
1092     {
1093     case REG:
1094       ADDR_BEG (file);
1095       fprintf (file, "%se", RP);
1096       fputs (hi_reg_name[REGNO (addr)], file);
1097       ADDR_END (file);
1098       break;
1099
1100     case PLUS:
1101       reg1 = 0;
1102       reg2 = 0;
1103       ireg = 0;
1104       breg = 0;
1105       offset = 0;
1106       if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
1107         {
1108           offset = XEXP (addr, 0);
1109           addr = XEXP (addr, 1);
1110         }
1111       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
1112         {
1113           offset = XEXP (addr, 1);
1114           addr = XEXP (addr, 0);
1115         }
1116       if (GET_CODE (addr) != PLUS) ;
1117       else if (GET_CODE (XEXP (addr, 0)) == MULT)
1118         {
1119           reg1 = XEXP (addr, 0);
1120           addr = XEXP (addr, 1);
1121         }
1122       else if (GET_CODE (XEXP (addr, 1)) == MULT)
1123         {
1124           reg1 = XEXP (addr, 1);
1125           addr = XEXP (addr, 0);
1126         }
1127       else if (GET_CODE (XEXP (addr, 0)) == REG)
1128         {
1129           reg1 = XEXP (addr, 0);
1130           addr = XEXP (addr, 1);
1131         }
1132       else if (GET_CODE (XEXP (addr, 1)) == REG)
1133         {
1134           reg1 = XEXP (addr, 1);
1135           addr = XEXP (addr, 0);
1136         }
1137       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
1138         {
1139           if (reg1 == 0) reg1 = addr;
1140           else reg2 = addr;
1141           addr = 0;
1142         }
1143       if (offset != 0)
1144         {
1145           if (addr != 0) abort ();
1146           addr = offset;
1147         }
1148       if ((reg1 && GET_CODE (reg1) == MULT)
1149           || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
1150         {
1151           breg = reg2;
1152           ireg = reg1;
1153         }
1154       else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
1155         {
1156           breg = reg1;
1157           ireg = reg2;
1158         }
1159
1160       if (ireg != 0 || breg != 0)
1161         {
1162           int scale = 1;
1163
1164           if (addr != 0)
1165             {
1166               if (GET_CODE (addr) == LABEL_REF)
1167                 output_asm_label (addr);
1168               else
1169                 {
1170                   if (flag_pic)
1171                     output_pic_addr_const (file, addr, 0);
1172                   else
1173                     output_addr_const (file, addr);
1174                 }
1175             }
1176
1177           if (ireg != 0 && GET_CODE (ireg) == MULT)
1178             {
1179               scale = INTVAL (XEXP (ireg, 1));
1180               ireg = XEXP (ireg, 0);
1181             }
1182
1183           /* The stack pointer can only appear as a base register,
1184              never an index register, so exchange the regs if it is wrong. */
1185
1186           if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM)
1187             {
1188               rtx tmp;
1189
1190               tmp = breg;
1191               breg = ireg;
1192               ireg = tmp;
1193             }
1194
1195           /* output breg+ireg*scale */
1196           PRINT_B_I_S (breg, ireg, scale, file);
1197           break;
1198         }
1199
1200     case MULT:
1201       {
1202         int scale;
1203         if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
1204           {
1205             scale = INTVAL (XEXP (addr, 0));
1206             ireg = XEXP (addr, 1);
1207           }
1208         else
1209           {
1210             scale = INTVAL (XEXP (addr, 1));
1211             ireg = XEXP (addr, 0);
1212           }
1213         output_addr_const (file, const0_rtx);
1214         PRINT_B_I_S ((rtx) 0, ireg, scale, file);
1215       }
1216       break;
1217
1218     default:
1219       if (GET_CODE (addr) == CONST_INT
1220           && INTVAL (addr) < 0x8000
1221           && INTVAL (addr) >= -0x8000)
1222         fprintf (file, "%d", INTVAL (addr));
1223       else
1224         {
1225           if (flag_pic)
1226             output_pic_addr_const (file, addr, 0);
1227           else
1228             output_addr_const (file, addr);
1229         }
1230     }
1231 }
1232 \f
1233 /* Set the cc_status for the results of an insn whose pattern is EXP.
1234    On the 80386, we assume that only test and compare insns, as well
1235    as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, ASHIFT, LSHIFT,
1236    ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
1237    Also, we assume that jumps, moves and sCOND don't affect the condition
1238    codes.  All else clobbers the condition codes, by assumption.
1239
1240    We assume that ALL integer add, minus, etc. instructions effect the
1241    condition codes.  This MUST be consistent with i386.md.
1242
1243    We don't record any float test or compare - the redundant test &
1244    compare check in final.c does not handle stack-like regs correctly. */
1245
1246 void
1247 notice_update_cc (exp)
1248      rtx exp;
1249 {
1250   if (GET_CODE (exp) == SET)
1251     {
1252       /* Jumps do not alter the cc's.  */
1253       if (SET_DEST (exp) == pc_rtx)
1254         return;
1255       /* Moving register or memory into a register:
1256          it doesn't alter the cc's, but it might invalidate
1257          the RTX's which we remember the cc's came from.
1258          (Note that moving a constant 0 or 1 MAY set the cc's).  */
1259       if (REG_P (SET_DEST (exp))
1260           && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM
1261               || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
1262         {
1263           if (cc_status.value1
1264               && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
1265             cc_status.value1 = 0;
1266           if (cc_status.value2
1267               && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
1268             cc_status.value2 = 0;
1269           return;
1270         }
1271       /* Moving register into memory doesn't alter the cc's.
1272          It may invalidate the RTX's which we remember the cc's came from.  */
1273       if (GET_CODE (SET_DEST (exp)) == MEM
1274           && (REG_P (SET_SRC (exp))
1275               || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
1276         {
1277           if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
1278             cc_status.value1 = 0;
1279           if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
1280             cc_status.value2 = 0;
1281           return;
1282         }
1283       /* Function calls clobber the cc's.  */
1284       else if (GET_CODE (SET_SRC (exp)) == CALL)
1285         {
1286           CC_STATUS_INIT;
1287           return;
1288         }
1289       /* Tests and compares set the cc's in predictable ways.  */
1290       else if (SET_DEST (exp) == cc0_rtx)
1291         {
1292           CC_STATUS_INIT;
1293           cc_status.value1 = SET_SRC (exp);
1294           return;
1295         }
1296       /* Certain instructions effect the condition codes. */
1297       else if (GET_MODE (SET_SRC (exp)) == SImode
1298                || GET_MODE (SET_SRC (exp)) == HImode
1299                || GET_MODE (SET_SRC (exp)) == QImode)
1300         switch (GET_CODE (SET_SRC (exp)))
1301           {
1302           case ASHIFTRT: case LSHIFTRT:
1303           case ASHIFT: case LSHIFT:
1304             /* Shifts on the 386 don't set the condition codes if the
1305                shift count is zero. */
1306             if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
1307               {
1308                 CC_STATUS_INIT;
1309                 break;
1310               }
1311             /* We assume that the CONST_INT is non-zero (this rtx would
1312                have been deleted if it were zero. */
1313
1314           case PLUS: case MINUS: case NEG:
1315           case AND: case IOR: case XOR:
1316             cc_status.flags = CC_NO_OVERFLOW;
1317             cc_status.value1 = SET_SRC (exp);
1318             cc_status.value2 = SET_DEST (exp);
1319             break;
1320
1321           default:
1322             CC_STATUS_INIT;
1323           }
1324       else
1325         {
1326           CC_STATUS_INIT;
1327         }
1328     }
1329   else if (GET_CODE (exp) == PARALLEL
1330            && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
1331     {
1332       if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
1333         return;
1334       if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
1335         {
1336           CC_STATUS_INIT;
1337           if (! stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
1338             cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
1339
1340           cc_status.flags |= CC_IN_80387;
1341           return;
1342         }
1343       CC_STATUS_INIT;
1344     }
1345   else
1346     {
1347       CC_STATUS_INIT;
1348     }
1349 }
1350 \f
1351 /* Split one or more DImode RTL references into pairs of SImode
1352    references.  The RTL can be REG, offsettable MEM, integer constant, or
1353    CONST_DOUBLE.  "operands" is a pointer to an array of DImode RTL to
1354    split and "num" is its length.  lo_half and hi_half are output arrays
1355    that parallel "operands". */
1356
1357 void
1358 split_di (operands, num, lo_half, hi_half)
1359      rtx operands[];
1360      int num;
1361      rtx lo_half[], hi_half[];
1362 {
1363   while (num--)
1364     {
1365       if (GET_CODE (operands[num]) == REG)
1366         {
1367           lo_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]));
1368           hi_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]) + 1);
1369         }
1370       else if (CONSTANT_P (operands[num]))
1371         {
1372           split_double (operands[num], &lo_half[num], &hi_half[num]);
1373         }
1374       else if (offsettable_memref_p (operands[num]))
1375         {
1376           lo_half[num] = operands[num];
1377           hi_half[num] = adj_offsettable_operand (operands[num], 4);
1378         }
1379       else
1380         abort();
1381     }
1382 }
1383 \f
1384 /* Return 1 if this is a valid binary operation on a 387.
1385    OP is the expression matched, and MODE is its mode. */
1386
1387 int
1388 binary_387_op (op, mode)
1389     register rtx op;
1390     enum machine_mode mode;
1391 {
1392   if (mode != VOIDmode && mode != GET_MODE (op))
1393     return 0;
1394
1395   switch (GET_CODE (op))
1396     {
1397     case PLUS:
1398     case MINUS:
1399     case MULT:
1400     case DIV:
1401       return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
1402
1403     default:
1404       return 0;
1405     }
1406 }
1407
1408 /* Return 1 if this is a valid conversion operation on a 387.
1409    OP is the expression matched, and MODE is its mode. */
1410
1411 int
1412 convert_387_op (op, mode)
1413     register rtx op;
1414     enum machine_mode mode;
1415 {
1416   if (mode != VOIDmode && mode != GET_MODE (op))
1417     return 0;
1418
1419   switch (GET_CODE (op))
1420     {
1421     case FLOAT:
1422       return GET_MODE (XEXP (op, 0)) == SImode;
1423
1424     case FLOAT_EXTEND:
1425       return mode == DFmode && GET_MODE (XEXP (op, 0)) == SFmode;
1426
1427     default:
1428       return 0;
1429     }
1430 }
1431
1432 /* Return 1 if this is a valid "float from int" operation on a 387.
1433    OP is the expression matched, and MODE is its mode. */
1434
1435 int
1436 float_op (op, mode)
1437     register rtx op;
1438     enum machine_mode mode;
1439 {
1440   if (mode != VOIDmode && mode != GET_MODE (op))
1441     return 0;
1442
1443   return GET_CODE (op) == FLOAT
1444     && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
1445 }
1446
1447 /* Return 1 if this is a valid shift or rotate operation on a 386.
1448    OP is the expression matched, and MODE is its mode. */
1449
1450 int
1451 shift_op (op, mode)
1452     register rtx op;
1453     enum machine_mode mode;
1454 {
1455   rtx operand = XEXP (op, 0);
1456
1457   if (mode != VOIDmode && mode != GET_MODE (op))
1458     return 0;
1459
1460   if (GET_MODE (operand) != GET_MODE (op)
1461       || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
1462     return 0;
1463
1464   return (GET_CODE (op) == ASHIFT
1465           || GET_CODE (op) == ASHIFTRT
1466           || GET_CODE (op) == LSHIFTRT
1467           || GET_CODE (op) == ROTATE
1468           || GET_CODE (op) == ROTATERT);
1469 }
1470 \f
1471 /* Output code to perform a 387 binary operation in INSN, one of PLUS,
1472    MINUS, MULT or DIV.  OPERANDS are the insn operands, where operands[3]
1473    is the expression of the binary operation.  The output may either be
1474    emitted here, or returned to the caller, like all output_* functions.
1475
1476    There is no guarantee that the operands are the same mode, as they
1477    might be within FLOAT or FLOAT_EXTEND expressions. */
1478
1479 char *
1480 output_387_binary_op (insn, operands)
1481      rtx insn;
1482      rtx *operands;
1483 {
1484   rtx temp;
1485   char *base_op;
1486   static char buf[100];
1487
1488   switch (GET_CODE (operands[3]))
1489     {
1490     case PLUS:
1491       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
1492           || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
1493         base_op = "fiadd";
1494       else
1495         base_op = "fadd";
1496       break;
1497
1498     case MINUS:
1499       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
1500           || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
1501         base_op = "fisub";
1502       else
1503         base_op = "fsub";
1504       break;
1505
1506     case MULT:
1507       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
1508           || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
1509         base_op = "fimul";
1510       else
1511         base_op = "fmul";
1512       break;
1513
1514     case DIV:
1515       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
1516           || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
1517         base_op = "fidiv";
1518       else
1519         base_op = "fdiv";
1520       break;
1521
1522     default:
1523       abort ();
1524     }
1525
1526   strcpy (buf, base_op);
1527
1528   switch (GET_CODE (operands[3]))
1529     {
1530     case MULT:
1531     case PLUS:
1532       if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
1533         {
1534           temp = operands[2];
1535           operands[2] = operands[1];
1536           operands[1] = temp;
1537         }
1538
1539       if (GET_CODE (operands[2]) == MEM)
1540         return strcat (buf, AS1 (%z2,%2));
1541
1542       if (NON_STACK_REG_P (operands[1]))
1543         {
1544           output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
1545           RET;
1546         }
1547       else if (NON_STACK_REG_P (operands[2]))
1548         {
1549           output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
1550           RET;
1551         }
1552
1553       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
1554         return strcat (buf, AS2 (p,%2,%0));
1555
1556       if (STACK_TOP_P (operands[0]))
1557         return strcat (buf, AS2 (,%y2,%0));
1558       else
1559         return strcat (buf, AS2 (,%2,%0));
1560
1561     case MINUS:
1562     case DIV:
1563       if (GET_CODE (operands[1]) == MEM)
1564         return strcat (buf, AS1 (r%z1,%1));
1565
1566       if (GET_CODE (operands[2]) == MEM)
1567         return strcat (buf, AS1 (%z2,%2));
1568
1569       if (NON_STACK_REG_P (operands[1]))
1570         {
1571           output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1)));
1572           RET;
1573         }
1574       else if (NON_STACK_REG_P (operands[2]))
1575         {
1576           output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
1577           RET;
1578         }
1579
1580       if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
1581         abort ();
1582
1583       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
1584         return strcat (buf, AS2 (rp,%2,%0));
1585
1586       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1587         return strcat (buf, AS2 (p,%1,%0));
1588
1589       if (STACK_TOP_P (operands[0]))
1590         {
1591           if (STACK_TOP_P (operands[1]))
1592             return strcat (buf, AS2 (,%y2,%0));
1593           else
1594             return strcat (buf, AS2 (r,%y1,%0));
1595         }
1596       else if (STACK_TOP_P (operands[1]))
1597         return strcat (buf, AS2 (,%1,%0));
1598       else
1599         return strcat (buf, AS2 (r,%2,%0));
1600
1601     default:
1602       abort ();
1603     }
1604 }
1605 \f
1606 /* Output code for INSN to convert a float to a signed int.  OPERANDS
1607    are the insn operands.  The output may be SFmode or DFmode and the
1608    input operand may be SImode or DImode.  As a special case, make sure
1609    that the 387 stack top dies if the output mode is DImode, because the
1610    hardware requires this.  */
1611
1612 char *
1613 output_fix_trunc (insn, operands)
1614      rtx insn;
1615      rtx *operands;
1616 {
1617   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1618   rtx xops[6];
1619
1620   if (! STACK_TOP_P (operands[1]) ||
1621       (GET_MODE (operands[0]) == DImode && ! stack_top_dies))
1622     abort ();
1623
1624   xops[0] = stack_pointer_rtx;
1625   xops[1] = AT_SP (SImode);
1626   xops[2] = adj_offsettable_operand (xops[1], 2);
1627   xops[3] = GEN_INT (4);
1628   xops[4] = GEN_INT (0xc00);
1629   xops[5] = operands[2];
1630
1631   output_asm_insn (AS2 (sub%L0,%3,%0), xops);
1632   output_asm_insn (AS1 (fnstc%W5,%1), xops);
1633   output_asm_insn (AS2 (mov%W5,%1,%5), xops);
1634   output_asm_insn (AS2 (or%W5,%4,%5), xops);
1635   output_asm_insn (AS2 (mov%W5,%5,%2), xops);
1636   output_asm_insn (AS1 (fldc%W5,%2), xops);
1637
1638   if (NON_STACK_REG_P (operands[0]))
1639     output_to_reg (operands[0], stack_top_dies);
1640   else if (GET_CODE (operands[0]) == MEM)
1641     {
1642       /* If frame pointer elimination is being done, the MEM reference
1643          might be an index off of the stack pointer.  In that case,
1644          since we have already adjusted %esp above, adjust the operand
1645          address so it points where it should. */
1646
1647       if (! frame_pointer_needed
1648           && reg_mentioned_p (stack_pointer_rtx, operands[0]))
1649         operands[0] = adj_offsettable_operand (operands[0], 4);
1650
1651       if (stack_top_dies)
1652         output_asm_insn (AS1 (fistp%z0,%0), operands);
1653       else
1654         output_asm_insn (AS1 (fist%z0,%0), operands);
1655     }
1656   else
1657     abort ();
1658
1659   output_asm_insn (AS1 (fldc%W5,%1), xops);
1660   output_asm_insn (AS2 (add%L0,%3,%0), xops);
1661
1662   RET;
1663 }
1664 \f
1665 /* Output code for INSN to compare OPERANDS.  The two operands might
1666    not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
1667    expression.  If the compare is in mode CCFPEQmode, use an opcode that
1668    will not fault if a qNaN is present. */
1669
1670 char *
1671 output_float_compare (insn, operands)
1672      rtx insn;
1673      rtx *operands;
1674 {
1675   int stack_top_dies;
1676   rtx body = XVECEXP (PATTERN (insn), 0, 0);
1677   int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
1678
1679   if (! STACK_TOP_P (operands[0]))
1680     abort ();
1681
1682   stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1683
1684   if (STACK_REG_P (operands[1])
1685       && stack_top_dies
1686       && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
1687       && REGNO (operands[1]) != FIRST_STACK_REG)
1688     {
1689       /* If both the top of the 387 stack dies, and the other operand
1690          is also a stack register that dies, then this must be a
1691          `fcompp' float compare */
1692
1693       if (unordered_compare)
1694         output_asm_insn ("fucompp", operands);
1695       else
1696         output_asm_insn ("fcompp", operands);
1697     }
1698   else
1699     {
1700       static char buf[100];
1701
1702       /* Decide if this is the integer or float compare opcode, or the
1703          unordered float compare. */
1704
1705       if (unordered_compare)
1706         strcpy (buf, "fucom");
1707       else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT)
1708         strcpy (buf, "fcom");
1709       else
1710         strcpy (buf, "ficom");
1711
1712       /* Modify the opcode if the 387 stack is to be popped. */
1713
1714       if (stack_top_dies)
1715         strcat (buf, "p");
1716
1717       if (NON_STACK_REG_P (operands[1]))
1718         output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
1719       else
1720         output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
1721     }
1722
1723   /* Now retrieve the condition code. */
1724
1725   return output_fp_cc0_set (insn);
1726 }
1727 \f
1728 /* Output opcodes to transfer the results of FP compare or test INSN
1729    from the FPU to the CPU flags.  If TARGET_IEEE_FP, ensure that if the
1730    result of the compare or test is unordered, no comparison operator
1731    succeeds except NE.  Return an output template, if any.  */
1732
1733 char *
1734 output_fp_cc0_set (insn)
1735      rtx insn;
1736 {
1737   rtx xops[3];
1738   rtx unordered_label;
1739   rtx next;
1740   enum rtx_code code;
1741
1742   xops[0] = gen_rtx (REG, HImode, 0);
1743   output_asm_insn (AS1 (fnsts%W0,%0), xops);
1744
1745   if (! TARGET_IEEE_FP)
1746     return "sahf";
1747
1748   next = next_cc0_user (insn);
1749
1750   if (GET_CODE (next) == JUMP_INSN
1751       && GET_CODE (PATTERN (next)) == SET
1752       && SET_DEST (PATTERN (next)) == pc_rtx
1753       && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
1754     {
1755       code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
1756     }
1757   else if (GET_CODE (PATTERN (next)) == SET)
1758     {
1759       code = GET_CODE (SET_SRC (PATTERN (next)));
1760     }
1761   else
1762     abort ();
1763
1764   xops[0] = gen_rtx (REG, QImode, 0);
1765
1766   switch (code)
1767     {
1768     case GT:
1769       xops[1] = GEN_INT (0x45);
1770       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1771       /* je label */
1772       break;
1773
1774     case LT:
1775       xops[1] = GEN_INT (0x45);
1776       xops[2] = GEN_INT (0x01);
1777       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1778       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
1779       /* je label */
1780       break;
1781
1782     case GE:
1783       xops[1] = GEN_INT (0x05);
1784       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1785       /* je label */
1786       break;
1787
1788     case LE:
1789       xops[1] = GEN_INT (0x45);
1790       xops[2] = GEN_INT (0x40);
1791       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1792       output_asm_insn (AS1 (dec%B0,%h0), xops);
1793       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
1794       /* jb label */
1795       break;
1796
1797     case EQ:
1798       xops[1] = GEN_INT (0x45);
1799       xops[2] = GEN_INT (0x40);
1800       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1801       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
1802       /* je label */
1803       break;
1804
1805     case NE:
1806       xops[1] = GEN_INT (0x44);
1807       xops[2] = GEN_INT (0x40);
1808       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1809       output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
1810       /* jne label */
1811       break;
1812
1813     case GTU:
1814     case LTU:
1815     case GEU:
1816     case LEU:
1817     default:
1818       abort ();
1819     }
1820   RET;
1821 }