OSDN Git Service

da08da1ff8af765e03370c98602fd91e1e29f6ef
[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         fputs ("ge", file);
3101         return;
3102
3103       case GT:
3104         fputs ("g", file);
3105         return;
3106
3107       case LE:
3108         fputs ("le", file);
3109         return;
3110
3111       case LT:
3112         fputs ("l", file);
3113         return;
3114
3115       case GEU:
3116         fputs ("ae", file);
3117         return;
3118
3119       case GTU:
3120         fputs ("a", file);
3121         return;
3122
3123       case LEU:
3124         fputs ("be", file);
3125         return;
3126
3127       case LTU:
3128         fputs ("b", file);
3129         return;
3130
3131       default:
3132         output_operand_lossage ("Invalid %%C operand");
3133       }
3134
3135   else if (mode == MODE_FLOAT)
3136     switch (code)
3137       {
3138       case NE: 
3139         fputs (ieee ? (reverse_cc ? "ne" : "e") : "ne", file);
3140         return;
3141       case EQ: 
3142         fputs (ieee ? (reverse_cc ? "ne" : "e") : "e", file);
3143         return;
3144       case GE: 
3145         fputs (ieee ? (reverse_cc ? "ne" : "e") : "nb", file);
3146         return;
3147       case GT: 
3148         fputs (ieee ? (reverse_cc ? "ne" : "e") : "nbe", file);
3149         return;
3150       case LE: 
3151         fputs (ieee ? (reverse_cc ? "nb" : "b") : "be", file);
3152         return;
3153       case LT: 
3154         fputs (ieee ? (reverse_cc ? "ne" : "e") : "b", file);
3155         return;
3156       case GEU: 
3157         fputs (ieee ? (reverse_cc ? "ne" : "e") : "nb", file);
3158         return;
3159       case GTU: 
3160         fputs (ieee ? (reverse_cc ? "ne" : "e") : "nbe", file);
3161         return;
3162       case LEU: 
3163         fputs (ieee ? (reverse_cc ? "nb" : "b") : "be", file);
3164         return;
3165       case LTU: 
3166         fputs (ieee ? (reverse_cc ? "ne" : "e") : "b", file);
3167         return;
3168       default:
3169         output_operand_lossage ("Invalid %%C operand");
3170     }
3171 }
3172
3173 /* Meaning of CODE:
3174    L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
3175    C -- print opcode suffix for set/cmov insn.
3176    c -- like C, but print reversed condition
3177    F -- print opcode suffix for fcmov insn.
3178    f -- like C, but print reversed condition
3179    R -- print the prefix for register names.
3180    z -- print the opcode suffix for the size of the current operand.
3181    * -- print a star (in certain assembler syntax)
3182    w -- print the operand as if it's a "word" (HImode) even if it isn't.
3183    c -- don't print special prefixes before constant operands.
3184    J -- print the appropriate jump operand.
3185    s -- print a shift double count, followed by the assemblers argument
3186         delimiter.
3187    b -- print the QImode name of the register for the indicated operand.
3188         %b0 would print %al if operands[0] is reg 0.
3189    w --  likewise, print the HImode name of the register.
3190    k --  likewise, print the SImode name of the register.
3191    h --  print the QImode name for a "high" register, either ah, bh, ch or dh.
3192    y --  print "st(0)" instead of "st" as a register.
3193    P --  print as a PIC constant */
3194
3195 void
3196 print_operand (file, x, code)
3197      FILE *file;
3198      rtx x;
3199      int code;
3200 {
3201   if (code)
3202     {
3203       switch (code)
3204         {
3205         case '*':
3206           if (USE_STAR)
3207             putc ('*', file);
3208           return;
3209
3210         case 'L':
3211           PUT_OP_SIZE (code, 'l', file);
3212           return;
3213
3214         case 'W':
3215           PUT_OP_SIZE (code, 'w', file);
3216           return;
3217
3218         case 'B':
3219           PUT_OP_SIZE (code, 'b', file);
3220           return;
3221
3222         case 'Q':
3223           PUT_OP_SIZE (code, 'l', file);
3224           return;
3225
3226         case 'S':
3227           PUT_OP_SIZE (code, 's', file);
3228           return;
3229
3230         case 'T':
3231           PUT_OP_SIZE (code, 't', file);
3232           return;
3233
3234         case 'z':
3235           /* 387 opcodes don't get size suffixes if the operands are
3236              registers. */
3237
3238           if (STACK_REG_P (x))
3239             return;
3240
3241           /* this is the size of op from size of operand */
3242           switch (GET_MODE_SIZE (GET_MODE (x)))
3243             {
3244             case 1:
3245               PUT_OP_SIZE ('B', 'b', file);
3246               return;
3247
3248             case 2:
3249               PUT_OP_SIZE ('W', 'w', file);
3250               return;
3251
3252             case 4:
3253               if (GET_MODE (x) == SFmode)
3254                 {
3255                   PUT_OP_SIZE ('S', 's', file);
3256                   return;
3257                 }
3258               else
3259                 PUT_OP_SIZE ('L', 'l', file);
3260               return;
3261
3262             case 12:
3263                   PUT_OP_SIZE ('T', 't', file);
3264                   return;
3265
3266             case 8:
3267               if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
3268                 {
3269 #ifdef GAS_MNEMONICS
3270                   PUT_OP_SIZE ('Q', 'q', file);
3271                   return;
3272 #else
3273                   PUT_OP_SIZE ('Q', 'l', file); /* Fall through */
3274 #endif
3275                 }
3276
3277               PUT_OP_SIZE ('Q', 'l', file);
3278               return;
3279             }
3280
3281         case 'b':
3282         case 'w':
3283         case 'k':
3284         case 'h':
3285         case 'y':
3286         case 'P':
3287         case 'X':
3288           break;
3289
3290         case 'J':
3291           switch (GET_CODE (x))
3292             {
3293               /* These conditions are appropriate for testing the result
3294                  of an arithmetic operation, not for a compare operation.
3295                  Cases GE, LT assume CC_NO_OVERFLOW true. All cases assume
3296                  CC_Z_IN_NOT_C false and not floating point.  */
3297             case NE:  fputs ("jne", file); return;
3298             case EQ:  fputs ("je",  file); return;
3299             case GE:  fputs ("jns", file); return;
3300             case LT:  fputs ("js",  file); return;
3301             case GEU: fputs ("jmp", file); return;
3302             case GTU: fputs ("jne",  file); return;
3303             case LEU: fputs ("je", file); return;
3304             case LTU: fputs ("#branch never",  file); return;
3305             
3306             /* no matching branches for GT nor LE */
3307             
3308             default:
3309               abort ();
3310             }
3311
3312         case 's':
3313           if (GET_CODE (x) == CONST_INT || ! SHIFT_DOUBLE_OMITS_COUNT)
3314             {
3315               PRINT_OPERAND (file, x, 0);
3316               fputs (AS2C (,) + 1, file);
3317             }
3318
3319           return;
3320
3321           /* This is used by the conditional move instructions.  */
3322         case 'C':
3323           put_condition_code (GET_CODE (x), 0, MODE_INT, file);
3324           return;
3325
3326           /* Like above, but reverse condition */
3327         case 'c':
3328           put_condition_code (GET_CODE (x), 1, MODE_INT, file); return;
3329
3330         case 'F':
3331           put_condition_code (GET_CODE (x), 0, MODE_FLOAT, file);
3332           return;
3333
3334           /* Like above, but reverse condition */
3335         case 'f':
3336           put_condition_code (GET_CODE (x), 1, MODE_FLOAT, file);
3337           return;
3338
3339         default:
3340           {
3341             char str[50];
3342
3343             sprintf (str, "invalid operand code `%c'", code);
3344             output_operand_lossage (str);
3345           }
3346         }
3347     }
3348
3349   if (GET_CODE (x) == REG)
3350     {
3351       PRINT_REG (x, code, file);
3352     }
3353
3354   else if (GET_CODE (x) == MEM)
3355     {
3356       PRINT_PTR (x, file);
3357       if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
3358         {
3359           if (flag_pic)
3360             output_pic_addr_const (file, XEXP (x, 0), code);
3361           else
3362             output_addr_const (file, XEXP (x, 0));
3363         }
3364       else
3365         output_address (XEXP (x, 0));
3366     }
3367
3368   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
3369     {
3370       REAL_VALUE_TYPE r;
3371       long l;
3372
3373       REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3374       REAL_VALUE_TO_TARGET_SINGLE (r, l);
3375       PRINT_IMMED_PREFIX (file);
3376       fprintf (file, "0x%x", l);
3377     }
3378
3379  /* These float cases don't actually occur as immediate operands. */
3380  else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
3381     {
3382       REAL_VALUE_TYPE r;
3383       char dstr[30];
3384
3385       REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3386       REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
3387       fprintf (file, "%s", dstr);
3388     }
3389
3390   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == XFmode)
3391     {
3392       REAL_VALUE_TYPE r;
3393       char dstr[30];
3394
3395       REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3396       REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
3397       fprintf (file, "%s", dstr);
3398     }
3399   else 
3400     {
3401       if (code != 'P')
3402         {
3403           if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
3404             PRINT_IMMED_PREFIX (file);
3405           else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
3406                    || GET_CODE (x) == LABEL_REF)
3407             PRINT_OFFSET_PREFIX (file);
3408         }
3409       if (flag_pic)
3410         output_pic_addr_const (file, x, code);
3411       else
3412         output_addr_const (file, x);
3413     }
3414 }
3415 \f
3416 /* Print a memory operand whose address is ADDR.  */
3417
3418 void
3419 print_operand_address (file, addr)
3420      FILE *file;
3421      register rtx addr;
3422 {
3423   register rtx reg1, reg2, breg, ireg;
3424   rtx offset;
3425
3426   switch (GET_CODE (addr))
3427     {
3428     case REG:
3429       ADDR_BEG (file);
3430       fprintf (file, "%se", RP);
3431       fputs (hi_reg_name[REGNO (addr)], file);
3432       ADDR_END (file);
3433       break;
3434
3435     case PLUS:
3436       reg1 = 0;
3437       reg2 = 0;
3438       ireg = 0;
3439       breg = 0;
3440       offset = 0;
3441       if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
3442         {
3443           offset = XEXP (addr, 0);
3444           addr = XEXP (addr, 1);
3445         }
3446       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
3447         {
3448           offset = XEXP (addr, 1);
3449           addr = XEXP (addr, 0);
3450         }
3451
3452       if (GET_CODE (addr) != PLUS)
3453         ;
3454       else if (GET_CODE (XEXP (addr, 0)) == MULT)
3455         reg1 = XEXP (addr, 0), addr = XEXP (addr, 1);
3456       else if (GET_CODE (XEXP (addr, 1)) == MULT)
3457         reg1 = XEXP (addr, 1), addr = XEXP (addr, 0);
3458       else if (GET_CODE (XEXP (addr, 0)) == REG)
3459         reg1 = XEXP (addr, 0), addr = XEXP (addr, 1);
3460       else if (GET_CODE (XEXP (addr, 1)) == REG)
3461         reg1 = XEXP (addr, 1), addr = XEXP (addr, 0);
3462
3463       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
3464         {
3465           if (reg1 == 0)
3466             reg1 = addr;
3467           else
3468             reg2 = addr;
3469
3470           addr = 0;
3471         }
3472
3473       if (offset != 0)
3474         {
3475           if (addr != 0)
3476             abort ();
3477           addr = offset;
3478         }
3479
3480       if ((reg1 && GET_CODE (reg1) == MULT)
3481           || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
3482         {
3483           breg = reg2;
3484           ireg = reg1;
3485         }
3486       else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
3487         {
3488           breg = reg1;
3489           ireg = reg2;
3490         }
3491
3492       if (ireg != 0 || breg != 0)
3493         {
3494           int scale = 1;
3495
3496           if (addr != 0)
3497             {
3498               if (flag_pic)
3499                 output_pic_addr_const (file, addr, 0);
3500               else if (GET_CODE (addr) == LABEL_REF)
3501                 output_asm_label (addr);
3502               else
3503                 output_addr_const (file, addr);
3504             }
3505
3506           if (ireg != 0 && GET_CODE (ireg) == MULT)
3507             {
3508               scale = INTVAL (XEXP (ireg, 1));
3509               ireg = XEXP (ireg, 0);
3510             }
3511
3512           /* The stack pointer can only appear as a base register,
3513              never an index register, so exchange the regs if it is wrong. */
3514
3515           if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM)
3516             {
3517               rtx tmp;
3518
3519               tmp = breg;
3520               breg = ireg;
3521               ireg = tmp;
3522             }
3523
3524           /* output breg+ireg*scale */
3525           PRINT_B_I_S (breg, ireg, scale, file);
3526           break;
3527         }
3528
3529     case MULT:
3530       {
3531         int scale;
3532
3533         if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
3534           {
3535             scale = INTVAL (XEXP (addr, 0));
3536             ireg = XEXP (addr, 1);
3537           }
3538         else
3539           {
3540             scale = INTVAL (XEXP (addr, 1));
3541             ireg = XEXP (addr, 0);
3542           }
3543
3544         output_addr_const (file, const0_rtx);
3545         PRINT_B_I_S (NULL_RTX, ireg, scale, file);
3546       }
3547       break;
3548
3549     default:
3550       if (GET_CODE (addr) == CONST_INT
3551           && INTVAL (addr) < 0x8000
3552           && INTVAL (addr) >= -0x8000)
3553         fprintf (file, "%d", (int) INTVAL (addr));
3554       else
3555         {
3556           if (flag_pic)
3557             output_pic_addr_const (file, addr, 0);
3558           else
3559             output_addr_const (file, addr);
3560         }
3561     }
3562 }
3563 \f
3564 /* Set the cc_status for the results of an insn whose pattern is EXP.
3565    On the 80386, we assume that only test and compare insns, as well
3566    as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, BSF, ASHIFT,
3567    ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
3568    Also, we assume that jumps, moves and sCOND don't affect the condition
3569    codes.  All else clobbers the condition codes, by assumption.
3570
3571    We assume that ALL integer add, minus, etc. instructions effect the
3572    condition codes.  This MUST be consistent with i386.md.
3573
3574    We don't record any float test or compare - the redundant test &
3575    compare check in final.c does not handle stack-like regs correctly. */
3576
3577 void
3578 notice_update_cc (exp)
3579      rtx exp;
3580 {
3581   if (GET_CODE (exp) == SET)
3582     {
3583       /* Jumps do not alter the cc's.  */
3584       if (SET_DEST (exp) == pc_rtx)
3585         return;
3586
3587       /* Moving register or memory into a register:
3588          it doesn't alter the cc's, but it might invalidate
3589          the RTX's which we remember the cc's came from.
3590          (Note that moving a constant 0 or 1 MAY set the cc's).  */
3591       if (REG_P (SET_DEST (exp))
3592           && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM
3593               || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
3594         {
3595           if (cc_status.value1
3596               && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
3597             cc_status.value1 = 0;
3598
3599           if (cc_status.value2
3600               && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
3601             cc_status.value2 = 0;
3602
3603           return;
3604         }
3605
3606       /* Moving register into memory doesn't alter the cc's.
3607          It may invalidate the RTX's which we remember the cc's came from.  */
3608       if (GET_CODE (SET_DEST (exp)) == MEM
3609           && (REG_P (SET_SRC (exp))
3610               || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
3611         {
3612           if (cc_status.value1
3613               && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
3614             cc_status.value1 = 0;
3615           if (cc_status.value2
3616               && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
3617             cc_status.value2 = 0;
3618
3619           return;
3620         }
3621
3622       /* Function calls clobber the cc's.  */
3623       else if (GET_CODE (SET_SRC (exp)) == CALL)
3624         {
3625           CC_STATUS_INIT;
3626           return;
3627         }
3628
3629       /* Tests and compares set the cc's in predictable ways.  */
3630       else if (SET_DEST (exp) == cc0_rtx)
3631         {
3632           CC_STATUS_INIT;
3633           cc_status.value1 = SET_SRC (exp);
3634           return;
3635         }
3636
3637       /* Certain instructions effect the condition codes. */
3638       else if (GET_MODE (SET_SRC (exp)) == SImode
3639                || GET_MODE (SET_SRC (exp)) == HImode
3640                || GET_MODE (SET_SRC (exp)) == QImode)
3641         switch (GET_CODE (SET_SRC (exp)))
3642           {
3643           case ASHIFTRT: case LSHIFTRT: case ASHIFT:
3644             /* Shifts on the 386 don't set the condition codes if the
3645                shift count is zero. */
3646             if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
3647               {
3648                 CC_STATUS_INIT;
3649                 break;
3650               }
3651
3652             /* We assume that the CONST_INT is non-zero (this rtx would
3653                have been deleted if it were zero. */
3654
3655           case PLUS: case MINUS: case NEG:
3656           case AND: case IOR: case XOR:
3657             cc_status.flags = CC_NO_OVERFLOW;
3658             cc_status.value1 = SET_SRC (exp);
3659             cc_status.value2 = SET_DEST (exp);
3660             break;
3661
3662             /* This is the bsf pattern used by ffs.  */
3663           case UNSPEC:
3664             if (XINT (SET_SRC (exp), 1) == 5)
3665               {
3666                 /* Only the Z flag is defined after bsf.  */
3667                 cc_status.flags
3668                   = CC_NOT_POSITIVE | CC_NOT_NEGATIVE | CC_NO_OVERFLOW;
3669                 cc_status.value1 = XVECEXP (SET_SRC (exp), 0, 0);
3670                 break;
3671               }
3672             /* FALLTHRU */
3673
3674           default:
3675             CC_STATUS_INIT;
3676           }
3677       else
3678         {
3679           CC_STATUS_INIT;
3680         }
3681     }
3682   else if (GET_CODE (exp) == PARALLEL
3683            && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
3684     {
3685       if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
3686         return;
3687       if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
3688
3689         {
3690           CC_STATUS_INIT;
3691           if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
3692             {
3693               cc_status.flags |= CC_IN_80387;
3694               if (0 && TARGET_CMOVE && stack_regs_mentioned_p
3695                   (XEXP (SET_SRC (XVECEXP (exp, 0, 0)), 1)))
3696                 cc_status.flags |= CC_FCOMI;
3697             }
3698           else
3699             cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
3700           return;
3701         }
3702
3703       CC_STATUS_INIT;
3704     }
3705   else
3706     {
3707       CC_STATUS_INIT;
3708     }
3709 }
3710 \f
3711 /* Split one or more DImode RTL references into pairs of SImode
3712    references.  The RTL can be REG, offsettable MEM, integer constant, or
3713    CONST_DOUBLE.  "operands" is a pointer to an array of DImode RTL to
3714    split and "num" is its length.  lo_half and hi_half are output arrays
3715    that parallel "operands". */
3716
3717 void
3718 split_di (operands, num, lo_half, hi_half)
3719      rtx operands[];
3720      int num;
3721      rtx lo_half[], hi_half[];
3722 {
3723   while (num--)
3724     {
3725       rtx op = operands[num];
3726       if (GET_CODE (op) == REG)
3727         {
3728           lo_half[num] = gen_rtx_REG (SImode, REGNO (op));
3729           hi_half[num] = gen_rtx_REG (SImode, REGNO (op) + 1);
3730         }
3731       else if (CONSTANT_P (op))
3732         split_double (op, &lo_half[num], &hi_half[num]);
3733       else if (offsettable_memref_p (op))
3734         {
3735           rtx lo_addr = XEXP (op, 0);
3736           rtx hi_addr = XEXP (adj_offsettable_operand (op, 4), 0);
3737           lo_half[num] = change_address (op, SImode, lo_addr);
3738           hi_half[num] = change_address (op, SImode, hi_addr);
3739         }
3740       else
3741         abort();
3742     }
3743 }
3744 \f
3745 /* Return 1 if this is a valid binary operation on a 387.
3746    OP is the expression matched, and MODE is its mode. */
3747
3748 int
3749 binary_387_op (op, mode)
3750     register rtx op;
3751     enum machine_mode mode;
3752 {
3753   if (mode != VOIDmode && mode != GET_MODE (op))
3754     return 0;
3755
3756   switch (GET_CODE (op))
3757     {
3758     case PLUS:
3759     case MINUS:
3760     case MULT:
3761     case DIV:
3762       return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
3763
3764     default:
3765       return 0;
3766     }
3767 }
3768 \f
3769 /* Return 1 if this is a valid shift or rotate operation on a 386.
3770    OP is the expression matched, and MODE is its mode. */
3771
3772 int
3773 shift_op (op, mode)
3774     register rtx op;
3775     enum machine_mode mode;
3776 {
3777   rtx operand = XEXP (op, 0);
3778
3779   if (mode != VOIDmode && mode != GET_MODE (op))
3780     return 0;
3781
3782   if (GET_MODE (operand) != GET_MODE (op)
3783       || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
3784     return 0;
3785
3786   return (GET_CODE (op) == ASHIFT
3787           || GET_CODE (op) == ASHIFTRT
3788           || GET_CODE (op) == LSHIFTRT
3789           || GET_CODE (op) == ROTATE
3790           || GET_CODE (op) == ROTATERT);
3791 }
3792
3793 /* Return 1 if OP is COMPARE rtx with mode VOIDmode.
3794    MODE is not used.  */
3795
3796 int
3797 VOIDmode_compare_op (op, mode)
3798     register rtx op;
3799     enum machine_mode mode;
3800 {
3801   return GET_CODE (op) == COMPARE && GET_MODE (op) == VOIDmode;
3802 }
3803 \f
3804 /* Output code to perform a 387 binary operation in INSN, one of PLUS,
3805    MINUS, MULT or DIV.  OPERANDS are the insn operands, where operands[3]
3806    is the expression of the binary operation.  The output may either be
3807    emitted here, or returned to the caller, like all output_* functions.
3808
3809    There is no guarantee that the operands are the same mode, as they
3810    might be within FLOAT or FLOAT_EXTEND expressions. */
3811
3812 char *
3813 output_387_binary_op (insn, operands)
3814      rtx insn;
3815      rtx *operands;
3816 {
3817   rtx temp;
3818   char *base_op;
3819   static char buf[100];
3820
3821   switch (GET_CODE (operands[3]))
3822     {
3823     case PLUS:
3824       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3825           || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3826         base_op = "fiadd";
3827       else
3828         base_op = "fadd";
3829       break;
3830
3831     case MINUS:
3832       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3833           || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3834         base_op = "fisub";
3835       else
3836         base_op = "fsub";
3837       break;
3838
3839     case MULT:
3840       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3841           || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3842         base_op = "fimul";
3843       else
3844         base_op = "fmul";
3845       break;
3846
3847     case DIV:
3848       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3849           || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3850         base_op = "fidiv";
3851       else
3852         base_op = "fdiv";
3853       break;
3854
3855     default:
3856       abort ();
3857     }
3858
3859   strcpy (buf, base_op);
3860
3861   switch (GET_CODE (operands[3]))
3862     {
3863     case MULT:
3864     case PLUS:
3865       if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
3866         {
3867           temp = operands[2];
3868           operands[2] = operands[1];
3869           operands[1] = temp;
3870         }
3871
3872       if (GET_CODE (operands[2]) == MEM)
3873         return strcat (buf, AS1 (%z2,%2));
3874
3875       if (NON_STACK_REG_P (operands[1]))
3876         {
3877           output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
3878           return "";
3879         }
3880
3881       else if (NON_STACK_REG_P (operands[2]))
3882         {
3883           output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
3884           return "";
3885         }
3886
3887       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
3888         {
3889           if (STACK_TOP_P (operands[0]))
3890             return strcat (buf, AS2 (p,%0,%2));
3891           else
3892             return strcat (buf, AS2 (p,%2,%0));
3893         }
3894
3895       if (STACK_TOP_P (operands[0]))
3896         return strcat (buf, AS2C (%y2,%0));
3897       else
3898         return strcat (buf, AS2C (%2,%0));
3899
3900     case MINUS:
3901     case DIV:
3902       if (GET_CODE (operands[1]) == MEM)
3903         return strcat (buf, AS1 (r%z1,%1));
3904
3905       if (GET_CODE (operands[2]) == MEM)
3906         return strcat (buf, AS1 (%z2,%2));
3907
3908       if (NON_STACK_REG_P (operands[1]))
3909         {
3910           output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1)));
3911           return "";
3912         }
3913
3914       else if (NON_STACK_REG_P (operands[2]))
3915         {
3916           output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
3917           return "";
3918         }
3919
3920       if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
3921         abort ();
3922
3923       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
3924         {
3925           if (STACK_TOP_P (operands[0]))
3926             return strcat (buf, AS2 (p,%0,%2));
3927           else
3928             return strcat (buf, AS2 (rp,%2,%0));
3929         }
3930
3931       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3932         {
3933           if (STACK_TOP_P (operands[0]))
3934             return strcat (buf, AS2 (rp,%0,%1));
3935           else
3936             return strcat (buf, AS2 (p,%1,%0));
3937         }
3938
3939       if (STACK_TOP_P (operands[0]))
3940         {
3941           if (STACK_TOP_P (operands[1]))
3942             return strcat (buf, AS2C (%y2,%0));
3943           else
3944             return strcat (buf, AS2 (r,%y1,%0));
3945         }
3946       else if (STACK_TOP_P (operands[1]))
3947         return strcat (buf, AS2C (%1,%0));
3948       else
3949         return strcat (buf, AS2 (r,%2,%0));
3950
3951     default:
3952       abort ();
3953     }
3954 }
3955 \f
3956 /* Output code for INSN to convert a float to a signed int.  OPERANDS
3957    are the insn operands.  The output may be SFmode or DFmode and the
3958    input operand may be SImode or DImode.  As a special case, make sure
3959    that the 387 stack top dies if the output mode is DImode, because the
3960    hardware requires this.  */
3961
3962 char *
3963 output_fix_trunc (insn, operands)
3964      rtx insn;
3965      rtx *operands;
3966 {
3967   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
3968   rtx xops[2];
3969
3970   if (! STACK_TOP_P (operands[1]))
3971     abort ();
3972
3973   xops[0] = GEN_INT (12);
3974   xops[1] = operands[4];
3975
3976   output_asm_insn (AS1 (fnstc%W2,%2), operands);
3977   output_asm_insn (AS2 (mov%L2,%2,%4), operands);
3978   output_asm_insn (AS2 (mov%B1,%0,%h1), xops);
3979   output_asm_insn (AS2 (mov%L4,%4,%3), operands);
3980   output_asm_insn (AS1 (fldc%W3,%3), operands);
3981
3982   if (NON_STACK_REG_P (operands[0]))
3983     output_to_reg (operands[0], stack_top_dies, operands[3]);
3984
3985   else if (GET_CODE (operands[0]) == MEM)
3986     {
3987       if (stack_top_dies)
3988         output_asm_insn (AS1 (fistp%z0,%0), operands);
3989       else if (GET_MODE (operands[0]) == DImode && ! stack_top_dies)
3990         {
3991           /* There is no DImode version of this without a stack pop, so
3992              we must emulate it.  It doesn't matter much what the second
3993              instruction is, because the value being pushed on the FP stack
3994              is not used except for the following stack popping store.
3995              This case can only happen without optimization, so it doesn't
3996              matter that it is inefficient.  */
3997           output_asm_insn (AS1 (fistp%z0,%0), operands);
3998           output_asm_insn (AS1 (fild%z0,%0), operands);
3999         }
4000       else
4001         output_asm_insn (AS1 (fist%z0,%0), operands);
4002     }
4003   else
4004     abort ();
4005
4006   return AS1 (fldc%W2,%2);
4007 }
4008 \f
4009 /* Output code for INSN to compare OPERANDS.  The two operands might
4010    not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
4011    expression.  If the compare is in mode CCFPEQmode, use an opcode that
4012    will not fault if a qNaN is present. */
4013
4014 char *
4015 output_float_compare (insn, operands)
4016      rtx insn;
4017      rtx *operands;
4018 {
4019   int stack_top_dies;
4020   rtx body = XVECEXP (PATTERN (insn), 0, 0);
4021   int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
4022   rtx tmp;
4023
4024   if (0 && TARGET_CMOVE && STACK_REG_P (operands[1]))
4025     {
4026       cc_status.flags |= CC_FCOMI;
4027       cc_prev_status.flags &= ~CC_TEST_AX;
4028     }
4029
4030   if (! STACK_TOP_P (operands[0]))
4031     {
4032       tmp = operands[0];
4033       operands[0] = operands[1];
4034       operands[1] = tmp;
4035       cc_status.flags |= CC_REVERSED;
4036     }
4037     
4038   if (! STACK_TOP_P (operands[0]))
4039     abort ();
4040
4041   stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
4042
4043   if (STACK_REG_P (operands[1])
4044       && stack_top_dies
4045       && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
4046       && REGNO (operands[1]) != FIRST_STACK_REG)
4047     {
4048       /* If both the top of the 387 stack dies, and the other operand
4049          is also a stack register that dies, then this must be a
4050          `fcompp' float compare */
4051
4052       if (unordered_compare)
4053         {
4054           if (cc_status.flags & CC_FCOMI)
4055             {
4056               output_asm_insn (AS2 (fucomip,%y1,%0), operands);
4057               output_asm_insn (AS1 (fstp, %y0), operands);
4058               return "";
4059             }
4060           else
4061             output_asm_insn ("fucompp", operands);
4062         }
4063       else
4064         {
4065           if (cc_status.flags & CC_FCOMI)
4066             {
4067               output_asm_insn (AS2 (fcomip, %y1,%0), operands);
4068               output_asm_insn (AS1 (fstp, %y0), operands);
4069               return "";
4070             }
4071           else
4072             output_asm_insn ("fcompp", operands);
4073         }
4074     }
4075   else
4076     {
4077       static char buf[100];
4078
4079       /* Decide if this is the integer or float compare opcode, or the
4080          unordered float compare. */
4081
4082       if (unordered_compare)
4083         strcpy (buf, (cc_status.flags & CC_FCOMI) ? "fucomi" : "fucom");
4084       else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT)
4085         strcpy (buf, (cc_status.flags & CC_FCOMI) ? "fcomi" : "fcom");
4086       else
4087         strcpy (buf, "ficom");
4088
4089       /* Modify the opcode if the 387 stack is to be popped. */
4090
4091       if (stack_top_dies)
4092         strcat (buf, "p");
4093
4094       if (NON_STACK_REG_P (operands[1]))
4095         output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
4096       else if (cc_status.flags & CC_FCOMI) 
4097         {
4098           output_asm_insn (strcat (buf, AS2 (%z1,%y1,%0)), operands);
4099           return "";
4100         }
4101       else
4102         output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
4103     }
4104
4105   /* Now retrieve the condition code. */
4106
4107   return output_fp_cc0_set (insn);
4108 }
4109 \f
4110 /* Output opcodes to transfer the results of FP compare or test INSN
4111    from the FPU to the CPU flags.  If TARGET_IEEE_FP, ensure that if the
4112    result of the compare or test is unordered, no comparison operator
4113    succeeds except NE.  Return an output template, if any.  */
4114
4115 char *
4116 output_fp_cc0_set (insn)
4117      rtx insn;
4118 {
4119   rtx xops[3];
4120   rtx next;
4121   enum rtx_code code;
4122
4123   xops[0] = gen_rtx_REG (HImode, 0);
4124   output_asm_insn (AS1 (fnsts%W0,%0), xops);
4125
4126   if (! TARGET_IEEE_FP)
4127     {
4128       if (!(cc_status.flags & CC_REVERSED))
4129         {
4130           next = next_cc0_user (insn);
4131         
4132           if (GET_CODE (next) == JUMP_INSN
4133               && GET_CODE (PATTERN (next)) == SET
4134               && SET_DEST (PATTERN (next)) == pc_rtx
4135               && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
4136             code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
4137           else if (GET_CODE (PATTERN (next)) == SET)
4138             code = GET_CODE (SET_SRC (PATTERN (next)));
4139           else
4140             return "sahf";
4141
4142           if (code == GT || code == LT || code == EQ || code == NE
4143               || code == LE || code == GE)
4144             {
4145               /* We will test eax directly. */
4146               cc_status.flags |= CC_TEST_AX;
4147               return "";
4148             }
4149         }
4150
4151       return "sahf";
4152     }
4153
4154   next = next_cc0_user (insn);
4155   if (next == NULL_RTX)
4156     abort ();
4157
4158   if (GET_CODE (next) == JUMP_INSN
4159       && GET_CODE (PATTERN (next)) == SET
4160       && SET_DEST (PATTERN (next)) == pc_rtx
4161       && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
4162     code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
4163   else if (GET_CODE (PATTERN (next)) == SET)
4164     {
4165       if (GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
4166         code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
4167       else
4168         code = GET_CODE (SET_SRC (PATTERN (next)));
4169     }
4170
4171   else if (GET_CODE (PATTERN (next)) == PARALLEL
4172            && GET_CODE (XVECEXP (PATTERN (next), 0, 0)) == SET)
4173     {
4174       if (GET_CODE (SET_SRC (XVECEXP (PATTERN (next), 0, 0))) == IF_THEN_ELSE)
4175         code = GET_CODE (XEXP (SET_SRC (XVECEXP (PATTERN (next), 0, 0)), 0));
4176       else
4177         code = GET_CODE (SET_SRC (XVECEXP (PATTERN (next), 0, 0)));
4178     }
4179   else
4180     abort ();
4181
4182   xops[0] = gen_rtx_REG (QImode, 0);
4183
4184   switch (code)
4185     {
4186     case GT:
4187       xops[1] = GEN_INT (0x45);
4188       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4189       /* je label */
4190       break;
4191
4192     case LT:
4193       xops[1] = GEN_INT (0x45);
4194       xops[2] = GEN_INT (0x01);
4195       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4196       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
4197       /* je label */
4198       break;
4199
4200     case GE:
4201       xops[1] = GEN_INT (0x05);
4202       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4203       /* je label */
4204       break;
4205
4206     case LE:
4207       xops[1] = GEN_INT (0x45);
4208       xops[2] = GEN_INT (0x40);
4209       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4210       output_asm_insn (AS1 (dec%B0,%h0), xops);
4211       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
4212       /* jb label */
4213       break;
4214
4215     case EQ:
4216       xops[1] = GEN_INT (0x45);
4217       xops[2] = GEN_INT (0x40);
4218       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4219       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
4220       /* je label */
4221       break;
4222
4223     case NE:
4224       xops[1] = GEN_INT (0x44);
4225       xops[2] = GEN_INT (0x40);
4226       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4227       output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
4228       /* jne label */
4229       break;
4230
4231     case GTU:
4232     case LTU:
4233     case GEU:
4234     case LEU:
4235     default:
4236       abort ();
4237     }
4238
4239   return "";
4240 }
4241 \f
4242 #define MAX_386_STACK_LOCALS 2
4243
4244 static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
4245
4246 /* Define the structure for the machine field in struct function.  */
4247 struct machine_function
4248 {
4249   rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
4250   rtx pic_label_rtx;
4251   char pic_label_name[256];
4252 };
4253
4254 /* Functions to save and restore i386_stack_locals.
4255    These will be called, via pointer variables,
4256    from push_function_context and pop_function_context.  */
4257
4258 void
4259 save_386_machine_status (p)
4260      struct function *p;
4261 {
4262   p->machine
4263     = (struct machine_function *) xmalloc (sizeof (struct machine_function));
4264   bcopy ((char *) i386_stack_locals, (char *) p->machine->i386_stack_locals,
4265          sizeof i386_stack_locals);
4266   p->machine->pic_label_rtx = pic_label_rtx;
4267   bcopy (pic_label_name, p->machine->pic_label_name, 256);
4268 }
4269
4270 void
4271 restore_386_machine_status (p)
4272      struct function *p;
4273 {
4274   bcopy ((char *) p->machine->i386_stack_locals, (char *) i386_stack_locals,
4275          sizeof i386_stack_locals);
4276   pic_label_rtx = p->machine->pic_label_rtx;
4277   bcopy (p->machine->pic_label_name, pic_label_name, 256);
4278   free (p->machine);
4279   p->machine = NULL;
4280 }
4281
4282 /* Clear stack slot assignments remembered from previous functions.
4283    This is called from INIT_EXPANDERS once before RTL is emitted for each
4284    function.  */
4285
4286 void
4287 clear_386_stack_locals ()
4288 {
4289   enum machine_mode mode;
4290   int n;
4291
4292   for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
4293        mode = (enum machine_mode) ((int) mode + 1))
4294     for (n = 0; n < MAX_386_STACK_LOCALS; n++)
4295       i386_stack_locals[(int) mode][n] = NULL_RTX;
4296
4297   pic_label_rtx = NULL_RTX;
4298   bzero (pic_label_name, 256);
4299   /* Arrange to save and restore i386_stack_locals around nested functions.  */
4300   save_machine_status = save_386_machine_status;
4301   restore_machine_status = restore_386_machine_status;
4302 }
4303
4304 /* Return a MEM corresponding to a stack slot with mode MODE.
4305    Allocate a new slot if necessary.
4306
4307    The RTL for a function can have several slots available: N is
4308    which slot to use.  */
4309
4310 rtx
4311 assign_386_stack_local (mode, n)
4312      enum machine_mode mode;
4313      int n;
4314 {
4315   if (n < 0 || n >= MAX_386_STACK_LOCALS)
4316     abort ();
4317
4318   if (i386_stack_locals[(int) mode][n] == NULL_RTX)
4319     i386_stack_locals[(int) mode][n]
4320       = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
4321
4322   return i386_stack_locals[(int) mode][n];
4323 }
4324 \f
4325 int is_mul(op,mode)
4326     register rtx op;
4327     enum machine_mode mode;
4328 {
4329   return (GET_CODE (op) == MULT);
4330 }
4331
4332 int is_div(op,mode)
4333     register rtx op;
4334     enum machine_mode mode;
4335 {
4336   return (GET_CODE (op) == DIV);
4337 }
4338 \f
4339 #ifdef NOTYET
4340 /* Create a new copy of an rtx.
4341    Recursively copies the operands of the rtx,
4342    except for those few rtx codes that are sharable.
4343    Doesn't share CONST  */
4344
4345 rtx
4346 copy_all_rtx (orig)
4347      register rtx orig;
4348 {
4349   register rtx copy;
4350   register int i, j;
4351   register RTX_CODE code;
4352   register char *format_ptr;
4353
4354   code = GET_CODE (orig);
4355
4356   switch (code)
4357     {
4358     case REG:
4359     case QUEUED:
4360     case CONST_INT:
4361     case CONST_DOUBLE:
4362     case SYMBOL_REF:
4363     case CODE_LABEL:
4364     case PC:
4365     case CC0:
4366     case SCRATCH:
4367       /* SCRATCH must be shared because they represent distinct values. */
4368       return orig;
4369
4370 #if 0
4371     case CONST:
4372       /* CONST can be shared if it contains a SYMBOL_REF.  If it contains
4373          a LABEL_REF, it isn't sharable.  */
4374       if (GET_CODE (XEXP (orig, 0)) == PLUS
4375           && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
4376           && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
4377         return orig;
4378       break;
4379 #endif
4380       /* A MEM with a constant address is not sharable.  The problem is that
4381          the constant address may need to be reloaded.  If the mem is shared,
4382          then reloading one copy of this mem will cause all copies to appear
4383          to have been reloaded.  */
4384     }
4385
4386   copy = rtx_alloc (code);
4387   PUT_MODE (copy, GET_MODE (orig));
4388   copy->in_struct = orig->in_struct;
4389   copy->volatil = orig->volatil;
4390   copy->unchanging = orig->unchanging;
4391   copy->integrated = orig->integrated;
4392   /* intel1 */
4393   copy->is_spill_rtx = orig->is_spill_rtx;
4394   
4395   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
4396
4397   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
4398     {
4399       switch (*format_ptr++)
4400         {
4401         case 'e':
4402           XEXP (copy, i) = XEXP (orig, i);
4403           if (XEXP (orig, i) != NULL)
4404             XEXP (copy, i) = copy_rtx (XEXP (orig, i));
4405           break;
4406
4407         case '0':
4408         case 'u':
4409           XEXP (copy, i) = XEXP (orig, i);
4410           break;
4411
4412         case 'E':
4413         case 'V':
4414           XVEC (copy, i) = XVEC (orig, i);
4415           if (XVEC (orig, i) != NULL)
4416             {
4417               XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
4418               for (j = 0; j < XVECLEN (copy, i); j++)
4419                 XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
4420             }
4421           break;
4422
4423         case 'w':
4424           XWINT (copy, i) = XWINT (orig, i);
4425           break;
4426
4427         case 'i':
4428           XINT (copy, i) = XINT (orig, i);
4429           break;
4430
4431         case 's':
4432         case 'S':
4433           XSTR (copy, i) = XSTR (orig, i);
4434           break;
4435
4436         default:
4437           abort ();
4438         }
4439     }
4440   return copy;
4441 }
4442
4443 \f
4444 /* Try to rewrite a memory address to make it valid */
4445
4446 void 
4447 rewrite_address (mem_rtx)
4448      rtx mem_rtx;
4449 {
4450   rtx index_rtx, base_rtx, offset_rtx, scale_rtx, ret_rtx;
4451   int scale = 1;
4452   int offset_adjust = 0;
4453   int was_only_offset = 0;
4454   rtx mem_addr = XEXP (mem_rtx, 0);
4455   char *storage = oballoc (0);
4456   int in_struct = 0;
4457   int is_spill_rtx = 0;
4458
4459   in_struct = MEM_IN_STRUCT_P (mem_rtx);
4460   is_spill_rtx = RTX_IS_SPILL_P (mem_rtx);
4461
4462   if (GET_CODE (mem_addr) == PLUS
4463       && GET_CODE (XEXP (mem_addr, 1)) == PLUS
4464       && GET_CODE (XEXP (XEXP (mem_addr, 1), 0)) == REG)
4465     {
4466       /* This part is utilized by the combiner. */
4467       ret_rtx
4468         = gen_rtx (PLUS, GET_MODE (mem_addr),
4469                    gen_rtx (PLUS, GET_MODE (XEXP (mem_addr, 1)),
4470                             XEXP (mem_addr, 0), XEXP (XEXP (mem_addr, 1), 0)),
4471                    XEXP (XEXP (mem_addr, 1), 1));
4472
4473       if (memory_address_p (GET_MODE (mem_rtx), ret_rtx))
4474         {
4475           XEXP (mem_rtx, 0) = ret_rtx;
4476           RTX_IS_SPILL_P (ret_rtx) = is_spill_rtx;
4477           return;
4478         }
4479
4480       obfree (storage);
4481     }
4482
4483   /* This part is utilized by loop.c.  
4484      If the address contains PLUS (reg,const) and this pattern is invalid
4485      in this case - try to rewrite the address to make it valid. */
4486   storage = oballoc (0);
4487   index_rtx = base_rtx = offset_rtx = NULL;
4488
4489   /* Find the base index and offset elements of the memory address. */
4490   if (GET_CODE (mem_addr) == PLUS)
4491     {
4492       if (GET_CODE (XEXP (mem_addr, 0)) == REG)
4493         {
4494           if (GET_CODE (XEXP (mem_addr, 1)) == REG)
4495             base_rtx = XEXP (mem_addr, 1), index_rtx = XEXP (mem_addr, 0);
4496           else
4497             base_rtx = XEXP (mem_addr, 0), offset_rtx = XEXP (mem_addr, 1);
4498         }
4499
4500       else if (GET_CODE (XEXP (mem_addr, 0)) == MULT)
4501         {
4502           index_rtx = XEXP (mem_addr, 0);
4503           if (GET_CODE (XEXP (mem_addr, 1)) == REG)
4504             base_rtx = XEXP (mem_addr, 1);
4505           else
4506             offset_rtx = XEXP (mem_addr, 1);
4507         }
4508
4509       else if (GET_CODE (XEXP (mem_addr, 0)) == PLUS)
4510         {
4511           if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == PLUS
4512               && GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0)) == MULT
4513               && (GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 0))
4514                   == REG)
4515               && (GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 1))
4516                   == CONST_INT)
4517               && (GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1))
4518                   == CONST_INT)
4519               && GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == REG
4520               && GET_CODE (XEXP (mem_addr, 1)) == SYMBOL_REF)
4521             {
4522               index_rtx = XEXP (XEXP (XEXP (mem_addr, 0), 0), 0);
4523               offset_rtx = XEXP (mem_addr, 1);
4524               base_rtx = XEXP (XEXP (mem_addr, 0), 1);
4525               offset_adjust = INTVAL (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1));
4526             }
4527           else
4528             {
4529               offset_rtx = XEXP (mem_addr, 1);
4530               index_rtx = XEXP (XEXP (mem_addr, 0), 0);
4531               base_rtx = XEXP (XEXP (mem_addr, 0), 1);
4532             }
4533         }
4534
4535       else if (GET_CODE (XEXP (mem_addr, 0)) == CONST_INT)
4536         {
4537           was_only_offset = 1;
4538           index_rtx = NULL;
4539           base_rtx = NULL;
4540           offset_rtx = XEXP (mem_addr, 1);
4541           offset_adjust = INTVAL (XEXP (mem_addr, 0));
4542           if (offset_adjust == 0)
4543             {
4544               XEXP (mem_rtx, 0) = offset_rtx;
4545               RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4546               return;
4547             }
4548         }
4549       else
4550         {
4551           obfree (storage);
4552           return;
4553         }
4554     }
4555   else if (GET_CODE (mem_addr) == MULT)
4556     index_rtx = mem_addr;
4557   else
4558     {
4559       obfree (storage);
4560       return;
4561     }
4562
4563   if (index_rtx != 0 && GET_CODE (index_rtx) == MULT)
4564     {
4565       if (GET_CODE (XEXP (index_rtx, 1)) != CONST_INT)
4566         {
4567           obfree (storage);
4568           return;
4569         }
4570
4571       scale_rtx = XEXP (index_rtx, 1);
4572       scale = INTVAL (scale_rtx);
4573       index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
4574     }
4575
4576   /* Now find which of the elements are invalid and try to fix them. */
4577   if (index_rtx && GET_CODE (index_rtx) == CONST_INT && base_rtx == NULL)
4578     {
4579       offset_adjust = INTVAL (index_rtx) * scale;
4580
4581       if (offset_rtx != 0 && CONSTANT_P (offset_rtx))
4582         offset_rtx = plus_constant (offset_rtx, offset_adjust);
4583       else if (offset_rtx == 0)
4584         offset_rtx = const0_rtx;
4585
4586       RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4587       XEXP (mem_rtx, 0) = offset_rtx;
4588       return;
4589     }
4590
4591   if (base_rtx && GET_CODE (base_rtx) == PLUS
4592       && GET_CODE (XEXP (base_rtx, 0)) == REG
4593       && GET_CODE (XEXP (base_rtx, 1)) == CONST_INT)
4594     {
4595       offset_adjust += INTVAL (XEXP (base_rtx, 1));
4596       base_rtx = copy_all_rtx (XEXP (base_rtx, 0));
4597     }
4598
4599   else if (base_rtx && GET_CODE (base_rtx) == CONST_INT)
4600     {
4601       offset_adjust += INTVAL (base_rtx);
4602       base_rtx = NULL;
4603     }
4604
4605   if (index_rtx && GET_CODE (index_rtx) == PLUS
4606       && GET_CODE (XEXP (index_rtx, 0)) == REG
4607       && GET_CODE (XEXP (index_rtx, 1)) == CONST_INT)
4608     {
4609       offset_adjust += INTVAL (XEXP (index_rtx, 1)) * scale;
4610       index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
4611     }
4612
4613   if (index_rtx)
4614     {
4615       if (! LEGITIMATE_INDEX_P (index_rtx)
4616           && ! (index_rtx == stack_pointer_rtx && scale == 1
4617                 && base_rtx == NULL))
4618         {
4619           obfree (storage);
4620           return;
4621         }
4622     }
4623
4624   if (base_rtx)
4625     {
4626       if (! LEGITIMATE_INDEX_P (base_rtx) && GET_CODE (base_rtx) != REG)
4627         {
4628           obfree (storage);
4629           return;
4630         }
4631     }
4632
4633   if (offset_adjust != 0)
4634     {
4635       if (offset_rtx != 0 && CONSTANT_P (offset_rtx))
4636         offset_rtx = plus_constant (offset_rtx, offset_adjust);
4637       else
4638         offset_rtx = const0_rtx;
4639
4640       if (index_rtx)
4641         {
4642           if (base_rtx)
4643             {
4644               if (scale != 1)
4645                 {
4646                   ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx),
4647                                      gen_rtx (MULT, GET_MODE (index_rtx),
4648                                               index_rtx, scale_rtx),
4649                                      base_rtx);
4650
4651                   if (GET_CODE (offset_rtx) != CONST_INT
4652                       || INTVAL (offset_rtx) != 0)
4653                     ret_rtx = gen_rtx (PLUS, GET_MODE (ret_rtx),
4654                                        ret_rtx, offset_rtx);
4655                 }
4656               else
4657                 {
4658                   ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx),
4659                                      index_rtx, base_rtx);
4660
4661                   if (GET_CODE (offset_rtx) != CONST_INT
4662                       || INTVAL (offset_rtx) != 0)
4663                     ret_rtx = gen_rtx (PLUS, GET_MODE (ret_rtx),
4664                                        ret_rtx, offset_rtx);
4665                 }
4666             }
4667           else
4668             {
4669               if (scale != 1)
4670                 {
4671                   ret_rtx = gen_rtx (MULT, GET_MODE (index_rtx),
4672                                      index_rtx, scale_rtx);
4673
4674                   if (GET_CODE (offset_rtx) != CONST_INT
4675                       || INTVAL (offset_rtx) != 0)
4676                     ret_rtx = gen_rtx (PLUS, GET_MODE (ret_rtx),
4677                                        ret_rtx, offset_rtx);
4678                 }
4679               else
4680                 {
4681                   if (GET_CODE (offset_rtx) == CONST_INT
4682                       && INTVAL (offset_rtx) == 0)
4683                     ret_rtx = index_rtx;
4684                   else
4685                     ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx),
4686                                        index_rtx, offset_rtx);
4687                 }
4688             }
4689         }
4690       else
4691         {
4692           if (base_rtx)
4693             {
4694               if (GET_CODE (offset_rtx) == CONST_INT
4695                   && INTVAL (offset_rtx) == 0)
4696                 ret_rtx = base_rtx;
4697               else
4698                 ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx), base_rtx,
4699                                    offset_rtx);
4700             }
4701           else if (was_only_offset)
4702             ret_rtx = offset_rtx;
4703           else
4704             {
4705               obfree (storage);
4706               return;
4707             }
4708         }
4709
4710       XEXP (mem_rtx, 0) = ret_rtx;
4711       RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4712       return;
4713     }
4714   else
4715     {
4716       obfree (storage);
4717       return;
4718     }
4719 }
4720 #endif /* NOTYET */
4721 \f
4722 /* Return 1 if the first insn to set cc before INSN also sets the register
4723    REG_RTX; otherwise return 0. */
4724 int
4725 last_to_set_cc (reg_rtx, insn)
4726      rtx reg_rtx, insn;
4727 {
4728   rtx prev_insn = PREV_INSN (insn);
4729
4730   while (prev_insn)
4731     {
4732       if (GET_CODE (prev_insn) == NOTE)
4733         ;
4734
4735       else if (GET_CODE (prev_insn) == INSN)
4736         {
4737           if (GET_CODE (PATTERN (prev_insn)) != SET)
4738             return (0);
4739
4740           if (rtx_equal_p (SET_DEST (PATTERN (prev_insn)), reg_rtx))
4741             {
4742               if (sets_condition_code (SET_SRC (PATTERN (prev_insn))))
4743                 return (1);
4744
4745               return (0);
4746             }
4747
4748           else if (! doesnt_set_condition_code (SET_SRC (PATTERN (prev_insn))))
4749             return (0);
4750         }
4751
4752       else
4753         return (0);
4754
4755       prev_insn = PREV_INSN (prev_insn);
4756     }
4757
4758   return (0);
4759 }
4760 \f
4761 int
4762 doesnt_set_condition_code (pat)
4763      rtx pat;
4764 {
4765   switch (GET_CODE (pat))
4766     {
4767     case MEM:
4768     case REG:
4769       return 1;
4770
4771     default:
4772       return 0;
4773
4774     }
4775 }
4776 \f
4777 int
4778 sets_condition_code (pat)
4779      rtx pat;
4780 {
4781   switch (GET_CODE (pat))
4782     {
4783     case PLUS:
4784     case MINUS:
4785     case AND:
4786     case IOR:
4787     case XOR:
4788     case NOT:
4789     case NEG:
4790     case MULT:
4791     case DIV:
4792     case MOD:
4793     case UDIV:
4794     case UMOD:
4795       return 1;
4796
4797     default:
4798       return (0);
4799     }
4800 }
4801 \f
4802 int
4803 str_immediate_operand (op, mode)
4804      register rtx op;
4805      enum machine_mode mode;
4806 {
4807   if (GET_CODE (op) == CONST_INT && INTVAL (op) <= 32 && INTVAL (op) >= 0)
4808     return 1;
4809
4810   return 0;
4811 }
4812 \f
4813 int
4814 is_fp_insn (insn)
4815      rtx insn;
4816 {
4817   if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4818       && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4819           || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4820           || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode))
4821     return 1;
4822
4823   return 0;
4824 }
4825
4826 /* Return 1 if the mode of the SET_DEST of insn is floating point
4827    and it is not an fld or a move from memory to memory.
4828    Otherwise return 0 */
4829
4830 int
4831 is_fp_dest (insn)
4832      rtx insn;
4833 {
4834   if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4835       && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4836           || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4837           || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
4838       && GET_CODE (SET_DEST (PATTERN (insn))) == REG
4839       && REGNO (SET_DEST (PATTERN (insn))) >= FIRST_FLOAT_REG
4840       && GET_CODE (SET_SRC (insn)) != MEM)
4841     return 1;
4842
4843   return 0;
4844 }
4845
4846 /* Return 1 if the mode of the SET_DEST of INSN is floating point and is
4847    memory and the source is a register.  */
4848
4849 int
4850 is_fp_store (insn)
4851      rtx insn;
4852 {
4853   if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4854       && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4855           || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4856           || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
4857       && GET_CODE (SET_DEST (PATTERN (insn))) == MEM
4858       && GET_CODE (SET_SRC (PATTERN (insn))) == REG)
4859     return 1;
4860
4861   return 0;
4862 }
4863 \f
4864 /* Return 1 if DEP_INSN sets a register which INSN uses as a base
4865    or index to reference memory.
4866    otherwise return 0 */
4867
4868 int
4869 agi_dependent (insn, dep_insn)
4870      rtx insn, dep_insn;
4871 {
4872   if (GET_CODE (dep_insn) == INSN
4873       && GET_CODE (PATTERN (dep_insn)) == SET
4874       && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG)
4875     return reg_mentioned_in_mem (SET_DEST (PATTERN (dep_insn)), insn);
4876
4877   if (GET_CODE (dep_insn) == INSN && GET_CODE (PATTERN (dep_insn)) == SET
4878       && GET_CODE (SET_DEST (PATTERN (dep_insn))) == MEM
4879       && push_operand (SET_DEST (PATTERN (dep_insn)),
4880                        GET_MODE (SET_DEST (PATTERN (dep_insn)))))
4881     return reg_mentioned_in_mem (stack_pointer_rtx, insn);
4882
4883   return 0;
4884 }
4885 \f
4886 /* Return 1 if reg is used in rtl as a base or index for a memory ref
4887    otherwise return 0. */
4888
4889 int
4890 reg_mentioned_in_mem (reg, rtl)
4891      rtx reg, rtl;
4892 {
4893   register char *fmt;
4894   register int i, j;
4895   register enum rtx_code code;
4896
4897   if (rtl == NULL)
4898     return 0;
4899
4900   code = GET_CODE (rtl);
4901
4902   switch (code)
4903     {
4904     case HIGH:
4905     case CONST_INT:
4906     case CONST:
4907     case CONST_DOUBLE:
4908     case SYMBOL_REF:
4909     case LABEL_REF:
4910     case PC:
4911     case CC0:
4912     case SUBREG:
4913       return 0;
4914     default:
4915       break;
4916     }
4917
4918   if (code == MEM && reg_mentioned_p (reg, rtl))
4919     return 1;
4920
4921   fmt = GET_RTX_FORMAT (code);
4922   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4923     {
4924       if (fmt[i] == 'E')
4925         {
4926           for (j = XVECLEN (rtl, i) - 1; j >= 0; j--)
4927             if (reg_mentioned_in_mem (reg, XVECEXP (rtl, i, j)))
4928               return 1;
4929         }
4930
4931       else if (fmt[i] == 'e' && reg_mentioned_in_mem (reg, XEXP (rtl, i)))
4932         return 1;
4933     }
4934
4935   return 0;
4936 }
4937 \f
4938 /* Output the appropriate insns for doing strlen if not just doing repnz; scasb
4939
4940    operands[0] = result, initialized with the startaddress
4941    operands[1] = alignment of the address.
4942    operands[2] = scratch register, initialized with the startaddress when
4943                  not aligned, otherwise undefined
4944
4945    This is just the body. It needs the initialisations mentioned above and
4946    some address computing at the end.  These things are done in i386.md.  */
4947
4948 char *
4949 output_strlen_unroll (operands)
4950      rtx operands[];
4951 {
4952   rtx xops[18];
4953
4954   xops[0] = operands[0];                /* Result */
4955   /*        operands[1];                 * Alignment */
4956   xops[1] = operands[2];                /* Scratch */
4957   xops[2] = GEN_INT (0);
4958   xops[3] = GEN_INT (2);
4959   xops[4] = GEN_INT (3);
4960   xops[5] = GEN_INT (4);
4961   /* xops[6] = gen_label_rtx ();         * label when aligned to 3-byte */
4962   /* xops[7] = gen_label_rtx ();         * label when aligned to 2-byte */
4963   xops[8] = gen_label_rtx ();           /* label of main loop */
4964
4965   if (TARGET_USE_Q_REG && QI_REG_P (xops[1]))
4966     xops[9] = gen_label_rtx ();         /* pentium optimisation */
4967
4968   xops[10] = gen_label_rtx ();          /* end label 2 */
4969   xops[11] = gen_label_rtx ();          /* end label 1 */
4970   xops[12] = gen_label_rtx ();          /* end label */
4971   /* xops[13]                            * Temporary used */
4972   xops[14] = GEN_INT (0xff);
4973   xops[15] = GEN_INT (0xff00);
4974   xops[16] = GEN_INT (0xff0000);
4975   xops[17] = GEN_INT (0xff000000);
4976
4977   /* Loop to check 1..3 bytes for null to get an aligned pointer.  */
4978
4979   /* Is there a known alignment and is it less than 4?  */
4980   if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) < 4)
4981     {
4982       /* Is there a known alignment and is it not 2? */
4983       if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
4984         {
4985           xops[6] = gen_label_rtx (); /* Label when aligned to 3-byte */
4986           xops[7] = gen_label_rtx (); /* Label when aligned to 2-byte */
4987
4988           /* Leave just the 3 lower bits.
4989              If this is a q-register, then the high part is used later
4990              therefore use andl rather than andb. */
4991           output_asm_insn (AS2 (and%L1,%4,%1), xops);
4992
4993           /* Is aligned to 4-byte address when zero */
4994           output_asm_insn (AS1 (je,%l8), xops);
4995
4996           /* Side-effect even Parity when %eax == 3 */
4997           output_asm_insn (AS1 (jp,%6), xops);
4998
4999           /* Is it aligned to 2 bytes ? */
5000           if (QI_REG_P (xops[1]))
5001             output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
5002           else
5003             output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
5004
5005           output_asm_insn (AS1 (je,%7), xops);
5006         }
5007       else
5008         {
5009           /* Since the alignment is 2, we have to check 2 or 0 bytes;
5010              check if is aligned to 4 - byte.  */
5011           output_asm_insn (AS2 (and%L1,%3,%1), xops);
5012
5013           /* Is aligned to 4-byte address when zero */
5014           output_asm_insn (AS1 (je,%l8), xops);
5015         }
5016
5017       xops[13] = gen_rtx_MEM (QImode, xops[0]);
5018
5019       /* Now compare the bytes; compare with the high part of a q-reg
5020          gives shorter code. */
5021       if (QI_REG_P (xops[1]))
5022         {
5023           /* Compare the first n unaligned byte on a byte per byte basis. */
5024           output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
5025
5026           /* When zero we reached the end. */
5027           output_asm_insn (AS1 (je,%l12), xops);
5028
5029           /* Increment the address. */
5030           output_asm_insn (AS1 (inc%L0,%0), xops);
5031
5032           /* Not needed with an alignment of 2 */
5033           if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
5034             {
5035               ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5036                                          CODE_LABEL_NUMBER (xops[7]));
5037               output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
5038               output_asm_insn (AS1 (je,%l12), xops);
5039               output_asm_insn (AS1 (inc%L0,%0), xops);
5040
5041               ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5042                                          CODE_LABEL_NUMBER (xops[6]));
5043             }
5044
5045           output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
5046         }
5047       else
5048         {
5049           output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
5050           output_asm_insn (AS1 (je,%l12), xops);
5051           output_asm_insn (AS1 (inc%L0,%0), xops);
5052
5053           ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5054                                      CODE_LABEL_NUMBER (xops[7]));
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[6]));
5061           output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
5062         }
5063
5064       output_asm_insn (AS1 (je,%l12), xops);
5065       output_asm_insn (AS1 (inc%L0,%0), xops);
5066     }
5067
5068     /* Generate loop to check 4 bytes at a time.  It is not a good idea to
5069        align this loop.  It gives only huge programs, but does not help to
5070        speed up.  */
5071   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[8]));
5072
5073   xops[13] = gen_rtx_MEM (SImode, xops[0]);
5074   output_asm_insn (AS2 (mov%L1,%13,%1), xops);
5075
5076   if (QI_REG_P (xops[1]))
5077     {
5078       /* On i586 it is faster to combine the hi- and lo- part as
5079          a kind of lookahead.  If anding both yields zero, then one
5080          of both *could* be zero, otherwise none of both is zero;
5081          this saves one instruction, on i486 this is slower
5082          tested with P-90, i486DX2-66, AMD486DX2-66  */
5083       if (TARGET_PENTIUM)
5084         {
5085           output_asm_insn (AS2 (test%B1,%h1,%b1), xops);
5086           output_asm_insn (AS1 (jne,%l9), xops);
5087         }
5088
5089       /* Check first byte. */
5090       output_asm_insn (AS2 (test%B1,%b1,%b1), xops);
5091       output_asm_insn (AS1 (je,%l12), xops);
5092
5093       /* Check second byte. */
5094       output_asm_insn (AS2 (test%B1,%h1,%h1), xops);
5095       output_asm_insn (AS1 (je,%l11), xops);
5096
5097       if (TARGET_PENTIUM)
5098         ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5099                                    CODE_LABEL_NUMBER (xops[9]));
5100     }
5101
5102   else
5103     {
5104       /* Check first byte. */
5105       output_asm_insn (AS2 (test%L1,%14,%1), xops);
5106       output_asm_insn (AS1 (je,%l12), xops);
5107
5108       /* Check second byte. */
5109       output_asm_insn (AS2 (test%L1,%15,%1), xops);
5110       output_asm_insn (AS1 (je,%l11), xops);
5111     }
5112
5113   /* Check third byte. */
5114   output_asm_insn (AS2 (test%L1,%16,%1), xops);
5115   output_asm_insn (AS1 (je,%l10), xops);
5116   
5117   /* Check fourth byte and increment address. */
5118   output_asm_insn (AS2 (add%L0,%5,%0), xops);
5119   output_asm_insn (AS2 (test%L1,%17,%1), xops);
5120   output_asm_insn (AS1 (jne,%l8), xops);
5121
5122   /* Now generate fixups when the compare stops within a 4-byte word. */
5123   output_asm_insn (AS2 (sub%L0,%4,%0), xops);
5124
5125   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[10]));
5126   output_asm_insn (AS1 (inc%L0,%0), xops);
5127
5128   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[11]));
5129   output_asm_insn (AS1 (inc%L0,%0), xops);
5130
5131   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[12]));
5132
5133   return "";
5134 }