OSDN Git Service

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