OSDN Git Service

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