OSDN Git Service

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