OSDN Git Service

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