OSDN Git Service

* i386.md: Delete floating point compare, add, subtract,
[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       /* ESI addressing makes instruction vector decoded on the K6.  We can
3776          avoid this by ESI+0 addressing.  */
3777       if (REGNO_REG_CLASS (REGNO (addr)) == SIREG
3778           && ix86_cpu == PROCESSOR_K6 && !optimize_size)
3779         output_addr_const (file, const0_rtx);
3780       ADDR_BEG (file);
3781       fprintf (file, "%se", RP);
3782       fputs (hi_reg_name[REGNO (addr)], file);
3783       ADDR_END (file);
3784       break;
3785
3786     case PLUS:
3787       reg1 = 0;
3788       reg2 = 0;
3789       ireg = 0;
3790       breg = 0;
3791       offset = 0;
3792       if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
3793         {
3794           offset = XEXP (addr, 0);
3795           addr = XEXP (addr, 1);
3796         }
3797       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
3798         {
3799           offset = XEXP (addr, 1);
3800           addr = XEXP (addr, 0);
3801         }
3802
3803       if (GET_CODE (addr) != PLUS)
3804         ;
3805       else if (GET_CODE (XEXP (addr, 0)) == MULT)
3806         reg1 = XEXP (addr, 0), addr = XEXP (addr, 1);
3807       else if (GET_CODE (XEXP (addr, 1)) == MULT)
3808         reg1 = XEXP (addr, 1), addr = XEXP (addr, 0);
3809       else if (GET_CODE (XEXP (addr, 0)) == REG)
3810         reg1 = XEXP (addr, 0), addr = XEXP (addr, 1);
3811       else if (GET_CODE (XEXP (addr, 1)) == REG)
3812         reg1 = XEXP (addr, 1), addr = XEXP (addr, 0);
3813
3814       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
3815         {
3816           if (reg1 == 0)
3817             reg1 = addr;
3818           else
3819             reg2 = addr;
3820
3821           addr = 0;
3822         }
3823
3824       if (offset != 0)
3825         {
3826           if (addr != 0)
3827             abort ();
3828           addr = offset;
3829         }
3830
3831       if ((reg1 && GET_CODE (reg1) == MULT)
3832           || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
3833         {
3834           breg = reg2;
3835           ireg = reg1;
3836         }
3837       else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
3838         {
3839           breg = reg1;
3840           ireg = reg2;
3841         }
3842
3843       if (ireg != 0 || breg != 0)
3844         {
3845           int scale = 1;
3846
3847           if (addr != 0)
3848             {
3849               if (flag_pic)
3850                 output_pic_addr_const (file, addr, 0);
3851               else if (GET_CODE (addr) == LABEL_REF)
3852                 output_asm_label (addr);
3853               else
3854                 output_addr_const (file, addr);
3855             }
3856
3857           if (ireg != 0 && GET_CODE (ireg) == MULT)
3858             {
3859               scale = INTVAL (XEXP (ireg, 1));
3860               ireg = XEXP (ireg, 0);
3861             }
3862
3863           /* The stack pointer can only appear as a base register,
3864              never an index register, so exchange the regs if it is wrong. */
3865
3866           if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM)
3867             {
3868               rtx tmp;
3869
3870               tmp = breg;
3871               breg = ireg;
3872               ireg = tmp;
3873             }
3874
3875           /* output breg+ireg*scale */
3876           PRINT_B_I_S (breg, ireg, scale, file);
3877           break;
3878         }
3879
3880     case MULT:
3881       {
3882         int scale;
3883
3884         if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
3885           {
3886             scale = INTVAL (XEXP (addr, 0));
3887             ireg = XEXP (addr, 1);
3888           }
3889         else
3890           {
3891             scale = INTVAL (XEXP (addr, 1));
3892             ireg = XEXP (addr, 0);
3893           }
3894
3895         /* (reg,reg,) is shorter than (,reg,2).  */
3896         if (scale == 2)
3897           {
3898             PRINT_B_I_S (ireg, ireg, 1, file);
3899           } 
3900         else 
3901           {
3902             output_addr_const (file, const0_rtx);
3903             PRINT_B_I_S (NULL_RTX, ireg, scale, file);
3904           }
3905       }
3906       break;
3907
3908     default:
3909       if (GET_CODE (addr) == CONST_INT
3910           && INTVAL (addr) < 0x8000
3911           && INTVAL (addr) >= -0x8000)
3912         fprintf (file, "%d", (int) INTVAL (addr));
3913       else
3914         {
3915           if (flag_pic)
3916             output_pic_addr_const (file, addr, 0);
3917           else
3918             output_addr_const (file, addr);
3919         }
3920     }
3921 }
3922 \f
3923 /* Set the cc_status for the results of an insn whose pattern is EXP.
3924    On the 80386, we assume that only test and compare insns, as well
3925    as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, BSF, ASHIFT,
3926    ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
3927    Also, we assume that jumps, moves and sCOND don't affect the condition
3928    codes.  All else clobbers the condition codes, by assumption.
3929
3930    We assume that ALL integer add, minus, etc. instructions effect the
3931    condition codes.  This MUST be consistent with i386.md.
3932
3933    We don't record any float test or compare - the redundant test &
3934    compare check in final.c does not handle stack-like regs correctly. */
3935
3936 void
3937 notice_update_cc (exp)
3938      rtx exp;
3939 {
3940   if (GET_CODE (exp) == SET)
3941     {
3942       /* Jumps do not alter the cc's.  */
3943       if (SET_DEST (exp) == pc_rtx)
3944         return;
3945
3946       /* Moving register or memory into a register:
3947          it doesn't alter the cc's, but it might invalidate
3948          the RTX's which we remember the cc's came from.
3949          (Note that moving a constant 0 or 1 MAY set the cc's).  */
3950       if (REG_P (SET_DEST (exp))
3951           && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM
3952               || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'
3953               || GET_CODE (SET_SRC (exp)) == IF_THEN_ELSE))
3954         {
3955           if (cc_status.value1
3956               && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
3957             cc_status.value1 = 0;
3958
3959           if (cc_status.value2
3960               && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
3961             cc_status.value2 = 0;
3962
3963           return;
3964         }
3965
3966       /* Moving register into memory doesn't alter the cc's.
3967          It may invalidate the RTX's which we remember the cc's came from.  */
3968       if (GET_CODE (SET_DEST (exp)) == MEM
3969           && (REG_P (SET_SRC (exp))
3970               || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
3971         {
3972           if (cc_status.value1
3973               && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
3974             cc_status.value1 = 0;
3975           if (cc_status.value2
3976               && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
3977             cc_status.value2 = 0;
3978
3979           return;
3980         }
3981
3982       /* Function calls clobber the cc's.  */
3983       else if (GET_CODE (SET_SRC (exp)) == CALL)
3984         {
3985           CC_STATUS_INIT;
3986           return;
3987         }
3988
3989       /* Tests and compares set the cc's in predictable ways.  */
3990       else if (SET_DEST (exp) == cc0_rtx)
3991         {
3992           CC_STATUS_INIT;
3993           cc_status.value1 = SET_SRC (exp);
3994           return;
3995         }
3996
3997       /* Certain instructions effect the condition codes. */
3998       else if (GET_MODE (SET_SRC (exp)) == SImode
3999                || GET_MODE (SET_SRC (exp)) == HImode
4000                || GET_MODE (SET_SRC (exp)) == QImode)
4001         switch (GET_CODE (SET_SRC (exp)))
4002           {
4003           case ASHIFTRT: case LSHIFTRT: case ASHIFT:
4004             /* Shifts on the 386 don't set the condition codes if the
4005                shift count is zero. */
4006             if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
4007               {
4008                 CC_STATUS_INIT;
4009                 break;
4010               }
4011
4012             /* We assume that the CONST_INT is non-zero (this rtx would
4013                have been deleted if it were zero. */
4014
4015           case PLUS: case MINUS: case NEG:
4016           case AND: case IOR: case XOR:
4017             cc_status.flags = CC_NO_OVERFLOW;
4018             cc_status.value1 = SET_SRC (exp);
4019             cc_status.value2 = SET_DEST (exp);
4020             break;
4021
4022             /* This is the bsf pattern used by ffs.  */
4023           case UNSPEC:
4024             if (XINT (SET_SRC (exp), 1) == 5)
4025               {
4026                 /* Only the Z flag is defined after bsf.  */
4027                 cc_status.flags
4028                   = CC_NOT_POSITIVE | CC_NOT_NEGATIVE | CC_NO_OVERFLOW;
4029                 cc_status.value1 = XVECEXP (SET_SRC (exp), 0, 0);
4030                 cc_status.value2 = 0;
4031                 break;
4032               }
4033             /* FALLTHRU */
4034
4035           default:
4036             CC_STATUS_INIT;
4037           }
4038       else
4039         {
4040           CC_STATUS_INIT;
4041         }
4042     }
4043   else if (GET_CODE (exp) == PARALLEL
4044            && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
4045     {
4046       if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
4047         return;
4048       if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
4049
4050         {
4051           CC_STATUS_INIT;
4052           if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
4053             {
4054               cc_status.flags |= CC_IN_80387;
4055               if (0 && TARGET_CMOVE && stack_regs_mentioned_p
4056                   (XEXP (SET_SRC (XVECEXP (exp, 0, 0)), 1)))
4057                 cc_status.flags |= CC_FCOMI;
4058             }
4059           else
4060             cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
4061           return;
4062         }
4063
4064       CC_STATUS_INIT;
4065     }
4066   else
4067     {
4068       CC_STATUS_INIT;
4069     }
4070 }
4071 \f
4072 /* Split one or more DImode RTL references into pairs of SImode
4073    references.  The RTL can be REG, offsettable MEM, integer constant, or
4074    CONST_DOUBLE.  "operands" is a pointer to an array of DImode RTL to
4075    split and "num" is its length.  lo_half and hi_half are output arrays
4076    that parallel "operands". */
4077
4078 void
4079 split_di (operands, num, lo_half, hi_half)
4080      rtx operands[];
4081      int num;
4082      rtx lo_half[], hi_half[];
4083 {
4084   while (num--)
4085     {
4086       rtx op = operands[num];
4087       if (! reload_completed)
4088         {
4089           lo_half[num] = gen_lowpart (SImode, op);
4090           hi_half[num] = gen_highpart (SImode, op);
4091         }
4092       else if (GET_CODE (op) == REG)
4093         {
4094           lo_half[num] = gen_rtx_REG (SImode, REGNO (op));
4095           hi_half[num] = gen_rtx_REG (SImode, REGNO (op) + 1);
4096         }
4097       else if (CONSTANT_P (op))
4098         split_double (op, &lo_half[num], &hi_half[num]);
4099       else if (offsettable_memref_p (op))
4100         {
4101           rtx lo_addr = XEXP (op, 0);
4102           rtx hi_addr = XEXP (adj_offsettable_operand (op, 4), 0);
4103           lo_half[num] = change_address (op, SImode, lo_addr);
4104           hi_half[num] = change_address (op, SImode, hi_addr);
4105         }
4106       else
4107         abort();
4108     }
4109 }
4110 \f
4111 /* Return 1 if this is a valid binary operation on a 387.
4112    OP is the expression matched, and MODE is its mode. */
4113
4114 int
4115 binary_387_op (op, mode)
4116     register rtx op;
4117     enum machine_mode mode;
4118 {
4119   if (mode != VOIDmode && mode != GET_MODE (op))
4120     return 0;
4121
4122   switch (GET_CODE (op))
4123     {
4124     case PLUS:
4125     case MINUS:
4126     case MULT:
4127     case DIV:
4128       return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
4129
4130     default:
4131       return 0;
4132     }
4133 }
4134 \f
4135 /* Return 1 if this is a valid shift or rotate operation on a 386.
4136    OP is the expression matched, and MODE is its mode. */
4137
4138 int
4139 shift_op (op, mode)
4140     register rtx op;
4141     enum machine_mode mode;
4142 {
4143   rtx operand = XEXP (op, 0);
4144
4145   if (mode != VOIDmode && mode != GET_MODE (op))
4146     return 0;
4147
4148   if (GET_MODE (operand) != GET_MODE (op)
4149       || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
4150     return 0;
4151
4152   return (GET_CODE (op) == ASHIFT
4153           || GET_CODE (op) == ASHIFTRT
4154           || GET_CODE (op) == LSHIFTRT
4155           || GET_CODE (op) == ROTATE
4156           || GET_CODE (op) == ROTATERT);
4157 }
4158
4159 /* Return 1 if OP is COMPARE rtx with mode VOIDmode.
4160    MODE is not used.  */
4161
4162 int
4163 VOIDmode_compare_op (op, mode)
4164     register rtx op;
4165     enum machine_mode mode ATTRIBUTE_UNUSED;
4166 {
4167   return GET_CODE (op) == COMPARE && GET_MODE (op) == VOIDmode;
4168 }
4169 \f
4170 /* Output code to perform a 387 binary operation in INSN, one of PLUS,
4171    MINUS, MULT or DIV.  OPERANDS are the insn operands, where operands[3]
4172    is the expression of the binary operation.  The output may either be
4173    emitted here, or returned to the caller, like all output_* functions.
4174
4175    There is no guarantee that the operands are the same mode, as they
4176    might be within FLOAT or FLOAT_EXTEND expressions. */
4177
4178 char *
4179 output_387_binary_op (insn, operands)
4180      rtx insn;
4181      rtx *operands;
4182 {
4183   rtx temp;
4184   char *base_op;
4185   static char buf[100];
4186
4187   switch (GET_CODE (operands[3]))
4188     {
4189     case PLUS:
4190       base_op = "fadd";
4191       break;
4192
4193     case MINUS:
4194       base_op = "fsub";
4195       break;
4196
4197     case MULT:
4198       base_op = "fmul";
4199       break;
4200
4201     case DIV:
4202       base_op = "fdiv";
4203       break;
4204
4205     default:
4206       abort ();
4207     }
4208
4209   strcpy (buf, base_op);
4210
4211   switch (GET_CODE (operands[3]))
4212     {
4213     case MULT:
4214     case PLUS:
4215       if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
4216         {
4217           temp = operands[2];
4218           operands[2] = operands[1];
4219           operands[1] = temp;
4220         }
4221
4222       if (GET_CODE (operands[2]) == MEM)
4223         return strcat (buf, AS1 (%z2,%2));
4224
4225       if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
4226         abort ();
4227
4228       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
4229         {
4230           if (STACK_TOP_P (operands[0]))
4231             return strcat (buf, AS2 (p,%0,%2));
4232           else
4233             return strcat (buf, AS2 (p,%2,%0));
4234         }
4235
4236       if (STACK_TOP_P (operands[0]))
4237         return strcat (buf, AS2C (%y2,%0));
4238       else
4239         return strcat (buf, AS2C (%2,%0));
4240
4241     case MINUS:
4242     case DIV:
4243       if (GET_CODE (operands[1]) == MEM)
4244         return strcat (buf, AS1 (r%z1,%1));
4245
4246       if (GET_CODE (operands[2]) == MEM)
4247         return strcat (buf, AS1 (%z2,%2));
4248
4249       if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
4250         abort ();
4251
4252       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
4253         {
4254           if (STACK_TOP_P (operands[0]))
4255             return strcat (buf, AS2 (p,%0,%2));
4256           else
4257             return strcat (buf, AS2 (rp,%2,%0));
4258         }
4259
4260       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4261         {
4262           if (STACK_TOP_P (operands[0]))
4263             return strcat (buf, AS2 (rp,%0,%1));
4264           else
4265             return strcat (buf, AS2 (p,%1,%0));
4266         }
4267
4268       if (STACK_TOP_P (operands[0]))
4269         {
4270           if (STACK_TOP_P (operands[1]))
4271             return strcat (buf, AS2C (%y2,%0));
4272           else
4273             return strcat (buf, AS2 (r,%y1,%0));
4274         }
4275       else if (STACK_TOP_P (operands[1]))
4276         return strcat (buf, AS2C (%1,%0));
4277       else
4278         return strcat (buf, AS2 (r,%2,%0));
4279
4280     default:
4281       abort ();
4282     }
4283 }
4284 \f
4285 /* Output code for INSN to convert a float to a signed int.  OPERANDS
4286    are the insn operands.  The output may be SFmode or DFmode and the
4287    input operand may be SImode or DImode.  As a special case, make sure
4288    that the 387 stack top dies if the output mode is DImode, because the
4289    hardware requires this.  */
4290
4291 char *
4292 output_fix_trunc (insn, operands)
4293      rtx insn;
4294      rtx *operands;
4295 {
4296   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
4297   rtx xops[2];
4298
4299   if (! STACK_TOP_P (operands[1]))
4300     abort ();
4301
4302   xops[0] = GEN_INT (12);
4303   xops[1] = operands[4];
4304
4305   output_asm_insn (AS1 (fnstc%W2,%2), operands);
4306   output_asm_insn (AS2 (mov%L2,%2,%4), operands);
4307   output_asm_insn (AS2 (mov%B1,%0,%h1), xops);
4308   output_asm_insn (AS2 (mov%L4,%4,%3), operands);
4309   output_asm_insn (AS1 (fldc%W3,%3), operands);
4310
4311   if (NON_STACK_REG_P (operands[0]))
4312     output_to_reg (operands[0], stack_top_dies, operands[3]);
4313
4314   else if (GET_CODE (operands[0]) == MEM)
4315     {
4316       if (stack_top_dies)
4317         output_asm_insn (AS1 (fistp%z0,%0), operands);
4318       else if (GET_MODE (operands[0]) == DImode && ! stack_top_dies)
4319         {
4320           /* There is no DImode version of this without a stack pop, so
4321              we must emulate it.  It doesn't matter much what the second
4322              instruction is, because the value being pushed on the FP stack
4323              is not used except for the following stack popping store.
4324              This case can only happen without optimization, so it doesn't
4325              matter that it is inefficient.  */
4326           output_asm_insn (AS1 (fistp%z0,%0), operands);
4327           output_asm_insn (AS1 (fild%z0,%0), operands);
4328         }
4329       else
4330         output_asm_insn (AS1 (fist%z0,%0), operands);
4331     }
4332   else
4333     abort ();
4334
4335   return AS1 (fldc%W2,%2);
4336 }
4337 \f
4338 /* Output code for INSN to compare OPERANDS.  The two operands might
4339    not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
4340    expression.  If the compare is in mode CCFPEQmode, use an opcode that
4341    will not fault if a qNaN is present. */
4342
4343 char *
4344 output_float_compare (insn, operands)
4345      rtx insn;
4346      rtx *operands;
4347 {
4348   int stack_top_dies;
4349   rtx body = XVECEXP (PATTERN (insn), 0, 0);
4350   int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
4351   rtx tmp;
4352
4353   if (0 && TARGET_CMOVE && STACK_REG_P (operands[1]))
4354     {
4355       cc_status.flags |= CC_FCOMI;
4356       cc_prev_status.flags &= ~CC_TEST_AX;
4357     }
4358
4359   if (! STACK_TOP_P (operands[0]))
4360     {
4361       tmp = operands[0];
4362       operands[0] = operands[1];
4363       operands[1] = tmp;
4364       cc_status.flags |= CC_REVERSED;
4365     }
4366
4367   if (! STACK_TOP_P (operands[0]))
4368     abort ();
4369
4370   stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
4371
4372   if (STACK_REG_P (operands[1])
4373       && stack_top_dies
4374       && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
4375       && REGNO (operands[1]) != FIRST_STACK_REG)
4376     {
4377       /* If both the top of the 387 stack dies, and the other operand
4378          is also a stack register that dies, then this must be a
4379          `fcompp' float compare */
4380
4381       if (unordered_compare)
4382         {
4383           if (cc_status.flags & CC_FCOMI)
4384             {
4385               output_asm_insn (AS2 (fucomip,%y1,%0), operands);
4386               output_asm_insn (AS1 (fstp, %y0), operands);
4387               return "";
4388             }
4389           else
4390             output_asm_insn ("fucompp", operands);
4391         }
4392       else
4393         {
4394           if (cc_status.flags & CC_FCOMI)
4395             {
4396               output_asm_insn (AS2 (fcomip, %y1,%0), operands);
4397               output_asm_insn (AS1 (fstp, %y0), operands);
4398               return "";
4399             }
4400           else
4401             output_asm_insn ("fcompp", operands);
4402         }
4403     }
4404   else
4405     {
4406       static char buf[100];
4407
4408       /* Decide if this is a float compare or an unordered float compare. */
4409
4410       if (unordered_compare)
4411         strcpy (buf, (cc_status.flags & CC_FCOMI) ? "fucomi" : "fucom");
4412       else
4413         strcpy (buf, (cc_status.flags & CC_FCOMI) ? "fcomi" : "fcom");
4414
4415       /* Modify the opcode if the 387 stack is to be popped. */
4416
4417       if (stack_top_dies)
4418         strcat (buf, "p");
4419
4420       if (cc_status.flags & CC_FCOMI)
4421         {
4422           output_asm_insn (strcat (buf, AS2 (%z1,%y1,%0)), operands);
4423           return "";
4424         }
4425       else
4426         output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
4427     }
4428
4429   /* Now retrieve the condition code. */
4430
4431   return output_fp_cc0_set (insn);
4432 }
4433 \f
4434 /* Output opcodes to transfer the results of FP compare or test INSN
4435    from the FPU to the CPU flags.  If TARGET_IEEE_FP, ensure that if the
4436    result of the compare or test is unordered, no comparison operator
4437    succeeds except NE.  Return an output template, if any.  */
4438
4439 char *
4440 output_fp_cc0_set (insn)
4441      rtx insn;
4442 {
4443   rtx xops[3];
4444   rtx next;
4445   enum rtx_code code;
4446
4447   xops[0] = gen_rtx_REG (HImode, 0);
4448   output_asm_insn (AS1 (fnsts%W0,%0), xops);
4449
4450   if (! TARGET_IEEE_FP)
4451     {
4452       if (!(cc_status.flags & CC_REVERSED))
4453         {
4454           next = next_cc0_user (insn);
4455
4456           if (GET_CODE (next) == JUMP_INSN
4457               && GET_CODE (PATTERN (next)) == SET
4458               && SET_DEST (PATTERN (next)) == pc_rtx
4459               && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
4460             code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
4461           else if (GET_CODE (PATTERN (next)) == SET)
4462             code = GET_CODE (SET_SRC (PATTERN (next)));
4463           else
4464             return "sahf";
4465
4466           if (code == GT || code == LT || code == EQ || code == NE
4467               || code == LE || code == GE)
4468             {
4469               /* We will test eax directly. */
4470               cc_status.flags |= CC_TEST_AX;
4471               return "";
4472             }
4473         }
4474
4475       return "sahf";
4476     }
4477
4478   next = next_cc0_user (insn);
4479   if (next == NULL_RTX)
4480     abort ();
4481
4482   if (GET_CODE (next) == JUMP_INSN
4483       && GET_CODE (PATTERN (next)) == SET
4484       && SET_DEST (PATTERN (next)) == pc_rtx
4485       && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
4486     code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
4487   else if (GET_CODE (PATTERN (next)) == SET)
4488     {
4489       if (GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
4490         code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
4491       else
4492         code = GET_CODE (SET_SRC (PATTERN (next)));
4493     }
4494
4495   else if (GET_CODE (PATTERN (next)) == PARALLEL
4496            && GET_CODE (XVECEXP (PATTERN (next), 0, 0)) == SET)
4497     {
4498       if (GET_CODE (SET_SRC (XVECEXP (PATTERN (next), 0, 0))) == IF_THEN_ELSE)
4499         code = GET_CODE (XEXP (SET_SRC (XVECEXP (PATTERN (next), 0, 0)), 0));
4500       else
4501         code = GET_CODE (SET_SRC (XVECEXP (PATTERN (next), 0, 0)));
4502     }
4503   else
4504     abort ();
4505
4506   xops[0] = gen_rtx_REG (QImode, 0);
4507
4508   switch (code)
4509     {
4510     case GT:
4511       xops[1] = GEN_INT (0x45);
4512       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4513       /* je label */
4514       break;
4515
4516     case LT:
4517       xops[1] = GEN_INT (0x45);
4518       xops[2] = GEN_INT (0x01);
4519       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4520       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
4521       /* je label */
4522       break;
4523
4524     case GE:
4525       xops[1] = GEN_INT (0x05);
4526       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4527       /* je label */
4528       break;
4529
4530     case LE:
4531       xops[1] = GEN_INT (0x45);
4532       xops[2] = GEN_INT (0x40);
4533       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4534       output_asm_insn (AS1 (dec%B0,%h0), xops);
4535       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
4536       /* jb label */
4537       break;
4538
4539     case EQ:
4540       xops[1] = GEN_INT (0x45);
4541       xops[2] = GEN_INT (0x40);
4542       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4543       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
4544       /* je label */
4545       break;
4546
4547     case NE:
4548       xops[1] = GEN_INT (0x44);
4549       xops[2] = GEN_INT (0x40);
4550       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4551       output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
4552       /* jne label */
4553       break;
4554
4555     case GTU:
4556     case LTU:
4557     case GEU:
4558     case LEU:
4559     default:
4560       abort ();
4561     }
4562
4563   return "";
4564 }
4565 \f
4566 #define MAX_386_STACK_LOCALS 2
4567
4568 static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
4569
4570 /* Define the structure for the machine field in struct function.  */
4571 struct machine_function
4572 {
4573   rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
4574   rtx pic_label_rtx;
4575   char pic_label_name[256];
4576 };
4577
4578 /* Functions to save and restore i386_stack_locals.
4579    These will be called, via pointer variables,
4580    from push_function_context and pop_function_context.  */
4581
4582 void
4583 save_386_machine_status (p)
4584      struct function *p;
4585 {
4586   p->machine
4587     = (struct machine_function *) xmalloc (sizeof (struct machine_function));
4588   bcopy ((char *) i386_stack_locals, (char *) p->machine->i386_stack_locals,
4589          sizeof i386_stack_locals);
4590   p->machine->pic_label_rtx = pic_label_rtx;
4591   bcopy (pic_label_name, p->machine->pic_label_name, 256);
4592 }
4593
4594 void
4595 restore_386_machine_status (p)
4596      struct function *p;
4597 {
4598   bcopy ((char *) p->machine->i386_stack_locals, (char *) i386_stack_locals,
4599          sizeof i386_stack_locals);
4600   pic_label_rtx = p->machine->pic_label_rtx;
4601   bcopy (p->machine->pic_label_name, pic_label_name, 256);
4602   free (p->machine);
4603   p->machine = NULL;
4604 }
4605
4606 /* Clear stack slot assignments remembered from previous functions.
4607    This is called from INIT_EXPANDERS once before RTL is emitted for each
4608    function.  */
4609
4610 void
4611 clear_386_stack_locals ()
4612 {
4613   enum machine_mode mode;
4614   int n;
4615
4616   for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
4617        mode = (enum machine_mode) ((int) mode + 1))
4618     for (n = 0; n < MAX_386_STACK_LOCALS; n++)
4619       i386_stack_locals[(int) mode][n] = NULL_RTX;
4620
4621   pic_label_rtx = NULL_RTX;
4622   bzero (pic_label_name, 256);
4623   /* Arrange to save and restore i386_stack_locals around nested functions.  */
4624   save_machine_status = save_386_machine_status;
4625   restore_machine_status = restore_386_machine_status;
4626 }
4627
4628 /* Return a MEM corresponding to a stack slot with mode MODE.
4629    Allocate a new slot if necessary.
4630
4631    The RTL for a function can have several slots available: N is
4632    which slot to use.  */
4633
4634 rtx
4635 assign_386_stack_local (mode, n)
4636      enum machine_mode mode;
4637      int n;
4638 {
4639   if (n < 0 || n >= MAX_386_STACK_LOCALS)
4640     abort ();
4641
4642   if (i386_stack_locals[(int) mode][n] == NULL_RTX)
4643     i386_stack_locals[(int) mode][n]
4644       = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
4645
4646   return i386_stack_locals[(int) mode][n];
4647 }
4648 \f
4649 int is_mul(op,mode)
4650     register rtx op;
4651     enum machine_mode mode ATTRIBUTE_UNUSED;
4652 {
4653   return (GET_CODE (op) == MULT);
4654 }
4655
4656 int is_div(op,mode)
4657     register rtx op;
4658     enum machine_mode mode ATTRIBUTE_UNUSED;
4659 {
4660   return (GET_CODE (op) == DIV);
4661 }
4662 \f
4663 #ifdef NOTYET
4664 /* Create a new copy of an rtx.
4665    Recursively copies the operands of the rtx,
4666    except for those few rtx codes that are sharable.
4667    Doesn't share CONST  */
4668
4669 rtx
4670 copy_all_rtx (orig)
4671      register rtx orig;
4672 {
4673   register rtx copy;
4674   register int i, j;
4675   register RTX_CODE code;
4676   register char *format_ptr;
4677
4678   code = GET_CODE (orig);
4679
4680   switch (code)
4681     {
4682     case REG:
4683     case QUEUED:
4684     case CONST_INT:
4685     case CONST_DOUBLE:
4686     case SYMBOL_REF:
4687     case CODE_LABEL:
4688     case PC:
4689     case CC0:
4690     case SCRATCH:
4691       /* SCRATCH must be shared because they represent distinct values. */
4692       return orig;
4693
4694 #if 0
4695     case CONST:
4696       /* CONST can be shared if it contains a SYMBOL_REF.  If it contains
4697          a LABEL_REF, it isn't sharable.  */
4698       if (GET_CODE (XEXP (orig, 0)) == PLUS
4699           && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
4700           && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
4701         return orig;
4702       break;
4703 #endif
4704       /* A MEM with a constant address is not sharable.  The problem is that
4705          the constant address may need to be reloaded.  If the mem is shared,
4706          then reloading one copy of this mem will cause all copies to appear
4707          to have been reloaded.  */
4708     }
4709
4710   copy = rtx_alloc (code);
4711   PUT_MODE (copy, GET_MODE (orig));
4712   copy->in_struct = orig->in_struct;
4713   copy->volatil = orig->volatil;
4714   copy->unchanging = orig->unchanging;
4715   copy->integrated = orig->integrated;
4716   /* intel1 */
4717   copy->is_spill_rtx = orig->is_spill_rtx;
4718
4719   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
4720
4721   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
4722     {
4723       switch (*format_ptr++)
4724         {
4725         case 'e':
4726           XEXP (copy, i) = XEXP (orig, i);
4727           if (XEXP (orig, i) != NULL)
4728             XEXP (copy, i) = copy_rtx (XEXP (orig, i));
4729           break;
4730
4731         case '0':
4732         case 'u':
4733           XEXP (copy, i) = XEXP (orig, i);
4734           break;
4735
4736         case 'E':
4737         case 'V':
4738           XVEC (copy, i) = XVEC (orig, i);
4739           if (XVEC (orig, i) != NULL)
4740             {
4741               XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
4742               for (j = 0; j < XVECLEN (copy, i); j++)
4743                 XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
4744             }
4745           break;
4746
4747         case 'w':
4748           XWINT (copy, i) = XWINT (orig, i);
4749           break;
4750
4751         case 'i':
4752           XINT (copy, i) = XINT (orig, i);
4753           break;
4754
4755         case 's':
4756         case 'S':
4757           XSTR (copy, i) = XSTR (orig, i);
4758           break;
4759
4760         default:
4761           abort ();
4762         }
4763     }
4764   return copy;
4765 }
4766
4767 \f
4768 /* Try to rewrite a memory address to make it valid */
4769
4770 void
4771 rewrite_address (mem_rtx)
4772      rtx mem_rtx;
4773 {
4774   rtx index_rtx, base_rtx, offset_rtx, scale_rtx, ret_rtx;
4775   int scale = 1;
4776   int offset_adjust = 0;
4777   int was_only_offset = 0;
4778   rtx mem_addr = XEXP (mem_rtx, 0);
4779   char *storage = oballoc (0);
4780   int in_struct = 0;
4781   int is_spill_rtx = 0;
4782
4783   in_struct = MEM_IN_STRUCT_P (mem_rtx);
4784   is_spill_rtx = RTX_IS_SPILL_P (mem_rtx);
4785
4786   if (GET_CODE (mem_addr) == PLUS
4787       && GET_CODE (XEXP (mem_addr, 1)) == PLUS
4788       && GET_CODE (XEXP (XEXP (mem_addr, 1), 0)) == REG)
4789     {
4790       /* This part is utilized by the combiner. */
4791       ret_rtx
4792         = gen_rtx (PLUS, GET_MODE (mem_addr),
4793                    gen_rtx (PLUS, GET_MODE (XEXP (mem_addr, 1)),
4794                             XEXP (mem_addr, 0), XEXP (XEXP (mem_addr, 1), 0)),
4795                    XEXP (XEXP (mem_addr, 1), 1));
4796
4797       if (memory_address_p (GET_MODE (mem_rtx), ret_rtx))
4798         {
4799           XEXP (mem_rtx, 0) = ret_rtx;
4800           RTX_IS_SPILL_P (ret_rtx) = is_spill_rtx;
4801           return;
4802         }
4803
4804       obfree (storage);
4805     }
4806
4807   /* This part is utilized by loop.c.
4808      If the address contains PLUS (reg,const) and this pattern is invalid
4809      in this case - try to rewrite the address to make it valid. */
4810   storage = oballoc (0);
4811   index_rtx = base_rtx = offset_rtx = NULL;
4812
4813   /* Find the base index and offset elements of the memory address. */
4814   if (GET_CODE (mem_addr) == PLUS)
4815     {
4816       if (GET_CODE (XEXP (mem_addr, 0)) == REG)
4817         {
4818           if (GET_CODE (XEXP (mem_addr, 1)) == REG)
4819             base_rtx = XEXP (mem_addr, 1), index_rtx = XEXP (mem_addr, 0);
4820           else
4821             base_rtx = XEXP (mem_addr, 0), offset_rtx = XEXP (mem_addr, 1);
4822         }
4823
4824       else if (GET_CODE (XEXP (mem_addr, 0)) == MULT)
4825         {
4826           index_rtx = XEXP (mem_addr, 0);
4827           if (GET_CODE (XEXP (mem_addr, 1)) == REG)
4828             base_rtx = XEXP (mem_addr, 1);
4829           else
4830             offset_rtx = XEXP (mem_addr, 1);
4831         }
4832
4833       else if (GET_CODE (XEXP (mem_addr, 0)) == PLUS)
4834         {
4835           if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == PLUS
4836               && GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0)) == MULT
4837               && (GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 0))
4838                   == REG)
4839               && (GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 1))
4840                   == CONST_INT)
4841               && (GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1))
4842                   == CONST_INT)
4843               && GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == REG
4844               && GET_CODE (XEXP (mem_addr, 1)) == SYMBOL_REF)
4845             {
4846               index_rtx = XEXP (XEXP (XEXP (mem_addr, 0), 0), 0);
4847               offset_rtx = XEXP (mem_addr, 1);
4848               base_rtx = XEXP (XEXP (mem_addr, 0), 1);
4849               offset_adjust = INTVAL (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1));
4850             }
4851           else
4852             {
4853               offset_rtx = XEXP (mem_addr, 1);
4854               index_rtx = XEXP (XEXP (mem_addr, 0), 0);
4855               base_rtx = XEXP (XEXP (mem_addr, 0), 1);
4856             }
4857         }
4858
4859       else if (GET_CODE (XEXP (mem_addr, 0)) == CONST_INT)
4860         {
4861           was_only_offset = 1;
4862           index_rtx = NULL;
4863           base_rtx = NULL;
4864           offset_rtx = XEXP (mem_addr, 1);
4865           offset_adjust = INTVAL (XEXP (mem_addr, 0));
4866           if (offset_adjust == 0)
4867             {
4868               XEXP (mem_rtx, 0) = offset_rtx;
4869               RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4870               return;
4871             }
4872         }
4873       else
4874         {
4875           obfree (storage);
4876           return;
4877         }
4878     }
4879   else if (GET_CODE (mem_addr) == MULT)
4880     index_rtx = mem_addr;
4881   else
4882     {
4883       obfree (storage);
4884       return;
4885     }
4886
4887   if (index_rtx != 0 && GET_CODE (index_rtx) == MULT)
4888     {
4889       if (GET_CODE (XEXP (index_rtx, 1)) != CONST_INT)
4890         {
4891           obfree (storage);
4892           return;
4893         }
4894
4895       scale_rtx = XEXP (index_rtx, 1);
4896       scale = INTVAL (scale_rtx);
4897       index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
4898     }
4899
4900   /* Now find which of the elements are invalid and try to fix them. */
4901   if (index_rtx && GET_CODE (index_rtx) == CONST_INT && base_rtx == NULL)
4902     {
4903       offset_adjust = INTVAL (index_rtx) * scale;
4904
4905       if (offset_rtx != 0 && CONSTANT_P (offset_rtx))
4906         offset_rtx = plus_constant (offset_rtx, offset_adjust);
4907       else if (offset_rtx == 0)
4908         offset_rtx = const0_rtx;
4909
4910       RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4911       XEXP (mem_rtx, 0) = offset_rtx;
4912       return;
4913     }
4914
4915   if (base_rtx && GET_CODE (base_rtx) == PLUS
4916       && GET_CODE (XEXP (base_rtx, 0)) == REG
4917       && GET_CODE (XEXP (base_rtx, 1)) == CONST_INT)
4918     {
4919       offset_adjust += INTVAL (XEXP (base_rtx, 1));
4920       base_rtx = copy_all_rtx (XEXP (base_rtx, 0));
4921     }
4922
4923   else if (base_rtx && GET_CODE (base_rtx) == CONST_INT)
4924     {
4925       offset_adjust += INTVAL (base_rtx);
4926       base_rtx = NULL;
4927     }
4928
4929   if (index_rtx && GET_CODE (index_rtx) == PLUS
4930       && GET_CODE (XEXP (index_rtx, 0)) == REG
4931       && GET_CODE (XEXP (index_rtx, 1)) == CONST_INT)
4932     {
4933       offset_adjust += INTVAL (XEXP (index_rtx, 1)) * scale;
4934       index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
4935     }
4936
4937   if (index_rtx)
4938     {
4939       if (! LEGITIMATE_INDEX_P (index_rtx)
4940           && ! (index_rtx == stack_pointer_rtx && scale == 1
4941                 && base_rtx == NULL))
4942         {
4943           obfree (storage);
4944           return;
4945         }
4946     }
4947
4948   if (base_rtx)
4949     {
4950       if (! LEGITIMATE_INDEX_P (base_rtx) && GET_CODE (base_rtx) != REG)
4951         {
4952           obfree (storage);
4953           return;
4954         }
4955     }
4956
4957   if (offset_adjust != 0)
4958     {
4959       if (offset_rtx != 0 && CONSTANT_P (offset_rtx))
4960         offset_rtx = plus_constant (offset_rtx, offset_adjust);
4961       else
4962         offset_rtx = const0_rtx;
4963
4964       if (index_rtx)
4965         {
4966           if (base_rtx)
4967             {
4968               if (scale != 1)
4969                 {
4970                   ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx),
4971                                      gen_rtx (MULT, GET_MODE (index_rtx),
4972                                               index_rtx, scale_rtx),
4973                                      base_rtx);
4974
4975                   if (GET_CODE (offset_rtx) != CONST_INT
4976                       || INTVAL (offset_rtx) != 0)
4977                     ret_rtx = gen_rtx (PLUS, GET_MODE (ret_rtx),
4978                                        ret_rtx, offset_rtx);
4979                 }
4980               else
4981                 {
4982                   ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx),
4983                                      index_rtx, base_rtx);
4984
4985                   if (GET_CODE (offset_rtx) != CONST_INT
4986                       || INTVAL (offset_rtx) != 0)
4987                     ret_rtx = gen_rtx (PLUS, GET_MODE (ret_rtx),
4988                                        ret_rtx, offset_rtx);
4989                 }
4990             }
4991           else
4992             {
4993               if (scale != 1)
4994                 {
4995                   ret_rtx = gen_rtx (MULT, GET_MODE (index_rtx),
4996                                      index_rtx, scale_rtx);
4997
4998                   if (GET_CODE (offset_rtx) != CONST_INT
4999                       || INTVAL (offset_rtx) != 0)
5000                     ret_rtx = gen_rtx (PLUS, GET_MODE (ret_rtx),
5001                                        ret_rtx, offset_rtx);
5002                 }
5003               else
5004                 {
5005                   if (GET_CODE (offset_rtx) == CONST_INT
5006                       && INTVAL (offset_rtx) == 0)
5007                     ret_rtx = index_rtx;
5008                   else
5009                     ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx),
5010                                        index_rtx, offset_rtx);
5011                 }
5012             }
5013         }
5014       else
5015         {
5016           if (base_rtx)
5017             {
5018               if (GET_CODE (offset_rtx) == CONST_INT
5019                   && INTVAL (offset_rtx) == 0)
5020                 ret_rtx = base_rtx;
5021               else
5022                 ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx), base_rtx,
5023                                    offset_rtx);
5024             }
5025           else if (was_only_offset)
5026             ret_rtx = offset_rtx;
5027           else
5028             {
5029               obfree (storage);
5030               return;
5031             }
5032         }
5033
5034       XEXP (mem_rtx, 0) = ret_rtx;
5035       RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
5036       return;
5037     }
5038   else
5039     {
5040       obfree (storage);
5041       return;
5042     }
5043 }
5044 #endif /* NOTYET */
5045 \f
5046 /* Return 1 if the first insn to set cc before INSN also sets the register
5047    REG_RTX; otherwise return 0. */
5048 int
5049 last_to_set_cc (reg_rtx, insn)
5050      rtx reg_rtx, insn;
5051 {
5052   rtx prev_insn = PREV_INSN (insn);
5053
5054   while (prev_insn)
5055     {
5056       if (GET_CODE (prev_insn) == NOTE)
5057         ;
5058
5059       else if (GET_CODE (prev_insn) == INSN)
5060         {
5061           if (GET_CODE (PATTERN (prev_insn)) != SET)
5062             return (0);
5063
5064           if (rtx_equal_p (SET_DEST (PATTERN (prev_insn)), reg_rtx))
5065             {
5066               if (sets_condition_code (SET_SRC (PATTERN (prev_insn))))
5067                 return (1);
5068
5069               return (0);
5070             }
5071
5072           else if (! doesnt_set_condition_code (SET_SRC (PATTERN (prev_insn))))
5073             return (0);
5074         }
5075
5076       else
5077         return (0);
5078
5079       prev_insn = PREV_INSN (prev_insn);
5080     }
5081
5082   return (0);
5083 }
5084 \f
5085 int
5086 doesnt_set_condition_code (pat)
5087      rtx pat;
5088 {
5089   switch (GET_CODE (pat))
5090     {
5091     case MEM:
5092     case REG:
5093       return 1;
5094
5095     default:
5096       return 0;
5097
5098     }
5099 }
5100 \f
5101 int
5102 sets_condition_code (pat)
5103      rtx pat;
5104 {
5105   switch (GET_CODE (pat))
5106     {
5107     case PLUS:
5108     case MINUS:
5109     case AND:
5110     case IOR:
5111     case XOR:
5112     case NOT:
5113     case NEG:
5114     case MULT:
5115     case DIV:
5116     case MOD:
5117     case UDIV:
5118     case UMOD:
5119       return 1;
5120
5121     default:
5122       return (0);
5123     }
5124 }
5125 \f
5126 int
5127 str_immediate_operand (op, mode)
5128      register rtx op;
5129      enum machine_mode mode ATTRIBUTE_UNUSED;
5130 {
5131   if (GET_CODE (op) == CONST_INT && INTVAL (op) <= 32 && INTVAL (op) >= 0)
5132     return 1;
5133
5134   return 0;
5135 }
5136 \f
5137 int
5138 is_fp_insn (insn)
5139      rtx insn;
5140 {
5141   if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
5142       && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
5143           || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
5144           || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode))
5145     return 1;
5146
5147   return 0;
5148 }
5149
5150 /* Return 1 if the mode of the SET_DEST of insn is floating point
5151    and it is not an fld or a move from memory to memory.
5152    Otherwise return 0 */
5153
5154 int
5155 is_fp_dest (insn)
5156      rtx insn;
5157 {
5158   if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
5159       && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
5160           || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
5161           || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
5162       && GET_CODE (SET_DEST (PATTERN (insn))) == REG
5163       && REGNO (SET_DEST (PATTERN (insn))) >= FIRST_FLOAT_REG
5164       && GET_CODE (SET_SRC (PATTERN (insn))) != MEM)
5165     return 1;
5166
5167   return 0;
5168 }
5169
5170 /* Return 1 if the mode of the SET_DEST of INSN is floating point and is
5171    memory and the source is a register.  */
5172
5173 int
5174 is_fp_store (insn)
5175      rtx insn;
5176 {
5177   if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
5178       && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
5179           || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
5180           || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
5181       && GET_CODE (SET_DEST (PATTERN (insn))) == MEM
5182       && GET_CODE (SET_SRC (PATTERN (insn))) == REG)
5183     return 1;
5184
5185   return 0;
5186 }
5187 \f
5188 /* Return 1 if DEP_INSN sets a register which INSN uses as a base
5189    or index to reference memory.
5190    otherwise return 0 */
5191
5192 int
5193 agi_dependent (insn, dep_insn)
5194      rtx insn, dep_insn;
5195 {
5196   if (GET_CODE (dep_insn) == INSN
5197       && GET_CODE (PATTERN (dep_insn)) == SET
5198       && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG)
5199     return reg_mentioned_in_mem (SET_DEST (PATTERN (dep_insn)), insn);
5200
5201   if (GET_CODE (dep_insn) == INSN && GET_CODE (PATTERN (dep_insn)) == SET
5202       && GET_CODE (SET_DEST (PATTERN (dep_insn))) == MEM
5203       && push_operand (SET_DEST (PATTERN (dep_insn)),
5204                        GET_MODE (SET_DEST (PATTERN (dep_insn)))))
5205     return reg_mentioned_in_mem (stack_pointer_rtx, insn);
5206
5207   return 0;
5208 }
5209 \f
5210 /* Return 1 if reg is used in rtl as a base or index for a memory ref
5211    otherwise return 0. */
5212
5213 int
5214 reg_mentioned_in_mem (reg, rtl)
5215      rtx reg, rtl;
5216 {
5217   register char *fmt;
5218   register int i, j;
5219   register enum rtx_code code;
5220
5221   if (rtl == NULL)
5222     return 0;
5223
5224   code = GET_CODE (rtl);
5225
5226   switch (code)
5227     {
5228     case HIGH:
5229     case CONST_INT:
5230     case CONST:
5231     case CONST_DOUBLE:
5232     case SYMBOL_REF:
5233     case LABEL_REF:
5234     case PC:
5235     case CC0:
5236     case SUBREG:
5237       return 0;
5238     default:
5239       break;
5240     }
5241
5242   if (code == MEM && reg_mentioned_p (reg, rtl))
5243     return 1;
5244
5245   fmt = GET_RTX_FORMAT (code);
5246   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
5247     {
5248       if (fmt[i] == 'E')
5249         {
5250           for (j = XVECLEN (rtl, i) - 1; j >= 0; j--)
5251             if (reg_mentioned_in_mem (reg, XVECEXP (rtl, i, j)))
5252               return 1;
5253         }
5254
5255       else if (fmt[i] == 'e' && reg_mentioned_in_mem (reg, XEXP (rtl, i)))
5256         return 1;
5257     }
5258
5259   return 0;
5260 }
5261 \f
5262 /* Output the appropriate insns for doing strlen if not just doing repnz; scasb
5263
5264    operands[0] = result, initialized with the startaddress
5265    operands[1] = alignment of the address.
5266    operands[2] = scratch register, initialized with the startaddress when
5267                  not aligned, otherwise undefined
5268
5269    This is just the body. It needs the initialisations mentioned above and
5270    some address computing at the end.  These things are done in i386.md.  */
5271
5272 char *
5273 output_strlen_unroll (operands)
5274      rtx operands[];
5275 {
5276   rtx xops[18];
5277
5278   xops[0] = operands[0];                /* Result */
5279   /*        operands[1];                 * Alignment */
5280   xops[1] = operands[2];                /* Scratch */
5281   xops[2] = GEN_INT (0);
5282   xops[3] = GEN_INT (2);
5283   xops[4] = GEN_INT (3);
5284   xops[5] = GEN_INT (4);
5285   /* xops[6] = gen_label_rtx ();         * label when aligned to 3-byte */
5286   /* xops[7] = gen_label_rtx ();         * label when aligned to 2-byte */
5287   xops[8] = gen_label_rtx ();           /* label of main loop */
5288
5289   if (TARGET_USE_Q_REG && QI_REG_P (xops[1]))
5290     xops[9] = gen_label_rtx ();         /* pentium optimisation */
5291
5292   xops[10] = gen_label_rtx ();          /* end label 2 */
5293   xops[11] = gen_label_rtx ();          /* end label 1 */
5294   xops[12] = gen_label_rtx ();          /* end label */
5295   /* xops[13]                            * Temporary used */
5296   xops[14] = GEN_INT (0xff);
5297   xops[15] = GEN_INT (0xff00);
5298   xops[16] = GEN_INT (0xff0000);
5299   xops[17] = GEN_INT (0xff000000);
5300
5301   /* Loop to check 1..3 bytes for null to get an aligned pointer.  */
5302
5303   /* Is there a known alignment and is it less than 4?  */
5304   if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) < 4)
5305     {
5306       /* Is there a known alignment and is it not 2? */
5307       if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
5308         {
5309           xops[6] = gen_label_rtx (); /* Label when aligned to 3-byte */
5310           xops[7] = gen_label_rtx (); /* Label when aligned to 2-byte */
5311
5312           /* Leave just the 3 lower bits.
5313              If this is a q-register, then the high part is used later
5314              therefore use andl rather than andb. */
5315           output_asm_insn (AS2 (and%L1,%4,%1), xops);
5316
5317           /* Is aligned to 4-byte address when zero */
5318           output_asm_insn (AS1 (je,%l8), xops);
5319
5320           /* Side-effect even Parity when %eax == 3 */
5321           output_asm_insn (AS1 (jp,%6), xops);
5322
5323           /* Is it aligned to 2 bytes ? */
5324           if (QI_REG_P (xops[1]))
5325             output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
5326           else
5327             output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
5328
5329           output_asm_insn (AS1 (je,%7), xops);
5330         }
5331       else
5332         {
5333           /* Since the alignment is 2, we have to check 2 or 0 bytes;
5334              check if is aligned to 4 - byte.  */
5335           output_asm_insn (AS2 (and%L1,%3,%1), xops);
5336
5337           /* Is aligned to 4-byte address when zero */
5338           output_asm_insn (AS1 (je,%l8), xops);
5339         }
5340
5341       xops[13] = gen_rtx_MEM (QImode, xops[0]);
5342
5343       /* Now compare the bytes; compare with the high part of a q-reg
5344          gives shorter code. */
5345       if (QI_REG_P (xops[1]))
5346         {
5347           /* Compare the first n unaligned byte on a byte per byte basis. */
5348           output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
5349
5350           /* When zero we reached the end. */
5351           output_asm_insn (AS1 (je,%l12), xops);
5352
5353           /* Increment the address. */
5354           output_asm_insn (AS1 (inc%L0,%0), xops);
5355
5356           /* Not needed with an alignment of 2 */
5357           if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
5358             {
5359               ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5360                                          CODE_LABEL_NUMBER (xops[7]));
5361               output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
5362               output_asm_insn (AS1 (je,%l12), xops);
5363               output_asm_insn (AS1 (inc%L0,%0), xops);
5364
5365               ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5366                                          CODE_LABEL_NUMBER (xops[6]));
5367             }
5368
5369           output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
5370         }
5371       else
5372         {
5373           output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
5374           output_asm_insn (AS1 (je,%l12), xops);
5375           output_asm_insn (AS1 (inc%L0,%0), xops);
5376
5377           ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5378                                      CODE_LABEL_NUMBER (xops[7]));
5379           output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
5380           output_asm_insn (AS1 (je,%l12), xops);
5381           output_asm_insn (AS1 (inc%L0,%0), xops);
5382
5383           ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5384                                      CODE_LABEL_NUMBER (xops[6]));
5385           output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
5386         }
5387
5388       output_asm_insn (AS1 (je,%l12), xops);
5389       output_asm_insn (AS1 (inc%L0,%0), xops);
5390     }
5391
5392     /* Generate loop to check 4 bytes at a time.  It is not a good idea to
5393        align this loop.  It gives only huge programs, but does not help to
5394        speed up.  */
5395   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[8]));
5396
5397   xops[13] = gen_rtx_MEM (SImode, xops[0]);
5398   output_asm_insn (AS2 (mov%L1,%13,%1), xops);
5399
5400   if (QI_REG_P (xops[1]))
5401     {
5402       /* On i586 it is faster to combine the hi- and lo- part as
5403          a kind of lookahead.  If anding both yields zero, then one
5404          of both *could* be zero, otherwise none of both is zero;
5405          this saves one instruction, on i486 this is slower
5406          tested with P-90, i486DX2-66, AMD486DX2-66  */
5407       if (TARGET_PENTIUM)
5408         {
5409           output_asm_insn (AS2 (test%B1,%h1,%b1), xops);
5410           output_asm_insn (AS1 (jne,%l9), xops);
5411         }
5412
5413       /* Check first byte. */
5414       output_asm_insn (AS2 (test%B1,%b1,%b1), xops);
5415       output_asm_insn (AS1 (je,%l12), xops);
5416
5417       /* Check second byte. */
5418       output_asm_insn (AS2 (test%B1,%h1,%h1), xops);
5419       output_asm_insn (AS1 (je,%l11), xops);
5420
5421       if (TARGET_PENTIUM)
5422         ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5423                                    CODE_LABEL_NUMBER (xops[9]));
5424     }
5425
5426   else
5427     {
5428       /* Check first byte. */
5429       output_asm_insn (AS2 (test%L1,%14,%1), xops);
5430       output_asm_insn (AS1 (je,%l12), xops);
5431
5432       /* Check second byte. */
5433       output_asm_insn (AS2 (test%L1,%15,%1), xops);
5434       output_asm_insn (AS1 (je,%l11), xops);
5435     }
5436
5437   /* Check third byte. */
5438   output_asm_insn (AS2 (test%L1,%16,%1), xops);
5439   output_asm_insn (AS1 (je,%l10), xops);
5440
5441   /* Check fourth byte and increment address. */
5442   output_asm_insn (AS2 (add%L0,%5,%0), xops);
5443   output_asm_insn (AS2 (test%L1,%17,%1), xops);
5444   output_asm_insn (AS1 (jne,%l8), xops);
5445
5446   /* Now generate fixups when the compare stops within a 4-byte word. */
5447   output_asm_insn (AS2 (sub%L0,%4,%0), xops);
5448
5449   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[10]));
5450   output_asm_insn (AS1 (inc%L0,%0), xops);
5451
5452   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[11]));
5453   output_asm_insn (AS1 (inc%L0,%0), xops);
5454
5455   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[12]));
5456
5457   return "";
5458 }
5459
5460 char *
5461 output_fp_conditional_move (which_alternative, operands)
5462      int which_alternative;
5463      rtx operands[];
5464 {
5465   enum rtx_code code = GET_CODE (operands[1]);
5466
5467   /* This should never happen.  */
5468   if (!(cc_prev_status.flags & CC_IN_80387)
5469       && (code == GT || code == LE || code == GE || code == LT))
5470     abort ();
5471
5472   switch (which_alternative)
5473     {
5474     case 0:
5475       /* r <- cond ? arg : r */
5476       output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
5477       break;
5478
5479     case 1:
5480       /* r <- cond ? r : arg */
5481       output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
5482       break;
5483
5484     default:
5485       abort ();
5486     }
5487
5488   return "";
5489 }
5490
5491 char *
5492 output_int_conditional_move (which_alternative, operands)
5493      int which_alternative;
5494      rtx operands[];
5495 {
5496   enum rtx_code code = GET_CODE (operands[1]);
5497
5498   /* This is very tricky. We have to do it right. For a code segement
5499      like:
5500
5501         int foo, bar;
5502         ....
5503         foo = foo - x;
5504         if (foo >= 0)
5505           bar = y;
5506
5507      final_scan_insn () may delete the insn which sets CC. We have to
5508      tell final_scan_insn () if it should be reinserted. When CODE is
5509      GT or LE, we have to check the CC_NO_OVERFLOW bit and return
5510      NULL_PTR to tell final to reinsert the test insn because the
5511      conditional move cannot be handled properly without it. */
5512   if ((code == GT || code == LE)
5513       && (cc_prev_status.flags & CC_NO_OVERFLOW))
5514     return NULL_PTR;
5515
5516   switch (which_alternative)
5517     {
5518     case 0:
5519       /* r <- cond ? arg : r */
5520       output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
5521       break;
5522
5523     case 1:
5524       /* r <- cond ? r : arg */
5525       output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
5526       break;
5527
5528     default:
5529       abort ();
5530     }
5531
5532   return "";
5533 }
5534
5535 int
5536 x86_adjust_cost (insn, link, dep_insn, cost)
5537      rtx insn, link, dep_insn;
5538      int cost;
5539 {
5540   rtx next_inst;
5541
5542   if (GET_CODE (dep_insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN)
5543     return 0;
5544
5545   if (GET_CODE (dep_insn) == INSN
5546       && GET_CODE (PATTERN (dep_insn)) == SET
5547       && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG
5548       && GET_CODE (insn) == INSN
5549       && GET_CODE (PATTERN (insn)) == SET
5550       && !reg_overlap_mentioned_p (SET_DEST (PATTERN (dep_insn)),
5551                                    SET_SRC (PATTERN (insn))))
5552     return 0;   /* ??? */
5553
5554
5555   switch (ix86_cpu)
5556     {
5557     case PROCESSOR_PENTIUM:
5558       if (cost != 0 && is_fp_insn (insn) && is_fp_insn (dep_insn)
5559           && !is_fp_dest (dep_insn))
5560         return 0;
5561
5562       if (agi_dependent (insn, dep_insn))
5563         return 3;
5564
5565       if (GET_CODE (insn) == INSN
5566           && GET_CODE (PATTERN (insn)) == SET
5567           && SET_DEST (PATTERN (insn)) == cc0_rtx
5568           && (next_inst = next_nonnote_insn (insn))
5569           && GET_CODE (next_inst) == JUMP_INSN)
5570         /* compare probably paired with jump */
5571         return 0;
5572       break;
5573
5574     case PROCESSOR_K6:
5575     default:
5576       if (!is_fp_dest (dep_insn))
5577         {
5578           if(!agi_dependent (insn, dep_insn))
5579             return 0;
5580           if (TARGET_486)
5581             return 2;
5582         }
5583       else
5584         if (is_fp_store (insn) && is_fp_insn (dep_insn)
5585             && NEXT_INSN (insn) && NEXT_INSN (NEXT_INSN (insn))
5586             && NEXT_INSN (NEXT_INSN (NEXT_INSN (insn)))
5587             && (GET_CODE (NEXT_INSN (insn)) == INSN)
5588             && (GET_CODE (NEXT_INSN (NEXT_INSN (insn))) == JUMP_INSN)
5589             && (GET_CODE (NEXT_INSN (NEXT_INSN (NEXT_INSN (insn)))) == NOTE)
5590             && (NOTE_LINE_NUMBER (NEXT_INSN (NEXT_INSN (NEXT_INSN (insn))))
5591                 == NOTE_INSN_LOOP_END))
5592           return 3;
5593       break;
5594     }
5595
5596   return cost;
5597 }