OSDN Git Service

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