OSDN Git Service

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