OSDN Git Service

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