OSDN Git Service

(output_move_double): Let split_double extract any constant in op 1;
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.c
1 /* Subroutines for insn-output.c for Intel X86.
2    Copyright (C) 1988, 1992, 1994, 1995 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 #include "function.h"
35
36 #ifdef EXTRA_CONSTRAINT
37 /* If EXTRA_CONSTRAINT is defined, then the 'S'
38    constraint in REG_CLASS_FROM_LETTER will no longer work, and various
39    asm statements that need 'S' for class SIREG will break.  */
40  error EXTRA_CONSTRAINT conflicts with S constraint letter
41 /* The previous line used to be #error, but some compilers barf
42    even if the conditional was untrue.  */
43 #endif
44
45 #define AT_BP(mode) (gen_rtx (MEM, (mode), frame_pointer_rtx))
46
47 extern FILE *asm_out_file;
48 extern char *strcat ();
49
50 char *singlemove_string ();
51 char *output_move_const_single ();
52 char *output_fp_cc0_set ();
53
54 char *hi_reg_name[] = HI_REGISTER_NAMES;
55 char *qi_reg_name[] = QI_REGISTER_NAMES;
56 char *qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES;
57
58 /* Array of the smallest class containing reg number REGNO, indexed by
59    REGNO.  Used by REGNO_REG_CLASS in i386.h. */
60
61 enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
62 {
63   /* ax, dx, cx, bx */
64   AREG, DREG, CREG, BREG,
65   /* si, di, bp, sp */
66   SIREG, DIREG, INDEX_REGS, GENERAL_REGS,
67   /* FP registers */
68   FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
69   FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,       
70   /* arg pointer */
71   INDEX_REGS
72 };
73
74 /* Test and compare insns in i386.md store the information needed to
75    generate branch and scc insns here.  */
76
77 struct rtx_def *i386_compare_op0 = NULL_RTX;
78 struct rtx_def *i386_compare_op1 = NULL_RTX;
79 struct rtx_def *(*i386_compare_gen)(), *(*i386_compare_gen_eq)();
80
81 /* Register allocation order */
82 char *i386_reg_alloc_order = (char *)0;
83 static char regs_allocated[FIRST_PSEUDO_REGISTER];
84
85 \f
86 /* Sometimes certain combinations of command options do not make
87    sense on a particular target machine.  You can define a macro
88    `OVERRIDE_OPTIONS' to take account of this.  This macro, if
89    defined, is executed once just after all the command options have
90    been parsed.
91
92    Don't use this macro to turn on various extra optimizations for
93    `-O'.  That is what `OPTIMIZATION_OPTIONS' is for.  */
94
95 void
96 override_options ()
97 {
98   int ch, i, regno;
99
100 #ifdef SUBTARGET_OVERRIDE_OPTIONS
101   SUBTARGET_OVERRIDE_OPTIONS;
102 #endif
103
104   /* Validate registers in register allocation order */
105   if (i386_reg_alloc_order)
106     {
107       for (i = 0; (ch = i386_reg_alloc_order[i]) != '\0'; i++)
108         {
109           switch (ch)
110             {
111             case 'a':   regno = 0;      break;
112             case 'd':   regno = 1;      break;
113             case 'c':   regno = 2;      break;
114             case 'b':   regno = 3;      break;
115             case 'S':   regno = 4;      break;
116             case 'D':   regno = 5;      break;
117             case 'B':   regno = 6;      break;
118
119             default:    fatal ("Register '%c' is unknown", ch);
120             }
121
122           if (regs_allocated[regno])
123             fatal ("Register '%c' was already specified in the allocation order", ch);
124
125           regs_allocated[regno] = 1;
126         }
127     }
128 }
129 \f
130 /* A C statement (sans semicolon) to choose the order in which to
131    allocate hard registers for pseudo-registers local to a basic
132    block.
133
134    Store the desired register order in the array `reg_alloc_order'.
135    Element 0 should be the register to allocate first; element 1, the
136    next register; and so on.
137
138    The macro body should not assume anything about the contents of
139    `reg_alloc_order' before execution of the macro.
140
141    On most machines, it is not necessary to define this macro.  */
142
143 void
144 order_regs_for_local_alloc ()
145 {
146   int i, ch, order, regno;
147
148   /* User specified the register allocation order */
149   if (i386_reg_alloc_order)
150     {
151       for (i = order = 0; (ch = i386_reg_alloc_order[i]) != '\0'; i++)
152         {
153           switch (ch)
154             {
155             case 'a':   regno = 0;      break;
156             case 'd':   regno = 1;      break;
157             case 'c':   regno = 2;      break;
158             case 'b':   regno = 3;      break;
159             case 'S':   regno = 4;      break;
160             case 'D':   regno = 5;      break;
161             case 'B':   regno = 6;      break;
162             }
163
164           reg_alloc_order[order++] = regno;
165         }
166
167       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
168         {
169           if (!regs_allocated[i])
170             reg_alloc_order[order++] = i;
171         }
172     }
173
174   /* If users did not specify a register allocation order, favor eax
175      normally except if DImode variables are used, in which case
176      favor edx before eax, which seems to cause less spill register
177      not found messages.  */
178   else
179     {
180       rtx insn;
181
182       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
183         reg_alloc_order[i] = i;
184
185       if (optimize)
186         {
187           int use_dca = FALSE;
188
189           for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
190             {
191               if (GET_CODE (insn) == INSN)
192                 {
193                   rtx set = NULL_RTX;
194                   rtx pattern = PATTERN (insn);
195
196                   if (GET_CODE (pattern) == SET)
197                     set = pattern;
198
199                   else if ((GET_CODE (pattern) == PARALLEL
200                             || GET_CODE (pattern) == SEQUENCE)
201                            && GET_CODE (XVECEXP (pattern, 0, 0)) == SET)
202                     set = XVECEXP (pattern, 0, 0);
203
204                   if (set && GET_MODE (SET_SRC (set)) == DImode)
205                     {
206                       use_dca = TRUE;
207                       break;
208                     }
209                 }
210             }
211
212           if (use_dca)
213             {
214               reg_alloc_order[0] = 1;   /* edx */
215               reg_alloc_order[1] = 2;   /* ecx */
216               reg_alloc_order[2] = 0;   /* eax */
217             }
218         }
219     }
220 }
221
222 \f
223 /* Output an insn whose source is a 386 integer register.  SRC is the
224    rtx for the register, and TEMPLATE is the op-code template.  SRC may
225    be either SImode or DImode.
226
227    The template will be output with operands[0] as SRC, and operands[1]
228    as a pointer to the top of the 386 stack.  So a call from floatsidf2
229    would look like this:
230
231       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
232
233    where %z0 corresponds to the caller's operands[1], and is used to
234    emit the proper size suffix.
235
236    ??? Extend this to handle HImode - a 387 can load and store HImode
237    values directly. */
238
239 void
240 output_op_from_reg (src, template)
241      rtx src;
242      char *template;
243 {
244   rtx xops[4];
245   int size = GET_MODE_SIZE (GET_MODE (src));
246
247   xops[0] = src;
248   xops[1] = AT_SP (Pmode);
249   xops[2] = GEN_INT (size);
250   xops[3] = stack_pointer_rtx;
251
252   if (size > UNITS_PER_WORD)
253     {
254       rtx high;
255       if (size > 2 * UNITS_PER_WORD)
256         {
257           high = gen_rtx (REG, SImode, REGNO (src) + 2);
258           output_asm_insn (AS1 (push%L0,%0), &high);
259         }
260       high = gen_rtx (REG, SImode, REGNO (src) + 1);
261       output_asm_insn (AS1 (push%L0,%0), &high);
262     }
263   output_asm_insn (AS1 (push%L0,%0), &src);
264
265   output_asm_insn (template, xops);
266
267   output_asm_insn (AS2 (add%L3,%2,%3), xops);
268 }
269 \f
270 /* Output an insn to pop an value from the 387 top-of-stack to 386
271    register DEST. The 387 register stack is popped if DIES is true.  If
272    the mode of DEST is an integer mode, a `fist' integer store is done,
273    otherwise a `fst' float store is done. */
274
275 void
276 output_to_reg (dest, dies)
277      rtx dest;
278      int dies;
279 {
280   rtx xops[4];
281   int size = GET_MODE_SIZE (GET_MODE (dest));
282
283   xops[0] = AT_SP (Pmode);
284   xops[1] = stack_pointer_rtx;
285   xops[2] = GEN_INT (size);
286   xops[3] = dest;
287
288   output_asm_insn (AS2 (sub%L1,%2,%1), xops);
289
290   if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_INT)
291     {
292       if (dies)
293         output_asm_insn (AS1 (fistp%z3,%y0), xops);
294       else
295         output_asm_insn (AS1 (fist%z3,%y0), xops);
296     }
297   else if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_FLOAT)
298     {
299       if (dies)
300         output_asm_insn (AS1 (fstp%z3,%y0), xops);
301       else
302         {
303           if (GET_MODE (dest) == XFmode)
304             {
305               output_asm_insn (AS1 (fstp%z3,%y0), xops);
306               output_asm_insn (AS1 (fld%z3,%y0), xops);
307             }
308           else
309             output_asm_insn (AS1 (fst%z3,%y0), xops);
310         }
311     }
312   else
313     abort ();
314
315   output_asm_insn (AS1 (pop%L0,%0), &dest);
316
317   if (size > UNITS_PER_WORD)
318     {
319       dest = gen_rtx (REG, SImode, REGNO (dest) + 1);
320       output_asm_insn (AS1 (pop%L0,%0), &dest);
321       if (size > 2 * UNITS_PER_WORD)
322         {
323           dest = gen_rtx (REG, SImode, REGNO (dest) + 1);
324           output_asm_insn (AS1 (pop%L0,%0), &dest);
325         }
326     }
327 }
328 \f
329 char *
330 singlemove_string (operands)
331      rtx *operands;
332 {
333   rtx x;
334   if (GET_CODE (operands[0]) == MEM
335       && GET_CODE (x = XEXP (operands[0], 0)) == PRE_DEC)
336     {
337       if (XEXP (x, 0) != stack_pointer_rtx)
338         abort ();
339       return "push%L1 %1";
340     }
341   else if (GET_CODE (operands[1]) == CONST_DOUBLE)
342     {
343       return output_move_const_single (operands);
344     }
345   else if (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == REG)
346     return AS2 (mov%L0,%1,%0);
347   else if (CONSTANT_P (operands[1]))
348     return AS2 (mov%L0,%1,%0);
349   else
350     {
351       output_asm_insn ("push%L1 %1", operands);
352       return "pop%L0 %0";
353     }
354 }
355 \f
356 /* Return a REG that occurs in ADDR with coefficient 1.
357    ADDR can be effectively incremented by incrementing REG.  */
358
359 static rtx
360 find_addr_reg (addr)
361      rtx addr;
362 {
363   while (GET_CODE (addr) == PLUS)
364     {
365       if (GET_CODE (XEXP (addr, 0)) == REG)
366         addr = XEXP (addr, 0);
367       else if (GET_CODE (XEXP (addr, 1)) == REG)
368         addr = XEXP (addr, 1);
369       else if (CONSTANT_P (XEXP (addr, 0)))
370         addr = XEXP (addr, 1);
371       else if (CONSTANT_P (XEXP (addr, 1)))
372         addr = XEXP (addr, 0);
373       else
374         abort ();
375     }
376   if (GET_CODE (addr) == REG)
377     return addr;
378   abort ();
379 }
380
381 \f
382 /* Output an insn to add the constant N to the register X.  */
383
384 static void
385 asm_add (n, x)
386      int n;
387      rtx x;
388 {
389   rtx xops[2];
390   xops[0] = x;
391
392   if (n == -1)
393     output_asm_insn (AS1 (dec%L0,%0), xops);
394   else if (n == 1)
395     output_asm_insn (AS1 (inc%L0,%0), xops);
396   else if (n < 0)
397     {
398       xops[1] = GEN_INT (-n);
399       output_asm_insn (AS2 (sub%L0,%1,%0), xops);
400     }
401   else if (n > 0)
402     {
403       xops[1] = GEN_INT (n);
404       output_asm_insn (AS2 (add%L0,%1,%0), xops);
405     }
406 }
407
408 \f
409 /* Output assembler code to perform a doubleword move insn
410    with operands OPERANDS.  */
411
412 char *
413 output_move_double (operands)
414      rtx *operands;
415 {
416   enum {REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
417   rtx latehalf[2];
418   rtx middlehalf[2];
419   rtx xops[2];
420   rtx addreg0 = 0, addreg1 = 0;
421   int dest_overlapped_low = 0;
422   int size = GET_MODE_SIZE (GET_MODE (operands[0]));
423
424   middlehalf[0] = 0;
425   middlehalf[1] = 0;
426
427   /* First classify both operands.  */
428
429   if (REG_P (operands[0]))
430     optype0 = REGOP;
431   else if (offsettable_memref_p (operands[0]))
432     optype0 = OFFSOP;
433   else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
434     optype0 = POPOP;
435   else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
436     optype0 = PUSHOP;
437   else if (GET_CODE (operands[0]) == MEM)
438     optype0 = MEMOP;
439   else
440     optype0 = RNDOP;
441
442   if (REG_P (operands[1]))
443     optype1 = REGOP;
444   else if (CONSTANT_P (operands[1]))
445     optype1 = CNSTOP;
446   else if (offsettable_memref_p (operands[1]))
447     optype1 = OFFSOP;
448   else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
449     optype1 = POPOP;
450   else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
451     optype1 = PUSHOP;
452   else if (GET_CODE (operands[1]) == MEM)
453     optype1 = MEMOP;
454   else
455     optype1 = RNDOP;
456
457   /* Check for the cases that the operand constraints are not
458      supposed to allow to happen.  Abort if we get one,
459      because generating code for these cases is painful.  */
460
461   if (optype0 == RNDOP || optype1 == RNDOP)
462     abort ();
463
464   /* If one operand is decrementing and one is incrementing
465      decrement the former register explicitly
466      and change that operand into ordinary indexing.  */
467
468   if (optype0 == PUSHOP && optype1 == POPOP)
469     {
470       /* ??? Can this ever happen on i386? */
471       operands[0] = XEXP (XEXP (operands[0], 0), 0);
472       asm_add (-size, operands[0]);
473       if (GET_MODE (operands[1]) == XFmode)
474         operands[0] = gen_rtx (MEM, XFmode, operands[0]);
475       else if (GET_MODE (operands[0]) == DFmode)
476         operands[0] = gen_rtx (MEM, DFmode, operands[0]);
477       else
478         operands[0] = gen_rtx (MEM, DImode, operands[0]);
479       optype0 = OFFSOP;
480     }
481
482   if (optype0 == POPOP && optype1 == PUSHOP)
483     {
484       /* ??? Can this ever happen on i386? */
485       operands[1] = XEXP (XEXP (operands[1], 0), 0);
486       asm_add (-size, operands[1]);
487       if (GET_MODE (operands[1]) == XFmode)
488         operands[1] = gen_rtx (MEM, XFmode, operands[1]);
489       else if (GET_MODE (operands[1]) == DFmode)
490         operands[1] = gen_rtx (MEM, DFmode, operands[1]);
491       else
492         operands[1] = gen_rtx (MEM, DImode, operands[1]);
493       optype1 = OFFSOP;
494     }
495
496   /* If an operand is an unoffsettable memory ref, find a register
497      we can increment temporarily to make it refer to the second word.  */
498
499   if (optype0 == MEMOP)
500     addreg0 = find_addr_reg (XEXP (operands[0], 0));
501
502   if (optype1 == MEMOP)
503     addreg1 = find_addr_reg (XEXP (operands[1], 0));
504
505   /* Ok, we can do one word at a time.
506      Normally we do the low-numbered word first,
507      but if either operand is autodecrementing then we
508      do the high-numbered word first.
509
510      In either case, set up in LATEHALF the operands to use
511      for the high-numbered word and in some cases alter the
512      operands in OPERANDS to be suitable for the low-numbered word.  */
513
514   if (size == 12)
515     {
516       if (optype0 == REGOP)
517         {
518           middlehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
519           latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 2);
520         }
521       else if (optype0 == OFFSOP)
522         {
523           middlehalf[0] = adj_offsettable_operand (operands[0], 4);
524           latehalf[0] = adj_offsettable_operand (operands[0], 8);
525         }
526       else
527         {
528          middlehalf[0] = operands[0];
529          latehalf[0] = operands[0];
530         }
531     
532       if (optype1 == REGOP)
533         {
534           middlehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
535           latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2);
536         }
537       else if (optype1 == OFFSOP)
538         {
539           middlehalf[1] = adj_offsettable_operand (operands[1], 4);
540           latehalf[1] = adj_offsettable_operand (operands[1], 8);
541         }
542       else if (optype1 == CNSTOP)
543         {
544           if (GET_CODE (operands[1]) == CONST_DOUBLE)
545             {
546               REAL_VALUE_TYPE r; long l[3];
547
548               REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
549               REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
550               operands[1] = GEN_INT (l[0]);
551               middlehalf[1] = GEN_INT (l[1]);
552               latehalf[1] = GEN_INT (l[2]);
553             }
554           else if (CONSTANT_P (operands[1]))
555             /* No non-CONST_DOUBLE constant should ever appear here.  */
556             abort ();
557         }
558       else
559         {
560           middlehalf[1] = operands[1];
561           latehalf[1] = operands[1];
562         }
563     }
564   else /* size is not 12: */
565     {
566       if (optype0 == REGOP)
567         latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
568       else if (optype0 == OFFSOP)
569         latehalf[0] = adj_offsettable_operand (operands[0], 4);
570       else
571         latehalf[0] = operands[0];
572
573       if (optype1 == REGOP)
574         latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
575       else if (optype1 == OFFSOP)
576         latehalf[1] = adj_offsettable_operand (operands[1], 4);
577       else if (optype1 == CNSTOP)
578         split_double (operands[1], &operands[1], &latehalf[1]);
579       else
580         latehalf[1] = operands[1];
581     }
582
583   /* If insn is effectively movd N (sp),-(sp) then we will do the
584      high word first.  We should use the adjusted operand 1
585      (which is N+4 (sp) or N+8 (sp))
586      for the low word and middle word as well,
587      to compensate for the first decrement of sp.  */
588   if (optype0 == PUSHOP
589       && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
590       && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
591     middlehalf[1] = operands[1] = latehalf[1];
592
593   /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
594      if the upper part of reg N does not appear in the MEM, arrange to
595      emit the move late-half first.  Otherwise, compute the MEM address
596      into the upper part of N and use that as a pointer to the memory
597      operand.  */
598   if (optype0 == REGOP
599       && (optype1 == OFFSOP || optype1 == MEMOP))
600     {
601       if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))
602           && reg_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
603         {
604           /* If both halves of dest are used in the src memory address,
605              compute the address into latehalf of dest.  */
606 compadr:
607           xops[0] = latehalf[0];
608           xops[1] = XEXP (operands[1], 0);
609           output_asm_insn (AS2 (lea%L0,%a1,%0), xops);
610           if( GET_MODE (operands[1]) == XFmode )
611             {
612 /*          abort (); */
613               operands[1] = gen_rtx (MEM, XFmode, latehalf[0]);
614               middlehalf[1] = adj_offsettable_operand (operands[1], size-8);
615               latehalf[1] = adj_offsettable_operand (operands[1], size-4);
616             }
617           else
618             {
619               operands[1] = gen_rtx (MEM, DImode, latehalf[0]);
620               latehalf[1] = adj_offsettable_operand (operands[1], size-4);
621             }
622         }
623       else if (size == 12
624                  && reg_mentioned_p (middlehalf[0], XEXP (operands[1], 0)))
625         {
626           /* Check for two regs used by both source and dest. */
627           if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))
628                 || reg_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
629                 goto compadr;
630
631           /* JRV says this can't happen: */
632           if (addreg0 || addreg1)
633               abort();
634
635           /* Only the middle reg conflicts; simply put it last. */
636           output_asm_insn (singlemove_string (operands), operands);
637           output_asm_insn (singlemove_string (latehalf), latehalf);
638           output_asm_insn (singlemove_string (middlehalf), middlehalf);
639           return "";
640         }
641       else if (reg_mentioned_p (operands[0], XEXP (operands[1], 0)))
642         /* If the low half of dest is mentioned in the source memory
643            address, the arrange to emit the move late half first.  */
644         dest_overlapped_low = 1;
645     }
646
647   /* If one or both operands autodecrementing,
648      do the two words, high-numbered first.  */
649
650   /* Likewise,  the first move would clobber the source of the second one,
651      do them in the other order.  This happens only for registers;
652      such overlap can't happen in memory unless the user explicitly
653      sets it up, and that is an undefined circumstance.  */
654
655 /*
656   if (optype0 == PUSHOP || optype1 == PUSHOP
657       || (optype0 == REGOP && optype1 == REGOP
658           && REGNO (operands[0]) == REGNO (latehalf[1]))
659       || dest_overlapped_low)
660 */
661   if (optype0 == PUSHOP || optype1 == PUSHOP
662       || (optype0 == REGOP && optype1 == REGOP
663           && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1]))
664               || REGNO (operands[0]) == REGNO (latehalf[1])))
665       || dest_overlapped_low)
666     {
667       /* Make any unoffsettable addresses point at high-numbered word.  */
668       if (addreg0)
669         asm_add (size-4, addreg0);
670       if (addreg1)
671         asm_add (size-4, addreg1);
672
673       /* Do that word.  */
674       output_asm_insn (singlemove_string (latehalf), latehalf);
675
676       /* Undo the adds we just did.  */
677       if (addreg0)
678          asm_add (-4, addreg0);
679       if (addreg1)
680         asm_add (-4, addreg1);
681
682       if (size == 12)
683         {
684         output_asm_insn (singlemove_string (middlehalf), middlehalf);
685         if (addreg0)
686            asm_add (-4, addreg0);
687         if (addreg1)
688            asm_add (-4, addreg1);
689         }
690
691       /* Do low-numbered word.  */
692       return singlemove_string (operands);
693     }
694
695   /* Normal case: do the two words, low-numbered first.  */
696
697   output_asm_insn (singlemove_string (operands), operands);
698
699   /* Do the middle one of the three words for long double */
700   if (size == 12)
701     {
702       if (addreg0)
703         asm_add (4, addreg0);
704       if (addreg1)
705         asm_add (4, addreg1);
706
707       output_asm_insn (singlemove_string (middlehalf), middlehalf);
708     }
709
710   /* Make any unoffsettable addresses point at high-numbered word.  */
711   if (addreg0)
712     asm_add (4, addreg0);
713   if (addreg1)
714     asm_add (4, addreg1);
715
716   /* Do that word.  */
717   output_asm_insn (singlemove_string (latehalf), latehalf);
718
719   /* Undo the adds we just did.  */
720   if (addreg0)
721     asm_add (4-size, addreg0);
722   if (addreg1)
723     asm_add (4-size, addreg1);
724
725   return "";
726 }
727
728 \f
729 #define MAX_TMPS 2              /* max temporary registers used */
730
731 /* Output the appropriate code to move push memory on the stack */
732
733 char *
734 output_move_pushmem (operands, insn, length, tmp_start, n_operands)
735      rtx operands[];
736      rtx insn;
737      int length;
738      int tmp_start;
739      int n_operands;
740 {
741
742   struct {
743     char *load;
744     char *push;
745     rtx   xops[2];
746   } tmp_info[MAX_TMPS];
747
748   rtx src = operands[1];
749   int max_tmps = 0;
750   int offset = 0;
751   int stack_p = reg_overlap_mentioned_p (stack_pointer_rtx, src);
752   int stack_offset = 0;
753   int i, num_tmps;
754   rtx xops[1];
755
756   if (!offsettable_memref_p (src))
757     fatal_insn ("Source is not offsettable", insn);
758
759   if ((length & 3) != 0)
760     fatal_insn ("Pushing non-word aligned size", insn);
761
762   /* Figure out which temporary registers we have available */
763   for (i = tmp_start; i < n_operands; i++)
764     {
765       if (GET_CODE (operands[i]) == REG)
766         {
767           if (reg_overlap_mentioned_p (operands[i], src))
768             continue;
769
770           tmp_info[ max_tmps++ ].xops[1] = operands[i];
771           if (max_tmps == MAX_TMPS)
772             break;
773         }
774     }
775
776   if (max_tmps == 0)
777     for (offset = length - 4; offset >= 0; offset -= 4)
778       {
779         xops[0] = adj_offsettable_operand (src, offset + stack_offset);
780         output_asm_insn (AS1(push%L0,%0), xops);
781         if (stack_p)
782           stack_offset += 4;
783       }
784
785   else
786     for (offset = length - 4; offset >= 0; )
787       {
788         for (num_tmps = 0; num_tmps < max_tmps && offset >= 0; num_tmps++)
789           {
790             tmp_info[num_tmps].load    = AS2(mov%L0,%0,%1);
791             tmp_info[num_tmps].push    = AS1(push%L0,%1);
792             tmp_info[num_tmps].xops[0] = adj_offsettable_operand (src, offset + stack_offset);
793             offset -= 4;
794           }
795
796         for (i = 0; i < num_tmps; i++)
797           output_asm_insn (tmp_info[i].load, tmp_info[i].xops);
798
799         for (i = 0; i < num_tmps; i++)
800           output_asm_insn (tmp_info[i].push, tmp_info[i].xops);
801
802         if (stack_p)
803           stack_offset += 4*num_tmps;
804       }
805
806   return "";
807 }
808
809 \f
810
811 /* Output the appropriate code to move data between two memory locations */
812
813 char *
814 output_move_memory (operands, insn, length, tmp_start, n_operands)
815      rtx operands[];
816      rtx insn;
817      int length;
818      int tmp_start;
819      int n_operands;
820 {
821   struct {
822     char *load;
823     char *store;
824     rtx   xops[3];
825   } tmp_info[MAX_TMPS];
826
827   rtx dest = operands[0];
828   rtx src  = operands[1];
829   rtx qi_tmp = NULL_RTX;
830   int max_tmps = 0;
831   int offset = 0;
832   int i, num_tmps;
833   rtx xops[3];
834
835   if (GET_CODE (dest) == MEM
836       && GET_CODE (XEXP (dest, 0)) == PRE_INC
837       && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx)
838     return output_move_pushmem (operands, insn, length, tmp_start, n_operands);
839
840   if (!offsettable_memref_p (src))
841     fatal_insn ("Source is not offsettable", insn);
842
843   if (!offsettable_memref_p (dest))
844     fatal_insn ("Destination is not offsettable", insn);
845
846   /* Figure out which temporary registers we have available */
847   for (i = tmp_start; i < n_operands; i++)
848     {
849       if (GET_CODE (operands[i]) == REG)
850         {
851           if ((length & 1) != 0 && !qi_tmp && QI_REG_P (operands[i]))
852             qi_tmp = operands[i];
853
854           if (reg_overlap_mentioned_p (operands[i], dest))
855             fatal_insn ("Temporary register overlaps the destination", insn);
856
857           if (reg_overlap_mentioned_p (operands[i], src))
858             fatal_insn ("Temporary register overlaps the source", insn);
859
860           tmp_info[ max_tmps++ ].xops[2] = operands[i];
861           if (max_tmps == MAX_TMPS)
862             break;
863         }
864     }
865
866   if (max_tmps == 0)
867     fatal_insn ("No scratch registers were found to do memory->memory moves", insn);
868
869   if ((length & 1) != 0)
870     {
871       if (!qi_tmp)
872         fatal_insn ("No byte register found when moving odd # of bytes.", insn);
873     }
874
875   while (length > 1)
876     {
877       for (num_tmps = 0; num_tmps < max_tmps; num_tmps++)
878         {
879           if (length >= 4)
880             {
881               tmp_info[num_tmps].load    = AS2(mov%L0,%1,%2);
882               tmp_info[num_tmps].store   = AS2(mov%L0,%2,%0);
883               tmp_info[num_tmps].xops[0] = adj_offsettable_operand (dest, offset);
884               tmp_info[num_tmps].xops[1] = adj_offsettable_operand (src, offset);
885               offset += 4;
886               length -= 4;
887             }
888           else if (length >= 2)
889             {
890               tmp_info[num_tmps].load    = AS2(mov%W0,%1,%2);
891               tmp_info[num_tmps].store   = AS2(mov%W0,%2,%0);
892               tmp_info[num_tmps].xops[0] = adj_offsettable_operand (dest, offset);
893               tmp_info[num_tmps].xops[1] = adj_offsettable_operand (src, offset);
894               offset += 2;
895               length -= 2;
896             }
897           else
898             break;
899         }
900
901       for (i = 0; i < num_tmps; i++)
902         output_asm_insn (tmp_info[i].load, tmp_info[i].xops);
903
904       for (i = 0; i < num_tmps; i++)
905         output_asm_insn (tmp_info[i].store, tmp_info[i].xops);
906     }
907
908   if (length == 1)
909     {
910       xops[0] = adj_offsettable_operand (dest, offset);
911       xops[1] = adj_offsettable_operand (src, offset);
912       xops[2] = qi_tmp;
913       output_asm_insn (AS2(mov%B0,%1,%2), xops);
914       output_asm_insn (AS2(mov%B0,%2,%0), xops);
915     }
916
917   return "";
918 }
919
920 \f
921 int
922 standard_80387_constant_p (x)
923      rtx x;
924 {
925 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
926   REAL_VALUE_TYPE d;
927   jmp_buf handler;
928   int is0, is1;
929
930   if (setjmp (handler))
931     return 0;
932
933   set_float_handler (handler);
934   REAL_VALUE_FROM_CONST_DOUBLE (d, x);
935   is0 = REAL_VALUES_EQUAL (d, dconst0);
936   is1 = REAL_VALUES_EQUAL (d, dconst1);
937   set_float_handler (NULL_PTR);
938
939   if (is0)
940     return 1;
941
942   if (is1)
943     return 2;
944
945   /* Note that on the 80387, other constants, such as pi,
946      are much slower to load as standard constants
947      than to load from doubles in memory!  */
948 #endif
949
950   return 0;
951 }
952
953 char *
954 output_move_const_single (operands)
955      rtx *operands;
956 {
957   if (FP_REG_P (operands[0]))
958     {
959       int conval = standard_80387_constant_p (operands[1]);
960
961       if (conval == 1)
962         return "fldz";
963
964       if (conval == 2)
965         return "fld1";
966     }
967   if (GET_CODE (operands[1]) == CONST_DOUBLE)
968     {
969       REAL_VALUE_TYPE r; long l;
970
971       if (GET_MODE (operands[1]) == XFmode)
972         abort ();
973
974       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
975       REAL_VALUE_TO_TARGET_SINGLE (r, l);
976       operands[1] = GEN_INT (l);
977     }
978   return singlemove_string (operands);
979 }
980 \f
981 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
982    reference and a constant.  */
983
984 int
985 symbolic_operand (op, mode)
986      register rtx op;
987      enum machine_mode mode;
988 {
989   switch (GET_CODE (op))
990     {
991     case SYMBOL_REF:
992     case LABEL_REF:
993       return 1;
994     case CONST:
995       op = XEXP (op, 0);
996       return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
997                || GET_CODE (XEXP (op, 0)) == LABEL_REF)
998               && GET_CODE (XEXP (op, 1)) == CONST_INT);
999     default:
1000       return 0;
1001     }
1002 }
1003
1004 /* Test for a valid operand for a call instruction.
1005    Don't allow the arg pointer register or virtual regs
1006    since they may change into reg + const, which the patterns
1007    can't handle yet.  */
1008
1009 int
1010 call_insn_operand (op, mode)
1011      rtx op;
1012      enum machine_mode mode;
1013 {
1014   if (GET_CODE (op) == MEM
1015       && ((CONSTANT_ADDRESS_P (XEXP (op, 0))
1016            /* This makes a difference for PIC.  */
1017            && general_operand (XEXP (op, 0), Pmode))
1018           || (GET_CODE (XEXP (op, 0)) == REG
1019               && XEXP (op, 0) != arg_pointer_rtx
1020               && !(REGNO (XEXP (op, 0)) >= FIRST_PSEUDO_REGISTER
1021                    && REGNO (XEXP (op, 0)) <= LAST_VIRTUAL_REGISTER))))
1022     return 1;
1023   return 0;
1024 }
1025
1026 /* Like call_insn_operand but allow (mem (symbol_ref ...))
1027    even if pic.  */
1028
1029 int
1030 expander_call_insn_operand (op, mode)
1031      rtx op;
1032      enum machine_mode mode;
1033 {
1034   if (GET_CODE (op) == MEM
1035       && (CONSTANT_ADDRESS_P (XEXP (op, 0))
1036           || (GET_CODE (XEXP (op, 0)) == REG
1037               && XEXP (op, 0) != arg_pointer_rtx
1038               && !(REGNO (XEXP (op, 0)) >= FIRST_PSEUDO_REGISTER
1039                    && REGNO (XEXP (op, 0)) <= LAST_VIRTUAL_REGISTER))))
1040     return 1;
1041   return 0;
1042 }
1043 \f
1044 /* Returns 1 if OP contains a symbol reference */
1045
1046 int
1047 symbolic_reference_mentioned_p (op)
1048      rtx op;
1049 {
1050   register char *fmt;
1051   register int i;
1052
1053   if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
1054     return 1;
1055
1056   fmt = GET_RTX_FORMAT (GET_CODE (op));
1057   for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
1058     {
1059       if (fmt[i] == 'E')
1060         {
1061           register int j;
1062
1063           for (j = XVECLEN (op, i) - 1; j >= 0; j--)
1064             if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
1065               return 1;
1066         }
1067       else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
1068         return 1;
1069     }
1070
1071   return 0;
1072 }
1073 \f
1074 /* This function generates the assembly code for function entry.
1075    FILE is an stdio stream to output the code to.
1076    SIZE is an int: how many units of temporary storage to allocate. */
1077
1078 void
1079 function_prologue (file, size)
1080      FILE *file;
1081      int size;
1082 {
1083   register int regno;
1084   int limit;
1085   rtx xops[4];
1086   int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1087                                   || current_function_uses_const_pool);
1088
1089   xops[0] = stack_pointer_rtx;
1090   xops[1] = frame_pointer_rtx;
1091   xops[2] = GEN_INT (size);
1092   if (frame_pointer_needed)
1093     {
1094       output_asm_insn ("push%L1 %1", xops);
1095       output_asm_insn (AS2 (mov%L0,%0,%1), xops);
1096     }
1097
1098   if (size)
1099     output_asm_insn (AS2 (sub%L0,%2,%0), xops);
1100
1101   /* Note If use enter it is NOT reversed args.
1102      This one is not reversed from intel!!
1103      I think enter is slower.  Also sdb doesn't like it.
1104      But if you want it the code is:
1105      {
1106      xops[3] = const0_rtx;
1107      output_asm_insn ("enter %2,%3", xops);
1108      }
1109      */
1110   limit = (frame_pointer_needed ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
1111   for (regno = limit - 1; regno >= 0; regno--)
1112     if ((regs_ever_live[regno] && ! call_used_regs[regno])
1113         || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1114       {
1115         xops[0] = gen_rtx (REG, SImode, regno);
1116         output_asm_insn ("push%L0 %0", xops);
1117       }
1118
1119   if (pic_reg_used)
1120     {
1121       xops[0] = pic_offset_table_rtx;
1122       xops[1] = (rtx) gen_label_rtx ();
1123
1124       output_asm_insn (AS1 (call,%P1), xops);
1125       ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (xops[1]));
1126       output_asm_insn (AS1 (pop%L0,%0), xops);
1127       output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops);
1128     }
1129 }
1130
1131 /* Return 1 if it is appropriate to emit `ret' instructions in the
1132    body of a function.  Do this only if the epilogue is simple, needing a
1133    couple of insns.  Prior to reloading, we can't tell how many registers
1134    must be saved, so return 0 then.
1135
1136    If NON_SAVING_SETJMP is defined and true, then it is not possible
1137    for the epilogue to be simple, so return 0.  This is a special case
1138    since NON_SAVING_SETJMP will not cause regs_ever_live to change until
1139    final, but jump_optimize may need to know sooner if a `return' is OK.  */
1140
1141 int
1142 simple_386_epilogue ()
1143 {
1144   int regno;
1145   int nregs = 0;
1146   int reglimit = (frame_pointer_needed
1147                   ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
1148   int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1149                                   || current_function_uses_const_pool);
1150
1151 #ifdef NON_SAVING_SETJMP
1152   if (NON_SAVING_SETJMP && current_function_calls_setjmp)
1153     return 0;
1154 #endif
1155
1156   if (! reload_completed)
1157     return 0;
1158
1159   for (regno = reglimit - 1; regno >= 0; regno--)
1160     if ((regs_ever_live[regno] && ! call_used_regs[regno])
1161         || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1162       nregs++;
1163
1164   return nregs == 0 || ! frame_pointer_needed;
1165 }
1166
1167 \f
1168 /* This function generates the assembly code for function exit.
1169    FILE is an stdio stream to output the code to.
1170    SIZE is an int: how many units of temporary storage to deallocate. */
1171
1172 void
1173 function_epilogue (file, size)
1174      FILE *file;
1175      int size;
1176 {
1177   register int regno;
1178   register int nregs, limit;
1179   int offset;
1180   rtx xops[3];
1181   int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1182                                   || current_function_uses_const_pool);
1183
1184   /* Compute the number of registers to pop */
1185
1186   limit = (frame_pointer_needed
1187            ? FRAME_POINTER_REGNUM
1188            : STACK_POINTER_REGNUM);
1189
1190   nregs = 0;
1191
1192   for (regno = limit - 1; regno >= 0; regno--)
1193     if ((regs_ever_live[regno] && ! call_used_regs[regno])
1194         || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1195       nregs++;
1196
1197   /* sp is often  unreliable so we must go off the frame pointer,
1198    */
1199
1200   /* In reality, we may not care if sp is unreliable, because we can
1201      restore the register relative to the frame pointer.  In theory,
1202      since each move is the same speed as a pop, and we don't need the
1203      leal, this is faster.  For now restore multiple registers the old
1204      way. */
1205
1206   offset = -size - (nregs * UNITS_PER_WORD);
1207
1208   xops[2] = stack_pointer_rtx;
1209
1210   if (nregs > 1 || ! frame_pointer_needed)
1211     {
1212       if (frame_pointer_needed)
1213         {
1214           xops[0] = adj_offsettable_operand (AT_BP (Pmode), offset);
1215           output_asm_insn (AS2 (lea%L2,%0,%2), xops);
1216         }
1217
1218       for (regno = 0; regno < limit; regno++)
1219         if ((regs_ever_live[regno] && ! call_used_regs[regno])
1220             || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1221           {
1222             xops[0] = gen_rtx (REG, SImode, regno);
1223             output_asm_insn ("pop%L0 %0", xops);
1224           }
1225     }
1226   else
1227     for (regno = 0; regno < limit; regno++)
1228       if ((regs_ever_live[regno] && ! call_used_regs[regno])
1229           || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1230         {
1231           xops[0] = gen_rtx (REG, SImode, regno);
1232           xops[1] = adj_offsettable_operand (AT_BP (Pmode), offset);
1233           output_asm_insn (AS2 (mov%L0,%1,%0), xops);
1234           offset += 4;
1235         }
1236
1237   if (frame_pointer_needed)
1238     {
1239       /* On i486, mov & pop is faster than "leave". */
1240
1241       if (!TARGET_386)
1242         {
1243           xops[0] = frame_pointer_rtx;
1244           output_asm_insn (AS2 (mov%L2,%0,%2), xops);
1245           output_asm_insn ("pop%L0 %0", xops);
1246         }
1247       else
1248         output_asm_insn ("leave", xops);
1249     }
1250   else if (size)
1251     {
1252       /* If there is no frame pointer, we must still release the frame. */
1253
1254       xops[0] = GEN_INT (size);
1255       output_asm_insn (AS2 (add%L2,%0,%2), xops);
1256     }
1257
1258   if (current_function_pops_args && current_function_args_size)
1259     {
1260       xops[1] = GEN_INT (current_function_pops_args);
1261
1262       /* i386 can only pop 32K bytes (maybe 64K?  Is it signed?).  If
1263          asked to pop more, pop return address, do explicit add, and jump
1264          indirectly to the caller. */
1265
1266       if (current_function_pops_args >= 32768)
1267         {
1268           /* ??? Which register to use here? */
1269           xops[0] = gen_rtx (REG, SImode, 2);
1270           output_asm_insn ("pop%L0 %0", xops);
1271           output_asm_insn (AS2 (add%L2,%1,%2), xops);
1272           output_asm_insn ("jmp %*%0", xops);
1273         }
1274       else
1275           output_asm_insn ("ret %1", xops);
1276     }
1277   else
1278     output_asm_insn ("ret", xops);
1279 }
1280
1281 \f
1282 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
1283    that is a valid memory address for an instruction.
1284    The MODE argument is the machine mode for the MEM expression
1285    that wants to use this address.
1286
1287    On x86, legitimate addresses are:
1288         base                            movl (base),reg
1289         displacement                    movl disp,reg
1290         base + displacement             movl disp(base),reg
1291         index + base                    movl (base,index),reg
1292         (index + base) + displacement   movl disp(base,index),reg
1293         index*scale                     movl (,index,scale),reg
1294         index*scale + disp              movl disp(,index,scale),reg
1295         index*scale + base              movl (base,index,scale),reg
1296         (index*scale + base) + disp     movl disp(base,index,scale),reg
1297
1298         In each case, scale can be 1, 2, 4, 8.  */
1299
1300 /* This is exactly the same as print_operand_addr, except that
1301    it recognizes addresses instead of printing them.
1302
1303    It only recognizes address in canonical form.  LEGITIMIZE_ADDRESS should
1304    convert common non-canonical forms to canonical form so that they will
1305    be recognized.  */
1306
1307 #define ADDR_INVALID(msg,insn)                                          \
1308 do {                                                                    \
1309   if (TARGET_DEBUG_ADDR)                                                \
1310     {                                                                   \
1311       fprintf (stderr, msg);                                            \
1312       debug_rtx (insn);                                                 \
1313     }                                                                   \
1314 } while (0)
1315
1316 int
1317 legitimate_address_p (mode, addr, strict)
1318      enum machine_mode mode;
1319      register rtx addr;
1320      int strict;
1321 {
1322   rtx base  = NULL_RTX;
1323   rtx indx  = NULL_RTX;
1324   rtx scale = NULL_RTX;
1325   rtx disp  = NULL_RTX;
1326
1327   if (TARGET_DEBUG_ADDR)
1328     {
1329       fprintf (stderr,
1330                "\n==========\nGO_IF_LEGITIMATE_ADDRESS, mode = %s, strict = %d\n",
1331                GET_MODE_NAME (mode), strict);
1332
1333       debug_rtx (addr);
1334     }
1335
1336   if (GET_CODE (addr) == REG || GET_CODE (addr) == SUBREG)
1337       base = addr;                              /* base reg */
1338
1339   else if (GET_CODE (addr) == PLUS)
1340     {
1341       rtx op0 = XEXP (addr, 0);
1342       rtx op1 = XEXP (addr, 1);
1343       enum rtx_code code0 = GET_CODE (op0);
1344       enum rtx_code code1 = GET_CODE (op1);
1345
1346       if (code0 == REG || code0 == SUBREG)
1347         {
1348           if (code1 == REG || code1 == SUBREG)
1349             {
1350               indx = op0;                       /* index + base */
1351               base = op1;
1352             }
1353
1354           else
1355             {
1356               base = op0;                       /* base + displacement */
1357               disp = op1;
1358             }
1359         }
1360
1361       else if (code0 == MULT)
1362         {
1363           indx  = XEXP (op0, 0);
1364           scale = XEXP (op0, 1);
1365
1366           if (code1 == REG || code1 == SUBREG)
1367             base = op1;                         /* index*scale + base */
1368
1369           else
1370             disp = op1;                         /* index*scale + disp */
1371         }
1372
1373       else if (code0 == PLUS && GET_CODE (XEXP (op0, 0)) == MULT)
1374         {
1375           indx  = XEXP (XEXP (op0, 0), 0);      /* index*scale + base + disp */
1376           scale = XEXP (XEXP (op0, 0), 1);
1377           base  = XEXP (op0, 1);
1378           disp  = op1;
1379         }
1380
1381       else if (code0 == PLUS)
1382         {
1383           indx = XEXP (op0, 0);                 /* index + base + disp */
1384           base = XEXP (op0, 1);
1385           disp = op1;
1386         }
1387
1388       else
1389         {
1390           ADDR_INVALID ("PLUS subcode is not valid.\n", op0);
1391           return FALSE;
1392         }
1393     }
1394
1395   else if (GET_CODE (addr) == MULT)
1396     {
1397       indx  = XEXP (addr, 0);                   /* index*scale */
1398       scale = XEXP (addr, 1);
1399     }
1400
1401   else
1402     disp = addr;                                /* displacement */
1403
1404   /* Allow arg pointer and stack pointer as index if there is not scaling */
1405   if (base && indx && !scale
1406       && (indx == arg_pointer_rtx || indx == stack_pointer_rtx))
1407     {
1408       rtx tmp = base;
1409       base = indx;
1410       indx = tmp;
1411     }
1412
1413   /* Validate base register */
1414   /* Don't allow SUBREG's here, it can lead to spill failures when the base
1415      is one word out of a two word structure, which is represented internally
1416      as a DImode int.  */
1417   if (base)
1418     {
1419       if (GET_CODE (base) != REG)
1420         {
1421           ADDR_INVALID ("Base is not a register.\n", base);
1422           return FALSE;
1423         }
1424
1425       if ((strict && !REG_OK_FOR_BASE_STRICT_P (base))
1426           || (!strict && !REG_OK_FOR_BASE_NONSTRICT_P (base)))
1427         {
1428           ADDR_INVALID ("Base is not valid.\n", base);
1429           return FALSE;
1430         }
1431     }
1432
1433   /* Validate index register */
1434   /* Don't allow SUBREG's here, it can lead to spill failures when the index
1435      is one word out of a two word structure, which is represented internally
1436      as a DImode int.  */
1437   if (indx)
1438     {
1439       if (GET_CODE (indx) != REG)
1440         {
1441           ADDR_INVALID ("Index is not a register.\n", indx);
1442           return FALSE;
1443         }
1444
1445       if ((strict && !REG_OK_FOR_INDEX_STRICT_P (indx))
1446           || (!strict && !REG_OK_FOR_INDEX_NONSTRICT_P (indx)))
1447         {
1448           ADDR_INVALID ("Index is not valid.\n", indx);
1449           return FALSE;
1450         }
1451     }
1452   else if (scale)
1453     abort ();                                   /* scale w/o index invalid */
1454
1455   /* Validate scale factor */
1456   if (scale)
1457     {
1458       HOST_WIDE_INT value;
1459
1460       if (GET_CODE (scale) != CONST_INT)
1461         {
1462           ADDR_INVALID ("Scale is not valid.\n", scale);
1463           return FALSE;
1464         }
1465
1466       value = INTVAL (scale);
1467       if (value != 1 && value != 2 && value != 4 && value != 8)
1468         {
1469           ADDR_INVALID ("Scale is not a good multiplier.\n", scale);
1470           return FALSE;
1471         }
1472     }
1473
1474   /* Validate displacement */
1475   if (disp)
1476     {
1477       if (!CONSTANT_ADDRESS_P (disp))
1478         {
1479           ADDR_INVALID ("Displacement is not valid.\n", disp);
1480           return FALSE;
1481         }
1482
1483       if (GET_CODE (disp) == CONST_DOUBLE)
1484         {
1485           ADDR_INVALID ("Displacement is a const_double.\n", disp);
1486           return FALSE;
1487         }
1488
1489       if (flag_pic && SYMBOLIC_CONST (disp) && base != pic_offset_table_rtx
1490           && (indx != pic_offset_table_rtx || scale != NULL_RTX))
1491         {
1492           ADDR_INVALID ("Displacement is an invalid pic reference.\n", disp);
1493           return FALSE;
1494         }
1495
1496       if (HALF_PIC_P () && HALF_PIC_ADDRESS_P (disp)
1497           && (base != NULL_RTX || indx != NULL_RTX))
1498         {
1499           ADDR_INVALID ("Displacement is an invalid half-pic reference.\n", disp);
1500           return FALSE;
1501         }
1502     }
1503
1504   if (TARGET_DEBUG_ADDR)
1505     fprintf (stderr, "Address is valid.\n");
1506
1507   /* Everything looks valid, return true */
1508   return TRUE;
1509 }
1510
1511 \f
1512 /* Return a legitimate reference for ORIG (an address) using the
1513    register REG.  If REG is 0, a new pseudo is generated.
1514
1515    There are three types of references that must be handled:
1516
1517    1. Global data references must load the address from the GOT, via
1518       the PIC reg.  An insn is emitted to do this load, and the reg is
1519       returned.
1520
1521    2. Static data references must compute the address as an offset
1522       from the GOT, whose base is in the PIC reg.  An insn is emitted to
1523       compute the address into a reg, and the reg is returned.  Static
1524       data objects have SYMBOL_REF_FLAG set to differentiate them from
1525       global data objects.
1526
1527    3. Constant pool addresses must be handled special.  They are
1528       considered legitimate addresses, but only if not used with regs.
1529       When printed, the output routines know to print the reference with the
1530       PIC reg, even though the PIC reg doesn't appear in the RTL.
1531
1532    GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
1533    reg also appears in the address (except for constant pool references,
1534    noted above).
1535
1536    "switch" statements also require special handling when generating
1537    PIC code.  See comments by the `casesi' insn in i386.md for details.  */
1538
1539 rtx
1540 legitimize_pic_address (orig, reg)
1541      rtx orig;
1542      rtx reg;
1543 {
1544   rtx addr = orig;
1545   rtx new = orig;
1546
1547   if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
1548     {
1549       if (GET_CODE (addr) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (addr))
1550         reg = new = orig;
1551       else
1552         {
1553           if (reg == 0)
1554             reg = gen_reg_rtx (Pmode);
1555
1556           if ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
1557               || GET_CODE (addr) == LABEL_REF)
1558             new = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig);
1559           else
1560             new = gen_rtx (MEM, Pmode,
1561                            gen_rtx (PLUS, Pmode,
1562                                     pic_offset_table_rtx, orig));
1563
1564           emit_move_insn (reg, new);
1565         }
1566       current_function_uses_pic_offset_table = 1;
1567       return reg;
1568     }
1569   else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
1570     {
1571       rtx base;
1572
1573       if (GET_CODE (addr) == CONST)
1574         {
1575           addr = XEXP (addr, 0);
1576           if (GET_CODE (addr) != PLUS)
1577             abort ();
1578         }
1579
1580       if (XEXP (addr, 0) == pic_offset_table_rtx)
1581         return orig;
1582
1583       if (reg == 0)
1584         reg = gen_reg_rtx (Pmode);
1585
1586       base = legitimize_pic_address (XEXP (addr, 0), reg);
1587       addr = legitimize_pic_address (XEXP (addr, 1),
1588                                      base == reg ? NULL_RTX : reg);
1589
1590       if (GET_CODE (addr) == CONST_INT)
1591         return plus_constant (base, INTVAL (addr));
1592
1593       if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
1594         {
1595           base = gen_rtx (PLUS, Pmode, base, XEXP (addr, 0));
1596           addr = XEXP (addr, 1);
1597         }
1598         return gen_rtx (PLUS, Pmode, base, addr);
1599     }
1600   return new;
1601 }
1602 \f
1603
1604 /* Emit insns to move operands[1] into operands[0].  */
1605
1606 void
1607 emit_pic_move (operands, mode)
1608      rtx *operands;
1609      enum machine_mode mode;
1610 {
1611   rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
1612
1613   if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
1614     operands[1] = (rtx) force_reg (SImode, operands[1]);
1615   else
1616     operands[1] = legitimize_pic_address (operands[1], temp);
1617 }
1618
1619 \f
1620 /* Try machine-dependent ways of modifying an illegitimate address
1621    to be legitimate.  If we find one, return the new, valid address.
1622    This macro is used in only one place: `memory_address' in explow.c.
1623
1624    OLDX is the address as it was before break_out_memory_refs was called.
1625    In some cases it is useful to look at this to decide what needs to be done.
1626
1627    MODE and WIN are passed so that this macro can use
1628    GO_IF_LEGITIMATE_ADDRESS.
1629
1630    It is always safe for this macro to do nothing.  It exists to recognize
1631    opportunities to optimize the output.
1632
1633    For the 80386, we handle X+REG by loading X into a register R and
1634    using R+REG.  R will go in a general reg and indexing will be used.
1635    However, if REG is a broken-out memory address or multiplication,
1636    nothing needs to be done because REG can certainly go in a general reg.
1637
1638    When -fpic is used, special handling is needed for symbolic references.
1639    See comments by legitimize_pic_address in i386.c for details.  */
1640
1641 rtx
1642 legitimize_address (x, oldx, mode)
1643      register rtx x;
1644      register rtx oldx;
1645      enum machine_mode mode;
1646 {
1647   int changed = 0;
1648   unsigned log;
1649
1650   if (TARGET_DEBUG_ADDR)
1651     {
1652       fprintf (stderr, "\n==========\nLEGITIMIZE_ADDRESS, mode = %s\n", GET_MODE_NAME (mode));
1653       debug_rtx (x);
1654     }
1655
1656   if (flag_pic && SYMBOLIC_CONST (x))
1657     return legitimize_pic_address (x, 0);
1658
1659   /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
1660   if (GET_CODE (x) == ASHIFT
1661       && GET_CODE (XEXP (x, 1)) == CONST_INT
1662       && (log = (unsigned)exact_log2 (INTVAL (XEXP (x, 1)))) < 4)
1663     {
1664       changed = 1;
1665       x = gen_rtx (MULT, Pmode,
1666                    force_reg (Pmode, XEXP (x, 0)),
1667                    GEN_INT (1 << log));
1668     }
1669
1670   if (GET_CODE (x) == PLUS)
1671     {
1672       /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
1673       if (GET_CODE (XEXP (x, 0)) == ASHIFT
1674           && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
1675           && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) < 4)
1676         {
1677           changed = 1;
1678           XEXP (x, 0) = gen_rtx (MULT, Pmode,
1679                                  force_reg (Pmode, XEXP (XEXP (x, 0), 0)),
1680                                  GEN_INT (1 << log));
1681         }
1682
1683       if (GET_CODE (XEXP (x, 1)) == ASHIFT
1684           && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
1685           && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 1), 1)))) < 4)
1686         {
1687           changed = 1;
1688           XEXP (x, 1) = gen_rtx (MULT, Pmode,
1689                                  force_reg (Pmode, XEXP (XEXP (x, 1), 0)),
1690                                  GEN_INT (1 << log));
1691         }
1692
1693       /* Put multiply first if it isn't already */
1694       if (GET_CODE (XEXP (x, 1)) == MULT)
1695         {
1696           rtx tmp = XEXP (x, 0);
1697           XEXP (x, 0) = XEXP (x, 1);
1698           XEXP (x, 1) = tmp;
1699           changed = 1;
1700         }
1701
1702       /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
1703          into (plus (plus (mult (reg) (const)) (reg)) (const)).  This can be
1704          created by virtual register instantiation, register elimination, and
1705          similar optimizations.  */
1706       if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS)
1707         {
1708           changed = 1;
1709           x = gen_rtx (PLUS, Pmode,
1710                        gen_rtx (PLUS, Pmode, XEXP (x, 0), XEXP (XEXP (x, 1), 0)),
1711                        XEXP (XEXP (x, 1), 1));
1712         }
1713
1714       /* Canonicalize (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
1715          into (plus (plus (mult (reg) (const)) (reg)) (const)).  */
1716       else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
1717                && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
1718                && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
1719                && CONSTANT_P (XEXP (x, 1)))
1720         {
1721           rtx constant, other;
1722
1723           if (GET_CODE (XEXP (x, 1)) == CONST_INT)
1724             {
1725               constant = XEXP (x, 1);
1726               other = XEXP (XEXP (XEXP (x, 0), 1), 1);
1727             }
1728           else if (GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 1)) == CONST_INT)
1729             {
1730               constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
1731               other = XEXP (x, 1);
1732             }
1733           else
1734             constant = 0;
1735
1736           if (constant)
1737             {
1738               changed = 1;
1739               x = gen_rtx (PLUS, Pmode,
1740                            gen_rtx (PLUS, Pmode, XEXP (XEXP (x, 0), 0),
1741                                     XEXP (XEXP (XEXP (x, 0), 1), 0)),
1742                            plus_constant (other, INTVAL (constant)));
1743             }
1744         }
1745
1746       if (changed && legitimate_address_p (mode, x, FALSE))
1747         return x;
1748
1749       if (GET_CODE (XEXP (x, 0)) == MULT)
1750         {
1751           changed = 1;
1752           XEXP (x, 0) = force_operand (XEXP (x, 0), 0);
1753         }
1754
1755       if (GET_CODE (XEXP (x, 1)) == MULT)
1756         {
1757           changed = 1;
1758           XEXP (x, 1) = force_operand (XEXP (x, 1), 0);
1759         }
1760
1761       if (changed
1762           && GET_CODE (XEXP (x, 1)) == REG
1763           && GET_CODE (XEXP (x, 0)) == REG)
1764         return x;
1765
1766       if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1)))
1767         {
1768           changed = 1;
1769           x = legitimize_pic_address (x, 0);
1770         }
1771
1772       if (changed && legitimate_address_p (mode, x, FALSE))
1773         return x;
1774
1775       if (GET_CODE (XEXP (x, 0)) == REG)
1776         {
1777           register rtx temp = gen_reg_rtx (Pmode);
1778           register rtx val  = force_operand (XEXP (x, 1), temp);
1779           if (val != temp)
1780             emit_move_insn (temp, val);
1781
1782           XEXP (x, 1) = temp;
1783           return x;
1784         }
1785
1786       else if (GET_CODE (XEXP (x, 1)) == REG)
1787         {
1788           register rtx temp = gen_reg_rtx (Pmode);
1789           register rtx val  = force_operand (XEXP (x, 0), temp);
1790           if (val != temp)
1791             emit_move_insn (temp, val);
1792
1793           XEXP (x, 0) = temp;
1794           return x;
1795         }
1796     }
1797
1798   return x;
1799 }
1800
1801 \f
1802 /* Print an integer constant expression in assembler syntax.  Addition
1803    and subtraction are the only arithmetic that may appear in these
1804    expressions.  FILE is the stdio stream to write to, X is the rtx, and
1805    CODE is the operand print code from the output string.  */
1806
1807 static void
1808 output_pic_addr_const (file, x, code)
1809      FILE *file;
1810      rtx x;
1811      int code;
1812 {
1813   char buf[256];
1814
1815   switch (GET_CODE (x))
1816     {
1817     case PC:
1818       if (flag_pic)
1819         putc ('.', file);
1820       else
1821         abort ();
1822       break;
1823
1824     case SYMBOL_REF:
1825     case LABEL_REF:
1826       if (GET_CODE (x) == SYMBOL_REF)
1827         assemble_name (file, XSTR (x, 0));
1828       else
1829         {
1830           ASM_GENERATE_INTERNAL_LABEL (buf, "L",
1831                                        CODE_LABEL_NUMBER (XEXP (x, 0)));
1832           assemble_name (asm_out_file, buf);
1833         }
1834
1835       if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
1836         fprintf (file, "@GOTOFF(%%ebx)");
1837       else if (code == 'P')
1838         fprintf (file, "@PLT");
1839       else if (GET_CODE (x) == LABEL_REF)
1840         fprintf (file, "@GOTOFF");
1841       else if (! SYMBOL_REF_FLAG (x))
1842         fprintf (file, "@GOT");
1843       else
1844         fprintf (file, "@GOTOFF");
1845
1846       break;
1847
1848     case CODE_LABEL:
1849       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
1850       assemble_name (asm_out_file, buf);
1851       break;
1852
1853     case CONST_INT:
1854       fprintf (file, "%d", INTVAL (x));
1855       break;
1856
1857     case CONST:
1858       /* This used to output parentheses around the expression,
1859          but that does not work on the 386 (either ATT or BSD assembler).  */
1860       output_pic_addr_const (file, XEXP (x, 0), code);
1861       break;
1862
1863     case CONST_DOUBLE:
1864       if (GET_MODE (x) == VOIDmode)
1865         {
1866           /* We can use %d if the number is <32 bits and positive.  */
1867           if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
1868             fprintf (file, "0x%x%08x",
1869                      CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
1870           else
1871             fprintf (file, "%d", CONST_DOUBLE_LOW (x));
1872         }
1873       else
1874         /* We can't handle floating point constants;
1875            PRINT_OPERAND must handle them.  */
1876         output_operand_lossage ("floating constant misused");
1877       break;
1878
1879     case PLUS:
1880       /* Some assemblers need integer constants to appear last (eg masm).  */
1881       if (GET_CODE (XEXP (x, 0)) == CONST_INT)
1882         {
1883           output_pic_addr_const (file, XEXP (x, 1), code);
1884           if (INTVAL (XEXP (x, 0)) >= 0)
1885             fprintf (file, "+");
1886           output_pic_addr_const (file, XEXP (x, 0), code);
1887         }
1888       else
1889         {
1890           output_pic_addr_const (file, XEXP (x, 0), code);
1891           if (INTVAL (XEXP (x, 1)) >= 0)
1892             fprintf (file, "+");
1893           output_pic_addr_const (file, XEXP (x, 1), code);
1894         }
1895       break;
1896
1897     case MINUS:
1898       output_pic_addr_const (file, XEXP (x, 0), code);
1899       fprintf (file, "-");
1900       output_pic_addr_const (file, XEXP (x, 1), code);
1901       break;
1902
1903     default:
1904       output_operand_lossage ("invalid expression as operand");
1905     }
1906 }
1907 \f
1908 /* Meaning of CODE:
1909    f -- float insn (print a CONST_DOUBLE as a float rather than in hex).
1910    D,L,W,B,Q,S -- print the opcode suffix for specified size of operand.
1911    R -- print the prefix for register names.
1912    z -- print the opcode suffix for the size of the current operand.
1913    * -- print a star (in certain assembler syntax)
1914    w -- print the operand as if it's a "word" (HImode) even if it isn't.
1915    c -- don't print special prefixes before constant operands.
1916 */
1917
1918 void
1919 print_operand (file, x, code)
1920      FILE *file;
1921      rtx x;
1922      int code;
1923 {
1924   if (code)
1925     {
1926       switch (code)
1927         {
1928         case '*':
1929           if (USE_STAR)
1930             putc ('*', file);
1931           return;
1932
1933         case 'L':
1934           PUT_OP_SIZE (code, 'l', file);
1935           return;
1936
1937         case 'W':
1938           PUT_OP_SIZE (code, 'w', file);
1939           return;
1940
1941         case 'B':
1942           PUT_OP_SIZE (code, 'b', file);
1943           return;
1944
1945         case 'Q':
1946           PUT_OP_SIZE (code, 'l', file);
1947           return;
1948
1949         case 'S':
1950           PUT_OP_SIZE (code, 's', file);
1951           return;
1952
1953         case 'T':
1954           PUT_OP_SIZE (code, 't', file);
1955           return;
1956
1957         case 'z':
1958           /* 387 opcodes don't get size suffixes if the operands are
1959              registers. */
1960
1961           if (STACK_REG_P (x))
1962             return;
1963
1964           /* this is the size of op from size of operand */
1965           switch (GET_MODE_SIZE (GET_MODE (x)))
1966             {
1967             case 1:
1968               PUT_OP_SIZE ('B', 'b', file);
1969               return;
1970
1971             case 2:
1972               PUT_OP_SIZE ('W', 'w', file);
1973               return;
1974
1975             case 4:
1976               if (GET_MODE (x) == SFmode)
1977                 {
1978                   PUT_OP_SIZE ('S', 's', file);
1979                   return;
1980                 }
1981               else
1982                 PUT_OP_SIZE ('L', 'l', file);
1983               return;
1984
1985             case 12:
1986                   PUT_OP_SIZE ('T', 't', file);
1987                   return;
1988
1989             case 8:
1990               if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
1991                 {
1992 #ifdef GAS_MNEMONICS
1993                   PUT_OP_SIZE ('Q', 'q', file);
1994                   return;
1995 #else
1996                   PUT_OP_SIZE ('Q', 'l', file); /* Fall through */
1997 #endif
1998                 }
1999
2000               PUT_OP_SIZE ('Q', 'l', file);
2001               return;
2002             }
2003
2004         case 'b':
2005         case 'w':
2006         case 'k':
2007         case 'h':
2008         case 'y':
2009         case 'P':
2010           break;
2011
2012         default:
2013           {
2014             char str[50];
2015
2016             sprintf (str, "invalid operand code `%c'", code);
2017             output_operand_lossage (str);
2018           }
2019         }
2020     }
2021   if (GET_CODE (x) == REG)
2022     {
2023       PRINT_REG (x, code, file);
2024     }
2025   else if (GET_CODE (x) == MEM)
2026     {
2027       PRINT_PTR (x, file);
2028       if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
2029         {
2030           if (flag_pic)
2031             output_pic_addr_const (file, XEXP (x, 0), code);
2032           else
2033             output_addr_const (file, XEXP (x, 0));
2034         }
2035       else
2036         output_address (XEXP (x, 0));
2037     }
2038   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
2039     {
2040       REAL_VALUE_TYPE r; long l;
2041       REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2042       REAL_VALUE_TO_TARGET_SINGLE (r, l);
2043       PRINT_IMMED_PREFIX (file);
2044       fprintf (file, "0x%x", l);
2045     }
2046  /* These float cases don't actually occur as immediate operands. */
2047  else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
2048     {
2049       REAL_VALUE_TYPE r; char dstr[30];
2050       REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2051       REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
2052       fprintf (file, "%s", dstr);
2053     }
2054   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == XFmode)
2055     {
2056       REAL_VALUE_TYPE r; char dstr[30];
2057       REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2058       REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
2059       fprintf (file, "%s", dstr);
2060     }
2061   else 
2062     {
2063       if (code != 'P')
2064         {
2065           if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
2066             PRINT_IMMED_PREFIX (file);
2067           else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
2068                    || GET_CODE (x) == LABEL_REF)
2069             PRINT_OFFSET_PREFIX (file);
2070         }
2071       if (flag_pic)
2072         output_pic_addr_const (file, x, code);
2073       else
2074         output_addr_const (file, x);
2075     }
2076 }
2077 \f
2078 /* Print a memory operand whose address is ADDR.  */
2079
2080 void
2081 print_operand_address (file, addr)
2082      FILE *file;
2083      register rtx addr;
2084 {
2085   register rtx reg1, reg2, breg, ireg;
2086   rtx offset;
2087
2088   switch (GET_CODE (addr))
2089     {
2090     case REG:
2091       ADDR_BEG (file);
2092       fprintf (file, "%se", RP);
2093       fputs (hi_reg_name[REGNO (addr)], file);
2094       ADDR_END (file);
2095       break;
2096
2097     case PLUS:
2098       reg1 = 0;
2099       reg2 = 0;
2100       ireg = 0;
2101       breg = 0;
2102       offset = 0;
2103       if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
2104         {
2105           offset = XEXP (addr, 0);
2106           addr = XEXP (addr, 1);
2107         }
2108       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
2109         {
2110           offset = XEXP (addr, 1);
2111           addr = XEXP (addr, 0);
2112         }
2113       if (GET_CODE (addr) != PLUS) ;
2114       else if (GET_CODE (XEXP (addr, 0)) == MULT)
2115         {
2116           reg1 = XEXP (addr, 0);
2117           addr = XEXP (addr, 1);
2118         }
2119       else if (GET_CODE (XEXP (addr, 1)) == MULT)
2120         {
2121           reg1 = XEXP (addr, 1);
2122           addr = XEXP (addr, 0);
2123         }
2124       else if (GET_CODE (XEXP (addr, 0)) == REG)
2125         {
2126           reg1 = XEXP (addr, 0);
2127           addr = XEXP (addr, 1);
2128         }
2129       else if (GET_CODE (XEXP (addr, 1)) == REG)
2130         {
2131           reg1 = XEXP (addr, 1);
2132           addr = XEXP (addr, 0);
2133         }
2134       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
2135         {
2136           if (reg1 == 0) reg1 = addr;
2137           else reg2 = addr;
2138           addr = 0;
2139         }
2140       if (offset != 0)
2141         {
2142           if (addr != 0) abort ();
2143           addr = offset;
2144         }
2145       if ((reg1 && GET_CODE (reg1) == MULT)
2146           || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
2147         {
2148           breg = reg2;
2149           ireg = reg1;
2150         }
2151       else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
2152         {
2153           breg = reg1;
2154           ireg = reg2;
2155         }
2156
2157       if (ireg != 0 || breg != 0)
2158         {
2159           int scale = 1;
2160
2161           if (addr != 0)
2162             {
2163               if (flag_pic)
2164                 output_pic_addr_const (file, addr, 0);
2165
2166               else if (GET_CODE (addr) == LABEL_REF)
2167                 output_asm_label (addr);
2168
2169               else
2170                 output_addr_const (file, addr);
2171             }
2172
2173           if (ireg != 0 && GET_CODE (ireg) == MULT)
2174             {
2175               scale = INTVAL (XEXP (ireg, 1));
2176               ireg = XEXP (ireg, 0);
2177             }
2178
2179           /* The stack pointer can only appear as a base register,
2180              never an index register, so exchange the regs if it is wrong. */
2181
2182           if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM)
2183             {
2184               rtx tmp;
2185
2186               tmp = breg;
2187               breg = ireg;
2188               ireg = tmp;
2189             }
2190
2191           /* output breg+ireg*scale */
2192           PRINT_B_I_S (breg, ireg, scale, file);
2193           break;
2194         }
2195
2196     case MULT:
2197       {
2198         int scale;
2199         if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
2200           {
2201             scale = INTVAL (XEXP (addr, 0));
2202             ireg = XEXP (addr, 1);
2203           }
2204         else
2205           {
2206             scale = INTVAL (XEXP (addr, 1));
2207             ireg = XEXP (addr, 0);
2208           }
2209         output_addr_const (file, const0_rtx);
2210         PRINT_B_I_S ((rtx) 0, ireg, scale, file);
2211       }
2212       break;
2213
2214     default:
2215       if (GET_CODE (addr) == CONST_INT
2216           && INTVAL (addr) < 0x8000
2217           && INTVAL (addr) >= -0x8000)
2218         fprintf (file, "%d", INTVAL (addr));
2219       else
2220         {
2221           if (flag_pic)
2222             output_pic_addr_const (file, addr, 0);
2223           else
2224             output_addr_const (file, addr);
2225         }
2226     }
2227 }
2228 \f
2229 /* Set the cc_status for the results of an insn whose pattern is EXP.
2230    On the 80386, we assume that only test and compare insns, as well
2231    as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, ASHIFT,
2232    ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
2233    Also, we assume that jumps, moves and sCOND don't affect the condition
2234    codes.  All else clobbers the condition codes, by assumption.
2235
2236    We assume that ALL integer add, minus, etc. instructions effect the
2237    condition codes.  This MUST be consistent with i386.md.
2238
2239    We don't record any float test or compare - the redundant test &
2240    compare check in final.c does not handle stack-like regs correctly. */
2241
2242 void
2243 notice_update_cc (exp)
2244      rtx exp;
2245 {
2246   if (GET_CODE (exp) == SET)
2247     {
2248       /* Jumps do not alter the cc's.  */
2249       if (SET_DEST (exp) == pc_rtx)
2250         return;
2251       /* Moving register or memory into a register:
2252          it doesn't alter the cc's, but it might invalidate
2253          the RTX's which we remember the cc's came from.
2254          (Note that moving a constant 0 or 1 MAY set the cc's).  */
2255       if (REG_P (SET_DEST (exp))
2256           && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM
2257               || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
2258         {
2259           if (cc_status.value1
2260               && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
2261             cc_status.value1 = 0;
2262           if (cc_status.value2
2263               && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
2264             cc_status.value2 = 0;
2265           return;
2266         }
2267       /* Moving register into memory doesn't alter the cc's.
2268          It may invalidate the RTX's which we remember the cc's came from.  */
2269       if (GET_CODE (SET_DEST (exp)) == MEM
2270           && (REG_P (SET_SRC (exp))
2271               || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
2272         {
2273           if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
2274             cc_status.value1 = 0;
2275           if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
2276             cc_status.value2 = 0;
2277           return;
2278         }
2279       /* Function calls clobber the cc's.  */
2280       else if (GET_CODE (SET_SRC (exp)) == CALL)
2281         {
2282           CC_STATUS_INIT;
2283           return;
2284         }
2285       /* Tests and compares set the cc's in predictable ways.  */
2286       else if (SET_DEST (exp) == cc0_rtx)
2287         {
2288           CC_STATUS_INIT;
2289           cc_status.value1 = SET_SRC (exp);
2290           return;
2291         }
2292       /* Certain instructions effect the condition codes. */
2293       else if (GET_MODE (SET_SRC (exp)) == SImode
2294                || GET_MODE (SET_SRC (exp)) == HImode
2295                || GET_MODE (SET_SRC (exp)) == QImode)
2296         switch (GET_CODE (SET_SRC (exp)))
2297           {
2298           case ASHIFTRT: case LSHIFTRT:
2299           case ASHIFT:
2300             /* Shifts on the 386 don't set the condition codes if the
2301                shift count is zero. */
2302             if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
2303               {
2304                 CC_STATUS_INIT;
2305                 break;
2306               }
2307             /* We assume that the CONST_INT is non-zero (this rtx would
2308                have been deleted if it were zero. */
2309
2310           case PLUS: case MINUS: case NEG:
2311           case AND: case IOR: case XOR:
2312             cc_status.flags = CC_NO_OVERFLOW;
2313             cc_status.value1 = SET_SRC (exp);
2314             cc_status.value2 = SET_DEST (exp);
2315             break;
2316
2317           default:
2318             CC_STATUS_INIT;
2319           }
2320       else
2321         {
2322           CC_STATUS_INIT;
2323         }
2324     }
2325   else if (GET_CODE (exp) == PARALLEL
2326            && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
2327     {
2328       if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
2329         return;
2330       if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
2331         {
2332           CC_STATUS_INIT;
2333           if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
2334             cc_status.flags |= CC_IN_80387;
2335           else
2336             cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
2337           return;
2338         }
2339       CC_STATUS_INIT;
2340     }
2341   else
2342     {
2343       CC_STATUS_INIT;
2344     }
2345 }
2346 \f
2347 /* Split one or more DImode RTL references into pairs of SImode
2348    references.  The RTL can be REG, offsettable MEM, integer constant, or
2349    CONST_DOUBLE.  "operands" is a pointer to an array of DImode RTL to
2350    split and "num" is its length.  lo_half and hi_half are output arrays
2351    that parallel "operands". */
2352
2353 void
2354 split_di (operands, num, lo_half, hi_half)
2355      rtx operands[];
2356      int num;
2357      rtx lo_half[], hi_half[];
2358 {
2359   while (num--)
2360     {
2361       if (GET_CODE (operands[num]) == REG)
2362         {
2363           lo_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]));
2364           hi_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]) + 1);
2365         }
2366       else if (CONSTANT_P (operands[num]))
2367         {
2368           split_double (operands[num], &lo_half[num], &hi_half[num]);
2369         }
2370       else if (offsettable_memref_p (operands[num]))
2371         {
2372           lo_half[num] = operands[num];
2373           hi_half[num] = adj_offsettable_operand (operands[num], 4);
2374         }
2375       else
2376         abort();
2377     }
2378 }
2379 \f
2380 /* Return 1 if this is a valid binary operation on a 387.
2381    OP is the expression matched, and MODE is its mode. */
2382
2383 int
2384 binary_387_op (op, mode)
2385     register rtx op;
2386     enum machine_mode mode;
2387 {
2388   if (mode != VOIDmode && mode != GET_MODE (op))
2389     return 0;
2390
2391   switch (GET_CODE (op))
2392     {
2393     case PLUS:
2394     case MINUS:
2395     case MULT:
2396     case DIV:
2397       return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
2398
2399     default:
2400       return 0;
2401     }
2402 }
2403
2404 \f
2405 /* Return 1 if this is a valid shift or rotate operation on a 386.
2406    OP is the expression matched, and MODE is its mode. */
2407
2408 int
2409 shift_op (op, mode)
2410     register rtx op;
2411     enum machine_mode mode;
2412 {
2413   rtx operand = XEXP (op, 0);
2414
2415   if (mode != VOIDmode && mode != GET_MODE (op))
2416     return 0;
2417
2418   if (GET_MODE (operand) != GET_MODE (op)
2419       || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
2420     return 0;
2421
2422   return (GET_CODE (op) == ASHIFT
2423           || GET_CODE (op) == ASHIFTRT
2424           || GET_CODE (op) == LSHIFTRT
2425           || GET_CODE (op) == ROTATE
2426           || GET_CODE (op) == ROTATERT);
2427 }
2428
2429 /* Return 1 if OP is COMPARE rtx with mode VOIDmode.
2430    MODE is not used.  */
2431
2432 int
2433 VOIDmode_compare_op (op, mode)
2434     register rtx op;
2435     enum machine_mode mode;
2436 {
2437   return GET_CODE (op) == COMPARE && GET_MODE (op) == VOIDmode;
2438 }
2439 \f
2440 /* Output code to perform a 387 binary operation in INSN, one of PLUS,
2441    MINUS, MULT or DIV.  OPERANDS are the insn operands, where operands[3]
2442    is the expression of the binary operation.  The output may either be
2443    emitted here, or returned to the caller, like all output_* functions.
2444
2445    There is no guarantee that the operands are the same mode, as they
2446    might be within FLOAT or FLOAT_EXTEND expressions. */
2447
2448 char *
2449 output_387_binary_op (insn, operands)
2450      rtx insn;
2451      rtx *operands;
2452 {
2453   rtx temp;
2454   char *base_op;
2455   static char buf[100];
2456
2457   switch (GET_CODE (operands[3]))
2458     {
2459     case PLUS:
2460       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2461           || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
2462         base_op = "fiadd";
2463       else
2464         base_op = "fadd";
2465       break;
2466
2467     case MINUS:
2468       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2469           || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
2470         base_op = "fisub";
2471       else
2472         base_op = "fsub";
2473       break;
2474
2475     case MULT:
2476       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2477           || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
2478         base_op = "fimul";
2479       else
2480         base_op = "fmul";
2481       break;
2482
2483     case DIV:
2484       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2485           || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
2486         base_op = "fidiv";
2487       else
2488         base_op = "fdiv";
2489       break;
2490
2491     default:
2492       abort ();
2493     }
2494
2495   strcpy (buf, base_op);
2496
2497   switch (GET_CODE (operands[3]))
2498     {
2499     case MULT:
2500     case PLUS:
2501       if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
2502         {
2503           temp = operands[2];
2504           operands[2] = operands[1];
2505           operands[1] = temp;
2506         }
2507
2508       if (GET_CODE (operands[2]) == MEM)
2509         return strcat (buf, AS1 (%z2,%2));
2510
2511       if (NON_STACK_REG_P (operands[1]))
2512         {
2513           output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
2514           RET;
2515         }
2516       else if (NON_STACK_REG_P (operands[2]))
2517         {
2518           output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
2519           RET;
2520         }
2521
2522       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
2523         return strcat (buf, AS2 (p,%2,%0));
2524
2525       if (STACK_TOP_P (operands[0]))
2526         return strcat (buf, AS2C (%y2,%0));
2527       else
2528         return strcat (buf, AS2C (%2,%0));
2529
2530     case MINUS:
2531     case DIV:
2532       if (GET_CODE (operands[1]) == MEM)
2533         return strcat (buf, AS1 (r%z1,%1));
2534
2535       if (GET_CODE (operands[2]) == MEM)
2536         return strcat (buf, AS1 (%z2,%2));
2537
2538       if (NON_STACK_REG_P (operands[1]))
2539         {
2540           output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1)));
2541           RET;
2542         }
2543       else if (NON_STACK_REG_P (operands[2]))
2544         {
2545           output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
2546           RET;
2547         }
2548
2549       if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
2550         abort ();
2551
2552       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
2553         return strcat (buf, AS2 (rp,%2,%0));
2554
2555       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2556         return strcat (buf, AS2 (p,%1,%0));
2557
2558       if (STACK_TOP_P (operands[0]))
2559         {
2560           if (STACK_TOP_P (operands[1]))
2561             return strcat (buf, AS2C (%y2,%0));
2562           else
2563             return strcat (buf, AS2 (r,%y1,%0));
2564         }
2565       else if (STACK_TOP_P (operands[1]))
2566         return strcat (buf, AS2C (%1,%0));
2567       else
2568         return strcat (buf, AS2 (r,%2,%0));
2569
2570     default:
2571       abort ();
2572     }
2573 }
2574 \f
2575 /* Output code for INSN to convert a float to a signed int.  OPERANDS
2576    are the insn operands.  The output may be SFmode or DFmode and the
2577    input operand may be SImode or DImode.  As a special case, make sure
2578    that the 387 stack top dies if the output mode is DImode, because the
2579    hardware requires this.  */
2580
2581 char *
2582 output_fix_trunc (insn, operands)
2583      rtx insn;
2584      rtx *operands;
2585 {
2586   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2587   rtx xops[2];
2588
2589   if (! STACK_TOP_P (operands[1]) ||
2590       (GET_MODE (operands[0]) == DImode && ! stack_top_dies))
2591     abort ();
2592
2593   xops[0] = GEN_INT (12);
2594   xops[1] = operands[4];
2595
2596   output_asm_insn (AS1 (fnstc%W2,%2), operands);
2597   output_asm_insn (AS2 (mov%L2,%2,%4), operands);
2598   output_asm_insn (AS2 (mov%B1,%0,%h1), xops);
2599   output_asm_insn (AS2 (mov%L4,%4,%3), operands);
2600   output_asm_insn (AS1 (fldc%W3,%3), operands);
2601
2602   if (NON_STACK_REG_P (operands[0]))
2603     output_to_reg (operands[0], stack_top_dies);
2604   else if (GET_CODE (operands[0]) == MEM)
2605     {
2606       if (stack_top_dies)
2607         output_asm_insn (AS1 (fistp%z0,%0), operands);
2608       else
2609         output_asm_insn (AS1 (fist%z0,%0), operands);
2610     }
2611   else
2612     abort ();
2613
2614   return AS1 (fldc%W2,%2);
2615 }
2616 \f
2617 /* Output code for INSN to compare OPERANDS.  The two operands might
2618    not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
2619    expression.  If the compare is in mode CCFPEQmode, use an opcode that
2620    will not fault if a qNaN is present. */
2621
2622 char *
2623 output_float_compare (insn, operands)
2624      rtx insn;
2625      rtx *operands;
2626 {
2627   int stack_top_dies;
2628   rtx body = XVECEXP (PATTERN (insn), 0, 0);
2629   int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
2630
2631   if (! STACK_TOP_P (operands[0]))
2632     abort ();
2633
2634   stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2635
2636   if (STACK_REG_P (operands[1])
2637       && stack_top_dies
2638       && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
2639       && REGNO (operands[1]) != FIRST_STACK_REG)
2640     {
2641       /* If both the top of the 387 stack dies, and the other operand
2642          is also a stack register that dies, then this must be a
2643          `fcompp' float compare */
2644
2645       if (unordered_compare)
2646         output_asm_insn ("fucompp", operands);
2647       else
2648         output_asm_insn ("fcompp", operands);
2649     }
2650   else
2651     {
2652       static char buf[100];
2653
2654       /* Decide if this is the integer or float compare opcode, or the
2655          unordered float compare. */
2656
2657       if (unordered_compare)
2658         strcpy (buf, "fucom");
2659       else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT)
2660         strcpy (buf, "fcom");
2661       else
2662         strcpy (buf, "ficom");
2663
2664       /* Modify the opcode if the 387 stack is to be popped. */
2665
2666       if (stack_top_dies)
2667         strcat (buf, "p");
2668
2669       if (NON_STACK_REG_P (operands[1]))
2670         output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
2671       else
2672         output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
2673     }
2674
2675   /* Now retrieve the condition code. */
2676
2677   return output_fp_cc0_set (insn);
2678 }
2679 \f
2680 /* Output opcodes to transfer the results of FP compare or test INSN
2681    from the FPU to the CPU flags.  If TARGET_IEEE_FP, ensure that if the
2682    result of the compare or test is unordered, no comparison operator
2683    succeeds except NE.  Return an output template, if any.  */
2684
2685 char *
2686 output_fp_cc0_set (insn)
2687      rtx insn;
2688 {
2689   rtx xops[3];
2690   rtx unordered_label;
2691   rtx next;
2692   enum rtx_code code;
2693
2694   xops[0] = gen_rtx (REG, HImode, 0);
2695   output_asm_insn (AS1 (fnsts%W0,%0), xops);
2696
2697   if (! TARGET_IEEE_FP)
2698     return "sahf";
2699
2700   next = next_cc0_user (insn);
2701   if (next == NULL_RTX)
2702     abort ();
2703
2704   if (GET_CODE (next) == JUMP_INSN
2705       && GET_CODE (PATTERN (next)) == SET
2706       && SET_DEST (PATTERN (next)) == pc_rtx
2707       && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
2708     {
2709       code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
2710     }
2711   else if (GET_CODE (PATTERN (next)) == SET)
2712     {
2713       code = GET_CODE (SET_SRC (PATTERN (next)));
2714     }
2715   else
2716     abort ();
2717
2718   xops[0] = gen_rtx (REG, QImode, 0);
2719
2720   switch (code)
2721     {
2722     case GT:
2723       xops[1] = GEN_INT (0x45);
2724       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
2725       /* je label */
2726       break;
2727
2728     case LT:
2729       xops[1] = GEN_INT (0x45);
2730       xops[2] = GEN_INT (0x01);
2731       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
2732       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
2733       /* je label */
2734       break;
2735
2736     case GE:
2737       xops[1] = GEN_INT (0x05);
2738       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
2739       /* je label */
2740       break;
2741
2742     case LE:
2743       xops[1] = GEN_INT (0x45);
2744       xops[2] = GEN_INT (0x40);
2745       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
2746       output_asm_insn (AS1 (dec%B0,%h0), xops);
2747       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
2748       /* jb label */
2749       break;
2750
2751     case EQ:
2752       xops[1] = GEN_INT (0x45);
2753       xops[2] = GEN_INT (0x40);
2754       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
2755       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
2756       /* je label */
2757       break;
2758
2759     case NE:
2760       xops[1] = GEN_INT (0x44);
2761       xops[2] = GEN_INT (0x40);
2762       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
2763       output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
2764       /* jne label */
2765       break;
2766
2767     case GTU:
2768     case LTU:
2769     case GEU:
2770     case LEU:
2771     default:
2772       abort ();
2773     }
2774   RET;
2775 }
2776 \f
2777 #define MAX_386_STACK_LOCALS 2
2778
2779 static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
2780
2781 /* Define the structure for the machine field in struct function.  */
2782 struct machine_function
2783 {
2784   rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
2785 };
2786
2787 /* Functions to save and restore i386_stack_locals.
2788    These will be called, via pointer variables,
2789    from push_function_context and pop_function_context.  */
2790
2791 void
2792 save_386_machine_status (p)
2793      struct function *p;
2794 {
2795   p->machine = (struct machine_function *) xmalloc (sizeof i386_stack_locals);
2796   bcopy ((char *) i386_stack_locals, (char *) p->machine->i386_stack_locals,
2797          sizeof i386_stack_locals);
2798 }
2799
2800 void
2801 restore_386_machine_status (p)
2802      struct function *p;
2803 {
2804   bcopy ((char *) p->machine->i386_stack_locals, (char *) i386_stack_locals,
2805          sizeof i386_stack_locals);
2806   free (p->machine);
2807 }
2808
2809 /* Clear stack slot assignments remembered from previous functions.
2810    This is called from INIT_EXPANDERS once before RTL is emitted for each
2811    function.  */
2812
2813 void
2814 clear_386_stack_locals ()
2815 {
2816   enum machine_mode mode;
2817   int n;
2818
2819   for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
2820        mode = (enum machine_mode) ((int) mode + 1))
2821     for (n = 0; n < MAX_386_STACK_LOCALS; n++)
2822       i386_stack_locals[(int) mode][n] = NULL_RTX;
2823
2824   /* Arrange to save and restore i386_stack_locals around nested functions.  */
2825   save_machine_status = save_386_machine_status;
2826   restore_machine_status = restore_386_machine_status;
2827 }
2828
2829 /* Return a MEM corresponding to a stack slot with mode MODE.
2830    Allocate a new slot if necessary.
2831
2832    The RTL for a function can have several slots available: N is
2833    which slot to use.  */
2834
2835 rtx
2836 assign_386_stack_local (mode, n)
2837      enum machine_mode mode;
2838      int n;
2839 {
2840   if (n < 0 || n >= MAX_386_STACK_LOCALS)
2841     abort ();
2842
2843   if (i386_stack_locals[(int) mode][n] == NULL_RTX)
2844     i386_stack_locals[(int) mode][n]
2845       = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
2846
2847   return i386_stack_locals[(int) mode][n];
2848 }