OSDN Git Service

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