OSDN Git Service

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