OSDN Git Service

* i386.c (ix86_epilogue): For pentium processors, try to deallocate
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.c
1 /* Subroutines for insn-output.c for Intel X86.
2    Copyright (C) 1988, 92, 94, 95, 96, 97, 1998 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, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21 #include <setjmp.h>
22 #include "config.h"
23 #include "system.h"
24 #include "rtl.h"
25 #include "regs.h"
26 #include "hard-reg-set.h"
27 #include "real.h"
28 #include "insn-config.h"
29 #include "conditions.h"
30 #include "insn-flags.h"
31 #include "output.h"
32 #include "insn-attr.h"
33 #include "tree.h"
34 #include "flags.h"
35 #include "except.h"
36 #include "function.h"
37 #include "recog.h"
38 #include "expr.h"
39 #include "toplev.h"
40
41 #ifdef EXTRA_CONSTRAINT
42 /* If EXTRA_CONSTRAINT is defined, then the 'S'
43    constraint in REG_CLASS_FROM_LETTER will no longer work, and various
44    asm statements that need 'S' for class SIREG will break.  */
45  error EXTRA_CONSTRAINT conflicts with S constraint letter
46 /* The previous line used to be #error, but some compilers barf
47    even if the conditional was untrue.  */
48 #endif
49
50 #ifndef CHECK_STACK_LIMIT
51 #define CHECK_STACK_LIMIT -1
52 #endif
53
54 /* Type of an operand for ix86_{binary,unary}_operator_ok */
55 enum reg_mem
56 {
57   reg_p,
58   mem_p,
59   imm_p
60 };
61
62 /* Processor costs (relative to an add) */
63 struct processor_costs i386_cost = {    /* 386 specific costs */
64   1,                                    /* cost of an add instruction */
65   1,                                    /* cost of a lea instruction */
66   3,                                    /* variable shift costs */
67   2,                                    /* constant shift costs */
68   6,                                    /* cost of starting a multiply */
69   1,                                    /* cost of multiply per each bit set */
70   23                                    /* cost of a divide/mod */
71 };
72
73 struct processor_costs i486_cost = {    /* 486 specific costs */
74   1,                                    /* cost of an add instruction */
75   1,                                    /* cost of a lea instruction */
76   3,                                    /* variable shift costs */
77   2,                                    /* constant shift costs */
78   12,                                   /* cost of starting a multiply */
79   1,                                    /* cost of multiply per each bit set */
80   40                                    /* cost of a divide/mod */
81 };
82
83 struct processor_costs pentium_cost = {
84   1,                                    /* cost of an add instruction */
85   1,                                    /* cost of a lea instruction */
86   4,                                    /* variable shift costs */
87   1,                                    /* constant shift costs */
88   11,                                   /* cost of starting a multiply */
89   0,                                    /* cost of multiply per each bit set */
90   25                                    /* cost of a divide/mod */
91 };
92
93 struct processor_costs pentiumpro_cost = {
94   1,                                    /* cost of an add instruction */
95   1,                                    /* cost of a lea instruction */
96   3,                                    /* variable shift costs */
97   1,                                    /* constant shift costs */
98   4,                                    /* cost of starting a multiply */
99   0,                                    /* cost of multiply per each bit set */
100   17                                    /* cost of a divide/mod */
101 };
102
103 struct processor_costs *ix86_cost = &pentium_cost;
104
105 #define AT_BP(mode) (gen_rtx_MEM ((mode), frame_pointer_rtx))
106
107 extern FILE *asm_out_file;
108 extern char *strcat ();
109
110 static void ix86_epilogue PROTO((int));
111 static void ix86_prologue PROTO((int));
112
113 char *singlemove_string ();
114 char *output_move_const_single ();
115 char *output_fp_cc0_set ();
116
117 char *hi_reg_name[] = HI_REGISTER_NAMES;
118 char *qi_reg_name[] = QI_REGISTER_NAMES;
119 char *qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES;
120
121 /* Array of the smallest class containing reg number REGNO, indexed by
122    REGNO.  Used by REGNO_REG_CLASS in i386.h. */
123
124 enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
125 {
126   /* ax, dx, cx, bx */
127   AREG, DREG, CREG, BREG,
128   /* si, di, bp, sp */
129   SIREG, DIREG, INDEX_REGS, GENERAL_REGS,
130   /* FP registers */
131   FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
132   FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,       
133   /* arg pointer */
134   INDEX_REGS
135 };
136
137 /* Test and compare insns in i386.md store the information needed to
138    generate branch and scc insns here.  */
139
140 struct rtx_def *i386_compare_op0 = NULL_RTX;
141 struct rtx_def *i386_compare_op1 = NULL_RTX;
142 struct rtx_def *(*i386_compare_gen)(), *(*i386_compare_gen_eq)();
143
144 /* which cpu are we scheduling for */
145 enum processor_type ix86_cpu;
146
147 /* which instruction set architecture to use.  */
148 int ix86_arch;
149
150 /* Strings to hold which cpu and instruction set architecture  to use.  */
151 char *ix86_cpu_string;          /* for -mcpu=<xxx> */
152 char *ix86_arch_string;         /* for -march=<xxx> */
153
154 /* Register allocation order */
155 char *i386_reg_alloc_order;
156 static char regs_allocated[FIRST_PSEUDO_REGISTER];
157
158 /* # of registers to use to pass arguments. */
159 char *i386_regparm_string;
160
161 /* i386_regparm_string as a number */
162 int i386_regparm;
163
164 /* Alignment to use for loops and jumps:  */
165
166 /* Power of two alignment for loops. */
167 char *i386_align_loops_string;
168
169 /* Power of two alignment for non-loop jumps. */
170 char *i386_align_jumps_string;
171
172 /* Values 1-5: see jump.c */
173 int i386_branch_cost;
174 char *i386_branch_cost_string;
175
176 /* Power of two alignment for functions. */
177 int i386_align_funcs;
178 char *i386_align_funcs_string;
179
180 /* Power of two alignment for loops. */
181 int i386_align_loops;
182
183 /* Power of two alignment for non-loop jumps. */
184 int i386_align_jumps;
185
186 /* Sometimes certain combinations of command options do not make
187    sense on a particular target machine.  You can define a macro
188    `OVERRIDE_OPTIONS' to take account of this.  This macro, if
189    defined, is executed once just after all the command options have
190    been parsed.
191
192    Don't use this macro to turn on various extra optimizations for
193    `-O'.  That is what `OPTIMIZATION_OPTIONS' is for.  */
194
195 void
196 override_options ()
197 {
198   int ch, i, j;
199   int def_align;
200
201   static struct ptt
202     {
203       char *name;               /* Canonical processor name.  */
204       enum processor_type processor; /* Processor type enum value.  */
205       struct processor_costs *cost; /* Processor costs */
206       int target_enable;        /* Target flags to enable.  */
207       int target_disable;       /* Target flags to disable.  */
208     } processor_target_table[]
209       = {{PROCESSOR_I386_STRING, PROCESSOR_I386, &i386_cost, 0, 0},
210            {PROCESSOR_I486_STRING, PROCESSOR_I486, &i486_cost, 0, 0},
211            {PROCESSOR_I586_STRING, PROCESSOR_PENTIUM, &pentium_cost, 0, 0},
212            {PROCESSOR_PENTIUM_STRING, PROCESSOR_PENTIUM, &pentium_cost, 0, 0},
213            {PROCESSOR_I686_STRING, PROCESSOR_PENTIUMPRO, &pentiumpro_cost,
214               0, 0},
215            {PROCESSOR_PENTIUMPRO_STRING, PROCESSOR_PENTIUMPRO,
216               &pentiumpro_cost, 0, 0}};
217
218   int ptt_size = sizeof (processor_target_table) / sizeof (struct ptt);
219
220 #ifdef SUBTARGET_OVERRIDE_OPTIONS
221   SUBTARGET_OVERRIDE_OPTIONS;
222 #endif
223
224   /* Validate registers in register allocation order.  */
225   if (i386_reg_alloc_order)
226     {
227       for (i = 0; (ch = i386_reg_alloc_order[i]) != '\0'; i++)
228         {
229           int regno = 0;
230           
231           switch (ch)
232             {
233             case 'a':   regno = 0;      break;
234             case 'd':   regno = 1;      break;
235             case 'c':   regno = 2;      break;
236             case 'b':   regno = 3;      break;
237             case 'S':   regno = 4;      break;
238             case 'D':   regno = 5;      break;
239             case 'B':   regno = 6;      break;
240
241             default:    fatal ("Register '%c' is unknown", ch);
242             }
243
244           if (regs_allocated[regno])
245             fatal ("Register '%c' already specified in allocation order", ch);
246
247           regs_allocated[regno] = 1;
248         }
249     }
250
251   if (ix86_arch_string == 0)
252     {
253       ix86_arch_string = PROCESSOR_PENTIUM_STRING;
254       if (ix86_cpu_string == 0)
255         ix86_cpu_string = PROCESSOR_DEFAULT_STRING;
256     }
257   
258   for (i = 0; i < ptt_size; i++)
259     if (! strcmp (ix86_arch_string, processor_target_table[i].name))
260       {
261         ix86_arch = processor_target_table[i].processor;
262         if (ix86_cpu_string == 0)
263           ix86_cpu_string = processor_target_table[i].name;
264         break;
265       }
266
267   if (i == ptt_size)
268     {
269       error ("bad value (%s) for -march= switch", ix86_arch_string);
270       ix86_arch_string = PROCESSOR_PENTIUM_STRING;
271       ix86_arch = PROCESSOR_DEFAULT;
272     }
273
274   if (ix86_cpu_string == 0)
275     ix86_cpu_string = PROCESSOR_DEFAULT_STRING;
276
277   for (j = 0; j < ptt_size; j++)
278     if (! strcmp (ix86_cpu_string, processor_target_table[j].name))
279       {
280         ix86_cpu = processor_target_table[j].processor;
281         ix86_cost = processor_target_table[j].cost;
282         if (i > j && (int) ix86_arch >= (int) PROCESSOR_PENTIUMPRO)
283           error ("-mcpu=%s does not support -march=%s",
284                  ix86_cpu_string, ix86_arch_string);
285
286         target_flags |= processor_target_table[j].target_enable;
287         target_flags &= ~processor_target_table[j].target_disable;
288         break;
289       }
290
291   if (j == ptt_size)
292     {
293       error ("bad value (%s) for -mcpu= switch", ix86_cpu_string);
294       ix86_cpu_string = PROCESSOR_DEFAULT_STRING;
295       ix86_cpu = PROCESSOR_DEFAULT;
296     }
297
298   /* Validate -mregparm= value. */
299   if (i386_regparm_string)
300     {
301       i386_regparm = atoi (i386_regparm_string);
302       if (i386_regparm < 0 || i386_regparm > REGPARM_MAX)
303         fatal ("-mregparm=%d is not between 0 and %d",
304                i386_regparm, REGPARM_MAX);
305     }
306
307   /* The 486 suffers more from non-aligned cache line fills, and the
308      larger code size results in a larger cache foot-print and more misses.
309      The 486 has a 16 byte cache line, pentium and pentiumpro have a 32 byte
310      cache line.  */
311   def_align = (TARGET_486) ? 4 : 2;
312
313   /* Validate -malign-loops= value, or provide default.  */
314   if (i386_align_loops_string)
315     {
316       i386_align_loops = atoi (i386_align_loops_string);
317       if (i386_align_loops < 0 || i386_align_loops > MAX_CODE_ALIGN)
318         fatal ("-malign-loops=%d is not between 0 and %d",
319                i386_align_loops, MAX_CODE_ALIGN);
320     }
321   else
322 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
323     i386_align_loops = 4;
324 #else
325     i386_align_loops = 2;
326 #endif
327
328   /* Validate -malign-jumps= value, or provide default.  */
329   if (i386_align_jumps_string)
330     {
331       i386_align_jumps = atoi (i386_align_jumps_string);
332       if (i386_align_jumps < 0 || i386_align_jumps > MAX_CODE_ALIGN)
333         fatal ("-malign-jumps=%d is not between 0 and %d",
334                i386_align_jumps, MAX_CODE_ALIGN);
335     }
336   else
337 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
338     i386_align_jumps = 4;
339 #else
340     i386_align_jumps = def_align;
341 #endif
342
343   /* Validate -malign-functions= value, or provide default. */
344   if (i386_align_funcs_string)
345     {
346       i386_align_funcs = atoi (i386_align_funcs_string);
347       if (i386_align_funcs < 0 || i386_align_funcs > MAX_CODE_ALIGN)
348         fatal ("-malign-functions=%d is not between 0 and %d",
349                i386_align_funcs, MAX_CODE_ALIGN);
350     }
351   else
352     i386_align_funcs = def_align;
353
354   /* Validate -mbranch-cost= value, or provide default. */
355   if (i386_branch_cost_string)
356     {
357       i386_branch_cost = atoi (i386_branch_cost_string);
358       if (i386_branch_cost < 0 || i386_branch_cost > 5)
359         fatal ("-mbranch-cost=%d is not between 0 and 5",
360                i386_branch_cost);
361     }
362   else
363     i386_branch_cost = 1;
364
365   /* Keep nonleaf frame pointers.  */
366   if (TARGET_OMIT_LEAF_FRAME_POINTER)
367     flag_omit_frame_pointer = 1;
368 }
369 \f
370 /* A C statement (sans semicolon) to choose the order in which to
371    allocate hard registers for pseudo-registers local to a basic
372    block.
373
374    Store the desired register order in the array `reg_alloc_order'.
375    Element 0 should be the register to allocate first; element 1, the
376    next register; and so on.
377
378    The macro body should not assume anything about the contents of
379    `reg_alloc_order' before execution of the macro.
380
381    On most machines, it is not necessary to define this macro.  */
382
383 void
384 order_regs_for_local_alloc ()
385 {
386   int i, ch, order;
387
388   /* User specified the register allocation order.  */
389
390   if (i386_reg_alloc_order)
391     {
392       for (i = order = 0; (ch = i386_reg_alloc_order[i]) != '\0'; i++)
393         {
394           int regno = 0;
395           
396           switch (ch)
397             {
398             case 'a':   regno = 0;      break;
399             case 'd':   regno = 1;      break;
400             case 'c':   regno = 2;      break;
401             case 'b':   regno = 3;      break;
402             case 'S':   regno = 4;      break;
403             case 'D':   regno = 5;      break;
404             case 'B':   regno = 6;      break;
405             }
406
407           reg_alloc_order[order++] = regno;
408         }
409
410       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
411         {
412           if (! regs_allocated[i])
413             reg_alloc_order[order++] = i;
414         }
415     }
416
417   /* If user did not specify a register allocation order, use natural order. */
418   else
419     {
420       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
421         reg_alloc_order[i] = i;
422     }
423 }
424 \f
425 void
426 optimization_options (level, size)
427      int level;
428      int size ATTRIBUTE_UNUSED;
429 {
430   /* For -O2 and beyond, turn off -fschedule-insns by default.  It tends to
431      make the problem with not enough registers even worse.  */
432 #ifdef INSN_SCHEDULING
433   if (level > 1)
434     flag_schedule_insns = 0;
435 #endif
436 }
437 \f
438 /* Sign-extend a 16-bit constant */
439
440 struct rtx_def *
441 i386_sext16_if_const (op)
442      struct rtx_def *op;
443 {
444   if (GET_CODE (op) == CONST_INT)
445     {
446       HOST_WIDE_INT val = INTVAL (op);
447       HOST_WIDE_INT sext_val;
448       if (val & 0x8000)
449         sext_val = val | ~0xffff;
450       else
451         sext_val = val & 0xffff;
452       if (sext_val != val)
453         op = GEN_INT (sext_val);
454     }
455   return op;
456 }
457 \f
458 /* Return nonzero if the rtx is aligned */
459
460 static int
461 i386_aligned_reg_p (regno)
462      int regno;
463 {
464   return (regno == STACK_POINTER_REGNUM
465           || (! flag_omit_frame_pointer && regno == FRAME_POINTER_REGNUM));
466 }
467
468 int
469 i386_aligned_p (op)
470      rtx op;
471 {
472   /* Registers and immediate operands are always "aligned". */
473   if (GET_CODE (op) != MEM)
474     return 1;
475
476   /* Don't even try to do any aligned optimizations with volatiles. */
477   if (MEM_VOLATILE_P (op))
478     return 0;
479
480   /* Get address of memory operand. */
481   op = XEXP (op, 0);
482
483   switch (GET_CODE (op))
484     {
485     case CONST_INT:
486       if (INTVAL (op) & 3)
487         break;
488       return 1;
489
490       /* Match "reg + offset" */
491     case PLUS:
492       if (GET_CODE (XEXP (op, 1)) != CONST_INT)
493         break;
494       if (INTVAL (XEXP (op, 1)) & 3)
495         break;
496
497       op = XEXP (op, 0);
498       if (GET_CODE (op) != REG)
499         break;
500
501       /* ... fall through ... */
502
503     case REG:
504       return i386_aligned_reg_p (REGNO (op));
505     
506     default:
507       break;
508     }
509
510   return 0;
511 }
512 \f
513 /* Return nonzero if INSN looks like it won't compute useful cc bits
514    as a side effect.  This information is only a hint. */
515
516 int
517 i386_cc_probably_useless_p (insn)
518      rtx insn;
519 {
520   return ! next_cc0_user (insn);
521 }
522 \f
523 /* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
524    attribute for DECL.  The attributes in ATTRIBUTES have previously been
525    assigned to DECL.  */
526
527 int
528 i386_valid_decl_attribute_p (decl, attributes, identifier, args)
529      tree decl ATTRIBUTE_UNUSED;
530      tree attributes ATTRIBUTE_UNUSED;
531      tree identifier ATTRIBUTE_UNUSED;
532      tree args ATTRIBUTE_UNUSED;
533 {
534   return 0;
535 }
536
537 /* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
538    attribute for TYPE.  The attributes in ATTRIBUTES have previously been
539    assigned to TYPE.  */
540
541 int
542 i386_valid_type_attribute_p (type, attributes, identifier, args)
543      tree type;
544      tree attributes ATTRIBUTE_UNUSED;
545      tree identifier;
546      tree args;
547 {
548   if (TREE_CODE (type) != FUNCTION_TYPE
549       && TREE_CODE (type) != FIELD_DECL
550       && TREE_CODE (type) != TYPE_DECL)
551     return 0;
552
553   /* Stdcall attribute says callee is responsible for popping arguments
554      if they are not variable.  */
555   if (is_attribute_p ("stdcall", identifier))
556     return (args == NULL_TREE);
557
558   /* Cdecl attribute says the callee is a normal C declaration. */
559   if (is_attribute_p ("cdecl", identifier))
560     return (args == NULL_TREE);
561
562   /* Regparm attribute specifies how many integer arguments are to be
563      passed in registers. */
564   if (is_attribute_p ("regparm", identifier))
565     {
566       tree cst;
567
568       if (! args || TREE_CODE (args) != TREE_LIST
569           || TREE_CHAIN (args) != NULL_TREE
570           || TREE_VALUE (args) == NULL_TREE)
571         return 0;
572
573       cst = TREE_VALUE (args);
574       if (TREE_CODE (cst) != INTEGER_CST)
575         return 0;
576
577       if (TREE_INT_CST_HIGH (cst) != 0
578           || TREE_INT_CST_LOW (cst) < 0
579           || TREE_INT_CST_LOW (cst) > REGPARM_MAX)
580         return 0;
581
582       return 1;
583     }
584
585   return 0;
586 }
587
588 /* Return 0 if the attributes for two types are incompatible, 1 if they
589    are compatible, and 2 if they are nearly compatible (which causes a
590    warning to be generated).  */
591
592 int
593 i386_comp_type_attributes (type1, type2)
594      tree type1 ATTRIBUTE_UNUSED;
595      tree type2 ATTRIBUTE_UNUSED;
596 {
597   return 1;
598 }
599
600 \f
601 /* Value is the number of bytes of arguments automatically
602    popped when returning from a subroutine call.
603    FUNDECL is the declaration node of the function (as a tree),
604    FUNTYPE is the data type of the function (as a tree),
605    or for a library call it is an identifier node for the subroutine name.
606    SIZE is the number of bytes of arguments passed on the stack.
607
608    On the 80386, the RTD insn may be used to pop them if the number
609      of args is fixed, but if the number is variable then the caller
610      must pop them all.  RTD can't be used for library calls now
611      because the library is compiled with the Unix compiler.
612    Use of RTD is a selectable option, since it is incompatible with
613    standard Unix calling sequences.  If the option is not selected,
614    the caller must always pop the args.
615
616    The attribute stdcall is equivalent to RTD on a per module basis.  */
617
618 int
619 i386_return_pops_args (fundecl, funtype, size)
620      tree fundecl;
621      tree funtype;
622      int size;
623
624   int rtd = TARGET_RTD && (!fundecl || TREE_CODE (fundecl) != IDENTIFIER_NODE);
625
626     /* Cdecl functions override -mrtd, and never pop the stack. */
627   if (! lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype))) {
628   
629     /* Stdcall functions will pop the stack if not variable args. */
630     if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype)))
631       rtd = 1;
632   
633     if (rtd
634         && (TYPE_ARG_TYPES (funtype) == NULL_TREE
635             || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (funtype)))
636                 == void_type_node)))
637       return size;
638   }
639   
640   /* Lose any fake structure return argument.  */
641   if (aggregate_value_p (TREE_TYPE (funtype)))
642     return GET_MODE_SIZE (Pmode);
643   
644     return 0;
645 }
646
647 \f
648 /* Argument support functions.  */
649
650 /* Initialize a variable CUM of type CUMULATIVE_ARGS
651    for a call to a function whose data type is FNTYPE.
652    For a library call, FNTYPE is 0.  */
653
654 void
655 init_cumulative_args (cum, fntype, libname)
656      CUMULATIVE_ARGS *cum;      /* Argument info to initialize */
657      tree fntype;               /* tree ptr for function decl */
658      rtx libname;               /* SYMBOL_REF of library name or 0 */
659 {
660   static CUMULATIVE_ARGS zero_cum;
661   tree param, next_param;
662
663   if (TARGET_DEBUG_ARG)
664     {
665       fprintf (stderr, "\ninit_cumulative_args (");
666       if (fntype)
667         fprintf (stderr, "fntype code = %s, ret code = %s",
668                  tree_code_name[(int) TREE_CODE (fntype)],
669                  tree_code_name[(int) TREE_CODE (TREE_TYPE (fntype))]);
670       else
671         fprintf (stderr, "no fntype");
672
673       if (libname)
674         fprintf (stderr, ", libname = %s", XSTR (libname, 0));
675     }
676
677   *cum = zero_cum;
678
679   /* Set up the number of registers to use for passing arguments.  */
680   cum->nregs = i386_regparm;
681   if (fntype)
682     {
683       tree attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (fntype));
684
685       if (attr)
686         cum->nregs = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
687     }
688
689   /* Determine if this function has variable arguments.  This is
690      indicated by the last argument being 'void_type_mode' if there
691      are no variable arguments.  If there are variable arguments, then
692      we won't pass anything in registers */
693
694   if (cum->nregs)
695     {
696       for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
697            param != 0; param = next_param)
698         {
699           next_param = TREE_CHAIN (param);
700           if (next_param == 0 && TREE_VALUE (param) != void_type_node)
701             cum->nregs = 0;
702         }
703     }
704
705   if (TARGET_DEBUG_ARG)
706     fprintf (stderr, ", nregs=%d )\n", cum->nregs);
707
708   return;
709 }
710
711 /* Update the data in CUM to advance over an argument
712    of mode MODE and data type TYPE.
713    (TYPE is null for libcalls where that information may not be available.)  */
714
715 void
716 function_arg_advance (cum, mode, type, named)
717      CUMULATIVE_ARGS *cum;      /* current arg information */
718      enum machine_mode mode;    /* current arg mode */
719      tree type;                 /* type of the argument or 0 if lib support */
720      int named;                 /* whether or not the argument was named */
721 {
722   int bytes
723     = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
724   int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
725
726   if (TARGET_DEBUG_ARG)
727     fprintf (stderr,
728              "function_adv (sz=%d, wds=%2d, nregs=%d, mode=%s, named=%d)\n\n",
729              words, cum->words, cum->nregs, GET_MODE_NAME (mode), named);
730
731   cum->words += words;
732   cum->nregs -= words;
733   cum->regno += words;
734
735   if (cum->nregs <= 0)
736     {
737       cum->nregs = 0;
738       cum->regno = 0;
739     }
740
741   return;
742 }
743
744 /* Define where to put the arguments to a function.
745    Value is zero to push the argument on the stack,
746    or a hard register in which to store the argument.
747
748    MODE is the argument's machine mode.
749    TYPE is the data type of the argument (as a tree).
750     This is null for libcalls where that information may
751     not be available.
752    CUM is a variable of type CUMULATIVE_ARGS which gives info about
753     the preceding args and about the function being called.
754    NAMED is nonzero if this argument is a named parameter
755     (otherwise it is an extra parameter matching an ellipsis).  */
756
757 struct rtx_def *
758 function_arg (cum, mode, type, named)
759      CUMULATIVE_ARGS *cum;      /* current arg information */
760      enum machine_mode mode;    /* current arg mode */
761      tree type;                 /* type of the argument or 0 if lib support */
762      int named;                 /* != 0 for normal args, == 0 for ... args */
763 {
764   rtx ret   = NULL_RTX;
765   int bytes
766     = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
767   int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
768
769   switch (mode)
770     {
771       /* For now, pass fp/complex values on the stack. */
772     default:
773       break;
774
775     case BLKmode:
776     case DImode:
777     case SImode:
778     case HImode:
779     case QImode:
780       if (words <= cum->nregs)
781         ret = gen_rtx_REG (mode, cum->regno);
782       break;
783     }
784
785   if (TARGET_DEBUG_ARG)
786     {
787       fprintf (stderr,
788                "function_arg (size=%d, wds=%2d, nregs=%d, mode=%4s, named=%d",
789                words, cum->words, cum->nregs, GET_MODE_NAME (mode), named);
790
791       if (ret)
792         fprintf (stderr, ", reg=%%e%s", reg_names[ REGNO(ret) ]);
793       else
794         fprintf (stderr, ", stack");
795
796       fprintf (stderr, " )\n");
797     }
798
799   return ret;
800 }
801
802 /* For an arg passed partly in registers and partly in memory,
803    this is the number of registers used.
804    For args passed entirely in registers or entirely in memory, zero.  */
805
806 int
807 function_arg_partial_nregs (cum, mode, type, named)
808      CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;     /* current arg information */
809      enum machine_mode mode ATTRIBUTE_UNUSED;   /* current arg mode */
810      tree type ATTRIBUTE_UNUSED;                /* type of the argument or 0 if lib support */
811      int named ATTRIBUTE_UNUSED;                /* != 0 for normal args, == 0 for ... args */
812 {
813   return 0;
814 }
815 \f
816 /* Output an insn whose source is a 386 integer register.  SRC is the
817    rtx for the register, and TEMPLATE is the op-code template.  SRC may
818    be either SImode or DImode.
819
820    The template will be output with operands[0] as SRC, and operands[1]
821    as a pointer to the top of the 386 stack.  So a call from floatsidf2
822    would look like this:
823
824       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
825
826    where %z0 corresponds to the caller's operands[1], and is used to
827    emit the proper size suffix.
828
829    ??? Extend this to handle HImode - a 387 can load and store HImode
830    values directly. */
831
832 void
833 output_op_from_reg (src, template)
834      rtx src;
835      char *template;
836 {
837   rtx xops[4];
838   int size = GET_MODE_SIZE (GET_MODE (src));
839
840   xops[0] = src;
841   xops[1] = AT_SP (Pmode);
842   xops[2] = GEN_INT (size);
843   xops[3] = stack_pointer_rtx;
844
845   if (size > UNITS_PER_WORD)
846     {
847       rtx high;
848
849       if (size > 2 * UNITS_PER_WORD)
850         {
851           high = gen_rtx_REG (SImode, REGNO (src) + 2);
852           output_asm_insn (AS1 (push%L0,%0), &high);
853         }
854
855       high = gen_rtx_REG (SImode, REGNO (src) + 1);
856       output_asm_insn (AS1 (push%L0,%0), &high);
857     }
858
859   output_asm_insn (AS1 (push%L0,%0), &src);
860   output_asm_insn (template, xops);
861   output_asm_insn (AS2 (add%L3,%2,%3), xops);
862 }
863 \f
864 /* Output an insn to pop an value from the 387 top-of-stack to 386
865    register DEST. The 387 register stack is popped if DIES is true.  If
866    the mode of DEST is an integer mode, a `fist' integer store is done,
867    otherwise a `fst' float store is done. */
868
869 void
870 output_to_reg (dest, dies, scratch_mem)
871      rtx dest;
872      int dies;
873      rtx scratch_mem;
874 {
875   rtx xops[4];
876   int size = GET_MODE_SIZE (GET_MODE (dest));
877
878   if (! scratch_mem)
879     xops[0] = AT_SP (Pmode);
880   else
881     xops[0] = scratch_mem;
882
883   xops[1] = stack_pointer_rtx;
884   xops[2] = GEN_INT (size);
885   xops[3] = dest;
886
887   if (! scratch_mem)
888     output_asm_insn (AS2 (sub%L1,%2,%1), xops);
889
890   if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_INT)
891     {
892       if (dies)
893         output_asm_insn (AS1 (fistp%z3,%y0), xops);
894       else
895         output_asm_insn (AS1 (fist%z3,%y0), xops);
896     }
897
898   else if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_FLOAT)
899     {
900       if (dies)
901         output_asm_insn (AS1 (fstp%z3,%y0), xops);
902       else
903         {
904           if (GET_MODE (dest) == XFmode)
905             {
906               output_asm_insn (AS1 (fstp%z3,%y0), xops);
907               output_asm_insn (AS1 (fld%z3,%y0), xops);
908             }
909           else
910             output_asm_insn (AS1 (fst%z3,%y0), xops);
911         }
912     }
913
914   else
915     abort ();
916
917   if (! scratch_mem)
918     output_asm_insn (AS1 (pop%L0,%0), &dest);
919   else
920     output_asm_insn (AS2 (mov%L0,%0,%3), xops);
921
922
923   if (size > UNITS_PER_WORD)
924     {
925       dest = gen_rtx_REG (SImode, REGNO (dest) + 1);
926       if (! scratch_mem)
927         output_asm_insn (AS1 (pop%L0,%0), &dest);
928       else
929         {
930           xops[0] = adj_offsettable_operand (xops[0], 4);             
931           xops[3] = dest;
932           output_asm_insn (AS2 (mov%L0,%0,%3), xops);
933         }
934
935       if (size > 2 * UNITS_PER_WORD)
936         {
937           dest = gen_rtx_REG (SImode, REGNO (dest) + 1);
938           if (! scratch_mem)
939             output_asm_insn (AS1 (pop%L0,%0), &dest);
940           else
941             {
942               xops[0] = adj_offsettable_operand (xops[0], 4);         
943               output_asm_insn (AS2 (mov%L0,%0,%3), xops);
944             }
945         }
946     }
947 }
948 \f
949 char *
950 singlemove_string (operands)
951      rtx *operands;
952 {
953   rtx x;
954   if (GET_CODE (operands[0]) == MEM
955       && GET_CODE (x = XEXP (operands[0], 0)) == PRE_DEC)
956     {
957       if (XEXP (x, 0) != stack_pointer_rtx)
958         abort ();
959       return "push%L1 %1";
960     }
961   else if (GET_CODE (operands[1]) == CONST_DOUBLE)
962     return output_move_const_single (operands);
963   else if (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == REG)
964     return AS2 (mov%L0,%1,%0);
965   else if (CONSTANT_P (operands[1]))
966     return AS2 (mov%L0,%1,%0);
967   else
968     {
969       output_asm_insn ("push%L1 %1", operands);
970       return "pop%L0 %0";
971     }
972 }
973 \f
974 /* Return a REG that occurs in ADDR with coefficient 1.
975    ADDR can be effectively incremented by incrementing REG.  */
976
977 static rtx
978 find_addr_reg (addr)
979      rtx addr;
980 {
981   while (GET_CODE (addr) == PLUS)
982     {
983       if (GET_CODE (XEXP (addr, 0)) == REG)
984         addr = XEXP (addr, 0);
985       else if (GET_CODE (XEXP (addr, 1)) == REG)
986         addr = XEXP (addr, 1);
987       else if (CONSTANT_P (XEXP (addr, 0)))
988         addr = XEXP (addr, 1);
989       else if (CONSTANT_P (XEXP (addr, 1)))
990         addr = XEXP (addr, 0);
991       else
992         abort ();
993     }
994
995   if (GET_CODE (addr) == REG)
996     return addr;
997   abort ();
998 }
999 \f
1000 /* Output an insn to add the constant N to the register X.  */
1001
1002 static void
1003 asm_add (n, x)
1004      int n;
1005      rtx x;
1006 {
1007   rtx xops[2];
1008   xops[0] = x;
1009
1010   if (n == -1)
1011     output_asm_insn (AS1 (dec%L0,%0), xops);
1012   else if (n == 1)
1013     output_asm_insn (AS1 (inc%L0,%0), xops);
1014   else if (n < 0 || n == 128)
1015     {
1016       xops[1] = GEN_INT (-n);
1017       output_asm_insn (AS2 (sub%L0,%1,%0), xops);
1018     }
1019   else if (n > 0)
1020     {
1021       xops[1] = GEN_INT (n);
1022       output_asm_insn (AS2 (add%L0,%1,%0), xops);
1023     }
1024 }
1025 \f
1026 /* Output assembler code to perform a doubleword move insn
1027    with operands OPERANDS.  */
1028
1029 char *
1030 output_move_double (operands)
1031      rtx *operands;
1032 {
1033   enum {REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
1034   rtx latehalf[2];
1035   rtx middlehalf[2];
1036   rtx xops[2];
1037   rtx addreg0 = 0, addreg1 = 0;
1038   int dest_overlapped_low = 0;
1039   int size = GET_MODE_SIZE (GET_MODE (operands[0]));
1040
1041   middlehalf[0] = 0;
1042   middlehalf[1] = 0;
1043
1044   /* First classify both operands.  */
1045
1046   if (REG_P (operands[0]))
1047     optype0 = REGOP;
1048   else if (offsettable_memref_p (operands[0]))
1049     optype0 = OFFSOP;
1050   else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1051     optype0 = POPOP;
1052   else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1053     optype0 = PUSHOP;
1054   else if (GET_CODE (operands[0]) == MEM)
1055     optype0 = MEMOP;
1056   else
1057     optype0 = RNDOP;
1058
1059   if (REG_P (operands[1]))
1060     optype1 = REGOP;
1061   else if (CONSTANT_P (operands[1]))
1062     optype1 = CNSTOP;
1063   else if (offsettable_memref_p (operands[1]))
1064     optype1 = OFFSOP;
1065   else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
1066     optype1 = POPOP;
1067   else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
1068     optype1 = PUSHOP;
1069   else if (GET_CODE (operands[1]) == MEM)
1070     optype1 = MEMOP;
1071   else
1072     optype1 = RNDOP;
1073
1074   /* Check for the cases that the operand constraints are not
1075      supposed to allow to happen.  Abort if we get one,
1076      because generating code for these cases is painful.  */
1077
1078   if (optype0 == RNDOP || optype1 == RNDOP)
1079     abort ();
1080
1081   /* If one operand is decrementing and one is incrementing
1082      decrement the former register explicitly
1083      and change that operand into ordinary indexing.  */
1084
1085   if (optype0 == PUSHOP && optype1 == POPOP)
1086     {
1087       /* ??? Can this ever happen on i386? */
1088       operands[0] = XEXP (XEXP (operands[0], 0), 0);
1089       asm_add (-size, operands[0]);
1090       if (GET_MODE (operands[1]) == XFmode)
1091         operands[0] = gen_rtx_MEM (XFmode, operands[0]);
1092       else if (GET_MODE (operands[0]) == DFmode)
1093         operands[0] = gen_rtx_MEM (DFmode, operands[0]);
1094       else
1095         operands[0] = gen_rtx_MEM (DImode, operands[0]);
1096       optype0 = OFFSOP;
1097     }
1098
1099   if (optype0 == POPOP && optype1 == PUSHOP)
1100     {
1101       /* ??? Can this ever happen on i386? */
1102       operands[1] = XEXP (XEXP (operands[1], 0), 0);
1103       asm_add (-size, operands[1]);
1104       if (GET_MODE (operands[1]) == XFmode)
1105         operands[1] = gen_rtx_MEM (XFmode, operands[1]);
1106       else if (GET_MODE (operands[1]) == DFmode)
1107         operands[1] = gen_rtx_MEM (DFmode, operands[1]);
1108       else
1109         operands[1] = gen_rtx_MEM (DImode, operands[1]);
1110       optype1 = OFFSOP;
1111     }
1112
1113   /* If an operand is an unoffsettable memory ref, find a register
1114      we can increment temporarily to make it refer to the second word.  */
1115
1116   if (optype0 == MEMOP)
1117     addreg0 = find_addr_reg (XEXP (operands[0], 0));
1118
1119   if (optype1 == MEMOP)
1120     addreg1 = find_addr_reg (XEXP (operands[1], 0));
1121
1122   /* Ok, we can do one word at a time.
1123      Normally we do the low-numbered word first,
1124      but if either operand is autodecrementing then we
1125      do the high-numbered word first.
1126
1127      In either case, set up in LATEHALF the operands to use
1128      for the high-numbered word and in some cases alter the
1129      operands in OPERANDS to be suitable for the low-numbered word.  */
1130
1131   if (size == 12)
1132     {
1133       if (optype0 == REGOP)
1134         {
1135           middlehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1136           latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 2);
1137         }
1138       else if (optype0 == OFFSOP)
1139         {
1140           middlehalf[0] = adj_offsettable_operand (operands[0], 4);
1141           latehalf[0] = adj_offsettable_operand (operands[0], 8);
1142         }
1143       else
1144         {
1145          middlehalf[0] = operands[0];
1146          latehalf[0] = operands[0];
1147         }
1148     
1149       if (optype1 == REGOP)
1150         {
1151           middlehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1152           latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
1153         }
1154       else if (optype1 == OFFSOP)
1155         {
1156           middlehalf[1] = adj_offsettable_operand (operands[1], 4);
1157           latehalf[1] = adj_offsettable_operand (operands[1], 8);
1158         }
1159       else if (optype1 == CNSTOP)
1160         {
1161           if (GET_CODE (operands[1]) == CONST_DOUBLE)
1162             {
1163               REAL_VALUE_TYPE r; long l[3];
1164
1165               REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1166               REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
1167               operands[1] = GEN_INT (l[0]);
1168               middlehalf[1] = GEN_INT (l[1]);
1169               latehalf[1] = GEN_INT (l[2]);
1170             }
1171           else if (CONSTANT_P (operands[1]))
1172             /* No non-CONST_DOUBLE constant should ever appear here.  */
1173             abort ();
1174         }
1175       else
1176         {
1177           middlehalf[1] = operands[1];
1178           latehalf[1] = operands[1];
1179         }
1180     }
1181
1182   else
1183     {
1184       /* Size is not 12. */
1185
1186       if (optype0 == REGOP)
1187         latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1188       else if (optype0 == OFFSOP)
1189         latehalf[0] = adj_offsettable_operand (operands[0], 4);
1190       else
1191         latehalf[0] = operands[0];
1192
1193       if (optype1 == REGOP)
1194         latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1195       else if (optype1 == OFFSOP)
1196         latehalf[1] = adj_offsettable_operand (operands[1], 4);
1197       else if (optype1 == CNSTOP)
1198         split_double (operands[1], &operands[1], &latehalf[1]);
1199       else
1200         latehalf[1] = operands[1];
1201     }
1202
1203   /* If insn is effectively movd N (sp),-(sp) then we will do the
1204      high word first.  We should use the adjusted operand 1
1205      (which is N+4 (sp) or N+8 (sp))
1206      for the low word and middle word as well,
1207      to compensate for the first decrement of sp.  */
1208   if (optype0 == PUSHOP
1209       && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
1210       && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
1211     middlehalf[1] = operands[1] = latehalf[1];
1212
1213   /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
1214      if the upper part of reg N does not appear in the MEM, arrange to
1215      emit the move late-half first.  Otherwise, compute the MEM address
1216      into the upper part of N and use that as a pointer to the memory
1217      operand.  */
1218   if (optype0 == REGOP
1219       && (optype1 == OFFSOP || optype1 == MEMOP))
1220     {
1221       if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))
1222           && reg_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
1223         {
1224           /* If both halves of dest are used in the src memory address,
1225              compute the address into latehalf of dest.  */
1226         compadr:
1227           xops[0] = latehalf[0];
1228           xops[1] = XEXP (operands[1], 0);
1229           output_asm_insn (AS2 (lea%L0,%a1,%0), xops);
1230           if (GET_MODE (operands[1]) == XFmode)
1231             {
1232               operands[1] = gen_rtx_MEM (XFmode, latehalf[0]);
1233               middlehalf[1] = adj_offsettable_operand (operands[1], size-8);
1234               latehalf[1] = adj_offsettable_operand (operands[1], size-4);
1235             }
1236           else
1237             {
1238               operands[1] = gen_rtx_MEM (DImode, latehalf[0]);
1239               latehalf[1] = adj_offsettable_operand (operands[1], size-4);
1240             }
1241         }
1242
1243       else if (size == 12
1244                  && reg_mentioned_p (middlehalf[0], XEXP (operands[1], 0)))
1245         {
1246           /* Check for two regs used by both source and dest. */
1247           if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))
1248                 || reg_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
1249             goto compadr;
1250
1251           /* JRV says this can't happen: */
1252           if (addreg0 || addreg1)
1253               abort ();
1254
1255           /* Only the middle reg conflicts; simply put it last. */
1256           output_asm_insn (singlemove_string (operands), operands);
1257           output_asm_insn (singlemove_string (latehalf), latehalf);
1258           output_asm_insn (singlemove_string (middlehalf), middlehalf);
1259           return "";
1260         }
1261
1262       else if (reg_mentioned_p (operands[0], XEXP (operands[1], 0)))
1263         /* If the low half of dest is mentioned in the source memory
1264            address, the arrange to emit the move late half first.  */
1265         dest_overlapped_low = 1;
1266     }
1267
1268   /* If one or both operands autodecrementing,
1269      do the two words, high-numbered first.  */
1270
1271   /* Likewise,  the first move would clobber the source of the second one,
1272      do them in the other order.  This happens only for registers;
1273      such overlap can't happen in memory unless the user explicitly
1274      sets it up, and that is an undefined circumstance.  */
1275
1276 #if 0
1277   if (optype0 == PUSHOP || optype1 == PUSHOP
1278       || (optype0 == REGOP && optype1 == REGOP
1279           && REGNO (operands[0]) == REGNO (latehalf[1]))
1280       || dest_overlapped_low)
1281 #endif
1282
1283   if (optype0 == PUSHOP || optype1 == PUSHOP
1284       || (optype0 == REGOP && optype1 == REGOP
1285           && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1]))
1286               || REGNO (operands[0]) == REGNO (latehalf[1])))
1287       || dest_overlapped_low)
1288     {
1289       /* Make any unoffsettable addresses point at high-numbered word.  */
1290       if (addreg0)
1291         asm_add (size-4, addreg0);
1292       if (addreg1)
1293         asm_add (size-4, addreg1);
1294
1295       /* Do that word.  */
1296       output_asm_insn (singlemove_string (latehalf), latehalf);
1297
1298       /* Undo the adds we just did.  */
1299       if (addreg0)
1300         asm_add (-4, addreg0);
1301       if (addreg1)
1302         asm_add (-4, addreg1);
1303
1304       if (size == 12)
1305         {
1306           output_asm_insn (singlemove_string (middlehalf), middlehalf);
1307           if (addreg0)
1308             asm_add (-4, addreg0);
1309           if (addreg1)
1310             asm_add (-4, addreg1);
1311         }
1312
1313       /* Do low-numbered word.  */
1314       return singlemove_string (operands);
1315     }
1316
1317   /* Normal case: do the two words, low-numbered first.  */
1318
1319   output_asm_insn (singlemove_string (operands), operands);
1320
1321   /* Do the middle one of the three words for long double */
1322   if (size == 12)
1323     {
1324       if (addreg0)
1325         asm_add (4, addreg0);
1326       if (addreg1)
1327         asm_add (4, addreg1);
1328
1329       output_asm_insn (singlemove_string (middlehalf), middlehalf);
1330     }
1331
1332   /* Make any unoffsettable addresses point at high-numbered word.  */
1333   if (addreg0)
1334     asm_add (4, addreg0);
1335   if (addreg1)
1336     asm_add (4, addreg1);
1337
1338   /* Do that word.  */
1339   output_asm_insn (singlemove_string (latehalf), latehalf);
1340
1341   /* Undo the adds we just did.  */
1342   if (addreg0)
1343     asm_add (4-size, addreg0);
1344   if (addreg1)
1345     asm_add (4-size, addreg1);
1346
1347   return "";
1348 }
1349 \f
1350 #define MAX_TMPS 2              /* max temporary registers used */
1351
1352 /* Output the appropriate code to move push memory on the stack */
1353
1354 char *
1355 output_move_pushmem (operands, insn, length, tmp_start, n_operands)
1356      rtx operands[];
1357      rtx insn;
1358      int length;
1359      int tmp_start;
1360      int n_operands;
1361 {
1362   struct
1363     {
1364       char *load;
1365       char *push;
1366       rtx   xops[2];
1367     } tmp_info[MAX_TMPS];
1368   
1369   rtx src = operands[1];
1370   int max_tmps = 0;
1371   int offset = 0;
1372   int stack_p = reg_overlap_mentioned_p (stack_pointer_rtx, src);
1373   int stack_offset = 0;
1374   int i, num_tmps;
1375   rtx xops[1];
1376
1377   if (! offsettable_memref_p (src))
1378     fatal_insn ("Source is not offsettable", insn);
1379
1380   if ((length & 3) != 0)
1381     fatal_insn ("Pushing non-word aligned size", insn);
1382
1383   /* Figure out which temporary registers we have available */
1384   for (i = tmp_start; i < n_operands; i++)
1385     {
1386       if (GET_CODE (operands[i]) == REG)
1387         {
1388           if (reg_overlap_mentioned_p (operands[i], src))
1389             continue;
1390
1391           tmp_info[ max_tmps++ ].xops[1] = operands[i];
1392           if (max_tmps == MAX_TMPS)
1393             break;
1394         }
1395     }
1396
1397   if (max_tmps == 0)
1398     for (offset = length - 4; offset >= 0; offset -= 4)
1399       {
1400         xops[0] = adj_offsettable_operand (src, offset + stack_offset);
1401         output_asm_insn (AS1(push%L0,%0), xops);
1402         if (stack_p)
1403           stack_offset += 4;
1404       }
1405
1406   else
1407     for (offset = length - 4; offset >= 0; )
1408       {
1409         for (num_tmps = 0; num_tmps < max_tmps && offset >= 0; num_tmps++)
1410           {
1411             tmp_info[num_tmps].load    = AS2(mov%L0,%0,%1);
1412             tmp_info[num_tmps].push    = AS1(push%L0,%1);
1413             tmp_info[num_tmps].xops[0]
1414               = adj_offsettable_operand (src, offset + stack_offset);
1415             offset -= 4;
1416           }
1417
1418         for (i = 0; i < num_tmps; i++)
1419           output_asm_insn (tmp_info[i].load, tmp_info[i].xops);
1420
1421         for (i = 0; i < num_tmps; i++)
1422           output_asm_insn (tmp_info[i].push, tmp_info[i].xops);
1423
1424         if (stack_p)
1425           stack_offset += 4*num_tmps;
1426       }
1427
1428   return "";
1429 }
1430 \f
1431 /* Output the appropriate code to move data between two memory locations */
1432
1433 char *
1434 output_move_memory (operands, insn, length, tmp_start, n_operands)
1435      rtx operands[];
1436      rtx insn;
1437      int length;
1438      int tmp_start;
1439      int n_operands;
1440 {
1441   struct
1442     {
1443       char *load;
1444       char *store;
1445       rtx   xops[3];
1446     } tmp_info[MAX_TMPS];
1447
1448   rtx dest = operands[0];
1449   rtx src  = operands[1];
1450   rtx qi_tmp = NULL_RTX;
1451   int max_tmps = 0;
1452   int offset = 0;
1453   int i, num_tmps;
1454   rtx xops[3];
1455
1456   if (GET_CODE (dest) == MEM
1457       && GET_CODE (XEXP (dest, 0)) == PRE_INC
1458       && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx)
1459     return output_move_pushmem (operands, insn, length, tmp_start, n_operands);
1460
1461   if (! offsettable_memref_p (src))
1462     fatal_insn ("Source is not offsettable", insn);
1463
1464   if (! offsettable_memref_p (dest))
1465     fatal_insn ("Destination is not offsettable", insn);
1466
1467   /* Figure out which temporary registers we have available */
1468   for (i = tmp_start; i < n_operands; i++)
1469     {
1470       if (GET_CODE (operands[i]) == REG)
1471         {
1472           if ((length & 1) != 0 && qi_tmp == 0 && QI_REG_P (operands[i]))
1473             qi_tmp = operands[i];
1474
1475           if (reg_overlap_mentioned_p (operands[i], dest))
1476             fatal_insn ("Temporary register overlaps the destination", insn);
1477
1478           if (reg_overlap_mentioned_p (operands[i], src))
1479             fatal_insn ("Temporary register overlaps the source", insn);
1480
1481           tmp_info[max_tmps++].xops[2] = operands[i];
1482           if (max_tmps == MAX_TMPS)
1483             break;
1484         }
1485     }
1486
1487   if (max_tmps == 0)
1488     fatal_insn ("No scratch registers were found to do memory->memory moves",
1489                 insn);
1490
1491   if ((length & 1) != 0)
1492     {
1493       if (qi_tmp == 0)
1494         fatal_insn ("No byte register found when moving odd # of bytes.",
1495                     insn);
1496     }
1497
1498   while (length > 1)
1499     {
1500       for (num_tmps = 0; num_tmps < max_tmps; num_tmps++)
1501         {
1502           if (length >= 4)
1503             {
1504               tmp_info[num_tmps].load    = AS2(mov%L0,%1,%2);
1505               tmp_info[num_tmps].store   = AS2(mov%L0,%2,%0);
1506               tmp_info[num_tmps].xops[0]
1507                 = adj_offsettable_operand (dest, offset);
1508               tmp_info[num_tmps].xops[1]
1509                 = adj_offsettable_operand (src, offset);
1510
1511               offset += 4;
1512               length -= 4;
1513             }
1514
1515           else if (length >= 2)
1516             {
1517               tmp_info[num_tmps].load    = AS2(mov%W0,%1,%2);
1518               tmp_info[num_tmps].store   = AS2(mov%W0,%2,%0);
1519               tmp_info[num_tmps].xops[0]
1520                 = adj_offsettable_operand (dest, offset);
1521               tmp_info[num_tmps].xops[1]
1522                 = adj_offsettable_operand (src, offset);
1523
1524               offset += 2;
1525               length -= 2;
1526             }
1527           else
1528             break;
1529         }
1530
1531       for (i = 0; i < num_tmps; i++)
1532         output_asm_insn (tmp_info[i].load, tmp_info[i].xops);
1533
1534       for (i = 0; i < num_tmps; i++)
1535         output_asm_insn (tmp_info[i].store, tmp_info[i].xops);
1536     }
1537
1538   if (length == 1)
1539     {
1540       xops[0] = adj_offsettable_operand (dest, offset);
1541       xops[1] = adj_offsettable_operand (src, offset);
1542       xops[2] = qi_tmp;
1543       output_asm_insn (AS2(mov%B0,%1,%2), xops);
1544       output_asm_insn (AS2(mov%B0,%2,%0), xops);
1545     }
1546
1547   return "";
1548 }
1549 \f
1550 int
1551 standard_80387_constant_p (x)
1552      rtx x;
1553 {
1554 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
1555   REAL_VALUE_TYPE d;
1556   jmp_buf handler;
1557   int is0, is1;
1558
1559   if (setjmp (handler))
1560     return 0;
1561
1562   set_float_handler (handler);
1563   REAL_VALUE_FROM_CONST_DOUBLE (d, x);
1564   is0 = REAL_VALUES_EQUAL (d, dconst0) && !REAL_VALUE_MINUS_ZERO (d);
1565   is1 = REAL_VALUES_EQUAL (d, dconst1);
1566   set_float_handler (NULL_PTR);
1567
1568   if (is0)
1569     return 1;
1570
1571   if (is1)
1572     return 2;
1573
1574   /* Note that on the 80387, other constants, such as pi,
1575      are much slower to load as standard constants
1576      than to load from doubles in memory!  */
1577 #endif
1578
1579   return 0;
1580 }
1581
1582 char *
1583 output_move_const_single (operands)
1584      rtx *operands;
1585 {
1586   if (FP_REG_P (operands[0]))
1587     {
1588       int conval = standard_80387_constant_p (operands[1]);
1589
1590       if (conval == 1)
1591         return "fldz";
1592
1593       if (conval == 2)
1594         return "fld1";
1595     }
1596
1597   if (GET_CODE (operands[1]) == CONST_DOUBLE)
1598     {
1599       REAL_VALUE_TYPE r; long l;
1600
1601       if (GET_MODE (operands[1]) == XFmode)
1602         abort ();
1603
1604       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1605       REAL_VALUE_TO_TARGET_SINGLE (r, l);
1606       operands[1] = GEN_INT (l);
1607     }
1608
1609   return singlemove_string (operands);
1610 }
1611 \f
1612 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
1613    reference and a constant.  */
1614
1615 int
1616 symbolic_operand (op, mode)
1617      register rtx op;
1618      enum machine_mode mode ATTRIBUTE_UNUSED;
1619 {
1620   switch (GET_CODE (op))
1621     {
1622     case SYMBOL_REF:
1623     case LABEL_REF:
1624       return 1;
1625
1626     case CONST:
1627       op = XEXP (op, 0);
1628       return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
1629                || GET_CODE (XEXP (op, 0)) == LABEL_REF)
1630               && GET_CODE (XEXP (op, 1)) == CONST_INT);
1631
1632     default:
1633       return 0;
1634     }
1635 }
1636
1637 /* Test for a valid operand for a call instruction.
1638    Don't allow the arg pointer register or virtual regs
1639    since they may change into reg + const, which the patterns
1640    can't handle yet.  */
1641
1642 int
1643 call_insn_operand (op, mode)
1644      rtx op;
1645      enum machine_mode mode ATTRIBUTE_UNUSED;
1646 {
1647   if (GET_CODE (op) == MEM
1648       && ((CONSTANT_ADDRESS_P (XEXP (op, 0))
1649            /* This makes a difference for PIC.  */
1650            && general_operand (XEXP (op, 0), Pmode))
1651           || (GET_CODE (XEXP (op, 0)) == REG
1652               && XEXP (op, 0) != arg_pointer_rtx
1653               && ! (REGNO (XEXP (op, 0)) >= FIRST_PSEUDO_REGISTER
1654                     && REGNO (XEXP (op, 0)) <= LAST_VIRTUAL_REGISTER))))
1655     return 1;
1656
1657   return 0;
1658 }
1659
1660 /* Like call_insn_operand but allow (mem (symbol_ref ...))
1661    even if pic.  */
1662
1663 int
1664 expander_call_insn_operand (op, mode)
1665      rtx op;
1666      enum machine_mode mode ATTRIBUTE_UNUSED;
1667 {
1668   if (GET_CODE (op) == MEM
1669       && (CONSTANT_ADDRESS_P (XEXP (op, 0))
1670           || (GET_CODE (XEXP (op, 0)) == REG
1671               && XEXP (op, 0) != arg_pointer_rtx
1672               && ! (REGNO (XEXP (op, 0)) >= FIRST_PSEUDO_REGISTER
1673                     && REGNO (XEXP (op, 0)) <= LAST_VIRTUAL_REGISTER))))
1674     return 1;
1675
1676   return 0;
1677 }
1678
1679 /* Return 1 if OP is a comparison operator that can use the condition code
1680    generated by an arithmetic operation. */
1681
1682 int
1683 arithmetic_comparison_operator (op, mode)
1684      register rtx op;
1685      enum machine_mode mode;
1686 {
1687   enum rtx_code code;
1688
1689   if (mode != VOIDmode && mode != GET_MODE (op))
1690     return 0;
1691
1692   code = GET_CODE (op);
1693   if (GET_RTX_CLASS (code) != '<')
1694     return 0;
1695
1696   return (code != GT && code != LE);
1697 }
1698
1699 int
1700 ix86_logical_operator (op, mode)
1701      register rtx op;
1702      enum machine_mode mode ATTRIBUTE_UNUSED;
1703 {
1704   return GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR;
1705 }
1706
1707 \f
1708 /* Returns 1 if OP contains a symbol reference */
1709
1710 int
1711 symbolic_reference_mentioned_p (op)
1712      rtx op;
1713 {
1714   register char *fmt;
1715   register int i;
1716
1717   if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
1718     return 1;
1719
1720   fmt = GET_RTX_FORMAT (GET_CODE (op));
1721   for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
1722     {
1723       if (fmt[i] == 'E')
1724         {
1725           register int j;
1726
1727           for (j = XVECLEN (op, i) - 1; j >= 0; j--)
1728             if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
1729               return 1;
1730         }
1731
1732       else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
1733         return 1;
1734     }
1735
1736   return 0;
1737 }
1738 \f
1739 /* Attempt to expand a binary operator.  Make the expansion closer to the
1740    actual machine, then just general_operand, which will allow 3 separate
1741    memory references (one output, two input) in a single insn.  Return
1742    whether the insn fails, or succeeds.  */
1743
1744 int
1745 ix86_expand_binary_operator (code, mode, operands)
1746      enum rtx_code code;
1747      enum machine_mode mode;
1748      rtx operands[];
1749 {
1750   int modified;
1751
1752   /* Recognize <var1> = <value> <op> <var1> for commutative operators */
1753   if (GET_RTX_CLASS (code) == 'c'
1754       && (rtx_equal_p (operands[0], operands[2])
1755           || immediate_operand (operands[1], mode)))
1756     {
1757       rtx temp = operands[1];
1758       operands[1] = operands[2];
1759       operands[2] = temp;
1760     }
1761
1762   /* If optimizing, copy to regs to improve CSE */
1763   if (TARGET_PSEUDO && optimize
1764       && ((reload_in_progress | reload_completed) == 0))
1765     {
1766       if (GET_CODE (operands[1]) == MEM
1767           && ! rtx_equal_p (operands[0], operands[1]))
1768         operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
1769
1770       if (GET_CODE (operands[2]) == MEM)
1771         operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
1772
1773       if (GET_CODE (operands[1]) == CONST_INT && code == MINUS)
1774         {
1775           rtx temp = gen_reg_rtx (GET_MODE (operands[0]));
1776
1777           emit_move_insn (temp, operands[1]);
1778           operands[1] = temp;
1779           return TRUE;
1780         }         
1781     }
1782
1783   if (!ix86_binary_operator_ok (code, mode, operands))
1784     {
1785       /* If not optimizing, try to make a valid insn (optimize code
1786          previously did this above to improve chances of CSE) */
1787
1788       if ((! TARGET_PSEUDO || !optimize)
1789           && ((reload_in_progress | reload_completed) == 0)
1790           && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM))
1791         {
1792           modified = FALSE;
1793           if (GET_CODE (operands[1]) == MEM
1794               && ! rtx_equal_p (operands[0], operands[1]))
1795             {
1796               operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
1797               modified = TRUE;
1798             }
1799
1800           if (GET_CODE (operands[2]) == MEM)
1801             {
1802               operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
1803               modified = TRUE;
1804             }
1805
1806           if (GET_CODE (operands[1]) == CONST_INT && code == MINUS)
1807             {
1808               rtx temp = gen_reg_rtx (GET_MODE (operands[0]));
1809
1810               emit_move_insn (temp, operands[1]);
1811               operands[1] = temp;
1812               return TRUE;
1813             }     
1814
1815           if (modified && ! ix86_binary_operator_ok (code, mode, operands))
1816             return FALSE;
1817         }
1818       else
1819         return FALSE;
1820     }
1821
1822   return TRUE;
1823 }
1824 \f
1825 /* Return TRUE or FALSE depending on whether the binary operator meets the
1826    appropriate constraints.  */
1827
1828 int
1829 ix86_binary_operator_ok (code, mode, operands)
1830      enum rtx_code code;
1831      enum machine_mode mode ATTRIBUTE_UNUSED;
1832      rtx operands[3];
1833 {
1834   return (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
1835     && (GET_CODE (operands[1]) != CONST_INT || GET_RTX_CLASS (code) == 'c');
1836 }
1837 \f
1838 /* Attempt to expand a unary operator.  Make the expansion closer to the
1839    actual machine, then just general_operand, which will allow 2 separate
1840    memory references (one output, one input) in a single insn.  Return
1841    whether the insn fails, or succeeds.  */
1842
1843 int
1844 ix86_expand_unary_operator (code, mode, operands)
1845      enum rtx_code code;
1846      enum machine_mode mode;
1847      rtx operands[];
1848 {
1849   /* If optimizing, copy to regs to improve CSE */
1850   if (TARGET_PSEUDO
1851       && optimize
1852       && ((reload_in_progress | reload_completed) == 0)
1853       && GET_CODE (operands[1]) == MEM)
1854     operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
1855
1856   if (! ix86_unary_operator_ok (code, mode, operands))
1857     {
1858       if ((! TARGET_PSEUDO || optimize == 0)
1859           && ((reload_in_progress | reload_completed) == 0)
1860           && GET_CODE (operands[1]) == MEM)
1861         {
1862           operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
1863           if (! ix86_unary_operator_ok (code, mode, operands))
1864             return FALSE;
1865         }
1866       else
1867         return FALSE;
1868     }
1869
1870   return TRUE;
1871 }
1872 \f
1873 /* Return TRUE or FALSE depending on whether the unary operator meets the
1874    appropriate constraints.  */
1875
1876 int
1877 ix86_unary_operator_ok (code, mode, operands)
1878      enum rtx_code code ATTRIBUTE_UNUSED;
1879      enum machine_mode mode ATTRIBUTE_UNUSED;
1880      rtx operands[2] ATTRIBUTE_UNUSED;
1881 {
1882   return TRUE;
1883 }
1884 \f
1885 static rtx pic_label_rtx;
1886 static char pic_label_name [256];
1887 static int pic_label_no = 0;
1888
1889 /* This function generates code for -fpic that loads %ebx with
1890    the return address of the caller and then returns.  */
1891
1892 void
1893 asm_output_function_prefix (file, name)
1894      FILE *file;
1895      char *name ATTRIBUTE_UNUSED;
1896 {
1897   rtx xops[2];
1898   int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1899                                   || current_function_uses_const_pool);
1900   xops[0] = pic_offset_table_rtx;
1901   xops[1] = stack_pointer_rtx;
1902
1903   /* Deep branch prediction favors having a return for every call. */
1904   if (pic_reg_used && TARGET_DEEP_BRANCH_PREDICTION)
1905     {
1906       tree prologue_node;
1907
1908       if (pic_label_rtx == 0)
1909         {
1910           pic_label_rtx = gen_label_rtx ();
1911           ASM_GENERATE_INTERNAL_LABEL (pic_label_name, "LPR", pic_label_no++);
1912           LABEL_NAME (pic_label_rtx) = pic_label_name;
1913         }
1914
1915       prologue_node = make_node (FUNCTION_DECL);
1916       DECL_RESULT (prologue_node) = 0;
1917
1918       /* This used to call ASM_DECLARE_FUNCTION_NAME() but since it's an
1919          internal (non-global) label that's being emitted, it didn't make
1920          sense to have .type information for local labels.   This caused
1921          the SCO OpenServer 5.0.4 ELF assembler grief (why are you giving
1922          me debug info for a label that you're declaring non-global?) this
1923          was changed to call ASM_OUTPUT_LABEL() instead. */
1924
1925
1926       ASM_OUTPUT_LABEL (file, pic_label_name); 
1927       output_asm_insn ("movl (%1),%0", xops);
1928       output_asm_insn ("ret", xops);
1929     }
1930 }
1931
1932 /* Generate the assembly code for function entry.
1933    FILE is an stdio stream to output the code to.
1934    SIZE is an int: how many units of temporary storage to allocate. */
1935
1936 void
1937 function_prologue (file, size)
1938      FILE *file ATTRIBUTE_UNUSED;
1939      int size ATTRIBUTE_UNUSED;
1940 {
1941   if (TARGET_SCHEDULE_PROLOGUE)
1942     {
1943       pic_label_rtx = 0;
1944       return;
1945     }
1946   
1947   ix86_prologue (0);
1948 }
1949
1950 /* Expand the prologue into a bunch of separate insns. */
1951
1952 void
1953 ix86_expand_prologue ()
1954 {
1955   if (! TARGET_SCHEDULE_PROLOGUE)
1956       return;
1957  
1958   ix86_prologue (1);
1959 }
1960
1961 void
1962 load_pic_register (do_rtl)
1963      int do_rtl;
1964 {
1965   rtx xops[4];
1966
1967   if (TARGET_DEEP_BRANCH_PREDICTION)
1968     {
1969       xops[0] = pic_offset_table_rtx;
1970       if (pic_label_rtx == 0)
1971         {
1972           pic_label_rtx = gen_label_rtx ();
1973           ASM_GENERATE_INTERNAL_LABEL (pic_label_name, "LPR", pic_label_no++);
1974           LABEL_NAME (pic_label_rtx) = pic_label_name;
1975         }
1976
1977       xops[1] = gen_rtx_MEM (QImode,
1978                          gen_rtx (SYMBOL_REF, Pmode,
1979                                   LABEL_NAME (pic_label_rtx)));
1980
1981       if (do_rtl)
1982         {
1983           emit_insn (gen_prologue_get_pc (xops[0], xops[1]));
1984           emit_insn (gen_prologue_set_got (xops[0], 
1985                                            gen_rtx (SYMBOL_REF, Pmode,
1986                                                     "$_GLOBAL_OFFSET_TABLE_"), 
1987                                            xops[1]));
1988         }
1989       else
1990         {
1991           output_asm_insn (AS1 (call,%X1), xops);
1992           output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_,%0", xops);
1993           pic_label_rtx = 0;
1994         }
1995     }
1996
1997   else
1998     {
1999       xops[0] = pic_offset_table_rtx;
2000       xops[1] = gen_label_rtx ();
2001  
2002       if (do_rtl)
2003         {
2004           /* We can't put a raw CODE_LABEL into the RTL, and we can't emit
2005              a new CODE_LABEL after reload, so we need a single pattern to
2006              emit the 3 necessary instructions.  */
2007           emit_insn (gen_prologue_get_pc_and_set_got (xops[0]));
2008         }
2009       else
2010         {
2011           output_asm_insn (AS1 (call,%P1), xops);
2012           ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", 
2013                                      CODE_LABEL_NUMBER (xops[1]));
2014           output_asm_insn (AS1 (pop%L0,%0), xops);
2015           output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops);
2016         }
2017     } 
2018
2019   /* When -fpic, we must emit a scheduling barrier, so that the instruction
2020      that restores %ebx (which is PIC_OFFSET_TABLE_REGNUM), does not get
2021      moved before any instruction which implicitly uses the got.   */
2022
2023   if (do_rtl)
2024     emit_insn (gen_blockage ());
2025 }
2026
2027 static void
2028 ix86_prologue (do_rtl)
2029      int do_rtl;
2030 {
2031   register int regno;
2032   int limit;
2033   rtx xops[4];
2034   int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
2035                                   || current_function_uses_const_pool);
2036   long tsize = get_frame_size ();
2037   rtx insn;
2038   int cfa_offset = INCOMING_FRAME_SP_OFFSET, cfa_store_offset = cfa_offset;
2039   
2040   xops[0] = stack_pointer_rtx;
2041   xops[1] = frame_pointer_rtx;
2042   xops[2] = GEN_INT (tsize);
2043
2044   if (frame_pointer_needed)
2045     {
2046       if (do_rtl)
2047         {
2048           insn = emit_insn (gen_rtx (SET, VOIDmode,
2049                                      gen_rtx_MEM (SImode,
2050                                               gen_rtx (PRE_DEC, SImode,
2051                                                        stack_pointer_rtx)),
2052                                      frame_pointer_rtx));
2053
2054           RTX_FRAME_RELATED_P (insn) = 1;
2055           insn = emit_move_insn (xops[1], xops[0]);
2056           RTX_FRAME_RELATED_P (insn) = 1;
2057         }
2058
2059       else
2060         {
2061           output_asm_insn ("push%L1 %1", xops); 
2062 #ifdef INCOMING_RETURN_ADDR_RTX
2063           if (dwarf2out_do_frame ())
2064             {
2065               char *l = dwarf2out_cfi_label ();
2066
2067               cfa_store_offset += 4;
2068               cfa_offset = cfa_store_offset;
2069               dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
2070               dwarf2out_reg_save (l, FRAME_POINTER_REGNUM, - cfa_store_offset);
2071             }
2072 #endif
2073
2074           output_asm_insn (AS2 (mov%L0,%0,%1), xops); 
2075 #ifdef INCOMING_RETURN_ADDR_RTX
2076           if (dwarf2out_do_frame ())
2077             dwarf2out_def_cfa ("", FRAME_POINTER_REGNUM, cfa_offset);
2078 #endif
2079         }
2080     }
2081
2082   if (tsize == 0)
2083     ;
2084   else if (! TARGET_STACK_PROBE || tsize < CHECK_STACK_LIMIT)
2085     {
2086       if (do_rtl)
2087         {
2088           insn = emit_insn (gen_prologue_set_stack_ptr (xops[2]));
2089           RTX_FRAME_RELATED_P (insn) = 1;
2090         }
2091       else 
2092         {
2093           output_asm_insn (AS2 (sub%L0,%2,%0), xops);
2094 #ifdef INCOMING_RETURN_ADDR_RTX
2095           if (dwarf2out_do_frame ())
2096             {
2097               cfa_store_offset += tsize;
2098               if (! frame_pointer_needed)
2099                 {
2100                   cfa_offset = cfa_store_offset;
2101                   dwarf2out_def_cfa ("", STACK_POINTER_REGNUM, cfa_offset);
2102                 }
2103             }
2104 #endif
2105         }
2106     }
2107   else 
2108     {
2109       xops[3] = gen_rtx_REG (SImode, 0);
2110       if (do_rtl)
2111       emit_move_insn (xops[3], xops[2]);
2112       else
2113         output_asm_insn (AS2 (mov%L0,%2,%3), xops);
2114
2115       xops[3] = gen_rtx_MEM (FUNCTION_MODE,
2116                          gen_rtx (SYMBOL_REF, Pmode, "_alloca"));
2117
2118       if (do_rtl)
2119         emit_call_insn (gen_rtx (CALL, VOIDmode, xops[3], const0_rtx));
2120       else
2121         output_asm_insn (AS1 (call,%P3), xops);
2122     }
2123
2124   /* Note If use enter it is NOT reversed args.
2125      This one is not reversed from intel!!
2126      I think enter is slower.  Also sdb doesn't like it.
2127      But if you want it the code is:
2128      {
2129      xops[3] = const0_rtx;
2130      output_asm_insn ("enter %2,%3", xops);
2131      }
2132      */
2133
2134   limit = (frame_pointer_needed ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
2135   for (regno = limit - 1; regno >= 0; regno--)
2136     if ((regs_ever_live[regno] && ! call_used_regs[regno])
2137         || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
2138       {
2139         xops[0] = gen_rtx_REG (SImode, regno);
2140         if (do_rtl)
2141           {
2142             insn = emit_insn (gen_rtx (SET, VOIDmode,
2143                                        gen_rtx_MEM (SImode,
2144                                                 gen_rtx (PRE_DEC, SImode,
2145                                                          stack_pointer_rtx)),
2146                                        xops[0]));
2147
2148             RTX_FRAME_RELATED_P (insn) = 1;
2149           }
2150         else
2151           {
2152             output_asm_insn ("push%L0 %0", xops);
2153 #ifdef INCOMING_RETURN_ADDR_RTX
2154             if (dwarf2out_do_frame ())
2155               {
2156                 char *l = dwarf2out_cfi_label ();
2157
2158                 cfa_store_offset += 4;
2159                 if (! frame_pointer_needed)
2160                   {
2161                     cfa_offset = cfa_store_offset;
2162                     dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
2163                   }
2164
2165                 dwarf2out_reg_save (l, regno, - cfa_store_offset);
2166               }
2167 #endif
2168           }
2169       }
2170
2171   if (pic_reg_used)
2172     load_pic_register (do_rtl);
2173
2174   /* If we are profiling, make sure no instructions are scheduled before
2175      the call to mcount.  However, if -fpic, the above call will have
2176      done that.  */
2177   if ((profile_flag || profile_block_flag)
2178       && ! pic_reg_used && do_rtl)
2179     emit_insn (gen_blockage ());
2180 }
2181
2182 /* Return 1 if it is appropriate to emit `ret' instructions in the
2183    body of a function.  Do this only if the epilogue is simple, needing a
2184    couple of insns.  Prior to reloading, we can't tell how many registers
2185    must be saved, so return 0 then.  Return 0 if there is no frame 
2186    marker to de-allocate.
2187
2188    If NON_SAVING_SETJMP is defined and true, then it is not possible
2189    for the epilogue to be simple, so return 0.  This is a special case
2190    since NON_SAVING_SETJMP will not cause regs_ever_live to change
2191    until final, but jump_optimize may need to know sooner if a
2192    `return' is OK.  */
2193
2194 int
2195 ix86_can_use_return_insn_p ()
2196 {
2197   int regno;
2198   int nregs = 0;
2199   int reglimit = (frame_pointer_needed
2200                   ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
2201   int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
2202                                   || current_function_uses_const_pool);
2203
2204 #ifdef NON_SAVING_SETJMP
2205   if (NON_SAVING_SETJMP && current_function_calls_setjmp)
2206     return 0;
2207 #endif
2208
2209   if (! reload_completed)
2210     return 0;
2211
2212   for (regno = reglimit - 1; regno >= 0; regno--)
2213     if ((regs_ever_live[regno] && ! call_used_regs[regno])
2214         || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
2215       nregs++;
2216
2217   return nregs == 0 || ! frame_pointer_needed;
2218 }
2219
2220 /* This function generates the assembly code for function exit.
2221    FILE is an stdio stream to output the code to.
2222    SIZE is an int: how many units of temporary storage to deallocate. */
2223
2224 void
2225 function_epilogue (file, size)
2226      FILE *file ATTRIBUTE_UNUSED;
2227      int size ATTRIBUTE_UNUSED;
2228 {
2229     return;
2230 }
2231
2232 /* Restore function stack, frame, and registers. */ 
2233
2234 void
2235 ix86_expand_epilogue ()
2236 {
2237   ix86_epilogue (1);
2238 }
2239
2240 static void
2241 ix86_epilogue (do_rtl)
2242      int do_rtl;
2243 {
2244   register int regno;
2245   register int nregs, limit;
2246   int offset;
2247   rtx xops[3];
2248   int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
2249                                   || current_function_uses_const_pool);
2250   long tsize = get_frame_size ();
2251
2252   /* Compute the number of registers to pop */
2253
2254   limit = (frame_pointer_needed ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
2255
2256   nregs = 0;
2257
2258   for (regno = limit - 1; regno >= 0; regno--)
2259     if ((regs_ever_live[regno] && ! call_used_regs[regno])
2260         || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
2261       nregs++;
2262
2263   /* sp is often  unreliable so we must go off the frame pointer.
2264
2265      In reality, we may not care if sp is unreliable, because we can restore
2266      the register relative to the frame pointer.  In theory, since each move
2267      is the same speed as a pop, and we don't need the leal, this is faster.
2268      For now restore multiple registers the old way. */
2269
2270   offset = - tsize - (nregs * UNITS_PER_WORD);
2271
2272   xops[2] = stack_pointer_rtx;
2273
2274   /* When -fpic, we must emit a scheduling barrier, so that the instruction
2275      that restores %ebx (which is PIC_OFFSET_TABLE_REGNUM), does not get
2276      moved before any instruction which implicitly uses the got.  This
2277      includes any instruction which uses a SYMBOL_REF or a LABEL_REF.
2278
2279      Alternatively, this could be fixed by making the dependence on the
2280      PIC_OFFSET_TABLE_REGNUM explicit in the RTL.  */
2281
2282   if (flag_pic || profile_flag || profile_block_flag)
2283     emit_insn (gen_blockage ());
2284
2285   if (nregs > 1 || ! frame_pointer_needed)
2286     {
2287       if (frame_pointer_needed)
2288         {
2289           xops[0] = adj_offsettable_operand (AT_BP (QImode), offset);
2290           if (do_rtl)
2291             emit_insn (gen_movsi_lea (xops[2], XEXP (xops[0], 0)));
2292           else
2293             output_asm_insn (AS2 (lea%L2,%0,%2), xops);
2294         }
2295
2296       for (regno = 0; regno < limit; regno++)
2297         if ((regs_ever_live[regno] && ! call_used_regs[regno])
2298             || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
2299           {
2300             xops[0] = gen_rtx_REG (SImode, regno);
2301
2302             if (do_rtl)
2303               emit_insn (gen_pop (xops[0]));
2304             else
2305               output_asm_insn ("pop%L0 %0", xops);
2306           }
2307     }
2308
2309   else
2310     for (regno = 0; regno < limit; regno++)
2311       if ((regs_ever_live[regno] && ! call_used_regs[regno])
2312           || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
2313         {
2314           xops[0] = gen_rtx_REG (SImode, regno);
2315           xops[1] = adj_offsettable_operand (AT_BP (Pmode), offset);
2316
2317           if (do_rtl)
2318             emit_move_insn (xops[0], xops[1]);
2319           else
2320             output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2321
2322           offset += 4;
2323         }
2324
2325   if (frame_pointer_needed)
2326     {
2327       /* If not an i386, mov & pop is faster than "leave". */
2328
2329       if (TARGET_USE_LEAVE)
2330         {
2331           if (do_rtl)
2332             emit_insn (gen_leave());
2333           else
2334             output_asm_insn ("leave", xops);
2335         }
2336       else
2337         {
2338           xops[0] = frame_pointer_rtx;
2339           xops[1] = stack_pointer_rtx;
2340
2341           if (do_rtl)
2342             {
2343               emit_insn (gen_epilogue_set_stack_ptr());
2344               emit_insn (gen_pop (xops[0]));
2345             }
2346           else
2347             {
2348               output_asm_insn (AS2 (mov%L2,%0,%2), xops);
2349               output_asm_insn ("pop%L0 %0", xops);
2350             }
2351         }
2352     }
2353
2354   else if (tsize)
2355     {
2356       /* Intel's docs say that for 4 or 8 bytes of stack frame one should
2357          use `pop' and not `add'.  */
2358       int use_pop = tsize == 4;
2359
2360       /* Use two pops only for the Pentium processors.  */
2361       if (tsize == 8 && !TARGET_386 && !TARGET_486)
2362         {
2363           rtx retval = current_function_return_rtx;
2364
2365           xops[1] = gen_rtx_REG (SImode, 1);    /* %edx */
2366
2367           /* This case is a bit more complex.  Since we cannot pop into
2368              %ecx twice we need a second register.  But this is only
2369              available if the return value is not of DImode in which
2370              case the %edx register is not available.  */
2371           use_pop = (retval == NULL
2372                      || ! reg_overlap_mentioned_p (xops[1], retval));
2373         }
2374
2375       if (use_pop)
2376         {
2377           xops[0] = gen_rtx_REG (SImode, 2);    /* %ecx */
2378
2379           if (do_rtl)
2380             {
2381               /* We have to prevent the two pops here from being scheduled.
2382                  GCC otherwise would try in some situation to put other
2383                  instructions in between them which has a bad effect.  */
2384               emit_insn (gen_blockage ());
2385               emit_insn (gen_pop (xops[0]));
2386               if (tsize == 8)
2387                 emit_insn (gen_pop (xops[1]));
2388             }
2389           else
2390             {
2391               output_asm_insn ("pop%L0 %0", xops);
2392               if (tsize == 8)
2393                 output_asm_insn ("pop%L1 %1", xops);
2394             }
2395         }
2396       else
2397         {
2398           /* If there is no frame pointer, we must still release the frame. */
2399           xops[0] = GEN_INT (tsize);
2400
2401           if (do_rtl)
2402             emit_insn (gen_rtx (SET, VOIDmode, xops[2],
2403                                 gen_rtx (PLUS, SImode, xops[2], xops[0])));
2404           else
2405             output_asm_insn (AS2 (add%L2,%0,%2), xops);
2406         }
2407     }
2408
2409 #ifdef FUNCTION_BLOCK_PROFILER_EXIT
2410   if (profile_block_flag == 2)
2411     {
2412       FUNCTION_BLOCK_PROFILER_EXIT(file);
2413     }
2414 #endif
2415
2416   if (current_function_pops_args && current_function_args_size)
2417     {
2418       xops[1] = GEN_INT (current_function_pops_args);
2419
2420       /* i386 can only pop 32K bytes (maybe 64K?  Is it signed?).  If
2421          asked to pop more, pop return address, do explicit add, and jump
2422          indirectly to the caller. */
2423
2424       if (current_function_pops_args >= 32768)
2425         {
2426           /* ??? Which register to use here? */
2427           xops[0] = gen_rtx_REG (SImode, 2);
2428
2429           if (do_rtl)
2430             {
2431               emit_insn (gen_pop (xops[0]));
2432               emit_insn (gen_rtx (SET, VOIDmode, xops[2],
2433                                   gen_rtx (PLUS, SImode, xops[1], xops[2])));
2434               emit_jump_insn (xops[0]);
2435             }
2436           else
2437             {
2438               output_asm_insn ("pop%L0 %0", xops);
2439               output_asm_insn (AS2 (add%L2,%1,%2), xops);
2440               output_asm_insn ("jmp %*%0", xops);
2441             }
2442         }
2443       else 
2444         {
2445           if (do_rtl)
2446             emit_jump_insn (gen_return_pop_internal (xops[1]));
2447           else
2448             output_asm_insn ("ret %1", xops);
2449         }
2450     }
2451   else
2452     {
2453       if (do_rtl)
2454         emit_jump_insn (gen_return_internal ());
2455       else
2456         output_asm_insn ("ret", xops);
2457     }
2458 }
2459 \f
2460 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
2461    that is a valid memory address for an instruction.
2462    The MODE argument is the machine mode for the MEM expression
2463    that wants to use this address.
2464
2465    On x86, legitimate addresses are:
2466         base                            movl (base),reg
2467         displacement                    movl disp,reg
2468         base + displacement             movl disp(base),reg
2469         index + base                    movl (base,index),reg
2470         (index + base) + displacement   movl disp(base,index),reg
2471         index*scale                     movl (,index,scale),reg
2472         index*scale + disp              movl disp(,index,scale),reg
2473         index*scale + base              movl (base,index,scale),reg
2474         (index*scale + base) + disp     movl disp(base,index,scale),reg
2475
2476         In each case, scale can be 1, 2, 4, 8.  */
2477
2478 /* This is exactly the same as print_operand_addr, except that
2479    it recognizes addresses instead of printing them.
2480
2481    It only recognizes address in canonical form.  LEGITIMIZE_ADDRESS should
2482    convert common non-canonical forms to canonical form so that they will
2483    be recognized.  */
2484
2485 #define ADDR_INVALID(msg,insn)                                          \
2486 do {                                                                    \
2487   if (TARGET_DEBUG_ADDR)                                                \
2488     {                                                                   \
2489       fprintf (stderr, msg);                                            \
2490       debug_rtx (insn);                                                 \
2491     }                                                                   \
2492 } while (0)
2493
2494 int
2495 legitimate_address_p (mode, addr, strict)
2496      enum machine_mode mode;
2497      register rtx addr;
2498      int strict;
2499 {
2500   rtx base  = NULL_RTX;
2501   rtx indx  = NULL_RTX;
2502   rtx scale = NULL_RTX;
2503   rtx disp  = NULL_RTX;
2504
2505   if (TARGET_DEBUG_ADDR)
2506     {
2507       fprintf (stderr,
2508                "\n======\nGO_IF_LEGITIMATE_ADDRESS, mode = %s, strict = %d\n",
2509                GET_MODE_NAME (mode), strict);
2510
2511       debug_rtx (addr);
2512     }
2513
2514   if (GET_CODE (addr) == REG || GET_CODE (addr) == SUBREG)
2515       base = addr;
2516
2517   else if (GET_CODE (addr) == PLUS)
2518     {
2519       rtx op0 = XEXP (addr, 0);
2520       rtx op1 = XEXP (addr, 1);
2521       enum rtx_code code0 = GET_CODE (op0);
2522       enum rtx_code code1 = GET_CODE (op1);
2523
2524       if (code0 == REG || code0 == SUBREG)
2525         {
2526           if (code1 == REG || code1 == SUBREG)
2527             {
2528               indx = op0;       /* index + base */
2529               base = op1;
2530             }
2531
2532           else
2533             {
2534               base = op0;       /* base + displacement */
2535               disp = op1;
2536             }
2537         }
2538
2539       else if (code0 == MULT)
2540         {
2541           indx  = XEXP (op0, 0);
2542           scale = XEXP (op0, 1);
2543
2544           if (code1 == REG || code1 == SUBREG)
2545             base = op1;         /* index*scale + base */
2546
2547           else
2548             disp = op1;         /* index*scale + disp */
2549         }
2550
2551       else if (code0 == PLUS && GET_CODE (XEXP (op0, 0)) == MULT)
2552         {
2553           indx  = XEXP (XEXP (op0, 0), 0);      /* index*scale + base + disp */
2554           scale = XEXP (XEXP (op0, 0), 1);
2555           base  = XEXP (op0, 1);
2556           disp  = op1;
2557         }
2558
2559       else if (code0 == PLUS)
2560         {
2561           indx = XEXP (op0, 0); /* index + base + disp */
2562           base = XEXP (op0, 1);
2563           disp = op1;
2564         }
2565
2566       else
2567         {
2568           ADDR_INVALID ("PLUS subcode is not valid.\n", op0);
2569           return FALSE;
2570         }
2571     }
2572
2573   else if (GET_CODE (addr) == MULT)
2574     {
2575       indx  = XEXP (addr, 0);   /* index*scale */
2576       scale = XEXP (addr, 1);
2577     }
2578
2579   else
2580     disp = addr;                /* displacement */
2581
2582   /* Allow arg pointer and stack pointer as index if there is not scaling */
2583   if (base && indx && !scale
2584       && (indx == arg_pointer_rtx || indx == stack_pointer_rtx))
2585     {
2586       rtx tmp = base;
2587       base = indx;
2588       indx = tmp;
2589     }
2590
2591   /* Validate base register:
2592
2593      Don't allow SUBREG's here, it can lead to spill failures when the base
2594      is one word out of a two word structure, which is represented internally
2595      as a DImode int.  */
2596
2597   if (base)
2598     {
2599       if (GET_CODE (base) != REG)
2600         {
2601           ADDR_INVALID ("Base is not a register.\n", base);
2602           return FALSE;
2603         }
2604
2605       if ((strict && ! REG_OK_FOR_BASE_STRICT_P (base))
2606           || (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (base)))
2607         {
2608           ADDR_INVALID ("Base is not valid.\n", base);
2609           return FALSE;
2610         }
2611     }
2612
2613   /* Validate index register:
2614
2615      Don't allow SUBREG's here, it can lead to spill failures when the index
2616      is one word out of a two word structure, which is represented internally
2617      as a DImode int.  */
2618   if (indx)
2619     {
2620       if (GET_CODE (indx) != REG)
2621         {
2622           ADDR_INVALID ("Index is not a register.\n", indx);
2623           return FALSE;
2624         }
2625
2626       if ((strict && ! REG_OK_FOR_INDEX_STRICT_P (indx))
2627           || (! strict && ! REG_OK_FOR_INDEX_NONSTRICT_P (indx)))
2628         {
2629           ADDR_INVALID ("Index is not valid.\n", indx);
2630           return FALSE;
2631         }
2632     }
2633   else if (scale)
2634     abort ();                   /* scale w/o index invalid */
2635
2636   /* Validate scale factor: */
2637   if (scale)
2638     {
2639       HOST_WIDE_INT value;
2640
2641       if (GET_CODE (scale) != CONST_INT)
2642         {
2643           ADDR_INVALID ("Scale is not valid.\n", scale);
2644           return FALSE;
2645         }
2646
2647       value = INTVAL (scale);
2648       if (value != 1 && value != 2 && value != 4 && value != 8)
2649         {
2650           ADDR_INVALID ("Scale is not a good multiplier.\n", scale);
2651           return FALSE;
2652         }
2653     }
2654
2655   /* Validate displacement
2656      Constant pool addresses must be handled special.  They are
2657      considered legitimate addresses, but only if not used with regs.
2658      When printed, the output routines know to print the reference with the
2659      PIC reg, even though the PIC reg doesn't appear in the RTL. */
2660   if (disp)
2661     {
2662       if (GET_CODE (disp) == SYMBOL_REF
2663           && CONSTANT_POOL_ADDRESS_P (disp)
2664           && base == 0
2665           && indx == 0)
2666         ;
2667
2668       else if (!CONSTANT_ADDRESS_P (disp))
2669         {
2670           ADDR_INVALID ("Displacement is not valid.\n", disp);
2671           return FALSE;
2672         }
2673
2674       else if (GET_CODE (disp) == CONST_DOUBLE)
2675         {
2676           ADDR_INVALID ("Displacement is a const_double.\n", disp);
2677           return FALSE;
2678         }
2679
2680       else if (flag_pic && SYMBOLIC_CONST (disp)
2681                && base != pic_offset_table_rtx
2682                && (indx != pic_offset_table_rtx || scale != NULL_RTX))
2683         {
2684           ADDR_INVALID ("Displacement is an invalid pic reference.\n", disp);
2685           return FALSE;
2686         }
2687
2688       else if (HALF_PIC_P () && HALF_PIC_ADDRESS_P (disp)
2689                && (base != NULL_RTX || indx != NULL_RTX))
2690         {
2691           ADDR_INVALID ("Displacement is an invalid half-pic reference.\n",
2692                         disp);
2693           return FALSE;
2694         }
2695     }
2696
2697   if (TARGET_DEBUG_ADDR)
2698     fprintf (stderr, "Address is valid.\n");
2699
2700   /* Everything looks valid, return true */
2701   return TRUE;
2702 }
2703 \f
2704 /* Return a legitimate reference for ORIG (an address) using the
2705    register REG.  If REG is 0, a new pseudo is generated.
2706
2707    There are three types of references that must be handled:
2708
2709    1. Global data references must load the address from the GOT, via
2710       the PIC reg.  An insn is emitted to do this load, and the reg is
2711       returned.
2712
2713    2. Static data references must compute the address as an offset
2714       from the GOT, whose base is in the PIC reg.  An insn is emitted to
2715       compute the address into a reg, and the reg is returned.  Static
2716       data objects have SYMBOL_REF_FLAG set to differentiate them from
2717       global data objects.
2718
2719    3. Constant pool addresses must be handled special.  They are
2720       considered legitimate addresses, but only if not used with regs.
2721       When printed, the output routines know to print the reference with the
2722       PIC reg, even though the PIC reg doesn't appear in the RTL.
2723
2724    GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2725    reg also appears in the address (except for constant pool references,
2726    noted above).
2727
2728    "switch" statements also require special handling when generating
2729    PIC code.  See comments by the `casesi' insn in i386.md for details.  */
2730
2731 rtx
2732 legitimize_pic_address (orig, reg)
2733      rtx orig;
2734      rtx reg;
2735 {
2736   rtx addr = orig;
2737   rtx new = orig;
2738
2739   if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
2740     {
2741       if (GET_CODE (addr) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (addr))
2742         reg = new = orig;
2743       else
2744         {
2745           if (reg == 0)
2746             reg = gen_reg_rtx (Pmode);
2747
2748           if ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
2749               || GET_CODE (addr) == LABEL_REF)
2750             new = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig);
2751           else
2752             new = gen_rtx_MEM (Pmode,
2753                            gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig));
2754
2755           emit_move_insn (reg, new);
2756         }
2757       current_function_uses_pic_offset_table = 1;
2758       return reg;
2759     }
2760
2761   else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
2762     {
2763       rtx base;
2764
2765       if (GET_CODE (addr) == CONST)
2766         {
2767           addr = XEXP (addr, 0);
2768           if (GET_CODE (addr) != PLUS)
2769             abort ();
2770         }
2771
2772       if (XEXP (addr, 0) == pic_offset_table_rtx)
2773         return orig;
2774
2775       if (reg == 0)
2776         reg = gen_reg_rtx (Pmode);
2777
2778       base = legitimize_pic_address (XEXP (addr, 0), reg);
2779       addr = legitimize_pic_address (XEXP (addr, 1),
2780                                      base == reg ? NULL_RTX : reg);
2781
2782       if (GET_CODE (addr) == CONST_INT)
2783         return plus_constant (base, INTVAL (addr));
2784
2785       if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
2786         {
2787           base = gen_rtx (PLUS, Pmode, base, XEXP (addr, 0));
2788           addr = XEXP (addr, 1);
2789         }
2790
2791       return gen_rtx (PLUS, Pmode, base, addr);
2792     }
2793   return new;
2794 }
2795 \f
2796 /* Emit insns to move operands[1] into operands[0].  */
2797
2798 void
2799 emit_pic_move (operands, mode)
2800      rtx *operands;
2801      enum machine_mode mode ATTRIBUTE_UNUSED;
2802 {
2803   rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
2804
2805   if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
2806     operands[1] = force_reg (SImode, operands[1]);
2807   else
2808     operands[1] = legitimize_pic_address (operands[1], temp);
2809 }
2810 \f
2811 /* Try machine-dependent ways of modifying an illegitimate address
2812    to be legitimate.  If we find one, return the new, valid address.
2813    This macro is used in only one place: `memory_address' in explow.c.
2814
2815    OLDX is the address as it was before break_out_memory_refs was called.
2816    In some cases it is useful to look at this to decide what needs to be done.
2817
2818    MODE and WIN are passed so that this macro can use
2819    GO_IF_LEGITIMATE_ADDRESS.
2820
2821    It is always safe for this macro to do nothing.  It exists to recognize
2822    opportunities to optimize the output.
2823
2824    For the 80386, we handle X+REG by loading X into a register R and
2825    using R+REG.  R will go in a general reg and indexing will be used.
2826    However, if REG is a broken-out memory address or multiplication,
2827    nothing needs to be done because REG can certainly go in a general reg.
2828
2829    When -fpic is used, special handling is needed for symbolic references.
2830    See comments by legitimize_pic_address in i386.c for details.  */
2831
2832 rtx
2833 legitimize_address (x, oldx, mode)
2834      register rtx x;
2835      register rtx oldx ATTRIBUTE_UNUSED;
2836      enum machine_mode mode;
2837 {
2838   int changed = 0;
2839   unsigned log;
2840
2841   if (TARGET_DEBUG_ADDR)
2842     {
2843       fprintf (stderr, "\n==========\nLEGITIMIZE_ADDRESS, mode = %s\n",
2844                GET_MODE_NAME (mode));
2845       debug_rtx (x);
2846     }
2847
2848   if (flag_pic && SYMBOLIC_CONST (x))
2849     return legitimize_pic_address (x, 0);
2850
2851   /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
2852   if (GET_CODE (x) == ASHIFT
2853       && GET_CODE (XEXP (x, 1)) == CONST_INT
2854       && (log = (unsigned)exact_log2 (INTVAL (XEXP (x, 1)))) < 4)
2855     {
2856       changed = 1;
2857       x = gen_rtx (MULT, Pmode, force_reg (Pmode, XEXP (x, 0)),
2858                    GEN_INT (1 << log));
2859     }
2860
2861   if (GET_CODE (x) == PLUS)
2862     {
2863       /* Canonicalize shifts by 0, 1, 2, 3 into multiply. */
2864
2865       if (GET_CODE (XEXP (x, 0)) == ASHIFT
2866           && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
2867           && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) < 4)
2868         {
2869           changed = 1;
2870           XEXP (x, 0) = gen_rtx (MULT, Pmode,
2871                                  force_reg (Pmode, XEXP (XEXP (x, 0), 0)),
2872                                  GEN_INT (1 << log));
2873         }
2874
2875       if (GET_CODE (XEXP (x, 1)) == ASHIFT
2876           && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
2877           && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 1), 1)))) < 4)
2878         {
2879           changed = 1;
2880           XEXP (x, 1) = gen_rtx (MULT, Pmode,
2881                                  force_reg (Pmode, XEXP (XEXP (x, 1), 0)),
2882                                  GEN_INT (1 << log));
2883         }
2884
2885       /* Put multiply first if it isn't already. */
2886       if (GET_CODE (XEXP (x, 1)) == MULT)
2887         {
2888           rtx tmp = XEXP (x, 0);
2889           XEXP (x, 0) = XEXP (x, 1);
2890           XEXP (x, 1) = tmp;
2891           changed = 1;
2892         }
2893
2894       /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
2895          into (plus (plus (mult (reg) (const)) (reg)) (const)).  This can be
2896          created by virtual register instantiation, register elimination, and
2897          similar optimizations.  */
2898       if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS)
2899         {
2900           changed = 1;
2901           x = gen_rtx (PLUS, Pmode,
2902                        gen_rtx (PLUS, Pmode, XEXP (x, 0),
2903                                 XEXP (XEXP (x, 1), 0)),
2904                        XEXP (XEXP (x, 1), 1));
2905         }
2906
2907       /* Canonicalize
2908          (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
2909          into (plus (plus (mult (reg) (const)) (reg)) (const)).  */
2910       else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
2911                && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
2912                && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
2913                && CONSTANT_P (XEXP (x, 1)))
2914         {
2915           rtx constant;
2916           rtx other = NULL_RTX;
2917
2918           if (GET_CODE (XEXP (x, 1)) == CONST_INT)
2919             {
2920               constant = XEXP (x, 1);
2921               other = XEXP (XEXP (XEXP (x, 0), 1), 1);
2922             }
2923           else if (GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 1)) == CONST_INT)
2924             {
2925               constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
2926               other = XEXP (x, 1);
2927             }
2928           else
2929             constant = 0;
2930
2931           if (constant)
2932             {
2933               changed = 1;
2934               x = gen_rtx (PLUS, Pmode,
2935                            gen_rtx (PLUS, Pmode, XEXP (XEXP (x, 0), 0),
2936                                     XEXP (XEXP (XEXP (x, 0), 1), 0)),
2937                            plus_constant (other, INTVAL (constant)));
2938             }
2939         }
2940
2941       if (changed && legitimate_address_p (mode, x, FALSE))
2942         return x;
2943
2944       if (GET_CODE (XEXP (x, 0)) == MULT)
2945         {
2946           changed = 1;
2947           XEXP (x, 0) = force_operand (XEXP (x, 0), 0);
2948         }
2949
2950       if (GET_CODE (XEXP (x, 1)) == MULT)
2951         {
2952           changed = 1;
2953           XEXP (x, 1) = force_operand (XEXP (x, 1), 0);
2954         }
2955
2956       if (changed
2957           && GET_CODE (XEXP (x, 1)) == REG
2958           && GET_CODE (XEXP (x, 0)) == REG)
2959         return x;
2960
2961       if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1)))
2962         {
2963           changed = 1;
2964           x = legitimize_pic_address (x, 0);
2965         }
2966
2967       if (changed && legitimate_address_p (mode, x, FALSE))
2968         return x;
2969
2970       if (GET_CODE (XEXP (x, 0)) == REG)
2971         {
2972           register rtx temp = gen_reg_rtx (Pmode);
2973           register rtx val  = force_operand (XEXP (x, 1), temp);
2974           if (val != temp)
2975             emit_move_insn (temp, val);
2976
2977           XEXP (x, 1) = temp;
2978           return x;
2979         }
2980
2981       else if (GET_CODE (XEXP (x, 1)) == REG)
2982         {
2983           register rtx temp = gen_reg_rtx (Pmode);
2984           register rtx val  = force_operand (XEXP (x, 0), temp);
2985           if (val != temp)
2986             emit_move_insn (temp, val);
2987
2988           XEXP (x, 0) = temp;
2989           return x;
2990         }
2991     }
2992
2993   return x;
2994 }
2995 \f
2996 /* Print an integer constant expression in assembler syntax.  Addition
2997    and subtraction are the only arithmetic that may appear in these
2998    expressions.  FILE is the stdio stream to write to, X is the rtx, and
2999    CODE is the operand print code from the output string.  */
3000
3001 static void
3002 output_pic_addr_const (file, x, code)
3003      FILE *file;
3004      rtx x;
3005      int code;
3006 {
3007   char buf[256];
3008
3009   switch (GET_CODE (x))
3010     {
3011     case PC:
3012       if (flag_pic)
3013         putc ('.', file);
3014       else
3015         abort ();
3016       break;
3017
3018     case SYMBOL_REF:
3019     case LABEL_REF:
3020       if (GET_CODE (x) == SYMBOL_REF)
3021         assemble_name (file, XSTR (x, 0));
3022       else
3023         {
3024           ASM_GENERATE_INTERNAL_LABEL (buf, "L",
3025                                        CODE_LABEL_NUMBER (XEXP (x, 0)));
3026           assemble_name (asm_out_file, buf);
3027         }
3028
3029       if (code == 'X')
3030         ; /* No suffix, dammit. */
3031       else if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
3032         fprintf (file, "@GOTOFF(%%ebx)");
3033       else if (code == 'P')
3034         fprintf (file, "@PLT");
3035       else if (GET_CODE (x) == LABEL_REF)
3036         fprintf (file, "@GOTOFF");
3037       else if (! SYMBOL_REF_FLAG (x))
3038         fprintf (file, "@GOT");
3039       else
3040         fprintf (file, "@GOTOFF");
3041
3042       break;
3043
3044     case CODE_LABEL:
3045       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
3046       assemble_name (asm_out_file, buf);
3047       break;
3048
3049     case CONST_INT:
3050       fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
3051       break;
3052
3053     case CONST:
3054       /* This used to output parentheses around the expression,
3055          but that does not work on the 386 (either ATT or BSD assembler).  */
3056       output_pic_addr_const (file, XEXP (x, 0), code);
3057       break;
3058
3059     case CONST_DOUBLE:
3060       if (GET_MODE (x) == VOIDmode)
3061         {
3062           /* We can use %d if the number is <32 bits and positive.  */
3063           if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
3064             fprintf (file, "0x%lx%08lx",
3065                      (unsigned long) CONST_DOUBLE_HIGH (x),
3066                      (unsigned long) CONST_DOUBLE_LOW (x));
3067           else
3068             fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
3069         }
3070       else
3071         /* We can't handle floating point constants;
3072            PRINT_OPERAND must handle them.  */
3073         output_operand_lossage ("floating constant misused");
3074       break;
3075
3076     case PLUS:
3077       /* Some assemblers need integer constants to appear first.  */
3078       if (GET_CODE (XEXP (x, 0)) == CONST_INT)
3079         {
3080           output_pic_addr_const (file, XEXP (x, 0), code);
3081           if (INTVAL (XEXP (x, 1)) >= 0)
3082             fprintf (file, "+");
3083           output_pic_addr_const (file, XEXP (x, 1), code);
3084         }
3085       else
3086         {
3087           output_pic_addr_const (file, XEXP (x, 1), code);
3088           if (INTVAL (XEXP (x, 0)) >= 0)
3089             fprintf (file, "+");
3090           output_pic_addr_const (file, XEXP (x, 0), code);
3091         }
3092       break;
3093
3094     case MINUS:
3095       output_pic_addr_const (file, XEXP (x, 0), code);
3096       fprintf (file, "-");
3097       output_pic_addr_const (file, XEXP (x, 1), code);
3098       break;
3099
3100     default:
3101       output_operand_lossage ("invalid expression as operand");
3102     }
3103 }
3104 \f
3105 /* Append the correct conditional move suffix which corresponds to CODE.  */
3106
3107 static void
3108 put_condition_code (code, reverse_cc, mode, file)
3109      enum rtx_code code;
3110      int  reverse_cc;
3111      enum mode_class mode;
3112      FILE * file;
3113 {
3114   int ieee = (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
3115               && ! (cc_prev_status.flags & CC_FCOMI));
3116   if (reverse_cc && ! ieee)
3117     code = reverse_condition (code);
3118
3119   if (mode == MODE_INT)
3120     switch (code)
3121       {
3122       case NE: 
3123         if (cc_prev_status.flags & CC_Z_IN_NOT_C)
3124           fputs ("b", file);
3125         else
3126           fputs ("ne", file);
3127         return;
3128
3129       case EQ:
3130         if (cc_prev_status.flags & CC_Z_IN_NOT_C)
3131           fputs ("ae", file);
3132         else
3133           fputs ("e", file);
3134         return;
3135
3136       case GE:
3137         if (cc_prev_status.flags & CC_NO_OVERFLOW)
3138           fputs ("ns", file);
3139         else
3140           fputs ("ge", file);
3141         return;
3142
3143       case GT:
3144         fputs ("g", file);
3145         return;
3146
3147       case LE:
3148         fputs ("le", file);
3149         return;
3150
3151       case LT:
3152         if (cc_prev_status.flags & CC_NO_OVERFLOW)
3153           fputs ("s", file);
3154         else
3155           fputs ("l", file);
3156         return;
3157
3158       case GEU:
3159         fputs ("ae", file);
3160         return;
3161
3162       case GTU:
3163         fputs ("a", file);
3164         return;
3165
3166       case LEU:
3167         fputs ("be", file);
3168         return;
3169
3170       case LTU:
3171         fputs ("b", file);
3172         return;
3173
3174       default:
3175         output_operand_lossage ("Invalid %%C operand");
3176       }
3177
3178   else if (mode == MODE_FLOAT)
3179     switch (code)
3180       {
3181       case NE: 
3182         fputs (ieee ? (reverse_cc ? "ne" : "e") : "ne", file);
3183         return;
3184       case EQ: 
3185         fputs (ieee ? (reverse_cc ? "ne" : "e") : "e", file);
3186         return;
3187       case GE: 
3188         fputs (ieee ? (reverse_cc ? "ne" : "e") : "nb", file);
3189         return;
3190       case GT: 
3191         fputs (ieee ? (reverse_cc ? "ne" : "e") : "nbe", file);
3192         return;
3193       case LE: 
3194         fputs (ieee ? (reverse_cc ? "nb" : "b") : "be", file);
3195         return;
3196       case LT: 
3197         fputs (ieee ? (reverse_cc ? "ne" : "e") : "b", file);
3198         return;
3199       case GEU: 
3200         fputs (ieee ? (reverse_cc ? "ne" : "e") : "nb", file);
3201         return;
3202       case GTU: 
3203         fputs (ieee ? (reverse_cc ? "ne" : "e") : "nbe", file);
3204         return;
3205       case LEU: 
3206         fputs (ieee ? (reverse_cc ? "nb" : "b") : "be", file);
3207         return;
3208       case LTU: 
3209         fputs (ieee ? (reverse_cc ? "ne" : "e") : "b", file);
3210         return;
3211       default:
3212         output_operand_lossage ("Invalid %%C operand");
3213     }
3214 }
3215
3216 /* Meaning of CODE:
3217    L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
3218    C -- print opcode suffix for set/cmov insn.
3219    c -- like C, but print reversed condition
3220    F -- print opcode suffix for fcmov insn.
3221    f -- like C, but print reversed condition
3222    R -- print the prefix for register names.
3223    z -- print the opcode suffix for the size of the current operand.
3224    * -- print a star (in certain assembler syntax)
3225    w -- print the operand as if it's a "word" (HImode) even if it isn't.
3226    c -- don't print special prefixes before constant operands.
3227    J -- print the appropriate jump operand.
3228    s -- print a shift double count, followed by the assemblers argument
3229         delimiter.
3230    b -- print the QImode name of the register for the indicated operand.
3231         %b0 would print %al if operands[0] is reg 0.
3232    w --  likewise, print the HImode name of the register.
3233    k --  likewise, print the SImode name of the register.
3234    h --  print the QImode name for a "high" register, either ah, bh, ch or dh.
3235    y --  print "st(0)" instead of "st" as a register.
3236    P --  print as a PIC constant */
3237
3238 void
3239 print_operand (file, x, code)
3240      FILE *file;
3241      rtx x;
3242      int code;
3243 {
3244   if (code)
3245     {
3246       switch (code)
3247         {
3248         case '*':
3249           if (USE_STAR)
3250             putc ('*', file);
3251           return;
3252
3253         case 'L':
3254           PUT_OP_SIZE (code, 'l', file);
3255           return;
3256
3257         case 'W':
3258           PUT_OP_SIZE (code, 'w', file);
3259           return;
3260
3261         case 'B':
3262           PUT_OP_SIZE (code, 'b', file);
3263           return;
3264
3265         case 'Q':
3266           PUT_OP_SIZE (code, 'l', file);
3267           return;
3268
3269         case 'S':
3270           PUT_OP_SIZE (code, 's', file);
3271           return;
3272
3273         case 'T':
3274           PUT_OP_SIZE (code, 't', file);
3275           return;
3276
3277         case 'z':
3278           /* 387 opcodes don't get size suffixes if the operands are
3279              registers. */
3280
3281           if (STACK_REG_P (x))
3282             return;
3283
3284           /* this is the size of op from size of operand */
3285           switch (GET_MODE_SIZE (GET_MODE (x)))
3286             {
3287             case 1:
3288               PUT_OP_SIZE ('B', 'b', file);
3289               return;
3290
3291             case 2:
3292               PUT_OP_SIZE ('W', 'w', file);
3293               return;
3294
3295             case 4:
3296               if (GET_MODE (x) == SFmode)
3297                 {
3298                   PUT_OP_SIZE ('S', 's', file);
3299                   return;
3300                 }
3301               else
3302                 PUT_OP_SIZE ('L', 'l', file);
3303               return;
3304
3305             case 12:
3306                   PUT_OP_SIZE ('T', 't', file);
3307                   return;
3308
3309             case 8:
3310               if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
3311                 {
3312 #ifdef GAS_MNEMONICS
3313                   PUT_OP_SIZE ('Q', 'q', file);
3314                   return;
3315 #else
3316                   PUT_OP_SIZE ('Q', 'l', file); /* Fall through */
3317 #endif
3318                 }
3319
3320               PUT_OP_SIZE ('Q', 'l', file);
3321               return;
3322             }
3323
3324         case 'b':
3325         case 'w':
3326         case 'k':
3327         case 'h':
3328         case 'y':
3329         case 'P':
3330         case 'X':
3331           break;
3332
3333         case 'J':
3334           switch (GET_CODE (x))
3335             {
3336               /* These conditions are appropriate for testing the result
3337                  of an arithmetic operation, not for a compare operation.
3338                  Cases GE, LT assume CC_NO_OVERFLOW true. All cases assume
3339                  CC_Z_IN_NOT_C false and not floating point.  */
3340             case NE:  fputs ("jne", file); return;
3341             case EQ:  fputs ("je",  file); return;
3342             case GE:  fputs ("jns", file); return;
3343             case LT:  fputs ("js",  file); return;
3344             case GEU: fputs ("jmp", file); return;
3345             case GTU: fputs ("jne",  file); return;
3346             case LEU: fputs ("je", file); return;
3347             case LTU: fputs ("#branch never",  file); return;
3348             
3349             /* no matching branches for GT nor LE */
3350             
3351             default:
3352               abort ();
3353             }
3354
3355         case 's':
3356           if (GET_CODE (x) == CONST_INT || ! SHIFT_DOUBLE_OMITS_COUNT)
3357             {
3358               PRINT_OPERAND (file, x, 0);
3359               fputs (AS2C (,) + 1, file);
3360             }
3361
3362           return;
3363
3364           /* This is used by the conditional move instructions.  */
3365         case 'C':
3366           put_condition_code (GET_CODE (x), 0, MODE_INT, file);
3367           return;
3368
3369           /* Like above, but reverse condition */
3370         case 'c':
3371           put_condition_code (GET_CODE (x), 1, MODE_INT, file); return;
3372
3373         case 'F':
3374           put_condition_code (GET_CODE (x), 0, MODE_FLOAT, file);
3375           return;
3376
3377           /* Like above, but reverse condition */
3378         case 'f':
3379           put_condition_code (GET_CODE (x), 1, MODE_FLOAT, file);
3380           return;
3381
3382         default:
3383           {
3384             char str[50];
3385
3386             sprintf (str, "invalid operand code `%c'", code);
3387             output_operand_lossage (str);
3388           }
3389         }
3390     }
3391
3392   if (GET_CODE (x) == REG)
3393     {
3394       PRINT_REG (x, code, file);
3395     }
3396
3397   else if (GET_CODE (x) == MEM)
3398     {
3399       PRINT_PTR (x, file);
3400       if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
3401         {
3402           if (flag_pic)
3403             output_pic_addr_const (file, XEXP (x, 0), code);
3404           else
3405             output_addr_const (file, XEXP (x, 0));
3406         }
3407       else
3408         output_address (XEXP (x, 0));
3409     }
3410
3411   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
3412     {
3413       REAL_VALUE_TYPE r;
3414       long l;
3415
3416       REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3417       REAL_VALUE_TO_TARGET_SINGLE (r, l);
3418       PRINT_IMMED_PREFIX (file);
3419       fprintf (file, "0x%lx", l);
3420     }
3421
3422  /* These float cases don't actually occur as immediate operands. */
3423  else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
3424     {
3425       REAL_VALUE_TYPE r;
3426       char dstr[30];
3427
3428       REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3429       REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
3430       fprintf (file, "%s", dstr);
3431     }
3432
3433   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == XFmode)
3434     {
3435       REAL_VALUE_TYPE r;
3436       char dstr[30];
3437
3438       REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3439       REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
3440       fprintf (file, "%s", dstr);
3441     }
3442   else 
3443     {
3444       if (code != 'P')
3445         {
3446           if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
3447             PRINT_IMMED_PREFIX (file);
3448           else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
3449                    || GET_CODE (x) == LABEL_REF)
3450             PRINT_OFFSET_PREFIX (file);
3451         }
3452       if (flag_pic)
3453         output_pic_addr_const (file, x, code);
3454       else
3455         output_addr_const (file, x);
3456     }
3457 }
3458 \f
3459 /* Print a memory operand whose address is ADDR.  */
3460
3461 void
3462 print_operand_address (file, addr)
3463      FILE *file;
3464      register rtx addr;
3465 {
3466   register rtx reg1, reg2, breg, ireg;
3467   rtx offset;
3468
3469   switch (GET_CODE (addr))
3470     {
3471     case REG:
3472       ADDR_BEG (file);
3473       fprintf (file, "%se", RP);
3474       fputs (hi_reg_name[REGNO (addr)], file);
3475       ADDR_END (file);
3476       break;
3477
3478     case PLUS:
3479       reg1 = 0;
3480       reg2 = 0;
3481       ireg = 0;
3482       breg = 0;
3483       offset = 0;
3484       if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
3485         {
3486           offset = XEXP (addr, 0);
3487           addr = XEXP (addr, 1);
3488         }
3489       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
3490         {
3491           offset = XEXP (addr, 1);
3492           addr = XEXP (addr, 0);
3493         }
3494
3495       if (GET_CODE (addr) != PLUS)
3496         ;
3497       else if (GET_CODE (XEXP (addr, 0)) == MULT)
3498         reg1 = XEXP (addr, 0), addr = XEXP (addr, 1);
3499       else if (GET_CODE (XEXP (addr, 1)) == MULT)
3500         reg1 = XEXP (addr, 1), addr = XEXP (addr, 0);
3501       else if (GET_CODE (XEXP (addr, 0)) == REG)
3502         reg1 = XEXP (addr, 0), addr = XEXP (addr, 1);
3503       else if (GET_CODE (XEXP (addr, 1)) == REG)
3504         reg1 = XEXP (addr, 1), addr = XEXP (addr, 0);
3505
3506       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
3507         {
3508           if (reg1 == 0)
3509             reg1 = addr;
3510           else
3511             reg2 = addr;
3512
3513           addr = 0;
3514         }
3515
3516       if (offset != 0)
3517         {
3518           if (addr != 0)
3519             abort ();
3520           addr = offset;
3521         }
3522
3523       if ((reg1 && GET_CODE (reg1) == MULT)
3524           || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
3525         {
3526           breg = reg2;
3527           ireg = reg1;
3528         }
3529       else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
3530         {
3531           breg = reg1;
3532           ireg = reg2;
3533         }
3534
3535       if (ireg != 0 || breg != 0)
3536         {
3537           int scale = 1;
3538
3539           if (addr != 0)
3540             {
3541               if (flag_pic)
3542                 output_pic_addr_const (file, addr, 0);
3543               else if (GET_CODE (addr) == LABEL_REF)
3544                 output_asm_label (addr);
3545               else
3546                 output_addr_const (file, addr);
3547             }
3548
3549           if (ireg != 0 && GET_CODE (ireg) == MULT)
3550             {
3551               scale = INTVAL (XEXP (ireg, 1));
3552               ireg = XEXP (ireg, 0);
3553             }
3554
3555           /* The stack pointer can only appear as a base register,
3556              never an index register, so exchange the regs if it is wrong. */
3557
3558           if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM)
3559             {
3560               rtx tmp;
3561
3562               tmp = breg;
3563               breg = ireg;
3564               ireg = tmp;
3565             }
3566
3567           /* output breg+ireg*scale */
3568           PRINT_B_I_S (breg, ireg, scale, file);
3569           break;
3570         }
3571
3572     case MULT:
3573       {
3574         int scale;
3575
3576         if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
3577           {
3578             scale = INTVAL (XEXP (addr, 0));
3579             ireg = XEXP (addr, 1);
3580           }
3581         else
3582           {
3583             scale = INTVAL (XEXP (addr, 1));
3584             ireg = XEXP (addr, 0);
3585           }
3586
3587         output_addr_const (file, const0_rtx);
3588         PRINT_B_I_S (NULL_RTX, ireg, scale, file);
3589       }
3590       break;
3591
3592     default:
3593       if (GET_CODE (addr) == CONST_INT
3594           && INTVAL (addr) < 0x8000
3595           && INTVAL (addr) >= -0x8000)
3596         fprintf (file, "%d", (int) INTVAL (addr));
3597       else
3598         {
3599           if (flag_pic)
3600             output_pic_addr_const (file, addr, 0);
3601           else
3602             output_addr_const (file, addr);
3603         }
3604     }
3605 }
3606 \f
3607 /* Set the cc_status for the results of an insn whose pattern is EXP.
3608    On the 80386, we assume that only test and compare insns, as well
3609    as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, BSF, ASHIFT,
3610    ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
3611    Also, we assume that jumps, moves and sCOND don't affect the condition
3612    codes.  All else clobbers the condition codes, by assumption.
3613
3614    We assume that ALL integer add, minus, etc. instructions effect the
3615    condition codes.  This MUST be consistent with i386.md.
3616
3617    We don't record any float test or compare - the redundant test &
3618    compare check in final.c does not handle stack-like regs correctly. */
3619
3620 void
3621 notice_update_cc (exp)
3622      rtx exp;
3623 {
3624   if (GET_CODE (exp) == SET)
3625     {
3626       /* Jumps do not alter the cc's.  */
3627       if (SET_DEST (exp) == pc_rtx)
3628         return;
3629
3630       /* Moving register or memory into a register:
3631          it doesn't alter the cc's, but it might invalidate
3632          the RTX's which we remember the cc's came from.
3633          (Note that moving a constant 0 or 1 MAY set the cc's).  */
3634       if (REG_P (SET_DEST (exp))
3635           && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM
3636               || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'
3637               || (GET_CODE (SET_SRC (exp)) == IF_THEN_ELSE
3638                   && GET_MODE_CLASS (GET_MODE (SET_DEST (exp))) == MODE_INT)))
3639         {
3640           if (cc_status.value1
3641               && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
3642             cc_status.value1 = 0;
3643
3644           if (cc_status.value2
3645               && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
3646             cc_status.value2 = 0;
3647
3648           return;
3649         }
3650
3651       /* Moving register into memory doesn't alter the cc's.
3652          It may invalidate the RTX's which we remember the cc's came from.  */
3653       if (GET_CODE (SET_DEST (exp)) == MEM
3654           && (REG_P (SET_SRC (exp))
3655               || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
3656         {
3657           if (cc_status.value1
3658               && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
3659             cc_status.value1 = 0;
3660           if (cc_status.value2
3661               && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
3662             cc_status.value2 = 0;
3663
3664           return;
3665         }
3666
3667       /* Function calls clobber the cc's.  */
3668       else if (GET_CODE (SET_SRC (exp)) == CALL)
3669         {
3670           CC_STATUS_INIT;
3671           return;
3672         }
3673
3674       /* Tests and compares set the cc's in predictable ways.  */
3675       else if (SET_DEST (exp) == cc0_rtx)
3676         {
3677           CC_STATUS_INIT;
3678           cc_status.value1 = SET_SRC (exp);
3679           return;
3680         }
3681
3682       /* Certain instructions effect the condition codes. */
3683       else if (GET_MODE (SET_SRC (exp)) == SImode
3684                || GET_MODE (SET_SRC (exp)) == HImode
3685                || GET_MODE (SET_SRC (exp)) == QImode)
3686         switch (GET_CODE (SET_SRC (exp)))
3687           {
3688           case ASHIFTRT: case LSHIFTRT: case ASHIFT:
3689             /* Shifts on the 386 don't set the condition codes if the
3690                shift count is zero. */
3691             if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
3692               {
3693                 CC_STATUS_INIT;
3694                 break;
3695               }
3696
3697             /* We assume that the CONST_INT is non-zero (this rtx would
3698                have been deleted if it were zero. */
3699
3700           case PLUS: case MINUS: case NEG:
3701           case AND: case IOR: case XOR:
3702             cc_status.flags = CC_NO_OVERFLOW;
3703             cc_status.value1 = SET_SRC (exp);
3704             cc_status.value2 = SET_DEST (exp);
3705             break;
3706
3707             /* This is the bsf pattern used by ffs.  */
3708           case UNSPEC:
3709             if (XINT (SET_SRC (exp), 1) == 5)
3710               {
3711                 /* Only the Z flag is defined after bsf.  */
3712                 cc_status.flags
3713                   = CC_NOT_POSITIVE | CC_NOT_NEGATIVE | CC_NO_OVERFLOW;
3714                 cc_status.value1 = XVECEXP (SET_SRC (exp), 0, 0);
3715                 cc_status.value2 = 0;
3716                 break;
3717               }
3718             /* FALLTHRU */
3719
3720           default:
3721             CC_STATUS_INIT;
3722           }
3723       else
3724         {
3725           CC_STATUS_INIT;
3726         }
3727     }
3728   else if (GET_CODE (exp) == PARALLEL
3729            && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
3730     {
3731       if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
3732         return;
3733       if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
3734
3735         {
3736           CC_STATUS_INIT;
3737           if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
3738             {
3739               cc_status.flags |= CC_IN_80387;
3740               if (0 && TARGET_CMOVE && stack_regs_mentioned_p
3741                   (XEXP (SET_SRC (XVECEXP (exp, 0, 0)), 1)))
3742                 cc_status.flags |= CC_FCOMI;
3743             }
3744           else
3745             cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
3746           return;
3747         }
3748
3749       CC_STATUS_INIT;
3750     }
3751   else
3752     {
3753       CC_STATUS_INIT;
3754     }
3755 }
3756 \f
3757 /* Split one or more DImode RTL references into pairs of SImode
3758    references.  The RTL can be REG, offsettable MEM, integer constant, or
3759    CONST_DOUBLE.  "operands" is a pointer to an array of DImode RTL to
3760    split and "num" is its length.  lo_half and hi_half are output arrays
3761    that parallel "operands". */
3762
3763 void
3764 split_di (operands, num, lo_half, hi_half)
3765      rtx operands[];
3766      int num;
3767      rtx lo_half[], hi_half[];
3768 {
3769   while (num--)
3770     {
3771       rtx op = operands[num];
3772       if (GET_CODE (op) == REG)
3773         {
3774           lo_half[num] = gen_rtx_REG (SImode, REGNO (op));
3775           hi_half[num] = gen_rtx_REG (SImode, REGNO (op) + 1);
3776         }
3777       else if (CONSTANT_P (op))
3778         split_double (op, &lo_half[num], &hi_half[num]);
3779       else if (offsettable_memref_p (op))
3780         {
3781           rtx lo_addr = XEXP (op, 0);
3782           rtx hi_addr = XEXP (adj_offsettable_operand (op, 4), 0);
3783           lo_half[num] = change_address (op, SImode, lo_addr);
3784           hi_half[num] = change_address (op, SImode, hi_addr);
3785         }
3786       else
3787         abort();
3788     }
3789 }
3790 \f
3791 /* Return 1 if this is a valid binary operation on a 387.
3792    OP is the expression matched, and MODE is its mode. */
3793
3794 int
3795 binary_387_op (op, mode)
3796     register rtx op;
3797     enum machine_mode mode;
3798 {
3799   if (mode != VOIDmode && mode != GET_MODE (op))
3800     return 0;
3801
3802   switch (GET_CODE (op))
3803     {
3804     case PLUS:
3805     case MINUS:
3806     case MULT:
3807     case DIV:
3808       return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
3809
3810     default:
3811       return 0;
3812     }
3813 }
3814 \f
3815 /* Return 1 if this is a valid shift or rotate operation on a 386.
3816    OP is the expression matched, and MODE is its mode. */
3817
3818 int
3819 shift_op (op, mode)
3820     register rtx op;
3821     enum machine_mode mode;
3822 {
3823   rtx operand = XEXP (op, 0);
3824
3825   if (mode != VOIDmode && mode != GET_MODE (op))
3826     return 0;
3827
3828   if (GET_MODE (operand) != GET_MODE (op)
3829       || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
3830     return 0;
3831
3832   return (GET_CODE (op) == ASHIFT
3833           || GET_CODE (op) == ASHIFTRT
3834           || GET_CODE (op) == LSHIFTRT
3835           || GET_CODE (op) == ROTATE
3836           || GET_CODE (op) == ROTATERT);
3837 }
3838
3839 /* Return 1 if OP is COMPARE rtx with mode VOIDmode.
3840    MODE is not used.  */
3841
3842 int
3843 VOIDmode_compare_op (op, mode)
3844     register rtx op;
3845     enum machine_mode mode ATTRIBUTE_UNUSED;
3846 {
3847   return GET_CODE (op) == COMPARE && GET_MODE (op) == VOIDmode;
3848 }
3849 \f
3850 /* Output code to perform a 387 binary operation in INSN, one of PLUS,
3851    MINUS, MULT or DIV.  OPERANDS are the insn operands, where operands[3]
3852    is the expression of the binary operation.  The output may either be
3853    emitted here, or returned to the caller, like all output_* functions.
3854
3855    There is no guarantee that the operands are the same mode, as they
3856    might be within FLOAT or FLOAT_EXTEND expressions. */
3857
3858 char *
3859 output_387_binary_op (insn, operands)
3860      rtx insn;
3861      rtx *operands;
3862 {
3863   rtx temp;
3864   char *base_op;
3865   static char buf[100];
3866
3867   switch (GET_CODE (operands[3]))
3868     {
3869     case PLUS:
3870       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3871           || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3872         base_op = "fiadd";
3873       else
3874         base_op = "fadd";
3875       break;
3876
3877     case MINUS:
3878       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3879           || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3880         base_op = "fisub";
3881       else
3882         base_op = "fsub";
3883       break;
3884
3885     case MULT:
3886       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3887           || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3888         base_op = "fimul";
3889       else
3890         base_op = "fmul";
3891       break;
3892
3893     case DIV:
3894       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3895           || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3896         base_op = "fidiv";
3897       else
3898         base_op = "fdiv";
3899       break;
3900
3901     default:
3902       abort ();
3903     }
3904
3905   strcpy (buf, base_op);
3906
3907   switch (GET_CODE (operands[3]))
3908     {
3909     case MULT:
3910     case PLUS:
3911       if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
3912         {
3913           temp = operands[2];
3914           operands[2] = operands[1];
3915           operands[1] = temp;
3916         }
3917
3918       if (GET_CODE (operands[2]) == MEM)
3919         return strcat (buf, AS1 (%z2,%2));
3920
3921       if (NON_STACK_REG_P (operands[1]))
3922         {
3923           output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
3924           return "";
3925         }
3926
3927       else if (NON_STACK_REG_P (operands[2]))
3928         {
3929           output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
3930           return "";
3931         }
3932
3933       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
3934         {
3935           if (STACK_TOP_P (operands[0]))
3936             return strcat (buf, AS2 (p,%0,%2));
3937           else
3938             return strcat (buf, AS2 (p,%2,%0));
3939         }
3940
3941       if (STACK_TOP_P (operands[0]))
3942         return strcat (buf, AS2C (%y2,%0));
3943       else
3944         return strcat (buf, AS2C (%2,%0));
3945
3946     case MINUS:
3947     case DIV:
3948       if (GET_CODE (operands[1]) == MEM)
3949         return strcat (buf, AS1 (r%z1,%1));
3950
3951       if (GET_CODE (operands[2]) == MEM)
3952         return strcat (buf, AS1 (%z2,%2));
3953
3954       if (NON_STACK_REG_P (operands[1]))
3955         {
3956           output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1)));
3957           return "";
3958         }
3959
3960       else if (NON_STACK_REG_P (operands[2]))
3961         {
3962           output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
3963           return "";
3964         }
3965
3966       if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
3967         abort ();
3968
3969       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
3970         {
3971           if (STACK_TOP_P (operands[0]))
3972             return strcat (buf, AS2 (p,%0,%2));
3973           else
3974             return strcat (buf, AS2 (rp,%2,%0));
3975         }
3976
3977       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3978         {
3979           if (STACK_TOP_P (operands[0]))
3980             return strcat (buf, AS2 (rp,%0,%1));
3981           else
3982             return strcat (buf, AS2 (p,%1,%0));
3983         }
3984
3985       if (STACK_TOP_P (operands[0]))
3986         {
3987           if (STACK_TOP_P (operands[1]))
3988             return strcat (buf, AS2C (%y2,%0));
3989           else
3990             return strcat (buf, AS2 (r,%y1,%0));
3991         }
3992       else if (STACK_TOP_P (operands[1]))
3993         return strcat (buf, AS2C (%1,%0));
3994       else
3995         return strcat (buf, AS2 (r,%2,%0));
3996
3997     default:
3998       abort ();
3999     }
4000 }
4001 \f
4002 /* Output code for INSN to convert a float to a signed int.  OPERANDS
4003    are the insn operands.  The output may be SFmode or DFmode and the
4004    input operand may be SImode or DImode.  As a special case, make sure
4005    that the 387 stack top dies if the output mode is DImode, because the
4006    hardware requires this.  */
4007
4008 char *
4009 output_fix_trunc (insn, operands)
4010      rtx insn;
4011      rtx *operands;
4012 {
4013   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
4014   rtx xops[2];
4015
4016   if (! STACK_TOP_P (operands[1]))
4017     abort ();
4018
4019   xops[0] = GEN_INT (12);
4020   xops[1] = operands[4];
4021
4022   output_asm_insn (AS1 (fnstc%W2,%2), operands);
4023   output_asm_insn (AS2 (mov%L2,%2,%4), operands);
4024   output_asm_insn (AS2 (mov%B1,%0,%h1), xops);
4025   output_asm_insn (AS2 (mov%L4,%4,%3), operands);
4026   output_asm_insn (AS1 (fldc%W3,%3), operands);
4027
4028   if (NON_STACK_REG_P (operands[0]))
4029     output_to_reg (operands[0], stack_top_dies, operands[3]);
4030
4031   else if (GET_CODE (operands[0]) == MEM)
4032     {
4033       if (stack_top_dies)
4034         output_asm_insn (AS1 (fistp%z0,%0), operands);
4035       else if (GET_MODE (operands[0]) == DImode && ! stack_top_dies)
4036         {
4037           /* There is no DImode version of this without a stack pop, so
4038              we must emulate it.  It doesn't matter much what the second
4039              instruction is, because the value being pushed on the FP stack
4040              is not used except for the following stack popping store.
4041              This case can only happen without optimization, so it doesn't
4042              matter that it is inefficient.  */
4043           output_asm_insn (AS1 (fistp%z0,%0), operands);
4044           output_asm_insn (AS1 (fild%z0,%0), operands);
4045         }
4046       else
4047         output_asm_insn (AS1 (fist%z0,%0), operands);
4048     }
4049   else
4050     abort ();
4051
4052   return AS1 (fldc%W2,%2);
4053 }
4054 \f
4055 /* Output code for INSN to compare OPERANDS.  The two operands might
4056    not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
4057    expression.  If the compare is in mode CCFPEQmode, use an opcode that
4058    will not fault if a qNaN is present. */
4059
4060 char *
4061 output_float_compare (insn, operands)
4062      rtx insn;
4063      rtx *operands;
4064 {
4065   int stack_top_dies;
4066   rtx body = XVECEXP (PATTERN (insn), 0, 0);
4067   int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
4068   rtx tmp;
4069
4070   if (0 && TARGET_CMOVE && STACK_REG_P (operands[1]))
4071     {
4072       cc_status.flags |= CC_FCOMI;
4073       cc_prev_status.flags &= ~CC_TEST_AX;
4074     }
4075
4076   if (! STACK_TOP_P (operands[0]))
4077     {
4078       tmp = operands[0];
4079       operands[0] = operands[1];
4080       operands[1] = tmp;
4081       cc_status.flags |= CC_REVERSED;
4082     }
4083     
4084   if (! STACK_TOP_P (operands[0]))
4085     abort ();
4086
4087   stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
4088
4089   if (STACK_REG_P (operands[1])
4090       && stack_top_dies
4091       && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
4092       && REGNO (operands[1]) != FIRST_STACK_REG)
4093     {
4094       /* If both the top of the 387 stack dies, and the other operand
4095          is also a stack register that dies, then this must be a
4096          `fcompp' float compare */
4097
4098       if (unordered_compare)
4099         {
4100           if (cc_status.flags & CC_FCOMI)
4101             {
4102               output_asm_insn (AS2 (fucomip,%y1,%0), operands);
4103               output_asm_insn (AS1 (fstp, %y0), operands);
4104               return "";
4105             }
4106           else
4107             output_asm_insn ("fucompp", operands);
4108         }
4109       else
4110         {
4111           if (cc_status.flags & CC_FCOMI)
4112             {
4113               output_asm_insn (AS2 (fcomip, %y1,%0), operands);
4114               output_asm_insn (AS1 (fstp, %y0), operands);
4115               return "";
4116             }
4117           else
4118             output_asm_insn ("fcompp", operands);
4119         }
4120     }
4121   else
4122     {
4123       static char buf[100];
4124
4125       /* Decide if this is the integer or float compare opcode, or the
4126          unordered float compare. */
4127
4128       if (unordered_compare)
4129         strcpy (buf, (cc_status.flags & CC_FCOMI) ? "fucomi" : "fucom");
4130       else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT)
4131         strcpy (buf, (cc_status.flags & CC_FCOMI) ? "fcomi" : "fcom");
4132       else
4133         strcpy (buf, "ficom");
4134
4135       /* Modify the opcode if the 387 stack is to be popped. */
4136
4137       if (stack_top_dies)
4138         strcat (buf, "p");
4139
4140       if (NON_STACK_REG_P (operands[1]))
4141         output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
4142       else if (cc_status.flags & CC_FCOMI) 
4143         {
4144           output_asm_insn (strcat (buf, AS2 (%z1,%y1,%0)), operands);
4145           return "";
4146         }
4147       else
4148         output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
4149     }
4150
4151   /* Now retrieve the condition code. */
4152
4153   return output_fp_cc0_set (insn);
4154 }
4155 \f
4156 /* Output opcodes to transfer the results of FP compare or test INSN
4157    from the FPU to the CPU flags.  If TARGET_IEEE_FP, ensure that if the
4158    result of the compare or test is unordered, no comparison operator
4159    succeeds except NE.  Return an output template, if any.  */
4160
4161 char *
4162 output_fp_cc0_set (insn)
4163      rtx insn;
4164 {
4165   rtx xops[3];
4166   rtx next;
4167   enum rtx_code code;
4168
4169   xops[0] = gen_rtx_REG (HImode, 0);
4170   output_asm_insn (AS1 (fnsts%W0,%0), xops);
4171
4172   if (! TARGET_IEEE_FP)
4173     {
4174       if (!(cc_status.flags & CC_REVERSED))
4175         {
4176           next = next_cc0_user (insn);
4177         
4178           if (GET_CODE (next) == JUMP_INSN
4179               && GET_CODE (PATTERN (next)) == SET
4180               && SET_DEST (PATTERN (next)) == pc_rtx
4181               && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
4182             code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
4183           else if (GET_CODE (PATTERN (next)) == SET)
4184             code = GET_CODE (SET_SRC (PATTERN (next)));
4185           else
4186             return "sahf";
4187
4188           if (code == GT || code == LT || code == EQ || code == NE
4189               || code == LE || code == GE)
4190             {
4191               /* We will test eax directly. */
4192               cc_status.flags |= CC_TEST_AX;
4193               return "";
4194             }
4195         }
4196
4197       return "sahf";
4198     }
4199
4200   next = next_cc0_user (insn);
4201   if (next == NULL_RTX)
4202     abort ();
4203
4204   if (GET_CODE (next) == JUMP_INSN
4205       && GET_CODE (PATTERN (next)) == SET
4206       && SET_DEST (PATTERN (next)) == pc_rtx
4207       && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
4208     code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
4209   else if (GET_CODE (PATTERN (next)) == SET)
4210     {
4211       if (GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
4212         code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
4213       else
4214         code = GET_CODE (SET_SRC (PATTERN (next)));
4215     }
4216
4217   else if (GET_CODE (PATTERN (next)) == PARALLEL
4218            && GET_CODE (XVECEXP (PATTERN (next), 0, 0)) == SET)
4219     {
4220       if (GET_CODE (SET_SRC (XVECEXP (PATTERN (next), 0, 0))) == IF_THEN_ELSE)
4221         code = GET_CODE (XEXP (SET_SRC (XVECEXP (PATTERN (next), 0, 0)), 0));
4222       else
4223         code = GET_CODE (SET_SRC (XVECEXP (PATTERN (next), 0, 0)));
4224     }
4225   else
4226     abort ();
4227
4228   xops[0] = gen_rtx_REG (QImode, 0);
4229
4230   switch (code)
4231     {
4232     case GT:
4233       xops[1] = GEN_INT (0x45);
4234       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4235       /* je label */
4236       break;
4237
4238     case LT:
4239       xops[1] = GEN_INT (0x45);
4240       xops[2] = GEN_INT (0x01);
4241       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4242       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
4243       /* je label */
4244       break;
4245
4246     case GE:
4247       xops[1] = GEN_INT (0x05);
4248       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4249       /* je label */
4250       break;
4251
4252     case LE:
4253       xops[1] = GEN_INT (0x45);
4254       xops[2] = GEN_INT (0x40);
4255       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4256       output_asm_insn (AS1 (dec%B0,%h0), xops);
4257       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
4258       /* jb label */
4259       break;
4260
4261     case EQ:
4262       xops[1] = GEN_INT (0x45);
4263       xops[2] = GEN_INT (0x40);
4264       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4265       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
4266       /* je label */
4267       break;
4268
4269     case NE:
4270       xops[1] = GEN_INT (0x44);
4271       xops[2] = GEN_INT (0x40);
4272       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4273       output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
4274       /* jne label */
4275       break;
4276
4277     case GTU:
4278     case LTU:
4279     case GEU:
4280     case LEU:
4281     default:
4282       abort ();
4283     }
4284
4285   return "";
4286 }
4287 \f
4288 #define MAX_386_STACK_LOCALS 2
4289
4290 static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
4291
4292 /* Define the structure for the machine field in struct function.  */
4293 struct machine_function
4294 {
4295   rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
4296   rtx pic_label_rtx;
4297   char pic_label_name[256];
4298 };
4299
4300 /* Functions to save and restore i386_stack_locals.
4301    These will be called, via pointer variables,
4302    from push_function_context and pop_function_context.  */
4303
4304 void
4305 save_386_machine_status (p)
4306      struct function *p;
4307 {
4308   p->machine
4309     = (struct machine_function *) xmalloc (sizeof (struct machine_function));
4310   bcopy ((char *) i386_stack_locals, (char *) p->machine->i386_stack_locals,
4311          sizeof i386_stack_locals);
4312   p->machine->pic_label_rtx = pic_label_rtx;
4313   bcopy (pic_label_name, p->machine->pic_label_name, 256);
4314 }
4315
4316 void
4317 restore_386_machine_status (p)
4318      struct function *p;
4319 {
4320   bcopy ((char *) p->machine->i386_stack_locals, (char *) i386_stack_locals,
4321          sizeof i386_stack_locals);
4322   pic_label_rtx = p->machine->pic_label_rtx;
4323   bcopy (p->machine->pic_label_name, pic_label_name, 256);
4324   free (p->machine);
4325   p->machine = NULL;
4326 }
4327
4328 /* Clear stack slot assignments remembered from previous functions.
4329    This is called from INIT_EXPANDERS once before RTL is emitted for each
4330    function.  */
4331
4332 void
4333 clear_386_stack_locals ()
4334 {
4335   enum machine_mode mode;
4336   int n;
4337
4338   for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
4339        mode = (enum machine_mode) ((int) mode + 1))
4340     for (n = 0; n < MAX_386_STACK_LOCALS; n++)
4341       i386_stack_locals[(int) mode][n] = NULL_RTX;
4342
4343   pic_label_rtx = NULL_RTX;
4344   bzero (pic_label_name, 256);
4345   /* Arrange to save and restore i386_stack_locals around nested functions.  */
4346   save_machine_status = save_386_machine_status;
4347   restore_machine_status = restore_386_machine_status;
4348 }
4349
4350 /* Return a MEM corresponding to a stack slot with mode MODE.
4351    Allocate a new slot if necessary.
4352
4353    The RTL for a function can have several slots available: N is
4354    which slot to use.  */
4355
4356 rtx
4357 assign_386_stack_local (mode, n)
4358      enum machine_mode mode;
4359      int n;
4360 {
4361   if (n < 0 || n >= MAX_386_STACK_LOCALS)
4362     abort ();
4363
4364   if (i386_stack_locals[(int) mode][n] == NULL_RTX)
4365     i386_stack_locals[(int) mode][n]
4366       = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
4367
4368   return i386_stack_locals[(int) mode][n];
4369 }
4370 \f
4371 int is_mul(op,mode)
4372     register rtx op;
4373     enum machine_mode mode ATTRIBUTE_UNUSED;
4374 {
4375   return (GET_CODE (op) == MULT);
4376 }
4377
4378 int is_div(op,mode)
4379     register rtx op;
4380     enum machine_mode mode ATTRIBUTE_UNUSED;
4381 {
4382   return (GET_CODE (op) == DIV);
4383 }
4384 \f
4385 #ifdef NOTYET
4386 /* Create a new copy of an rtx.
4387    Recursively copies the operands of the rtx,
4388    except for those few rtx codes that are sharable.
4389    Doesn't share CONST  */
4390
4391 rtx
4392 copy_all_rtx (orig)
4393      register rtx orig;
4394 {
4395   register rtx copy;
4396   register int i, j;
4397   register RTX_CODE code;
4398   register char *format_ptr;
4399
4400   code = GET_CODE (orig);
4401
4402   switch (code)
4403     {
4404     case REG:
4405     case QUEUED:
4406     case CONST_INT:
4407     case CONST_DOUBLE:
4408     case SYMBOL_REF:
4409     case CODE_LABEL:
4410     case PC:
4411     case CC0:
4412     case SCRATCH:
4413       /* SCRATCH must be shared because they represent distinct values. */
4414       return orig;
4415
4416 #if 0
4417     case CONST:
4418       /* CONST can be shared if it contains a SYMBOL_REF.  If it contains
4419          a LABEL_REF, it isn't sharable.  */
4420       if (GET_CODE (XEXP (orig, 0)) == PLUS
4421           && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
4422           && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
4423         return orig;
4424       break;
4425 #endif
4426       /* A MEM with a constant address is not sharable.  The problem is that
4427          the constant address may need to be reloaded.  If the mem is shared,
4428          then reloading one copy of this mem will cause all copies to appear
4429          to have been reloaded.  */
4430     }
4431
4432   copy = rtx_alloc (code);
4433   PUT_MODE (copy, GET_MODE (orig));
4434   copy->in_struct = orig->in_struct;
4435   copy->volatil = orig->volatil;
4436   copy->unchanging = orig->unchanging;
4437   copy->integrated = orig->integrated;
4438   /* intel1 */
4439   copy->is_spill_rtx = orig->is_spill_rtx;
4440   
4441   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
4442
4443   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
4444     {
4445       switch (*format_ptr++)
4446         {
4447         case 'e':
4448           XEXP (copy, i) = XEXP (orig, i);
4449           if (XEXP (orig, i) != NULL)
4450             XEXP (copy, i) = copy_rtx (XEXP (orig, i));
4451           break;
4452
4453         case '0':
4454         case 'u':
4455           XEXP (copy, i) = XEXP (orig, i);
4456           break;
4457
4458         case 'E':
4459         case 'V':
4460           XVEC (copy, i) = XVEC (orig, i);
4461           if (XVEC (orig, i) != NULL)
4462             {
4463               XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
4464               for (j = 0; j < XVECLEN (copy, i); j++)
4465                 XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
4466             }
4467           break;
4468
4469         case 'w':
4470           XWINT (copy, i) = XWINT (orig, i);
4471           break;
4472
4473         case 'i':
4474           XINT (copy, i) = XINT (orig, i);
4475           break;
4476
4477         case 's':
4478         case 'S':
4479           XSTR (copy, i) = XSTR (orig, i);
4480           break;
4481
4482         default:
4483           abort ();
4484         }
4485     }
4486   return copy;
4487 }
4488
4489 \f
4490 /* Try to rewrite a memory address to make it valid */
4491
4492 void 
4493 rewrite_address (mem_rtx)
4494      rtx mem_rtx;
4495 {
4496   rtx index_rtx, base_rtx, offset_rtx, scale_rtx, ret_rtx;
4497   int scale = 1;
4498   int offset_adjust = 0;
4499   int was_only_offset = 0;
4500   rtx mem_addr = XEXP (mem_rtx, 0);
4501   char *storage = oballoc (0);
4502   int in_struct = 0;
4503   int is_spill_rtx = 0;
4504
4505   in_struct = MEM_IN_STRUCT_P (mem_rtx);
4506   is_spill_rtx = RTX_IS_SPILL_P (mem_rtx);
4507
4508   if (GET_CODE (mem_addr) == PLUS
4509       && GET_CODE (XEXP (mem_addr, 1)) == PLUS
4510       && GET_CODE (XEXP (XEXP (mem_addr, 1), 0)) == REG)
4511     {
4512       /* This part is utilized by the combiner. */
4513       ret_rtx
4514         = gen_rtx (PLUS, GET_MODE (mem_addr),
4515                    gen_rtx (PLUS, GET_MODE (XEXP (mem_addr, 1)),
4516                             XEXP (mem_addr, 0), XEXP (XEXP (mem_addr, 1), 0)),
4517                    XEXP (XEXP (mem_addr, 1), 1));
4518
4519       if (memory_address_p (GET_MODE (mem_rtx), ret_rtx))
4520         {
4521           XEXP (mem_rtx, 0) = ret_rtx;
4522           RTX_IS_SPILL_P (ret_rtx) = is_spill_rtx;
4523           return;
4524         }
4525
4526       obfree (storage);
4527     }
4528
4529   /* This part is utilized by loop.c.  
4530      If the address contains PLUS (reg,const) and this pattern is invalid
4531      in this case - try to rewrite the address to make it valid. */
4532   storage = oballoc (0);
4533   index_rtx = base_rtx = offset_rtx = NULL;
4534
4535   /* Find the base index and offset elements of the memory address. */
4536   if (GET_CODE (mem_addr) == PLUS)
4537     {
4538       if (GET_CODE (XEXP (mem_addr, 0)) == REG)
4539         {
4540           if (GET_CODE (XEXP (mem_addr, 1)) == REG)
4541             base_rtx = XEXP (mem_addr, 1), index_rtx = XEXP (mem_addr, 0);
4542           else
4543             base_rtx = XEXP (mem_addr, 0), offset_rtx = XEXP (mem_addr, 1);
4544         }
4545
4546       else if (GET_CODE (XEXP (mem_addr, 0)) == MULT)
4547         {
4548           index_rtx = XEXP (mem_addr, 0);
4549           if (GET_CODE (XEXP (mem_addr, 1)) == REG)
4550             base_rtx = XEXP (mem_addr, 1);
4551           else
4552             offset_rtx = XEXP (mem_addr, 1);
4553         }
4554
4555       else if (GET_CODE (XEXP (mem_addr, 0)) == PLUS)
4556         {
4557           if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == PLUS
4558               && GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0)) == MULT
4559               && (GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 0))
4560                   == REG)
4561               && (GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 1))
4562                   == CONST_INT)
4563               && (GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1))
4564                   == CONST_INT)
4565               && GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == REG
4566               && GET_CODE (XEXP (mem_addr, 1)) == SYMBOL_REF)
4567             {
4568               index_rtx = XEXP (XEXP (XEXP (mem_addr, 0), 0), 0);
4569               offset_rtx = XEXP (mem_addr, 1);
4570               base_rtx = XEXP (XEXP (mem_addr, 0), 1);
4571               offset_adjust = INTVAL (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1));
4572             }
4573           else
4574             {
4575               offset_rtx = XEXP (mem_addr, 1);
4576               index_rtx = XEXP (XEXP (mem_addr, 0), 0);
4577               base_rtx = XEXP (XEXP (mem_addr, 0), 1);
4578             }
4579         }
4580
4581       else if (GET_CODE (XEXP (mem_addr, 0)) == CONST_INT)
4582         {
4583           was_only_offset = 1;
4584           index_rtx = NULL;
4585           base_rtx = NULL;
4586           offset_rtx = XEXP (mem_addr, 1);
4587           offset_adjust = INTVAL (XEXP (mem_addr, 0));
4588           if (offset_adjust == 0)
4589             {
4590               XEXP (mem_rtx, 0) = offset_rtx;
4591               RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4592               return;
4593             }
4594         }
4595       else
4596         {
4597           obfree (storage);
4598           return;
4599         }
4600     }
4601   else if (GET_CODE (mem_addr) == MULT)
4602     index_rtx = mem_addr;
4603   else
4604     {
4605       obfree (storage);
4606       return;
4607     }
4608
4609   if (index_rtx != 0 && GET_CODE (index_rtx) == MULT)
4610     {
4611       if (GET_CODE (XEXP (index_rtx, 1)) != CONST_INT)
4612         {
4613           obfree (storage);
4614           return;
4615         }
4616
4617       scale_rtx = XEXP (index_rtx, 1);
4618       scale = INTVAL (scale_rtx);
4619       index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
4620     }
4621
4622   /* Now find which of the elements are invalid and try to fix them. */
4623   if (index_rtx && GET_CODE (index_rtx) == CONST_INT && base_rtx == NULL)
4624     {
4625       offset_adjust = INTVAL (index_rtx) * scale;
4626
4627       if (offset_rtx != 0 && CONSTANT_P (offset_rtx))
4628         offset_rtx = plus_constant (offset_rtx, offset_adjust);
4629       else if (offset_rtx == 0)
4630         offset_rtx = const0_rtx;
4631
4632       RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4633       XEXP (mem_rtx, 0) = offset_rtx;
4634       return;
4635     }
4636
4637   if (base_rtx && GET_CODE (base_rtx) == PLUS
4638       && GET_CODE (XEXP (base_rtx, 0)) == REG
4639       && GET_CODE (XEXP (base_rtx, 1)) == CONST_INT)
4640     {
4641       offset_adjust += INTVAL (XEXP (base_rtx, 1));
4642       base_rtx = copy_all_rtx (XEXP (base_rtx, 0));
4643     }
4644
4645   else if (base_rtx && GET_CODE (base_rtx) == CONST_INT)
4646     {
4647       offset_adjust += INTVAL (base_rtx);
4648       base_rtx = NULL;
4649     }
4650
4651   if (index_rtx && GET_CODE (index_rtx) == PLUS
4652       && GET_CODE (XEXP (index_rtx, 0)) == REG
4653       && GET_CODE (XEXP (index_rtx, 1)) == CONST_INT)
4654     {
4655       offset_adjust += INTVAL (XEXP (index_rtx, 1)) * scale;
4656       index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
4657     }
4658
4659   if (index_rtx)
4660     {
4661       if (! LEGITIMATE_INDEX_P (index_rtx)
4662           && ! (index_rtx == stack_pointer_rtx && scale == 1
4663                 && base_rtx == NULL))
4664         {
4665           obfree (storage);
4666           return;
4667         }
4668     }
4669
4670   if (base_rtx)
4671     {
4672       if (! LEGITIMATE_INDEX_P (base_rtx) && GET_CODE (base_rtx) != REG)
4673         {
4674           obfree (storage);
4675           return;
4676         }
4677     }
4678
4679   if (offset_adjust != 0)
4680     {
4681       if (offset_rtx != 0 && CONSTANT_P (offset_rtx))
4682         offset_rtx = plus_constant (offset_rtx, offset_adjust);
4683       else
4684         offset_rtx = const0_rtx;
4685
4686       if (index_rtx)
4687         {
4688           if (base_rtx)
4689             {
4690               if (scale != 1)
4691                 {
4692                   ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx),
4693                                      gen_rtx (MULT, GET_MODE (index_rtx),
4694                                               index_rtx, scale_rtx),
4695                                      base_rtx);
4696
4697                   if (GET_CODE (offset_rtx) != CONST_INT
4698                       || INTVAL (offset_rtx) != 0)
4699                     ret_rtx = gen_rtx (PLUS, GET_MODE (ret_rtx),
4700                                        ret_rtx, offset_rtx);
4701                 }
4702               else
4703                 {
4704                   ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx),
4705                                      index_rtx, base_rtx);
4706
4707                   if (GET_CODE (offset_rtx) != CONST_INT
4708                       || INTVAL (offset_rtx) != 0)
4709                     ret_rtx = gen_rtx (PLUS, GET_MODE (ret_rtx),
4710                                        ret_rtx, offset_rtx);
4711                 }
4712             }
4713           else
4714             {
4715               if (scale != 1)
4716                 {
4717                   ret_rtx = gen_rtx (MULT, GET_MODE (index_rtx),
4718                                      index_rtx, scale_rtx);
4719
4720                   if (GET_CODE (offset_rtx) != CONST_INT
4721                       || INTVAL (offset_rtx) != 0)
4722                     ret_rtx = gen_rtx (PLUS, GET_MODE (ret_rtx),
4723                                        ret_rtx, offset_rtx);
4724                 }
4725               else
4726                 {
4727                   if (GET_CODE (offset_rtx) == CONST_INT
4728                       && INTVAL (offset_rtx) == 0)
4729                     ret_rtx = index_rtx;
4730                   else
4731                     ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx),
4732                                        index_rtx, offset_rtx);
4733                 }
4734             }
4735         }
4736       else
4737         {
4738           if (base_rtx)
4739             {
4740               if (GET_CODE (offset_rtx) == CONST_INT
4741                   && INTVAL (offset_rtx) == 0)
4742                 ret_rtx = base_rtx;
4743               else
4744                 ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx), base_rtx,
4745                                    offset_rtx);
4746             }
4747           else if (was_only_offset)
4748             ret_rtx = offset_rtx;
4749           else
4750             {
4751               obfree (storage);
4752               return;
4753             }
4754         }
4755
4756       XEXP (mem_rtx, 0) = ret_rtx;
4757       RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4758       return;
4759     }
4760   else
4761     {
4762       obfree (storage);
4763       return;
4764     }
4765 }
4766 #endif /* NOTYET */
4767 \f
4768 /* Return 1 if the first insn to set cc before INSN also sets the register
4769    REG_RTX; otherwise return 0. */
4770 int
4771 last_to_set_cc (reg_rtx, insn)
4772      rtx reg_rtx, insn;
4773 {
4774   rtx prev_insn = PREV_INSN (insn);
4775
4776   while (prev_insn)
4777     {
4778       if (GET_CODE (prev_insn) == NOTE)
4779         ;
4780
4781       else if (GET_CODE (prev_insn) == INSN)
4782         {
4783           if (GET_CODE (PATTERN (prev_insn)) != SET)
4784             return (0);
4785
4786           if (rtx_equal_p (SET_DEST (PATTERN (prev_insn)), reg_rtx))
4787             {
4788               if (sets_condition_code (SET_SRC (PATTERN (prev_insn))))
4789                 return (1);
4790
4791               return (0);
4792             }
4793
4794           else if (! doesnt_set_condition_code (SET_SRC (PATTERN (prev_insn))))
4795             return (0);
4796         }
4797
4798       else
4799         return (0);
4800
4801       prev_insn = PREV_INSN (prev_insn);
4802     }
4803
4804   return (0);
4805 }
4806 \f
4807 int
4808 doesnt_set_condition_code (pat)
4809      rtx pat;
4810 {
4811   switch (GET_CODE (pat))
4812     {
4813     case MEM:
4814     case REG:
4815       return 1;
4816
4817     default:
4818       return 0;
4819
4820     }
4821 }
4822 \f
4823 int
4824 sets_condition_code (pat)
4825      rtx pat;
4826 {
4827   switch (GET_CODE (pat))
4828     {
4829     case PLUS:
4830     case MINUS:
4831     case AND:
4832     case IOR:
4833     case XOR:
4834     case NOT:
4835     case NEG:
4836     case MULT:
4837     case DIV:
4838     case MOD:
4839     case UDIV:
4840     case UMOD:
4841       return 1;
4842
4843     default:
4844       return (0);
4845     }
4846 }
4847 \f
4848 int
4849 str_immediate_operand (op, mode)
4850      register rtx op;
4851      enum machine_mode mode ATTRIBUTE_UNUSED;
4852 {
4853   if (GET_CODE (op) == CONST_INT && INTVAL (op) <= 32 && INTVAL (op) >= 0)
4854     return 1;
4855
4856   return 0;
4857 }
4858 \f
4859 int
4860 is_fp_insn (insn)
4861      rtx insn;
4862 {
4863   if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4864       && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4865           || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4866           || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode))
4867     return 1;
4868
4869   return 0;
4870 }
4871
4872 /* Return 1 if the mode of the SET_DEST of insn is floating point
4873    and it is not an fld or a move from memory to memory.
4874    Otherwise return 0 */
4875
4876 int
4877 is_fp_dest (insn)
4878      rtx insn;
4879 {
4880   if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4881       && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4882           || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4883           || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
4884       && GET_CODE (SET_DEST (PATTERN (insn))) == REG
4885       && REGNO (SET_DEST (PATTERN (insn))) >= FIRST_FLOAT_REG
4886       && GET_CODE (SET_SRC (PATTERN (insn))) != MEM)
4887     return 1;
4888
4889   return 0;
4890 }
4891
4892 /* Return 1 if the mode of the SET_DEST of INSN is floating point and is
4893    memory and the source is a register.  */
4894
4895 int
4896 is_fp_store (insn)
4897      rtx insn;
4898 {
4899   if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4900       && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4901           || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4902           || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
4903       && GET_CODE (SET_DEST (PATTERN (insn))) == MEM
4904       && GET_CODE (SET_SRC (PATTERN (insn))) == REG)
4905     return 1;
4906
4907   return 0;
4908 }
4909 \f
4910 /* Return 1 if DEP_INSN sets a register which INSN uses as a base
4911    or index to reference memory.
4912    otherwise return 0 */
4913
4914 int
4915 agi_dependent (insn, dep_insn)
4916      rtx insn, dep_insn;
4917 {
4918   if (GET_CODE (dep_insn) == INSN
4919       && GET_CODE (PATTERN (dep_insn)) == SET
4920       && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG)
4921     return reg_mentioned_in_mem (SET_DEST (PATTERN (dep_insn)), insn);
4922
4923   if (GET_CODE (dep_insn) == INSN && GET_CODE (PATTERN (dep_insn)) == SET
4924       && GET_CODE (SET_DEST (PATTERN (dep_insn))) == MEM
4925       && push_operand (SET_DEST (PATTERN (dep_insn)),
4926                        GET_MODE (SET_DEST (PATTERN (dep_insn)))))
4927     return reg_mentioned_in_mem (stack_pointer_rtx, insn);
4928
4929   return 0;
4930 }
4931 \f
4932 /* Return 1 if reg is used in rtl as a base or index for a memory ref
4933    otherwise return 0. */
4934
4935 int
4936 reg_mentioned_in_mem (reg, rtl)
4937      rtx reg, rtl;
4938 {
4939   register char *fmt;
4940   register int i, j;
4941   register enum rtx_code code;
4942
4943   if (rtl == NULL)
4944     return 0;
4945
4946   code = GET_CODE (rtl);
4947
4948   switch (code)
4949     {
4950     case HIGH:
4951     case CONST_INT:
4952     case CONST:
4953     case CONST_DOUBLE:
4954     case SYMBOL_REF:
4955     case LABEL_REF:
4956     case PC:
4957     case CC0:
4958     case SUBREG:
4959       return 0;
4960     default:
4961       break;
4962     }
4963
4964   if (code == MEM && reg_mentioned_p (reg, rtl))
4965     return 1;
4966
4967   fmt = GET_RTX_FORMAT (code);
4968   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4969     {
4970       if (fmt[i] == 'E')
4971         {
4972           for (j = XVECLEN (rtl, i) - 1; j >= 0; j--)
4973             if (reg_mentioned_in_mem (reg, XVECEXP (rtl, i, j)))
4974               return 1;
4975         }
4976
4977       else if (fmt[i] == 'e' && reg_mentioned_in_mem (reg, XEXP (rtl, i)))
4978         return 1;
4979     }
4980
4981   return 0;
4982 }
4983 \f
4984 /* Output the appropriate insns for doing strlen if not just doing repnz; scasb
4985
4986    operands[0] = result, initialized with the startaddress
4987    operands[1] = alignment of the address.
4988    operands[2] = scratch register, initialized with the startaddress when
4989                  not aligned, otherwise undefined
4990
4991    This is just the body. It needs the initialisations mentioned above and
4992    some address computing at the end.  These things are done in i386.md.  */
4993
4994 char *
4995 output_strlen_unroll (operands)
4996      rtx operands[];
4997 {
4998   rtx xops[18];
4999
5000   xops[0] = operands[0];                /* Result */
5001   /*        operands[1];                 * Alignment */
5002   xops[1] = operands[2];                /* Scratch */
5003   xops[2] = GEN_INT (0);
5004   xops[3] = GEN_INT (2);
5005   xops[4] = GEN_INT (3);
5006   xops[5] = GEN_INT (4);
5007   /* xops[6] = gen_label_rtx ();         * label when aligned to 3-byte */
5008   /* xops[7] = gen_label_rtx ();         * label when aligned to 2-byte */
5009   xops[8] = gen_label_rtx ();           /* label of main loop */
5010
5011   if (TARGET_USE_Q_REG && QI_REG_P (xops[1]))
5012     xops[9] = gen_label_rtx ();         /* pentium optimisation */
5013
5014   xops[10] = gen_label_rtx ();          /* end label 2 */
5015   xops[11] = gen_label_rtx ();          /* end label 1 */
5016   xops[12] = gen_label_rtx ();          /* end label */
5017   /* xops[13]                            * Temporary used */
5018   xops[14] = GEN_INT (0xff);
5019   xops[15] = GEN_INT (0xff00);
5020   xops[16] = GEN_INT (0xff0000);
5021   xops[17] = GEN_INT (0xff000000);
5022
5023   /* Loop to check 1..3 bytes for null to get an aligned pointer.  */
5024
5025   /* Is there a known alignment and is it less than 4?  */
5026   if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) < 4)
5027     {
5028       /* Is there a known alignment and is it not 2? */
5029       if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
5030         {
5031           xops[6] = gen_label_rtx (); /* Label when aligned to 3-byte */
5032           xops[7] = gen_label_rtx (); /* Label when aligned to 2-byte */
5033
5034           /* Leave just the 3 lower bits.
5035              If this is a q-register, then the high part is used later
5036              therefore use andl rather than andb. */
5037           output_asm_insn (AS2 (and%L1,%4,%1), xops);
5038
5039           /* Is aligned to 4-byte address when zero */
5040           output_asm_insn (AS1 (je,%l8), xops);
5041
5042           /* Side-effect even Parity when %eax == 3 */
5043           output_asm_insn (AS1 (jp,%6), xops);
5044
5045           /* Is it aligned to 2 bytes ? */
5046           if (QI_REG_P (xops[1]))
5047             output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
5048           else
5049             output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
5050
5051           output_asm_insn (AS1 (je,%7), xops);
5052         }
5053       else
5054         {
5055           /* Since the alignment is 2, we have to check 2 or 0 bytes;
5056              check if is aligned to 4 - byte.  */
5057           output_asm_insn (AS2 (and%L1,%3,%1), xops);
5058
5059           /* Is aligned to 4-byte address when zero */
5060           output_asm_insn (AS1 (je,%l8), xops);
5061         }
5062
5063       xops[13] = gen_rtx_MEM (QImode, xops[0]);
5064
5065       /* Now compare the bytes; compare with the high part of a q-reg
5066          gives shorter code. */
5067       if (QI_REG_P (xops[1]))
5068         {
5069           /* Compare the first n unaligned byte on a byte per byte basis. */
5070           output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
5071
5072           /* When zero we reached the end. */
5073           output_asm_insn (AS1 (je,%l12), xops);
5074
5075           /* Increment the address. */
5076           output_asm_insn (AS1 (inc%L0,%0), xops);
5077
5078           /* Not needed with an alignment of 2 */
5079           if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
5080             {
5081               ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5082                                          CODE_LABEL_NUMBER (xops[7]));
5083               output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
5084               output_asm_insn (AS1 (je,%l12), xops);
5085               output_asm_insn (AS1 (inc%L0,%0), xops);
5086
5087               ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5088                                          CODE_LABEL_NUMBER (xops[6]));
5089             }
5090
5091           output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
5092         }
5093       else
5094         {
5095           output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
5096           output_asm_insn (AS1 (je,%l12), xops);
5097           output_asm_insn (AS1 (inc%L0,%0), xops);
5098
5099           ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5100                                      CODE_LABEL_NUMBER (xops[7]));
5101           output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
5102           output_asm_insn (AS1 (je,%l12), xops);
5103           output_asm_insn (AS1 (inc%L0,%0), xops);
5104
5105           ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5106                                      CODE_LABEL_NUMBER (xops[6]));
5107           output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
5108         }
5109
5110       output_asm_insn (AS1 (je,%l12), xops);
5111       output_asm_insn (AS1 (inc%L0,%0), xops);
5112     }
5113
5114     /* Generate loop to check 4 bytes at a time.  It is not a good idea to
5115        align this loop.  It gives only huge programs, but does not help to
5116        speed up.  */
5117   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[8]));
5118
5119   xops[13] = gen_rtx_MEM (SImode, xops[0]);
5120   output_asm_insn (AS2 (mov%L1,%13,%1), xops);
5121
5122   if (QI_REG_P (xops[1]))
5123     {
5124       /* On i586 it is faster to combine the hi- and lo- part as
5125          a kind of lookahead.  If anding both yields zero, then one
5126          of both *could* be zero, otherwise none of both is zero;
5127          this saves one instruction, on i486 this is slower
5128          tested with P-90, i486DX2-66, AMD486DX2-66  */
5129       if (TARGET_PENTIUM)
5130         {
5131           output_asm_insn (AS2 (test%B1,%h1,%b1), xops);
5132           output_asm_insn (AS1 (jne,%l9), xops);
5133         }
5134
5135       /* Check first byte. */
5136       output_asm_insn (AS2 (test%B1,%b1,%b1), xops);
5137       output_asm_insn (AS1 (je,%l12), xops);
5138
5139       /* Check second byte. */
5140       output_asm_insn (AS2 (test%B1,%h1,%h1), xops);
5141       output_asm_insn (AS1 (je,%l11), xops);
5142
5143       if (TARGET_PENTIUM)
5144         ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5145                                    CODE_LABEL_NUMBER (xops[9]));
5146     }
5147
5148   else
5149     {
5150       /* Check first byte. */
5151       output_asm_insn (AS2 (test%L1,%14,%1), xops);
5152       output_asm_insn (AS1 (je,%l12), xops);
5153
5154       /* Check second byte. */
5155       output_asm_insn (AS2 (test%L1,%15,%1), xops);
5156       output_asm_insn (AS1 (je,%l11), xops);
5157     }
5158
5159   /* Check third byte. */
5160   output_asm_insn (AS2 (test%L1,%16,%1), xops);
5161   output_asm_insn (AS1 (je,%l10), xops);
5162   
5163   /* Check fourth byte and increment address. */
5164   output_asm_insn (AS2 (add%L0,%5,%0), xops);
5165   output_asm_insn (AS2 (test%L1,%17,%1), xops);
5166   output_asm_insn (AS1 (jne,%l8), xops);
5167
5168   /* Now generate fixups when the compare stops within a 4-byte word. */
5169   output_asm_insn (AS2 (sub%L0,%4,%0), xops);
5170
5171   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[10]));
5172   output_asm_insn (AS1 (inc%L0,%0), xops);
5173
5174   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[11]));
5175   output_asm_insn (AS1 (inc%L0,%0), xops);
5176
5177   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[12]));
5178
5179   return "";
5180 }
5181
5182 char *
5183 output_fp_conditional_move (which_alternative, operands)
5184      int which_alternative;
5185      rtx operands[];
5186 {
5187   switch (which_alternative)
5188     {
5189     case 0:
5190       /* r <- cond ? arg : r */
5191       output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
5192       break;
5193   
5194     case 1:
5195       /* r <- cond ? r : arg */
5196       output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
5197       break;
5198
5199     case 2:
5200       /* r <- cond ? r : arg */
5201       output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
5202       output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
5203       break;
5204
5205     default:
5206       abort ();
5207     }
5208
5209   return "";
5210 }
5211
5212 char *
5213 output_int_conditional_move (which_alternative, operands)
5214      int which_alternative;
5215      rtx operands[];
5216 {
5217   int code = GET_CODE (operands[1]);
5218   enum machine_mode mode;
5219   rtx xops[4];
5220
5221   /* This is very tricky. We have to do it right. For a code segement
5222      like:
5223
5224         int foo, bar;
5225         ....
5226         foo = foo - x;
5227         if (foo >= 0)
5228           bar = y;
5229
5230      final_scan_insn () may delete the insn which sets CC. We have to
5231      tell final_scan_insn () if it should be reinserted. When CODE is
5232      GT or LE, we have to check the CC_NO_OVERFLOW bit and return
5233      NULL_PTR to tell final to reinsert the test insn because the
5234      conditional move cannot be handled properly without it. */
5235   if ((code == GT || code == LE)
5236       && (cc_prev_status.flags & CC_NO_OVERFLOW))
5237     return NULL_PTR;
5238
5239   mode = GET_MODE (operands [0]);
5240   if (mode == DImode)
5241     {
5242       xops [0] = gen_rtx_SUBREG (SImode, operands [0], 1);
5243       xops [1] = operands [1];
5244       xops [2] = gen_rtx_SUBREG (SImode, operands [2], 1);
5245       xops [3] = gen_rtx_SUBREG (SImode, operands [3], 1);
5246     }
5247
5248   switch (which_alternative)
5249     {
5250     case 0:
5251       /* r <- cond ? arg : r */
5252       output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
5253       if (mode == DImode)
5254         output_asm_insn (AS2 (cmov%C1,%2,%0), xops);
5255       break;
5256
5257     case 1:
5258       /* r <- cond ? r : arg */
5259       output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
5260       if (mode == DImode)
5261         output_asm_insn (AS2 (cmov%c1,%3,%0), xops);
5262       break;
5263
5264     case 2:
5265       /* rm <- cond ? arg1 : arg2 */
5266       output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
5267       output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
5268       if (mode == DImode)
5269         {
5270           output_asm_insn (AS2 (cmov%C1,%2,%0), xops);
5271           output_asm_insn (AS2 (cmov%c1,%3,%0), xops);
5272         }
5273       break;
5274
5275     default:
5276       abort ();
5277     }
5278
5279   return "";
5280 }