OSDN Git Service

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