1 /* Subroutines for insn-output.c for Intel X86.
2 Copyright (C) 1988, 1992, 1994, 1995, 1996 Free Software Foundation, Inc.
4 This file is part of GNU CC.
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)
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.
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. */
27 #include "hard-reg-set.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "insn-flags.h"
33 #include "insn-attr.h"
38 #ifdef EXTRA_CONSTRAINT
39 /* If EXTRA_CONSTRAINT is defined, then the 'S'
40 constraint in REG_CLASS_FROM_LETTER will no longer work, and various
41 asm statements that need 'S' for class SIREG will break. */
42 error EXTRA_CONSTRAINT conflicts with S constraint letter
43 /* The previous line used to be #error, but some compilers barf
44 even if the conditional was untrue. */
47 enum reg_mem /* Type of an operand for ix86_{binary,unary}_operator_ok */
54 /* Processor costs (relative to an add) */
55 struct processor_costs i386_cost = { /* 386 specific costs */
56 1, /* cost of an add instruction (2 cycles) */
57 1, /* cost of a lea instruction */
58 3, /* variable shift costs */
59 2, /* constant shift costs */
60 6, /* cost of starting a multiply */
61 1, /* cost of multiply per each bit set */
62 23 /* cost of a divide/mod */
65 struct processor_costs i486_cost = { /* 486 specific costs */
66 1, /* cost of an add instruction */
67 1, /* cost of a lea instruction */
68 3, /* variable shift costs */
69 2, /* constant shift costs */
70 12, /* cost of starting a multiply */
71 1, /* cost of multiply per each bit set */
72 40 /* cost of a divide/mod */
75 struct processor_costs pentium_cost = { /* 486 specific costs */
76 1, /* cost of an add instruction */
77 1, /* cost of a lea instruction */
78 3, /* variable shift costs */
79 2, /* constant shift costs */
80 12, /* cost of starting a multiply */
81 1, /* cost of multiply per each bit set */
82 40 /* cost of a divide/mod */
85 struct processor_costs *ix86_cost = &pentium_cost;
87 #define AT_BP(mode) (gen_rtx (MEM, (mode), frame_pointer_rtx))
89 extern FILE *asm_out_file;
90 extern char *strcat ();
92 char *singlemove_string ();
93 char *output_move_const_single ();
94 char *output_fp_cc0_set ();
96 char *hi_reg_name[] = HI_REGISTER_NAMES;
97 char *qi_reg_name[] = QI_REGISTER_NAMES;
98 char *qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES;
100 /* Array of the smallest class containing reg number REGNO, indexed by
101 REGNO. Used by REGNO_REG_CLASS in i386.h. */
103 enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
106 AREG, DREG, CREG, BREG,
108 SIREG, DIREG, INDEX_REGS, GENERAL_REGS,
110 FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
111 FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,
116 /* Test and compare insns in i386.md store the information needed to
117 generate branch and scc insns here. */
119 struct rtx_def *i386_compare_op0 = NULL_RTX;
120 struct rtx_def *i386_compare_op1 = NULL_RTX;
121 struct rtx_def *(*i386_compare_gen)(), *(*i386_compare_gen_eq)();
123 /* which cpu are we scheduling for */
124 enum processor_type ix86_cpu;
126 /* which instruction set architecture to use. */
129 /* Strings to hold which cpu and instruction set architecture to use. */
130 char *ix86_cpu_string; /* for -mcpu=<xxx> */
131 char *ix86_isa_string; /* for -misa=<xxx> */
133 /* Register allocation order */
134 char *i386_reg_alloc_order;
135 static char regs_allocated[FIRST_PSEUDO_REGISTER];
137 /* # of registers to use to pass arguments. */
138 char *i386_regparm_string; /* # registers to use to pass args */
139 int i386_regparm; /* i386_regparm_string as a number */
141 /* Alignment to use for loops and jumps */
142 char *i386_align_loops_string; /* power of two alignment for loops */
143 char *i386_align_jumps_string; /* power of two alignment for non-loop jumps */
144 char *i386_align_funcs_string; /* power of two alignment for functions */
146 int i386_align_loops; /* power of two alignment for loops */
147 int i386_align_jumps; /* power of two alignment for non-loop jumps */
148 int i386_align_funcs; /* power of two alignment for functions */
151 /* Sometimes certain combinations of command options do not make
152 sense on a particular target machine. You can define a macro
153 `OVERRIDE_OPTIONS' to take account of this. This macro, if
154 defined, is executed once just after all the command options have
157 Don't use this macro to turn on various extra optimizations for
158 `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
169 char *name; /* Canonical processor name. */
170 enum processor_type processor; /* Processor type enum value. */
171 struct processor_costs *cost; /* Processor costs */
172 int target_enable; /* Target flags to enable. */
173 int target_disable; /* Target flags to disable. */
174 } processor_target_table[]
175 = {{PROCESSOR_COMMON_STRING, PROCESSOR_COMMON, &i486_cost, 0, 0},
176 {PROCESSOR_I386_STRING, PROCESSOR_I386, &i386_cost, 0, 0},
177 {PROCESSOR_I486_STRING, PROCESSOR_I486, &i486_cost, 0, 0},
178 {PROCESSOR_I586_STRING, PROCESSOR_PENTIUM, &pentium_cost, 0, 0},
179 {PROCESSOR_PENTIUM_STRING, PROCESSOR_PENTIUM, &pentium_cost, 0, 0},
180 {PROCESSOR_I686_STRING, PROCESSOR_PENTIUMPRO, &pentium_cost, 0, 0},
181 {PROCESSOR_PENTIUMPRO_STRING, PROCESSOR_PENTIUMPRO, &pentium_cost, 0, 0}};
183 int ptt_size = sizeof (processor_target_table) / sizeof (struct ptt);
185 #ifdef SUBTARGET_OVERRIDE_OPTIONS
186 SUBTARGET_OVERRIDE_OPTIONS;
189 /* Validate registers in register allocation order */
190 if (i386_reg_alloc_order)
192 for (i = 0; (ch = i386_reg_alloc_order[i]) != '\0'; i++)
196 case 'a': regno = 0; break;
197 case 'd': regno = 1; break;
198 case 'c': regno = 2; break;
199 case 'b': regno = 3; break;
200 case 'S': regno = 4; break;
201 case 'D': regno = 5; break;
202 case 'B': regno = 6; break;
204 default: fatal ("Register '%c' is unknown", ch);
207 if (regs_allocated[regno])
208 fatal ("Register '%c' was already specified in the allocation order", ch);
210 regs_allocated[regno] = 1;
214 /* Get the architectural level. */
215 if (ix86_isa_string == (char *)0)
216 ix86_isa_string = PROCESSOR_DEFAULT_STRING;
218 for (i = 0; i < ptt_size; i++)
219 if (! strcmp (ix86_isa_string, processor_target_table[i].name))
221 ix86_isa = processor_target_table[i].processor;
227 error ("bad value (%s) for -misa= switch", ix86_isa_string);
228 ix86_isa_string = PROCESSOR_DEFAULT_STRING;
229 ix86_isa = PROCESSOR_DEFAULT;
232 if (ix86_cpu_string == (char *)0)
233 ix86_cpu_string = PROCESSOR_DEFAULT_STRING;
235 for (j = 0; j < ptt_size; j++)
236 if (! strcmp (ix86_cpu_string, processor_target_table[j].name))
238 ix86_cpu = processor_target_table[j].processor;
239 if (i > j && (int)ix86_isa >= (int)PROCESSOR_PENTIUMPRO)
240 error ("-mcpu=%s does not support -march=%s", ix86_cpu_string, ix86_isa_string);
242 target_flags |= processor_target_table[j].target_enable;
243 target_flags &= ~processor_target_table[j].target_disable;
249 error ("bad value (%s) for -mcpu= switch", ix86_cpu_string);
250 ix86_cpu_string = PROCESSOR_DEFAULT_STRING;
251 ix86_cpu = PROCESSOR_DEFAULT;
254 /* Validate -mregparm= value */
255 if (i386_regparm_string)
257 i386_regparm = atoi (i386_regparm_string);
258 if (i386_regparm < 0 || i386_regparm > REGPARM_MAX)
259 fatal ("-mregparm=%d is not between 0 and %d", i386_regparm, REGPARM_MAX);
262 def_align = (TARGET_386) ? 2 : 4;
264 /* Validate -malign-loops= value, or provide default */
265 if (i386_align_loops_string)
267 i386_align_loops = atoi (i386_align_loops_string);
268 if (i386_align_loops < 0 || i386_align_loops > MAX_CODE_ALIGN)
269 fatal ("-malign-loops=%d is not between 0 and %d",
270 i386_align_loops, MAX_CODE_ALIGN);
273 i386_align_loops = 2;
275 /* Validate -malign-jumps= value, or provide default */
276 if (i386_align_jumps_string)
278 i386_align_jumps = atoi (i386_align_jumps_string);
279 if (i386_align_jumps < 0 || i386_align_jumps > MAX_CODE_ALIGN)
280 fatal ("-malign-jumps=%d is not between 0 and %d",
281 i386_align_jumps, MAX_CODE_ALIGN);
284 i386_align_jumps = def_align;
286 /* Validate -malign-functions= value, or provide default */
287 if (i386_align_funcs_string)
289 i386_align_funcs = atoi (i386_align_funcs_string);
290 if (i386_align_funcs < 0 || i386_align_funcs > MAX_CODE_ALIGN)
291 fatal ("-malign-functions=%d is not between 0 and %d",
292 i386_align_funcs, MAX_CODE_ALIGN);
295 i386_align_funcs = def_align;
298 /* A C statement (sans semicolon) to choose the order in which to
299 allocate hard registers for pseudo-registers local to a basic
302 Store the desired register order in the array `reg_alloc_order'.
303 Element 0 should be the register to allocate first; element 1, the
304 next register; and so on.
306 The macro body should not assume anything about the contents of
307 `reg_alloc_order' before execution of the macro.
309 On most machines, it is not necessary to define this macro. */
312 order_regs_for_local_alloc ()
314 int i, ch, order, regno;
316 /* User specified the register allocation order */
317 if (i386_reg_alloc_order)
319 for (i = order = 0; (ch = i386_reg_alloc_order[i]) != '\0'; i++)
323 case 'a': regno = 0; break;
324 case 'd': regno = 1; break;
325 case 'c': regno = 2; break;
326 case 'b': regno = 3; break;
327 case 'S': regno = 4; break;
328 case 'D': regno = 5; break;
329 case 'B': regno = 6; break;
332 reg_alloc_order[order++] = regno;
335 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
337 if (!regs_allocated[i])
338 reg_alloc_order[order++] = i;
342 /* If users did not specify a register allocation order, use natural order */
345 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
346 reg_alloc_order[i] = i;
352 optimization_options (level)
355 /* For -O2, and beyond, turn off -fschedule-insns by default. It tends to
356 make the problem with not enough registers even worse */
357 #ifdef INSN_SCHEDULING
359 flag_schedule_insns = 0;
363 /* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
364 attribute for DECL. The attributes in ATTRIBUTES have previously been
368 i386_valid_decl_attribute_p (decl, attributes, identifier, args)
377 /* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
378 attribute for TYPE. The attributes in ATTRIBUTES have previously been
382 i386_valid_type_attribute_p (type, attributes, identifier, args)
388 if (TREE_CODE (type) != FUNCTION_TYPE
389 && TREE_CODE (type) != FIELD_DECL
390 && TREE_CODE (type) != TYPE_DECL)
393 /* Stdcall attribute says callee is responsible for popping arguments
394 if they are not variable. */
395 if (is_attribute_p ("stdcall", identifier))
396 return (args == NULL_TREE);
398 /* Cdecl attribute says the callee is a normal C declaration */
399 if (is_attribute_p ("cdecl", identifier))
400 return (args == NULL_TREE);
402 /* Regparm attribute specifies how many integer arguments are to be
403 passed in registers */
404 if (is_attribute_p ("regparm", identifier))
408 if (!args || TREE_CODE (args) != TREE_LIST
409 || TREE_CHAIN (args) != NULL_TREE
410 || TREE_VALUE (args) == NULL_TREE)
413 cst = TREE_VALUE (args);
414 if (TREE_CODE (cst) != INTEGER_CST)
417 if (TREE_INT_CST_HIGH (cst) != 0
418 || TREE_INT_CST_LOW (cst) < 0
419 || TREE_INT_CST_LOW (cst) > REGPARM_MAX)
428 /* Return 0 if the attributes for two types are incompatible, 1 if they
429 are compatible, and 2 if they are nearly compatible (which causes a
430 warning to be generated). */
433 i386_comp_type_attributes (type1, type2)
441 /* Value is the number of bytes of arguments automatically
442 popped when returning from a subroutine call.
443 FUNDECL is the declaration node of the function (as a tree),
444 FUNTYPE is the data type of the function (as a tree),
445 or for a library call it is an identifier node for the subroutine name.
446 SIZE is the number of bytes of arguments passed on the stack.
448 On the 80386, the RTD insn may be used to pop them if the number
449 of args is fixed, but if the number is variable then the caller
450 must pop them all. RTD can't be used for library calls now
451 because the library is compiled with the Unix compiler.
452 Use of RTD is a selectable option, since it is incompatible with
453 standard Unix calling sequences. If the option is not selected,
454 the caller must always pop the args.
456 The attribute stdcall is equivalent to RTD on a per module basis. */
459 i386_return_pops_args (fundecl, funtype, size)
464 int rtd = TARGET_RTD;
466 if (TREE_CODE (funtype) == IDENTIFIER_NODE)
469 /* Cdecl functions override -mrtd, and never pop the stack */
470 if (lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype)))
473 /* Stdcall functions will pop the stack if not variable args */
474 if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype)))
479 if (TYPE_ARG_TYPES (funtype) == NULL_TREE
480 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (funtype))) == void_type_node))
483 if (aggregate_value_p (TREE_TYPE (funtype)))
484 return GET_MODE_SIZE (Pmode);
491 /* Argument support functions. */
493 /* Initialize a variable CUM of type CUMULATIVE_ARGS
494 for a call to a function whose data type is FNTYPE.
495 For a library call, FNTYPE is 0. */
498 init_cumulative_args (cum, fntype, libname)
499 CUMULATIVE_ARGS *cum; /* argument info to initialize */
500 tree fntype; /* tree ptr for function decl */
501 rtx libname; /* SYMBOL_REF of library name or 0 */
503 static CUMULATIVE_ARGS zero_cum;
504 tree param, next_param;
506 if (TARGET_DEBUG_ARG)
508 fprintf (stderr, "\ninit_cumulative_args (");
511 tree ret_type = TREE_TYPE (fntype);
512 fprintf (stderr, "fntype code = %s, ret code = %s",
513 tree_code_name[ (int)TREE_CODE (fntype) ],
514 tree_code_name[ (int)TREE_CODE (ret_type) ]);
517 fprintf (stderr, "no fntype");
520 fprintf (stderr, ", libname = %s", XSTR (libname, 0));
525 /* Set up the number of registers to use for passing arguments. */
526 cum->nregs = i386_regparm;
529 tree attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (fntype));
531 cum->nregs = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
534 /* Determine if this function has variable arguments. This is
535 indicated by the last argument being 'void_type_mode' if there
536 are no variable arguments. If there are variable arguments, then
537 we won't pass anything in registers */
541 for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
545 next_param = TREE_CHAIN (param);
546 if (next_param == (tree)0 && TREE_VALUE (param) != void_type_node)
551 if (TARGET_DEBUG_ARG)
552 fprintf (stderr, ", nregs=%d )\n", cum->nregs);
557 /* Update the data in CUM to advance over an argument
558 of mode MODE and data type TYPE.
559 (TYPE is null for libcalls where that information may not be available.) */
562 function_arg_advance (cum, mode, type, named)
563 CUMULATIVE_ARGS *cum; /* current arg information */
564 enum machine_mode mode; /* current arg mode */
565 tree type; /* type of the argument or 0 if lib support */
566 int named; /* whether or not the argument was named */
568 int bytes = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
569 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
571 if (TARGET_DEBUG_ARG)
573 "function_adv( size=%d, words=%2d, nregs=%d, mode=%4s, named=%d )\n\n",
574 words, cum->words, cum->nregs, GET_MODE_NAME (mode), named);
589 /* Define where to put the arguments to a function.
590 Value is zero to push the argument on the stack,
591 or a hard register in which to store the argument.
593 MODE is the argument's machine mode.
594 TYPE is the data type of the argument (as a tree).
595 This is null for libcalls where that information may
597 CUM is a variable of type CUMULATIVE_ARGS which gives info about
598 the preceding args and about the function being called.
599 NAMED is nonzero if this argument is a named parameter
600 (otherwise it is an extra parameter matching an ellipsis). */
603 function_arg (cum, mode, type, named)
604 CUMULATIVE_ARGS *cum; /* current arg information */
605 enum machine_mode mode; /* current arg mode */
606 tree type; /* type of the argument or 0 if lib support */
607 int named; /* != 0 for normal args, == 0 for ... args */
610 int bytes = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
611 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
615 default: /* for now, pass fp/complex values on the stack */
623 if (words <= cum->nregs)
624 ret = gen_rtx (REG, mode, cum->regno);
628 if (TARGET_DEBUG_ARG)
631 "function_arg( size=%d, words=%2d, nregs=%d, mode=%4s, named=%d",
632 words, cum->words, cum->nregs, GET_MODE_NAME (mode), named);
635 fprintf (stderr, ", reg=%%e%s", reg_names[ REGNO(ret) ]);
637 fprintf (stderr, ", stack");
639 fprintf (stderr, " )\n");
645 /* For an arg passed partly in registers and partly in memory,
646 this is the number of registers used.
647 For args passed entirely in registers or entirely in memory, zero. */
650 function_arg_partial_nregs (cum, mode, type, named)
651 CUMULATIVE_ARGS *cum; /* current arg information */
652 enum machine_mode mode; /* current arg mode */
653 tree type; /* type of the argument or 0 if lib support */
654 int named; /* != 0 for normal args, == 0 for ... args */
660 /* Output an insn whose source is a 386 integer register. SRC is the
661 rtx for the register, and TEMPLATE is the op-code template. SRC may
662 be either SImode or DImode.
664 The template will be output with operands[0] as SRC, and operands[1]
665 as a pointer to the top of the 386 stack. So a call from floatsidf2
666 would look like this:
668 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
670 where %z0 corresponds to the caller's operands[1], and is used to
671 emit the proper size suffix.
673 ??? Extend this to handle HImode - a 387 can load and store HImode
677 output_op_from_reg (src, template)
682 int size = GET_MODE_SIZE (GET_MODE (src));
685 xops[1] = AT_SP (Pmode);
686 xops[2] = GEN_INT (size);
687 xops[3] = stack_pointer_rtx;
689 if (size > UNITS_PER_WORD)
692 if (size > 2 * UNITS_PER_WORD)
694 high = gen_rtx (REG, SImode, REGNO (src) + 2);
695 output_asm_insn (AS1 (push%L0,%0), &high);
697 high = gen_rtx (REG, SImode, REGNO (src) + 1);
698 output_asm_insn (AS1 (push%L0,%0), &high);
700 output_asm_insn (AS1 (push%L0,%0), &src);
702 output_asm_insn (template, xops);
704 output_asm_insn (AS2 (add%L3,%2,%3), xops);
707 /* Output an insn to pop an value from the 387 top-of-stack to 386
708 register DEST. The 387 register stack is popped if DIES is true. If
709 the mode of DEST is an integer mode, a `fist' integer store is done,
710 otherwise a `fst' float store is done. */
713 output_to_reg (dest, dies)
718 int size = GET_MODE_SIZE (GET_MODE (dest));
720 xops[0] = AT_SP (Pmode);
721 xops[1] = stack_pointer_rtx;
722 xops[2] = GEN_INT (size);
725 output_asm_insn (AS2 (sub%L1,%2,%1), xops);
727 if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_INT)
730 output_asm_insn (AS1 (fistp%z3,%y0), xops);
732 output_asm_insn (AS1 (fist%z3,%y0), xops);
734 else if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_FLOAT)
737 output_asm_insn (AS1 (fstp%z3,%y0), xops);
740 if (GET_MODE (dest) == XFmode)
742 output_asm_insn (AS1 (fstp%z3,%y0), xops);
743 output_asm_insn (AS1 (fld%z3,%y0), xops);
746 output_asm_insn (AS1 (fst%z3,%y0), xops);
752 output_asm_insn (AS1 (pop%L0,%0), &dest);
754 if (size > UNITS_PER_WORD)
756 dest = gen_rtx (REG, SImode, REGNO (dest) + 1);
757 output_asm_insn (AS1 (pop%L0,%0), &dest);
758 if (size > 2 * UNITS_PER_WORD)
760 dest = gen_rtx (REG, SImode, REGNO (dest) + 1);
761 output_asm_insn (AS1 (pop%L0,%0), &dest);
767 singlemove_string (operands)
771 if (GET_CODE (operands[0]) == MEM
772 && GET_CODE (x = XEXP (operands[0], 0)) == PRE_DEC)
774 if (XEXP (x, 0) != stack_pointer_rtx)
778 else if (GET_CODE (operands[1]) == CONST_DOUBLE)
780 return output_move_const_single (operands);
782 else if (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == REG)
783 return AS2 (mov%L0,%1,%0);
784 else if (CONSTANT_P (operands[1]))
785 return AS2 (mov%L0,%1,%0);
788 output_asm_insn ("push%L1 %1", operands);
793 /* Return a REG that occurs in ADDR with coefficient 1.
794 ADDR can be effectively incremented by incrementing REG. */
800 while (GET_CODE (addr) == PLUS)
802 if (GET_CODE (XEXP (addr, 0)) == REG)
803 addr = XEXP (addr, 0);
804 else if (GET_CODE (XEXP (addr, 1)) == REG)
805 addr = XEXP (addr, 1);
806 else if (CONSTANT_P (XEXP (addr, 0)))
807 addr = XEXP (addr, 1);
808 else if (CONSTANT_P (XEXP (addr, 1)))
809 addr = XEXP (addr, 0);
813 if (GET_CODE (addr) == REG)
819 /* Output an insn to add the constant N to the register X. */
830 output_asm_insn (AS1 (dec%L0,%0), xops);
832 output_asm_insn (AS1 (inc%L0,%0), xops);
835 xops[1] = GEN_INT (-n);
836 output_asm_insn (AS2 (sub%L0,%1,%0), xops);
840 xops[1] = GEN_INT (n);
841 output_asm_insn (AS2 (add%L0,%1,%0), xops);
846 /* Output assembler code to perform a doubleword move insn
847 with operands OPERANDS. */
850 output_move_double (operands)
853 enum {REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
857 rtx addreg0 = 0, addreg1 = 0;
858 int dest_overlapped_low = 0;
859 int size = GET_MODE_SIZE (GET_MODE (operands[0]));
864 /* First classify both operands. */
866 if (REG_P (operands[0]))
868 else if (offsettable_memref_p (operands[0]))
870 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
872 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
874 else if (GET_CODE (operands[0]) == MEM)
879 if (REG_P (operands[1]))
881 else if (CONSTANT_P (operands[1]))
883 else if (offsettable_memref_p (operands[1]))
885 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
887 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
889 else if (GET_CODE (operands[1]) == MEM)
894 /* Check for the cases that the operand constraints are not
895 supposed to allow to happen. Abort if we get one,
896 because generating code for these cases is painful. */
898 if (optype0 == RNDOP || optype1 == RNDOP)
901 /* If one operand is decrementing and one is incrementing
902 decrement the former register explicitly
903 and change that operand into ordinary indexing. */
905 if (optype0 == PUSHOP && optype1 == POPOP)
907 /* ??? Can this ever happen on i386? */
908 operands[0] = XEXP (XEXP (operands[0], 0), 0);
909 asm_add (-size, operands[0]);
910 if (GET_MODE (operands[1]) == XFmode)
911 operands[0] = gen_rtx (MEM, XFmode, operands[0]);
912 else if (GET_MODE (operands[0]) == DFmode)
913 operands[0] = gen_rtx (MEM, DFmode, operands[0]);
915 operands[0] = gen_rtx (MEM, DImode, operands[0]);
919 if (optype0 == POPOP && optype1 == PUSHOP)
921 /* ??? Can this ever happen on i386? */
922 operands[1] = XEXP (XEXP (operands[1], 0), 0);
923 asm_add (-size, operands[1]);
924 if (GET_MODE (operands[1]) == XFmode)
925 operands[1] = gen_rtx (MEM, XFmode, operands[1]);
926 else if (GET_MODE (operands[1]) == DFmode)
927 operands[1] = gen_rtx (MEM, DFmode, operands[1]);
929 operands[1] = gen_rtx (MEM, DImode, operands[1]);
933 /* If an operand is an unoffsettable memory ref, find a register
934 we can increment temporarily to make it refer to the second word. */
936 if (optype0 == MEMOP)
937 addreg0 = find_addr_reg (XEXP (operands[0], 0));
939 if (optype1 == MEMOP)
940 addreg1 = find_addr_reg (XEXP (operands[1], 0));
942 /* Ok, we can do one word at a time.
943 Normally we do the low-numbered word first,
944 but if either operand is autodecrementing then we
945 do the high-numbered word first.
947 In either case, set up in LATEHALF the operands to use
948 for the high-numbered word and in some cases alter the
949 operands in OPERANDS to be suitable for the low-numbered word. */
953 if (optype0 == REGOP)
955 middlehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
956 latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 2);
958 else if (optype0 == OFFSOP)
960 middlehalf[0] = adj_offsettable_operand (operands[0], 4);
961 latehalf[0] = adj_offsettable_operand (operands[0], 8);
965 middlehalf[0] = operands[0];
966 latehalf[0] = operands[0];
969 if (optype1 == REGOP)
971 middlehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
972 latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2);
974 else if (optype1 == OFFSOP)
976 middlehalf[1] = adj_offsettable_operand (operands[1], 4);
977 latehalf[1] = adj_offsettable_operand (operands[1], 8);
979 else if (optype1 == CNSTOP)
981 if (GET_CODE (operands[1]) == CONST_DOUBLE)
983 REAL_VALUE_TYPE r; long l[3];
985 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
986 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
987 operands[1] = GEN_INT (l[0]);
988 middlehalf[1] = GEN_INT (l[1]);
989 latehalf[1] = GEN_INT (l[2]);
991 else if (CONSTANT_P (operands[1]))
992 /* No non-CONST_DOUBLE constant should ever appear here. */
997 middlehalf[1] = operands[1];
998 latehalf[1] = operands[1];
1001 else /* size is not 12: */
1003 if (optype0 == REGOP)
1004 latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1005 else if (optype0 == OFFSOP)
1006 latehalf[0] = adj_offsettable_operand (operands[0], 4);
1008 latehalf[0] = operands[0];
1010 if (optype1 == REGOP)
1011 latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
1012 else if (optype1 == OFFSOP)
1013 latehalf[1] = adj_offsettable_operand (operands[1], 4);
1014 else if (optype1 == CNSTOP)
1015 split_double (operands[1], &operands[1], &latehalf[1]);
1017 latehalf[1] = operands[1];
1020 /* If insn is effectively movd N (sp),-(sp) then we will do the
1021 high word first. We should use the adjusted operand 1
1022 (which is N+4 (sp) or N+8 (sp))
1023 for the low word and middle word as well,
1024 to compensate for the first decrement of sp. */
1025 if (optype0 == PUSHOP
1026 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
1027 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
1028 middlehalf[1] = operands[1] = latehalf[1];
1030 /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
1031 if the upper part of reg N does not appear in the MEM, arrange to
1032 emit the move late-half first. Otherwise, compute the MEM address
1033 into the upper part of N and use that as a pointer to the memory
1035 if (optype0 == REGOP
1036 && (optype1 == OFFSOP || optype1 == MEMOP))
1038 if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))
1039 && reg_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
1041 /* If both halves of dest are used in the src memory address,
1042 compute the address into latehalf of dest. */
1044 xops[0] = latehalf[0];
1045 xops[1] = XEXP (operands[1], 0);
1046 output_asm_insn (AS2 (lea%L0,%a1,%0), xops);
1047 if( GET_MODE (operands[1]) == XFmode )
1050 operands[1] = gen_rtx (MEM, XFmode, latehalf[0]);
1051 middlehalf[1] = adj_offsettable_operand (operands[1], size-8);
1052 latehalf[1] = adj_offsettable_operand (operands[1], size-4);
1056 operands[1] = gen_rtx (MEM, DImode, latehalf[0]);
1057 latehalf[1] = adj_offsettable_operand (operands[1], size-4);
1061 && reg_mentioned_p (middlehalf[0], XEXP (operands[1], 0)))
1063 /* Check for two regs used by both source and dest. */
1064 if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))
1065 || reg_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
1068 /* JRV says this can't happen: */
1069 if (addreg0 || addreg1)
1072 /* Only the middle reg conflicts; simply put it last. */
1073 output_asm_insn (singlemove_string (operands), operands);
1074 output_asm_insn (singlemove_string (latehalf), latehalf);
1075 output_asm_insn (singlemove_string (middlehalf), middlehalf);
1078 else if (reg_mentioned_p (operands[0], XEXP (operands[1], 0)))
1079 /* If the low half of dest is mentioned in the source memory
1080 address, the arrange to emit the move late half first. */
1081 dest_overlapped_low = 1;
1084 /* If one or both operands autodecrementing,
1085 do the two words, high-numbered first. */
1087 /* Likewise, the first move would clobber the source of the second one,
1088 do them in the other order. This happens only for registers;
1089 such overlap can't happen in memory unless the user explicitly
1090 sets it up, and that is an undefined circumstance. */
1093 if (optype0 == PUSHOP || optype1 == PUSHOP
1094 || (optype0 == REGOP && optype1 == REGOP
1095 && REGNO (operands[0]) == REGNO (latehalf[1]))
1096 || dest_overlapped_low)
1098 if (optype0 == PUSHOP || optype1 == PUSHOP
1099 || (optype0 == REGOP && optype1 == REGOP
1100 && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1]))
1101 || REGNO (operands[0]) == REGNO (latehalf[1])))
1102 || dest_overlapped_low)
1104 /* Make any unoffsettable addresses point at high-numbered word. */
1106 asm_add (size-4, addreg0);
1108 asm_add (size-4, addreg1);
1111 output_asm_insn (singlemove_string (latehalf), latehalf);
1113 /* Undo the adds we just did. */
1115 asm_add (-4, addreg0);
1117 asm_add (-4, addreg1);
1121 output_asm_insn (singlemove_string (middlehalf), middlehalf);
1123 asm_add (-4, addreg0);
1125 asm_add (-4, addreg1);
1128 /* Do low-numbered word. */
1129 return singlemove_string (operands);
1132 /* Normal case: do the two words, low-numbered first. */
1134 output_asm_insn (singlemove_string (operands), operands);
1136 /* Do the middle one of the three words for long double */
1140 asm_add (4, addreg0);
1142 asm_add (4, addreg1);
1144 output_asm_insn (singlemove_string (middlehalf), middlehalf);
1147 /* Make any unoffsettable addresses point at high-numbered word. */
1149 asm_add (4, addreg0);
1151 asm_add (4, addreg1);
1154 output_asm_insn (singlemove_string (latehalf), latehalf);
1156 /* Undo the adds we just did. */
1158 asm_add (4-size, addreg0);
1160 asm_add (4-size, addreg1);
1166 #define MAX_TMPS 2 /* max temporary registers used */
1168 /* Output the appropriate code to move push memory on the stack */
1171 output_move_pushmem (operands, insn, length, tmp_start, n_operands)
1183 } tmp_info[MAX_TMPS];
1185 rtx src = operands[1];
1188 int stack_p = reg_overlap_mentioned_p (stack_pointer_rtx, src);
1189 int stack_offset = 0;
1193 if (!offsettable_memref_p (src))
1194 fatal_insn ("Source is not offsettable", insn);
1196 if ((length & 3) != 0)
1197 fatal_insn ("Pushing non-word aligned size", insn);
1199 /* Figure out which temporary registers we have available */
1200 for (i = tmp_start; i < n_operands; i++)
1202 if (GET_CODE (operands[i]) == REG)
1204 if (reg_overlap_mentioned_p (operands[i], src))
1207 tmp_info[ max_tmps++ ].xops[1] = operands[i];
1208 if (max_tmps == MAX_TMPS)
1214 for (offset = length - 4; offset >= 0; offset -= 4)
1216 xops[0] = adj_offsettable_operand (src, offset + stack_offset);
1217 output_asm_insn (AS1(push%L0,%0), xops);
1223 for (offset = length - 4; offset >= 0; )
1225 for (num_tmps = 0; num_tmps < max_tmps && offset >= 0; num_tmps++)
1227 tmp_info[num_tmps].load = AS2(mov%L0,%0,%1);
1228 tmp_info[num_tmps].push = AS1(push%L0,%1);
1229 tmp_info[num_tmps].xops[0] = adj_offsettable_operand (src, offset + stack_offset);
1233 for (i = 0; i < num_tmps; i++)
1234 output_asm_insn (tmp_info[i].load, tmp_info[i].xops);
1236 for (i = 0; i < num_tmps; i++)
1237 output_asm_insn (tmp_info[i].push, tmp_info[i].xops);
1240 stack_offset += 4*num_tmps;
1248 /* Output the appropriate code to move data between two memory locations */
1251 output_move_memory (operands, insn, length, tmp_start, n_operands)
1262 } tmp_info[MAX_TMPS];
1264 rtx dest = operands[0];
1265 rtx src = operands[1];
1266 rtx qi_tmp = NULL_RTX;
1272 if (GET_CODE (dest) == MEM
1273 && GET_CODE (XEXP (dest, 0)) == PRE_INC
1274 && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx)
1275 return output_move_pushmem (operands, insn, length, tmp_start, n_operands);
1277 if (!offsettable_memref_p (src))
1278 fatal_insn ("Source is not offsettable", insn);
1280 if (!offsettable_memref_p (dest))
1281 fatal_insn ("Destination is not offsettable", insn);
1283 /* Figure out which temporary registers we have available */
1284 for (i = tmp_start; i < n_operands; i++)
1286 if (GET_CODE (operands[i]) == REG)
1288 if ((length & 1) != 0 && !qi_tmp && QI_REG_P (operands[i]))
1289 qi_tmp = operands[i];
1291 if (reg_overlap_mentioned_p (operands[i], dest))
1292 fatal_insn ("Temporary register overlaps the destination", insn);
1294 if (reg_overlap_mentioned_p (operands[i], src))
1295 fatal_insn ("Temporary register overlaps the source", insn);
1297 tmp_info[ max_tmps++ ].xops[2] = operands[i];
1298 if (max_tmps == MAX_TMPS)
1304 fatal_insn ("No scratch registers were found to do memory->memory moves", insn);
1306 if ((length & 1) != 0)
1309 fatal_insn ("No byte register found when moving odd # of bytes.", insn);
1314 for (num_tmps = 0; num_tmps < max_tmps; num_tmps++)
1318 tmp_info[num_tmps].load = AS2(mov%L0,%1,%2);
1319 tmp_info[num_tmps].store = AS2(mov%L0,%2,%0);
1320 tmp_info[num_tmps].xops[0] = adj_offsettable_operand (dest, offset);
1321 tmp_info[num_tmps].xops[1] = adj_offsettable_operand (src, offset);
1325 else if (length >= 2)
1327 tmp_info[num_tmps].load = AS2(mov%W0,%1,%2);
1328 tmp_info[num_tmps].store = AS2(mov%W0,%2,%0);
1329 tmp_info[num_tmps].xops[0] = adj_offsettable_operand (dest, offset);
1330 tmp_info[num_tmps].xops[1] = adj_offsettable_operand (src, offset);
1338 for (i = 0; i < num_tmps; i++)
1339 output_asm_insn (tmp_info[i].load, tmp_info[i].xops);
1341 for (i = 0; i < num_tmps; i++)
1342 output_asm_insn (tmp_info[i].store, tmp_info[i].xops);
1347 xops[0] = adj_offsettable_operand (dest, offset);
1348 xops[1] = adj_offsettable_operand (src, offset);
1350 output_asm_insn (AS2(mov%B0,%1,%2), xops);
1351 output_asm_insn (AS2(mov%B0,%2,%0), xops);
1359 standard_80387_constant_p (x)
1362 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
1367 if (setjmp (handler))
1370 set_float_handler (handler);
1371 REAL_VALUE_FROM_CONST_DOUBLE (d, x);
1372 is0 = REAL_VALUES_EQUAL (d, dconst0);
1373 is1 = REAL_VALUES_EQUAL (d, dconst1);
1374 set_float_handler (NULL_PTR);
1382 /* Note that on the 80387, other constants, such as pi,
1383 are much slower to load as standard constants
1384 than to load from doubles in memory! */
1391 output_move_const_single (operands)
1394 if (FP_REG_P (operands[0]))
1396 int conval = standard_80387_constant_p (operands[1]);
1404 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1406 REAL_VALUE_TYPE r; long l;
1408 if (GET_MODE (operands[1]) == XFmode)
1411 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1412 REAL_VALUE_TO_TARGET_SINGLE (r, l);
1413 operands[1] = GEN_INT (l);
1415 return singlemove_string (operands);
1418 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
1419 reference and a constant. */
1422 symbolic_operand (op, mode)
1424 enum machine_mode mode;
1426 switch (GET_CODE (op))
1433 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
1434 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
1435 && GET_CODE (XEXP (op, 1)) == CONST_INT);
1441 /* Test for a valid operand for a call instruction.
1442 Don't allow the arg pointer register or virtual regs
1443 since they may change into reg + const, which the patterns
1444 can't handle yet. */
1447 call_insn_operand (op, mode)
1449 enum machine_mode mode;
1451 if (GET_CODE (op) == MEM
1452 && ((CONSTANT_ADDRESS_P (XEXP (op, 0))
1453 /* This makes a difference for PIC. */
1454 && general_operand (XEXP (op, 0), Pmode))
1455 || (GET_CODE (XEXP (op, 0)) == REG
1456 && XEXP (op, 0) != arg_pointer_rtx
1457 && !(REGNO (XEXP (op, 0)) >= FIRST_PSEUDO_REGISTER
1458 && REGNO (XEXP (op, 0)) <= LAST_VIRTUAL_REGISTER))))
1463 /* Like call_insn_operand but allow (mem (symbol_ref ...))
1467 expander_call_insn_operand (op, mode)
1469 enum machine_mode mode;
1471 if (GET_CODE (op) == MEM
1472 && (CONSTANT_ADDRESS_P (XEXP (op, 0))
1473 || (GET_CODE (XEXP (op, 0)) == REG
1474 && XEXP (op, 0) != arg_pointer_rtx
1475 && !(REGNO (XEXP (op, 0)) >= FIRST_PSEUDO_REGISTER
1476 && REGNO (XEXP (op, 0)) <= LAST_VIRTUAL_REGISTER))))
1481 /* Return 1 if OP is a comparison operator that can use the condition code
1482 generated by an arithmetic operation. */
1485 arithmetic_comparison_operator (op, mode)
1487 enum machine_mode mode;
1491 if (mode != VOIDmode && mode != GET_MODE (op))
1493 code = GET_CODE (op);
1494 if (GET_RTX_CLASS (code) != '<')
1497 return (code != GT && code != LE);
1500 /* Returns 1 if OP contains a symbol reference */
1503 symbolic_reference_mentioned_p (op)
1509 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
1512 fmt = GET_RTX_FORMAT (GET_CODE (op));
1513 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
1519 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
1520 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
1523 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
1530 /* Attempt to expand a binary operator. Make the expansion closer to the
1531 actual machine, then just general_operand, which will allow 3 separate
1532 memory references (one output, two input) in a single insn. Return
1533 whether the insn fails, or succeeds. */
1536 ix86_expand_binary_operator (code, mode, operands)
1538 enum machine_mode mode;
1545 /* Recognize <var1> = <value> <op> <var1> for commutative operators */
1546 if (GET_RTX_CLASS (code) == 'c'
1547 && (rtx_equal_p (operands[0], operands[2])
1548 || immediate_operand (operands[1], mode)))
1550 rtx temp = operands[1];
1551 operands[1] = operands[2];
1555 /* If optimizing, copy to regs to improve CSE */
1556 if (TARGET_PSEUDO && optimize && ((reload_in_progress | reload_completed) == 0))
1558 if (GET_CODE (operands[1]) == MEM && !rtx_equal_p (operands[0], operands[1]))
1559 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
1561 if (GET_CODE (operands[2]) == MEM)
1562 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
1565 if (!ix86_binary_operator_ok (code, mode, operands))
1567 /* If not optimizing, try to make a valid insn (optimize code previously did
1568 this above to improve chances of CSE) */
1570 if ((!TARGET_PSEUDO || !optimize)
1571 && ((reload_in_progress | reload_completed) == 0)
1572 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM))
1575 if (GET_CODE (operands[1]) == MEM && !rtx_equal_p (operands[0], operands[1]))
1577 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
1581 if (GET_CODE (operands[2]) == MEM)
1583 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
1587 if (modified && !ix86_binary_operator_ok (code, mode, operands))
1597 /* Return TRUE or FALSE depending on whether the binary operator meets the
1598 appropriate constraints. */
1601 ix86_binary_operator_ok (code, mode, operands)
1603 enum machine_mode mode;
1609 /* Attempt to expand a unary operator. Make the expansion closer to the
1610 actual machine, then just general_operand, which will allow 2 separate
1611 memory references (one output, one input) in a single insn. Return
1612 whether the insn fails, or succeeds. */
1615 ix86_expand_unary_operator (code, mode, operands)
1617 enum machine_mode mode;
1622 /* If optimizing, copy to regs to improve CSE */
1625 && ((reload_in_progress | reload_completed) == 0)
1626 && GET_CODE (operands[1]) == MEM)
1628 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
1631 if (!ix86_unary_operator_ok (code, mode, operands))
1633 if ((!TARGET_PSEUDO || !optimize)
1634 && ((reload_in_progress | reload_completed) == 0)
1635 && GET_CODE (operands[1]) == MEM)
1637 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
1638 if (!ix86_unary_operator_ok (code, mode, operands))
1648 /* Return TRUE or FALSE depending on whether the unary operator meets the
1649 appropriate constraints. */
1652 ix86_unary_operator_ok (code, mode, operands)
1654 enum machine_mode mode;
1661 /* This function generates the assembly code for function entry.
1662 FILE is an stdio stream to output the code to.
1663 SIZE is an int: how many units of temporary storage to allocate. */
1666 function_prologue (file, size)
1673 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1674 || current_function_uses_const_pool);
1676 xops[0] = stack_pointer_rtx;
1677 xops[1] = frame_pointer_rtx;
1678 xops[2] = GEN_INT (size);
1679 if (frame_pointer_needed)
1681 output_asm_insn ("push%L1 %1", xops);
1682 output_asm_insn (AS2 (mov%L0,%0,%1), xops);
1686 output_asm_insn (AS2 (sub%L0,%2,%0), xops);
1688 /* Note If use enter it is NOT reversed args.
1689 This one is not reversed from intel!!
1690 I think enter is slower. Also sdb doesn't like it.
1691 But if you want it the code is:
1693 xops[3] = const0_rtx;
1694 output_asm_insn ("enter %2,%3", xops);
1697 limit = (frame_pointer_needed ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
1698 for (regno = limit - 1; regno >= 0; regno--)
1699 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1700 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1702 xops[0] = gen_rtx (REG, SImode, regno);
1703 output_asm_insn ("push%L0 %0", xops);
1708 xops[0] = pic_offset_table_rtx;
1709 xops[1] = (rtx) gen_label_rtx ();
1711 output_asm_insn (AS1 (call,%P1), xops);
1712 ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (xops[1]));
1713 output_asm_insn (AS1 (pop%L0,%0), xops);
1714 output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops);
1718 /* Return 1 if it is appropriate to emit `ret' instructions in the
1719 body of a function. Do this only if the epilogue is simple, needing a
1720 couple of insns. Prior to reloading, we can't tell how many registers
1721 must be saved, so return 0 then.
1723 If NON_SAVING_SETJMP is defined and true, then it is not possible
1724 for the epilogue to be simple, so return 0. This is a special case
1725 since NON_SAVING_SETJMP will not cause regs_ever_live to change until
1726 final, but jump_optimize may need to know sooner if a `return' is OK. */
1729 simple_386_epilogue ()
1733 int reglimit = (frame_pointer_needed
1734 ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
1735 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1736 || current_function_uses_const_pool);
1738 #ifdef NON_SAVING_SETJMP
1739 if (NON_SAVING_SETJMP && current_function_calls_setjmp)
1743 if (! reload_completed)
1746 for (regno = reglimit - 1; regno >= 0; regno--)
1747 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1748 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1751 return nregs == 0 || ! frame_pointer_needed;
1755 /* This function generates the assembly code for function exit.
1756 FILE is an stdio stream to output the code to.
1757 SIZE is an int: how many units of temporary storage to deallocate. */
1760 function_epilogue (file, size)
1765 register int nregs, limit;
1768 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1769 || current_function_uses_const_pool);
1771 /* Compute the number of registers to pop */
1773 limit = (frame_pointer_needed
1774 ? FRAME_POINTER_REGNUM
1775 : STACK_POINTER_REGNUM);
1779 for (regno = limit - 1; regno >= 0; regno--)
1780 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1781 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1784 /* sp is often unreliable so we must go off the frame pointer,
1787 /* In reality, we may not care if sp is unreliable, because we can
1788 restore the register relative to the frame pointer. In theory,
1789 since each move is the same speed as a pop, and we don't need the
1790 leal, this is faster. For now restore multiple registers the old
1793 offset = -size - (nregs * UNITS_PER_WORD);
1795 xops[2] = stack_pointer_rtx;
1797 if (nregs > 1 || ! frame_pointer_needed)
1799 if (frame_pointer_needed)
1801 xops[0] = adj_offsettable_operand (AT_BP (Pmode), offset);
1802 output_asm_insn (AS2 (lea%L2,%0,%2), xops);
1805 for (regno = 0; regno < limit; regno++)
1806 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1807 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1809 xops[0] = gen_rtx (REG, SImode, regno);
1810 output_asm_insn ("pop%L0 %0", xops);
1814 for (regno = 0; regno < limit; regno++)
1815 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1816 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1818 xops[0] = gen_rtx (REG, SImode, regno);
1819 xops[1] = adj_offsettable_operand (AT_BP (Pmode), offset);
1820 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
1824 if (frame_pointer_needed)
1826 /* If not an i386, mov & pop is faster than "leave". */
1828 if (TARGET_USE_LEAVE)
1829 output_asm_insn ("leave", xops);
1832 xops[0] = frame_pointer_rtx;
1833 output_asm_insn (AS2 (mov%L2,%0,%2), xops);
1834 output_asm_insn ("pop%L0 %0", xops);
1839 /* If there is no frame pointer, we must still release the frame. */
1841 xops[0] = GEN_INT (size);
1842 output_asm_insn (AS2 (add%L2,%0,%2), xops);
1845 #ifdef FUNCTION_BLOCK_PROFILER_EXIT
1846 if (profile_block_flag == 2)
1848 FUNCTION_BLOCK_PROFILER_EXIT(file);
1852 if (current_function_pops_args && current_function_args_size)
1854 xops[1] = GEN_INT (current_function_pops_args);
1856 /* i386 can only pop 32K bytes (maybe 64K? Is it signed?). If
1857 asked to pop more, pop return address, do explicit add, and jump
1858 indirectly to the caller. */
1860 if (current_function_pops_args >= 32768)
1862 /* ??? Which register to use here? */
1863 xops[0] = gen_rtx (REG, SImode, 2);
1864 output_asm_insn ("pop%L0 %0", xops);
1865 output_asm_insn (AS2 (add%L2,%1,%2), xops);
1866 output_asm_insn ("jmp %*%0", xops);
1869 output_asm_insn ("ret %1", xops);
1872 output_asm_insn ("ret", xops);
1876 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
1877 that is a valid memory address for an instruction.
1878 The MODE argument is the machine mode for the MEM expression
1879 that wants to use this address.
1881 On x86, legitimate addresses are:
1882 base movl (base),reg
1883 displacement movl disp,reg
1884 base + displacement movl disp(base),reg
1885 index + base movl (base,index),reg
1886 (index + base) + displacement movl disp(base,index),reg
1887 index*scale movl (,index,scale),reg
1888 index*scale + disp movl disp(,index,scale),reg
1889 index*scale + base movl (base,index,scale),reg
1890 (index*scale + base) + disp movl disp(base,index,scale),reg
1892 In each case, scale can be 1, 2, 4, 8. */
1894 /* This is exactly the same as print_operand_addr, except that
1895 it recognizes addresses instead of printing them.
1897 It only recognizes address in canonical form. LEGITIMIZE_ADDRESS should
1898 convert common non-canonical forms to canonical form so that they will
1901 #define ADDR_INVALID(msg,insn) \
1903 if (TARGET_DEBUG_ADDR) \
1905 fprintf (stderr, msg); \
1911 legitimate_address_p (mode, addr, strict)
1912 enum machine_mode mode;
1916 rtx base = NULL_RTX;
1917 rtx indx = NULL_RTX;
1918 rtx scale = NULL_RTX;
1919 rtx disp = NULL_RTX;
1921 if (TARGET_DEBUG_ADDR)
1924 "\n==========\nGO_IF_LEGITIMATE_ADDRESS, mode = %s, strict = %d\n",
1925 GET_MODE_NAME (mode), strict);
1930 if (GET_CODE (addr) == REG || GET_CODE (addr) == SUBREG)
1931 base = addr; /* base reg */
1933 else if (GET_CODE (addr) == PLUS)
1935 rtx op0 = XEXP (addr, 0);
1936 rtx op1 = XEXP (addr, 1);
1937 enum rtx_code code0 = GET_CODE (op0);
1938 enum rtx_code code1 = GET_CODE (op1);
1940 if (code0 == REG || code0 == SUBREG)
1942 if (code1 == REG || code1 == SUBREG)
1944 indx = op0; /* index + base */
1950 base = op0; /* base + displacement */
1955 else if (code0 == MULT)
1957 indx = XEXP (op0, 0);
1958 scale = XEXP (op0, 1);
1960 if (code1 == REG || code1 == SUBREG)
1961 base = op1; /* index*scale + base */
1964 disp = op1; /* index*scale + disp */
1967 else if (code0 == PLUS && GET_CODE (XEXP (op0, 0)) == MULT)
1969 indx = XEXP (XEXP (op0, 0), 0); /* index*scale + base + disp */
1970 scale = XEXP (XEXP (op0, 0), 1);
1971 base = XEXP (op0, 1);
1975 else if (code0 == PLUS)
1977 indx = XEXP (op0, 0); /* index + base + disp */
1978 base = XEXP (op0, 1);
1984 ADDR_INVALID ("PLUS subcode is not valid.\n", op0);
1989 else if (GET_CODE (addr) == MULT)
1991 indx = XEXP (addr, 0); /* index*scale */
1992 scale = XEXP (addr, 1);
1996 disp = addr; /* displacement */
1998 /* Allow arg pointer and stack pointer as index if there is not scaling */
1999 if (base && indx && !scale
2000 && (indx == arg_pointer_rtx || indx == stack_pointer_rtx))
2007 /* Validate base register */
2008 /* Don't allow SUBREG's here, it can lead to spill failures when the base
2009 is one word out of a two word structure, which is represented internally
2013 if (GET_CODE (base) != REG)
2015 ADDR_INVALID ("Base is not a register.\n", base);
2019 if ((strict && !REG_OK_FOR_BASE_STRICT_P (base))
2020 || (!strict && !REG_OK_FOR_BASE_NONSTRICT_P (base)))
2022 ADDR_INVALID ("Base is not valid.\n", base);
2027 /* Validate index register */
2028 /* Don't allow SUBREG's here, it can lead to spill failures when the index
2029 is one word out of a two word structure, which is represented internally
2033 if (GET_CODE (indx) != REG)
2035 ADDR_INVALID ("Index is not a register.\n", indx);
2039 if ((strict && !REG_OK_FOR_INDEX_STRICT_P (indx))
2040 || (!strict && !REG_OK_FOR_INDEX_NONSTRICT_P (indx)))
2042 ADDR_INVALID ("Index is not valid.\n", indx);
2047 abort (); /* scale w/o index invalid */
2049 /* Validate scale factor */
2052 HOST_WIDE_INT value;
2054 if (GET_CODE (scale) != CONST_INT)
2056 ADDR_INVALID ("Scale is not valid.\n", scale);
2060 value = INTVAL (scale);
2061 if (value != 1 && value != 2 && value != 4 && value != 8)
2063 ADDR_INVALID ("Scale is not a good multiplier.\n", scale);
2068 /* Validate displacement
2069 Constant pool addresses must be handled special. They are
2070 considered legitimate addresses, but only if not used with regs.
2071 When printed, the output routines know to print the reference with the
2072 PIC reg, even though the PIC reg doesn't appear in the RTL. */
2075 if (GET_CODE (disp) == SYMBOL_REF
2076 && CONSTANT_POOL_ADDRESS_P (disp)
2081 else if (!CONSTANT_ADDRESS_P (disp))
2083 ADDR_INVALID ("Displacement is not valid.\n", disp);
2087 else if (GET_CODE (disp) == CONST_DOUBLE)
2089 ADDR_INVALID ("Displacement is a const_double.\n", disp);
2093 else if (flag_pic && SYMBOLIC_CONST (disp)
2094 && base != pic_offset_table_rtx
2095 && (indx != pic_offset_table_rtx || scale != NULL_RTX))
2097 ADDR_INVALID ("Displacement is an invalid pic reference.\n", disp);
2101 else if (HALF_PIC_P () && HALF_PIC_ADDRESS_P (disp)
2102 && (base != NULL_RTX || indx != NULL_RTX))
2104 ADDR_INVALID ("Displacement is an invalid half-pic reference.\n", disp);
2109 if (TARGET_DEBUG_ADDR)
2110 fprintf (stderr, "Address is valid.\n");
2112 /* Everything looks valid, return true */
2117 /* Return a legitimate reference for ORIG (an address) using the
2118 register REG. If REG is 0, a new pseudo is generated.
2120 There are three types of references that must be handled:
2122 1. Global data references must load the address from the GOT, via
2123 the PIC reg. An insn is emitted to do this load, and the reg is
2126 2. Static data references must compute the address as an offset
2127 from the GOT, whose base is in the PIC reg. An insn is emitted to
2128 compute the address into a reg, and the reg is returned. Static
2129 data objects have SYMBOL_REF_FLAG set to differentiate them from
2130 global data objects.
2132 3. Constant pool addresses must be handled special. They are
2133 considered legitimate addresses, but only if not used with regs.
2134 When printed, the output routines know to print the reference with the
2135 PIC reg, even though the PIC reg doesn't appear in the RTL.
2137 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2138 reg also appears in the address (except for constant pool references,
2141 "switch" statements also require special handling when generating
2142 PIC code. See comments by the `casesi' insn in i386.md for details. */
2145 legitimize_pic_address (orig, reg)
2152 if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
2154 if (GET_CODE (addr) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (addr))
2159 reg = gen_reg_rtx (Pmode);
2161 if ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
2162 || GET_CODE (addr) == LABEL_REF)
2163 new = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig);
2165 new = gen_rtx (MEM, Pmode,
2166 gen_rtx (PLUS, Pmode,
2167 pic_offset_table_rtx, orig));
2169 emit_move_insn (reg, new);
2171 current_function_uses_pic_offset_table = 1;
2174 else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
2178 if (GET_CODE (addr) == CONST)
2180 addr = XEXP (addr, 0);
2181 if (GET_CODE (addr) != PLUS)
2185 if (XEXP (addr, 0) == pic_offset_table_rtx)
2189 reg = gen_reg_rtx (Pmode);
2191 base = legitimize_pic_address (XEXP (addr, 0), reg);
2192 addr = legitimize_pic_address (XEXP (addr, 1),
2193 base == reg ? NULL_RTX : reg);
2195 if (GET_CODE (addr) == CONST_INT)
2196 return plus_constant (base, INTVAL (addr));
2198 if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
2200 base = gen_rtx (PLUS, Pmode, base, XEXP (addr, 0));
2201 addr = XEXP (addr, 1);
2203 return gen_rtx (PLUS, Pmode, base, addr);
2209 /* Emit insns to move operands[1] into operands[0]. */
2212 emit_pic_move (operands, mode)
2214 enum machine_mode mode;
2216 rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
2218 if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
2219 operands[1] = (rtx) force_reg (SImode, operands[1]);
2221 operands[1] = legitimize_pic_address (operands[1], temp);
2225 /* Try machine-dependent ways of modifying an illegitimate address
2226 to be legitimate. If we find one, return the new, valid address.
2227 This macro is used in only one place: `memory_address' in explow.c.
2229 OLDX is the address as it was before break_out_memory_refs was called.
2230 In some cases it is useful to look at this to decide what needs to be done.
2232 MODE and WIN are passed so that this macro can use
2233 GO_IF_LEGITIMATE_ADDRESS.
2235 It is always safe for this macro to do nothing. It exists to recognize
2236 opportunities to optimize the output.
2238 For the 80386, we handle X+REG by loading X into a register R and
2239 using R+REG. R will go in a general reg and indexing will be used.
2240 However, if REG is a broken-out memory address or multiplication,
2241 nothing needs to be done because REG can certainly go in a general reg.
2243 When -fpic is used, special handling is needed for symbolic references.
2244 See comments by legitimize_pic_address in i386.c for details. */
2247 legitimize_address (x, oldx, mode)
2250 enum machine_mode mode;
2255 if (TARGET_DEBUG_ADDR)
2257 fprintf (stderr, "\n==========\nLEGITIMIZE_ADDRESS, mode = %s\n", GET_MODE_NAME (mode));
2261 if (flag_pic && SYMBOLIC_CONST (x))
2262 return legitimize_pic_address (x, 0);
2264 /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
2265 if (GET_CODE (x) == ASHIFT
2266 && GET_CODE (XEXP (x, 1)) == CONST_INT
2267 && (log = (unsigned)exact_log2 (INTVAL (XEXP (x, 1)))) < 4)
2270 x = gen_rtx (MULT, Pmode,
2271 force_reg (Pmode, XEXP (x, 0)),
2272 GEN_INT (1 << log));
2275 if (GET_CODE (x) == PLUS)
2277 /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
2278 if (GET_CODE (XEXP (x, 0)) == ASHIFT
2279 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
2280 && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) < 4)
2283 XEXP (x, 0) = gen_rtx (MULT, Pmode,
2284 force_reg (Pmode, XEXP (XEXP (x, 0), 0)),
2285 GEN_INT (1 << log));
2288 if (GET_CODE (XEXP (x, 1)) == ASHIFT
2289 && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
2290 && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 1), 1)))) < 4)
2293 XEXP (x, 1) = gen_rtx (MULT, Pmode,
2294 force_reg (Pmode, XEXP (XEXP (x, 1), 0)),
2295 GEN_INT (1 << log));
2298 /* Put multiply first if it isn't already */
2299 if (GET_CODE (XEXP (x, 1)) == MULT)
2301 rtx tmp = XEXP (x, 0);
2302 XEXP (x, 0) = XEXP (x, 1);
2307 /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
2308 into (plus (plus (mult (reg) (const)) (reg)) (const)). This can be
2309 created by virtual register instantiation, register elimination, and
2310 similar optimizations. */
2311 if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS)
2314 x = gen_rtx (PLUS, Pmode,
2315 gen_rtx (PLUS, Pmode, XEXP (x, 0), XEXP (XEXP (x, 1), 0)),
2316 XEXP (XEXP (x, 1), 1));
2319 /* Canonicalize (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
2320 into (plus (plus (mult (reg) (const)) (reg)) (const)). */
2321 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
2322 && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
2323 && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
2324 && CONSTANT_P (XEXP (x, 1)))
2326 rtx constant, other;
2328 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
2330 constant = XEXP (x, 1);
2331 other = XEXP (XEXP (XEXP (x, 0), 1), 1);
2333 else if (GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 1)) == CONST_INT)
2335 constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
2336 other = XEXP (x, 1);
2344 x = gen_rtx (PLUS, Pmode,
2345 gen_rtx (PLUS, Pmode, XEXP (XEXP (x, 0), 0),
2346 XEXP (XEXP (XEXP (x, 0), 1), 0)),
2347 plus_constant (other, INTVAL (constant)));
2351 if (changed && legitimate_address_p (mode, x, FALSE))
2354 if (GET_CODE (XEXP (x, 0)) == MULT)
2357 XEXP (x, 0) = force_operand (XEXP (x, 0), 0);
2360 if (GET_CODE (XEXP (x, 1)) == MULT)
2363 XEXP (x, 1) = force_operand (XEXP (x, 1), 0);
2367 && GET_CODE (XEXP (x, 1)) == REG
2368 && GET_CODE (XEXP (x, 0)) == REG)
2371 if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1)))
2374 x = legitimize_pic_address (x, 0);
2377 if (changed && legitimate_address_p (mode, x, FALSE))
2380 if (GET_CODE (XEXP (x, 0)) == REG)
2382 register rtx temp = gen_reg_rtx (Pmode);
2383 register rtx val = force_operand (XEXP (x, 1), temp);
2385 emit_move_insn (temp, val);
2391 else if (GET_CODE (XEXP (x, 1)) == REG)
2393 register rtx temp = gen_reg_rtx (Pmode);
2394 register rtx val = force_operand (XEXP (x, 0), temp);
2396 emit_move_insn (temp, val);
2407 /* Print an integer constant expression in assembler syntax. Addition
2408 and subtraction are the only arithmetic that may appear in these
2409 expressions. FILE is the stdio stream to write to, X is the rtx, and
2410 CODE is the operand print code from the output string. */
2413 output_pic_addr_const (file, x, code)
2420 switch (GET_CODE (x))
2431 if (GET_CODE (x) == SYMBOL_REF)
2432 assemble_name (file, XSTR (x, 0));
2435 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
2436 CODE_LABEL_NUMBER (XEXP (x, 0)));
2437 assemble_name (asm_out_file, buf);
2440 if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
2441 fprintf (file, "@GOTOFF(%%ebx)");
2442 else if (code == 'P')
2443 fprintf (file, "@PLT");
2444 else if (GET_CODE (x) == LABEL_REF)
2445 fprintf (file, "@GOTOFF");
2446 else if (! SYMBOL_REF_FLAG (x))
2447 fprintf (file, "@GOT");
2449 fprintf (file, "@GOTOFF");
2454 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
2455 assemble_name (asm_out_file, buf);
2459 fprintf (file, "%d", INTVAL (x));
2463 /* This used to output parentheses around the expression,
2464 but that does not work on the 386 (either ATT or BSD assembler). */
2465 output_pic_addr_const (file, XEXP (x, 0), code);
2469 if (GET_MODE (x) == VOIDmode)
2471 /* We can use %d if the number is <32 bits and positive. */
2472 if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
2473 fprintf (file, "0x%x%08x",
2474 CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
2476 fprintf (file, "%d", CONST_DOUBLE_LOW (x));
2479 /* We can't handle floating point constants;
2480 PRINT_OPERAND must handle them. */
2481 output_operand_lossage ("floating constant misused");
2485 /* Some assemblers need integer constants to appear last (eg masm). */
2486 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
2488 output_pic_addr_const (file, XEXP (x, 1), code);
2489 if (INTVAL (XEXP (x, 0)) >= 0)
2490 fprintf (file, "+");
2491 output_pic_addr_const (file, XEXP (x, 0), code);
2495 output_pic_addr_const (file, XEXP (x, 0), code);
2496 if (INTVAL (XEXP (x, 1)) >= 0)
2497 fprintf (file, "+");
2498 output_pic_addr_const (file, XEXP (x, 1), code);
2503 output_pic_addr_const (file, XEXP (x, 0), code);
2504 fprintf (file, "-");
2505 output_pic_addr_const (file, XEXP (x, 1), code);
2509 output_operand_lossage ("invalid expression as operand");
2514 f -- float insn (print a CONST_DOUBLE as a float rather than in hex).
2515 D,L,W,B,Q,S -- print the opcode suffix for specified size of operand.
2516 R -- print the prefix for register names.
2517 z -- print the opcode suffix for the size of the current operand.
2518 * -- print a star (in certain assembler syntax)
2519 w -- print the operand as if it's a "word" (HImode) even if it isn't.
2520 c -- don't print special prefixes before constant operands.
2521 J -- print the appropriate jump operand.
2525 print_operand (file, x, code)
2540 PUT_OP_SIZE (code, 'l', file);
2544 PUT_OP_SIZE (code, 'w', file);
2548 PUT_OP_SIZE (code, 'b', file);
2552 PUT_OP_SIZE (code, 'l', file);
2556 PUT_OP_SIZE (code, 's', file);
2560 PUT_OP_SIZE (code, 't', file);
2564 /* 387 opcodes don't get size suffixes if the operands are
2567 if (STACK_REG_P (x))
2570 /* this is the size of op from size of operand */
2571 switch (GET_MODE_SIZE (GET_MODE (x)))
2574 PUT_OP_SIZE ('B', 'b', file);
2578 PUT_OP_SIZE ('W', 'w', file);
2582 if (GET_MODE (x) == SFmode)
2584 PUT_OP_SIZE ('S', 's', file);
2588 PUT_OP_SIZE ('L', 'l', file);
2592 PUT_OP_SIZE ('T', 't', file);
2596 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
2598 #ifdef GAS_MNEMONICS
2599 PUT_OP_SIZE ('Q', 'q', file);
2602 PUT_OP_SIZE ('Q', 'l', file); /* Fall through */
2606 PUT_OP_SIZE ('Q', 'l', file);
2619 switch (GET_CODE (x))
2621 /* These conditions are appropriate for testing the result
2622 of an arithmetic operation, not for a compare operation.
2623 Cases GE, LT assume CC_NO_OVERFLOW true. All cases assume
2624 CC_Z_IN_NOT_C false and not floating point. */
2625 case NE: fputs ("jne", file); return;
2626 case EQ: fputs ("je", file); return;
2627 case GE: fputs ("jns", file); return;
2628 case LT: fputs ("js", file); return;
2629 case GEU: fputs ("jmp", file); return;
2630 case GTU: fputs ("jne", file); return;
2631 case LEU: fputs ("je", file); return;
2632 case LTU: fputs ("#branch never", file); return;
2634 /* no matching branches for GT nor LE */
2642 sprintf (str, "invalid operand code `%c'", code);
2643 output_operand_lossage (str);
2647 if (GET_CODE (x) == REG)
2649 PRINT_REG (x, code, file);
2651 else if (GET_CODE (x) == MEM)
2653 PRINT_PTR (x, file);
2654 if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
2657 output_pic_addr_const (file, XEXP (x, 0), code);
2659 output_addr_const (file, XEXP (x, 0));
2662 output_address (XEXP (x, 0));
2664 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
2666 REAL_VALUE_TYPE r; long l;
2667 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2668 REAL_VALUE_TO_TARGET_SINGLE (r, l);
2669 PRINT_IMMED_PREFIX (file);
2670 fprintf (file, "0x%x", l);
2672 /* These float cases don't actually occur as immediate operands. */
2673 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
2675 REAL_VALUE_TYPE r; char dstr[30];
2676 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2677 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
2678 fprintf (file, "%s", dstr);
2680 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == XFmode)
2682 REAL_VALUE_TYPE r; char dstr[30];
2683 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2684 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
2685 fprintf (file, "%s", dstr);
2691 if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
2692 PRINT_IMMED_PREFIX (file);
2693 else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
2694 || GET_CODE (x) == LABEL_REF)
2695 PRINT_OFFSET_PREFIX (file);
2698 output_pic_addr_const (file, x, code);
2700 output_addr_const (file, x);
2704 /* Print a memory operand whose address is ADDR. */
2707 print_operand_address (file, addr)
2711 register rtx reg1, reg2, breg, ireg;
2714 switch (GET_CODE (addr))
2718 fprintf (file, "%se", RP);
2719 fputs (hi_reg_name[REGNO (addr)], file);
2729 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
2731 offset = XEXP (addr, 0);
2732 addr = XEXP (addr, 1);
2734 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
2736 offset = XEXP (addr, 1);
2737 addr = XEXP (addr, 0);
2739 if (GET_CODE (addr) != PLUS) ;
2740 else if (GET_CODE (XEXP (addr, 0)) == MULT)
2742 reg1 = XEXP (addr, 0);
2743 addr = XEXP (addr, 1);
2745 else if (GET_CODE (XEXP (addr, 1)) == MULT)
2747 reg1 = XEXP (addr, 1);
2748 addr = XEXP (addr, 0);
2750 else if (GET_CODE (XEXP (addr, 0)) == REG)
2752 reg1 = XEXP (addr, 0);
2753 addr = XEXP (addr, 1);
2755 else if (GET_CODE (XEXP (addr, 1)) == REG)
2757 reg1 = XEXP (addr, 1);
2758 addr = XEXP (addr, 0);
2760 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
2762 if (reg1 == 0) reg1 = addr;
2768 if (addr != 0) abort ();
2771 if ((reg1 && GET_CODE (reg1) == MULT)
2772 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
2777 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
2783 if (ireg != 0 || breg != 0)
2790 output_pic_addr_const (file, addr, 0);
2792 else if (GET_CODE (addr) == LABEL_REF)
2793 output_asm_label (addr);
2796 output_addr_const (file, addr);
2799 if (ireg != 0 && GET_CODE (ireg) == MULT)
2801 scale = INTVAL (XEXP (ireg, 1));
2802 ireg = XEXP (ireg, 0);
2805 /* The stack pointer can only appear as a base register,
2806 never an index register, so exchange the regs if it is wrong. */
2808 if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM)
2817 /* output breg+ireg*scale */
2818 PRINT_B_I_S (breg, ireg, scale, file);
2825 if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
2827 scale = INTVAL (XEXP (addr, 0));
2828 ireg = XEXP (addr, 1);
2832 scale = INTVAL (XEXP (addr, 1));
2833 ireg = XEXP (addr, 0);
2835 output_addr_const (file, const0_rtx);
2836 PRINT_B_I_S ((rtx) 0, ireg, scale, file);
2841 if (GET_CODE (addr) == CONST_INT
2842 && INTVAL (addr) < 0x8000
2843 && INTVAL (addr) >= -0x8000)
2844 fprintf (file, "%d", INTVAL (addr));
2848 output_pic_addr_const (file, addr, 0);
2850 output_addr_const (file, addr);
2855 /* Set the cc_status for the results of an insn whose pattern is EXP.
2856 On the 80386, we assume that only test and compare insns, as well
2857 as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, ASHIFT,
2858 ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
2859 Also, we assume that jumps, moves and sCOND don't affect the condition
2860 codes. All else clobbers the condition codes, by assumption.
2862 We assume that ALL integer add, minus, etc. instructions effect the
2863 condition codes. This MUST be consistent with i386.md.
2865 We don't record any float test or compare - the redundant test &
2866 compare check in final.c does not handle stack-like regs correctly. */
2869 notice_update_cc (exp)
2872 if (GET_CODE (exp) == SET)
2874 /* Jumps do not alter the cc's. */
2875 if (SET_DEST (exp) == pc_rtx)
2877 #ifdef IS_STACK_MODE
2878 /* Moving into a memory of stack_mode may have been moved
2879 in between the use and set of cc0 by loop_spl(). So
2880 old value of cc.status must be retained */
2881 if(GET_CODE(SET_DEST(exp))==MEM
2882 && IS_STACK_MODE(GET_MODE(SET_DEST(exp))))
2887 /* Moving register or memory into a register:
2888 it doesn't alter the cc's, but it might invalidate
2889 the RTX's which we remember the cc's came from.
2890 (Note that moving a constant 0 or 1 MAY set the cc's). */
2891 if (REG_P (SET_DEST (exp))
2892 && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM
2893 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
2895 if (cc_status.value1
2896 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
2897 cc_status.value1 = 0;
2898 if (cc_status.value2
2899 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
2900 cc_status.value2 = 0;
2903 /* Moving register into memory doesn't alter the cc's.
2904 It may invalidate the RTX's which we remember the cc's came from. */
2905 if (GET_CODE (SET_DEST (exp)) == MEM
2906 && (REG_P (SET_SRC (exp))
2907 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
2909 if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
2910 cc_status.value1 = 0;
2911 if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
2912 cc_status.value2 = 0;
2915 /* Function calls clobber the cc's. */
2916 else if (GET_CODE (SET_SRC (exp)) == CALL)
2921 /* Tests and compares set the cc's in predictable ways. */
2922 else if (SET_DEST (exp) == cc0_rtx)
2925 cc_status.value1 = SET_SRC (exp);
2928 /* Certain instructions effect the condition codes. */
2929 else if (GET_MODE (SET_SRC (exp)) == SImode
2930 || GET_MODE (SET_SRC (exp)) == HImode
2931 || GET_MODE (SET_SRC (exp)) == QImode)
2932 switch (GET_CODE (SET_SRC (exp)))
2934 case ASHIFTRT: case LSHIFTRT:
2936 /* Shifts on the 386 don't set the condition codes if the
2937 shift count is zero. */
2938 if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
2943 /* We assume that the CONST_INT is non-zero (this rtx would
2944 have been deleted if it were zero. */
2946 case PLUS: case MINUS: case NEG:
2947 case AND: case IOR: case XOR:
2948 cc_status.flags = CC_NO_OVERFLOW;
2949 cc_status.value1 = SET_SRC (exp);
2950 cc_status.value2 = SET_DEST (exp);
2961 else if (GET_CODE (exp) == PARALLEL
2962 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
2964 if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
2966 if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
2969 if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
2970 cc_status.flags |= CC_IN_80387;
2972 cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
2983 /* Split one or more DImode RTL references into pairs of SImode
2984 references. The RTL can be REG, offsettable MEM, integer constant, or
2985 CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to
2986 split and "num" is its length. lo_half and hi_half are output arrays
2987 that parallel "operands". */
2990 split_di (operands, num, lo_half, hi_half)
2993 rtx lo_half[], hi_half[];
2997 if (GET_CODE (operands[num]) == REG)
2999 lo_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]));
3000 hi_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]) + 1);
3002 else if (CONSTANT_P (operands[num]))
3004 split_double (operands[num], &lo_half[num], &hi_half[num]);
3006 else if (offsettable_memref_p (operands[num]))
3008 lo_half[num] = operands[num];
3009 hi_half[num] = adj_offsettable_operand (operands[num], 4);
3016 /* Return 1 if this is a valid binary operation on a 387.
3017 OP is the expression matched, and MODE is its mode. */
3020 binary_387_op (op, mode)
3022 enum machine_mode mode;
3024 if (mode != VOIDmode && mode != GET_MODE (op))
3027 switch (GET_CODE (op))
3033 return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
3041 /* Return 1 if this is a valid shift or rotate operation on a 386.
3042 OP is the expression matched, and MODE is its mode. */
3047 enum machine_mode mode;
3049 rtx operand = XEXP (op, 0);
3051 if (mode != VOIDmode && mode != GET_MODE (op))
3054 if (GET_MODE (operand) != GET_MODE (op)
3055 || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
3058 return (GET_CODE (op) == ASHIFT
3059 || GET_CODE (op) == ASHIFTRT
3060 || GET_CODE (op) == LSHIFTRT
3061 || GET_CODE (op) == ROTATE
3062 || GET_CODE (op) == ROTATERT);
3065 /* Return 1 if OP is COMPARE rtx with mode VOIDmode.
3066 MODE is not used. */
3069 VOIDmode_compare_op (op, mode)
3071 enum machine_mode mode;
3073 return GET_CODE (op) == COMPARE && GET_MODE (op) == VOIDmode;
3076 /* Output code to perform a 387 binary operation in INSN, one of PLUS,
3077 MINUS, MULT or DIV. OPERANDS are the insn operands, where operands[3]
3078 is the expression of the binary operation. The output may either be
3079 emitted here, or returned to the caller, like all output_* functions.
3081 There is no guarantee that the operands are the same mode, as they
3082 might be within FLOAT or FLOAT_EXTEND expressions. */
3085 output_387_binary_op (insn, operands)
3091 static char buf[100];
3093 switch (GET_CODE (operands[3]))
3096 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3097 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3104 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3105 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3112 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3113 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3120 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3121 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3131 strcpy (buf, base_op);
3133 switch (GET_CODE (operands[3]))
3137 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
3140 operands[2] = operands[1];
3144 if (GET_CODE (operands[2]) == MEM)
3145 return strcat (buf, AS1 (%z2,%2));
3147 if (NON_STACK_REG_P (operands[1]))
3149 output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
3152 else if (NON_STACK_REG_P (operands[2]))
3154 output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
3158 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
3159 return strcat (buf, AS2 (p,%2,%0));
3161 if (STACK_TOP_P (operands[0]))
3162 return strcat (buf, AS2C (%y2,%0));
3164 return strcat (buf, AS2C (%2,%0));
3168 if (GET_CODE (operands[1]) == MEM)
3169 return strcat (buf, AS1 (r%z1,%1));
3171 if (GET_CODE (operands[2]) == MEM)
3172 return strcat (buf, AS1 (%z2,%2));
3174 if (NON_STACK_REG_P (operands[1]))
3176 output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1)));
3179 else if (NON_STACK_REG_P (operands[2]))
3181 output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
3185 if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
3188 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
3189 return strcat (buf, AS2 (rp,%2,%0));
3191 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3192 return strcat (buf, AS2 (p,%1,%0));
3194 if (STACK_TOP_P (operands[0]))
3196 if (STACK_TOP_P (operands[1]))
3197 return strcat (buf, AS2C (%y2,%0));
3199 return strcat (buf, AS2 (r,%y1,%0));
3201 else if (STACK_TOP_P (operands[1]))
3202 return strcat (buf, AS2C (%1,%0));
3204 return strcat (buf, AS2 (r,%2,%0));
3211 /* Output code for INSN to convert a float to a signed int. OPERANDS
3212 are the insn operands. The output may be SFmode or DFmode and the
3213 input operand may be SImode or DImode. As a special case, make sure
3214 that the 387 stack top dies if the output mode is DImode, because the
3215 hardware requires this. */
3218 output_fix_trunc (insn, operands)
3222 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
3225 if (! STACK_TOP_P (operands[1]) ||
3226 (GET_MODE (operands[0]) == DImode && ! stack_top_dies))
3229 xops[0] = GEN_INT (12);
3230 xops[1] = operands[4];
3232 output_asm_insn (AS1 (fnstc%W2,%2), operands);
3233 output_asm_insn (AS2 (mov%L2,%2,%4), operands);
3234 output_asm_insn (AS2 (mov%B1,%0,%h1), xops);
3235 output_asm_insn (AS2 (mov%L4,%4,%3), operands);
3236 output_asm_insn (AS1 (fldc%W3,%3), operands);
3238 if (NON_STACK_REG_P (operands[0]))
3239 output_to_reg (operands[0], stack_top_dies);
3240 else if (GET_CODE (operands[0]) == MEM)
3243 output_asm_insn (AS1 (fistp%z0,%0), operands);
3245 output_asm_insn (AS1 (fist%z0,%0), operands);
3250 return AS1 (fldc%W2,%2);
3253 /* Output code for INSN to compare OPERANDS. The two operands might
3254 not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
3255 expression. If the compare is in mode CCFPEQmode, use an opcode that
3256 will not fault if a qNaN is present. */
3259 output_float_compare (insn, operands)
3264 rtx body = XVECEXP (PATTERN (insn), 0, 0);
3265 int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
3268 if (! STACK_TOP_P (operands[0]))
3271 operands[0] = operands[1];
3273 cc_status.flags |= CC_REVERSED;
3276 if (! STACK_TOP_P (operands[0]))
3279 stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
3281 if (STACK_REG_P (operands[1])
3283 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3284 && REGNO (operands[1]) != FIRST_STACK_REG)
3286 /* If both the top of the 387 stack dies, and the other operand
3287 is also a stack register that dies, then this must be a
3288 `fcompp' float compare */
3290 if (unordered_compare)
3291 output_asm_insn ("fucompp", operands);
3293 output_asm_insn ("fcompp", operands);
3297 static char buf[100];
3299 /* Decide if this is the integer or float compare opcode, or the
3300 unordered float compare. */
3302 if (unordered_compare)
3303 strcpy (buf, "fucom");
3304 else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT)
3305 strcpy (buf, "fcom");
3307 strcpy (buf, "ficom");
3309 /* Modify the opcode if the 387 stack is to be popped. */
3314 if (NON_STACK_REG_P (operands[1]))
3315 output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
3317 output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
3320 /* Now retrieve the condition code. */
3322 return output_fp_cc0_set (insn);
3325 /* Output opcodes to transfer the results of FP compare or test INSN
3326 from the FPU to the CPU flags. If TARGET_IEEE_FP, ensure that if the
3327 result of the compare or test is unordered, no comparison operator
3328 succeeds except NE. Return an output template, if any. */
3331 output_fp_cc0_set (insn)
3335 rtx unordered_label;
3339 xops[0] = gen_rtx (REG, HImode, 0);
3340 output_asm_insn (AS1 (fnsts%W0,%0), xops);
3342 if (! TARGET_IEEE_FP)
3344 if (!(cc_status.flags & CC_REVERSED))
3346 next = next_cc0_user (insn);
3348 if (GET_CODE (next) == JUMP_INSN
3349 && GET_CODE (PATTERN (next)) == SET
3350 && SET_DEST (PATTERN (next)) == pc_rtx
3351 && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
3353 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
3355 else if (GET_CODE (PATTERN (next)) == SET)
3357 code = GET_CODE (SET_SRC (PATTERN (next)));
3363 if (code == GT || code == LT || code == EQ || code == NE
3364 || code == LE || code == GE)
3365 { /* We will test eax directly */
3366 cc_status.flags |= CC_TEST_AX;
3373 next = next_cc0_user (insn);
3374 if (next == NULL_RTX)
3377 if (GET_CODE (next) == JUMP_INSN
3378 && GET_CODE (PATTERN (next)) == SET
3379 && SET_DEST (PATTERN (next)) == pc_rtx
3380 && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
3382 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
3384 else if (GET_CODE (PATTERN (next)) == SET)
3386 code = GET_CODE (SET_SRC (PATTERN (next)));
3391 xops[0] = gen_rtx (REG, QImode, 0);
3396 xops[1] = GEN_INT (0x45);
3397 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3402 xops[1] = GEN_INT (0x45);
3403 xops[2] = GEN_INT (0x01);
3404 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3405 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
3410 xops[1] = GEN_INT (0x05);
3411 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3416 xops[1] = GEN_INT (0x45);
3417 xops[2] = GEN_INT (0x40);
3418 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3419 output_asm_insn (AS1 (dec%B0,%h0), xops);
3420 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
3425 xops[1] = GEN_INT (0x45);
3426 xops[2] = GEN_INT (0x40);
3427 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3428 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
3433 xops[1] = GEN_INT (0x44);
3434 xops[2] = GEN_INT (0x40);
3435 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3436 output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
3450 #define MAX_386_STACK_LOCALS 2
3452 static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
3454 /* Define the structure for the machine field in struct function. */
3455 struct machine_function
3457 rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
3460 /* Functions to save and restore i386_stack_locals.
3461 These will be called, via pointer variables,
3462 from push_function_context and pop_function_context. */
3465 save_386_machine_status (p)
3468 p->machine = (struct machine_function *) xmalloc (sizeof i386_stack_locals);
3469 bcopy ((char *) i386_stack_locals, (char *) p->machine->i386_stack_locals,
3470 sizeof i386_stack_locals);
3474 restore_386_machine_status (p)
3477 bcopy ((char *) p->machine->i386_stack_locals, (char *) i386_stack_locals,
3478 sizeof i386_stack_locals);
3482 /* Clear stack slot assignments remembered from previous functions.
3483 This is called from INIT_EXPANDERS once before RTL is emitted for each
3487 clear_386_stack_locals ()
3489 enum machine_mode mode;
3492 for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
3493 mode = (enum machine_mode) ((int) mode + 1))
3494 for (n = 0; n < MAX_386_STACK_LOCALS; n++)
3495 i386_stack_locals[(int) mode][n] = NULL_RTX;
3497 /* Arrange to save and restore i386_stack_locals around nested functions. */
3498 save_machine_status = save_386_machine_status;
3499 restore_machine_status = restore_386_machine_status;
3502 /* Return a MEM corresponding to a stack slot with mode MODE.
3503 Allocate a new slot if necessary.
3505 The RTL for a function can have several slots available: N is
3506 which slot to use. */
3509 assign_386_stack_local (mode, n)
3510 enum machine_mode mode;
3513 if (n < 0 || n >= MAX_386_STACK_LOCALS)
3516 if (i386_stack_locals[(int) mode][n] == NULL_RTX)
3517 i386_stack_locals[(int) mode][n]
3518 = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
3520 return i386_stack_locals[(int) mode][n];
3526 enum machine_mode mode;
3528 return (GET_CODE (op) == MULT);
3533 enum machine_mode mode;
3535 return (GET_CODE (op) == DIV);
3540 /* Create a new copy of an rtx.
3541 Recursively copies the operands of the rtx,
3542 except for those few rtx codes that are sharable.
3543 Doesn't share CONST */
3551 register RTX_CODE code;
3552 register char *format_ptr;
3554 code = GET_CODE (orig);
3567 /* SCRATCH must be shared because they represent distinct values. */
3572 /* CONST can be shared if it contains a SYMBOL_REF. If it contains
3573 a LABEL_REF, it isn't sharable. */
3574 if (GET_CODE (XEXP (orig, 0)) == PLUS
3575 && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
3576 && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
3580 /* A MEM with a constant address is not sharable. The problem is that
3581 the constant address may need to be reloaded. If the mem is shared,
3582 then reloading one copy of this mem will cause all copies to appear
3583 to have been reloaded. */
3586 copy = rtx_alloc (code);
3587 PUT_MODE (copy, GET_MODE (orig));
3588 copy->in_struct = orig->in_struct;
3589 copy->volatil = orig->volatil;
3590 copy->unchanging = orig->unchanging;
3591 copy->integrated = orig->integrated;
3593 copy->is_spill_rtx = orig->is_spill_rtx;
3595 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
3597 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
3599 switch (*format_ptr++)
3602 XEXP (copy, i) = XEXP (orig, i);
3603 if (XEXP (orig, i) != NULL)
3604 XEXP (copy, i) = copy_rtx (XEXP (orig, i));
3609 XEXP (copy, i) = XEXP (orig, i);
3614 XVEC (copy, i) = XVEC (orig, i);
3615 if (XVEC (orig, i) != NULL)
3617 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
3618 for (j = 0; j < XVECLEN (copy, i); j++)
3619 XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
3624 XWINT (copy, i) = XWINT (orig, i);
3628 XINT (copy, i) = XINT (orig, i);
3633 XSTR (copy, i) = XSTR (orig, i);
3644 /* try to rewrite a memory address to make it valid */
3646 rewrite_address (mem_rtx)
3649 rtx index_rtx, base_rtx, offset_rtx, scale_rtx, ret_rtx;
3651 int offset_adjust = 0;
3652 int was_only_offset = 0;
3653 rtx mem_addr = XEXP (mem_rtx, 0);
3654 char *storage = (char *) oballoc (0);
3656 int is_spill_rtx = 0;
3658 in_struct = MEM_IN_STRUCT_P (mem_rtx);
3659 is_spill_rtx = RTX_IS_SPILL_P (mem_rtx);
3661 if (GET_CODE (mem_addr) == PLUS &&
3662 GET_CODE (XEXP (mem_addr, 1)) == PLUS &&
3663 GET_CODE (XEXP (XEXP (mem_addr, 1), 0)) == REG)
3664 { /* this part is utilized by the combiner */
3666 gen_rtx (PLUS, GET_MODE (mem_addr),
3667 gen_rtx (PLUS, GET_MODE (XEXP (mem_addr, 1)),
3669 XEXP (XEXP (mem_addr, 1), 0)),
3670 XEXP (XEXP (mem_addr, 1), 1));
3671 if (memory_address_p (GET_MODE (mem_rtx), ret_rtx))
3673 XEXP (mem_rtx, 0) = ret_rtx;
3674 RTX_IS_SPILL_P (ret_rtx) = is_spill_rtx;
3680 /* this part is utilized by loop.c */
3681 /* If the address contains PLUS (reg,const) and this pattern is invalid
3682 in this case - try to rewrite the address to make it valid intel1
3684 storage = (char *) oballoc (0);
3685 index_rtx = base_rtx = offset_rtx = NULL;
3686 /* find the base index and offset elements of the memory address */
3687 if (GET_CODE (mem_addr) == PLUS)
3689 if (GET_CODE (XEXP (mem_addr, 0)) == REG)
3691 if (GET_CODE (XEXP (mem_addr, 1)) == REG)
3693 base_rtx = XEXP (mem_addr, 1);
3694 index_rtx = XEXP (mem_addr, 0);
3698 base_rtx = XEXP (mem_addr, 0);
3699 offset_rtx = XEXP (mem_addr, 1);
3702 else if (GET_CODE (XEXP (mem_addr, 0)) == MULT)
3704 index_rtx = XEXP (mem_addr, 0);
3705 if (GET_CODE (XEXP (mem_addr, 1)) == REG)
3707 base_rtx = XEXP (mem_addr, 1);
3711 offset_rtx = XEXP (mem_addr, 1);
3714 else if (GET_CODE (XEXP (mem_addr, 0)) == PLUS)
3717 if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == PLUS &&
3718 GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0)) == MULT &&
3719 GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 0)) == REG &&
3720 GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 1)) == CONST_INT &&
3721 GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1)) == CONST_INT &&
3722 GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == REG &&
3723 GET_CODE (XEXP (mem_addr, 1)) == SYMBOL_REF)
3725 index_rtx = XEXP (XEXP (XEXP (mem_addr, 0), 0), 0);
3726 offset_rtx = XEXP (mem_addr, 1);
3727 base_rtx = XEXP (XEXP (mem_addr, 0), 1);
3728 offset_adjust = INTVAL (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1));
3732 offset_rtx = XEXP (mem_addr, 1);
3733 index_rtx = XEXP (XEXP (mem_addr, 0), 0);
3734 base_rtx = XEXP (XEXP (mem_addr, 0), 1);
3737 else if (GET_CODE (XEXP (mem_addr, 0)) == CONST_INT)
3739 was_only_offset = 1;
3742 offset_rtx = XEXP (mem_addr, 1);
3743 offset_adjust = INTVAL (XEXP (mem_addr, 0));
3744 if (offset_adjust == 0)
3746 XEXP (mem_rtx, 0) = offset_rtx;
3747 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
3757 else if (GET_CODE (mem_addr) == MULT)
3759 index_rtx = mem_addr;
3766 if (index_rtx && GET_CODE (index_rtx) == MULT)
3768 if (GET_CODE (XEXP (index_rtx, 1)) != CONST_INT)
3773 scale_rtx = XEXP (index_rtx, 1);
3774 scale = INTVAL (scale_rtx);
3775 index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
3777 /* now find which of the elements are invalid and try to fix them */
3778 if (index_rtx && GET_CODE (index_rtx) == CONST_INT && base_rtx == NULL)
3780 offset_adjust = INTVAL (index_rtx) * scale;
3781 if (offset_rtx && GET_CODE (offset_rtx) == CONST &&
3782 GET_CODE (XEXP (offset_rtx, 0)) == PLUS)
3784 if (GET_CODE (XEXP (XEXP (offset_rtx, 0), 0)) == SYMBOL_REF &&
3785 GET_CODE (XEXP (XEXP (offset_rtx, 0), 1)) == CONST_INT)
3787 offset_rtx = copy_all_rtx (offset_rtx);
3788 XEXP (XEXP (offset_rtx, 0), 1) =
3789 gen_rtx (CONST_INT, 0, INTVAL (XEXP (XEXP (offset_rtx, 0), 1)) + offset_adjust);
3790 if (!CONSTANT_P (offset_rtx))
3797 else if (offset_rtx && GET_CODE (offset_rtx) == SYMBOL_REF)
3800 gen_rtx (CONST, GET_MODE (offset_rtx),
3801 gen_rtx (PLUS, GET_MODE (offset_rtx),
3803 gen_rtx (CONST_INT, 0, offset_adjust)));
3804 if (!CONSTANT_P (offset_rtx))
3810 else if (offset_rtx && GET_CODE (offset_rtx) == CONST_INT)
3812 offset_rtx = gen_rtx (CONST_INT, 0, INTVAL (offset_rtx) + offset_adjust);
3814 else if (!offset_rtx)
3816 offset_rtx = gen_rtx (CONST_INT, 0, 0);
3818 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
3819 XEXP (mem_rtx, 0) = offset_rtx;
3822 if (base_rtx && GET_CODE (base_rtx) == PLUS &&
3823 GET_CODE (XEXP (base_rtx, 0)) == REG &&
3824 GET_CODE (XEXP (base_rtx, 1)) == CONST_INT)
3826 offset_adjust += INTVAL (XEXP (base_rtx, 1));
3827 base_rtx = copy_all_rtx (XEXP (base_rtx, 0));
3829 else if (base_rtx && GET_CODE (base_rtx) == CONST_INT)
3831 offset_adjust += INTVAL (base_rtx);
3834 if (index_rtx && GET_CODE (index_rtx) == PLUS &&
3835 GET_CODE (XEXP (index_rtx, 0)) == REG &&
3836 GET_CODE (XEXP (index_rtx, 1)) == CONST_INT)
3838 offset_adjust += INTVAL (XEXP (index_rtx, 1)) * scale;
3839 index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
3843 if (!LEGITIMATE_INDEX_P (index_rtx)
3844 && !(index_rtx == stack_pointer_rtx && scale == 1 && base_rtx == NULL))
3852 if (!LEGITIMATE_INDEX_P (base_rtx) && GET_CODE (base_rtx) != REG)
3858 if (offset_adjust != 0)
3862 if (GET_CODE (offset_rtx) == CONST &&
3863 GET_CODE (XEXP (offset_rtx, 0)) == PLUS)
3865 if (GET_CODE (XEXP (XEXP (offset_rtx, 0), 0)) == SYMBOL_REF &&
3866 GET_CODE (XEXP (XEXP (offset_rtx, 0), 1)) == CONST_INT)
3868 offset_rtx = copy_all_rtx (offset_rtx);
3869 XEXP (XEXP (offset_rtx, 0), 1) =
3870 gen_rtx (CONST_INT, 0, INTVAL (XEXP (XEXP (offset_rtx, 0), 1)) + offset_adjust);
3871 if (!CONSTANT_P (offset_rtx))
3878 else if (GET_CODE (offset_rtx) == SYMBOL_REF)
3881 gen_rtx (CONST, GET_MODE (offset_rtx),
3882 gen_rtx (PLUS, GET_MODE (offset_rtx),
3884 gen_rtx (CONST_INT, 0, offset_adjust)));
3885 if (!CONSTANT_P (offset_rtx))
3891 else if (GET_CODE (offset_rtx) == CONST_INT)
3893 offset_rtx = gen_rtx (CONST_INT, 0, INTVAL (offset_rtx) + offset_adjust);
3903 offset_rtx = gen_rtx (CONST_INT, 0, offset_adjust);
3911 if (GET_CODE (offset_rtx) == CONST_INT &&
3912 INTVAL (offset_rtx) == 0)
3914 ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx),
3915 gen_rtx (MULT, GET_MODE (index_rtx), index_rtx,
3921 ret_rtx = gen_rtx (PLUS, GET_MODE (offset_rtx),
3922 gen_rtx (PLUS, GET_MODE (base_rtx),
3923 gen_rtx (MULT, GET_MODE (index_rtx), index_rtx,
3931 if (GET_CODE (offset_rtx) == CONST_INT &&
3932 INTVAL (offset_rtx) == 0)
3934 ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx), index_rtx, base_rtx);
3938 ret_rtx = gen_rtx (PLUS, GET_MODE (offset_rtx),
3939 gen_rtx (PLUS, GET_MODE (index_rtx), index_rtx,
3949 if (GET_CODE (offset_rtx) == CONST_INT &&
3950 INTVAL (offset_rtx) == 0)
3952 ret_rtx = gen_rtx (MULT, GET_MODE (index_rtx), index_rtx, scale_rtx);
3957 gen_rtx (PLUS, GET_MODE (offset_rtx),
3958 gen_rtx (MULT, GET_MODE (index_rtx), index_rtx,
3965 if (GET_CODE (offset_rtx) == CONST_INT &&
3966 INTVAL (offset_rtx) == 0)
3968 ret_rtx = index_rtx;
3972 ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx), index_rtx, offset_rtx);
3981 if (GET_CODE (offset_rtx) == CONST_INT &&
3982 INTVAL (offset_rtx) == 0)
3988 ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx), base_rtx, offset_rtx);
3991 else if (was_only_offset)
3993 ret_rtx = offset_rtx;
4001 XEXP (mem_rtx, 0) = ret_rtx;
4002 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4014 /* return 1 if the first insn to set cc before insn also sets the register
4015 reg_rtx - otherwise return 0 */
4017 last_to_set_cc (reg_rtx, insn)
4020 rtx prev_insn = PREV_INSN (insn);
4024 if (GET_CODE (prev_insn) == NOTE)
4027 else if (GET_CODE (prev_insn) == INSN)
4029 if (GET_CODE (PATTERN (prev_insn)) != SET)
4032 if (rtx_equal_p (SET_DEST (PATTERN (prev_insn)), reg_rtx))
4034 if (sets_condition_code (SET_SRC (PATTERN (prev_insn))))
4040 else if (!doesnt_set_condition_code (SET_SRC (PATTERN (prev_insn))))
4047 prev_insn = PREV_INSN (prev_insn);
4055 doesnt_set_condition_code (pat)
4058 switch (GET_CODE (pat))
4072 sets_condition_code (pat)
4075 switch (GET_CODE (pat))
4099 str_immediate_operand (op, mode)
4101 enum machine_mode mode;
4103 if (GET_CODE (op) == CONST_INT && INTVAL (op) <= 32 && INTVAL (op) >= 0)
4115 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4116 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4117 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4118 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode))
4127 Return 1 if the mode of the SET_DEST of insn is floating point
4128 and it is not an fld or a move from memory to memory.
4129 Otherwise return 0 */
4134 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4135 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4136 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4137 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
4138 && GET_CODE (SET_DEST (PATTERN (insn))) == REG
4139 && REGNO (SET_DEST (PATTERN (insn))) >= FIRST_FLOAT_REG
4140 && GET_CODE (SET_SRC (insn)) != MEM)
4149 Return 1 if the mode of the SET_DEST floating point and is memory
4150 and the source is a register.
4156 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4157 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4158 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4159 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
4160 && GET_CODE (SET_DEST (PATTERN (insn))) == MEM
4161 && GET_CODE (SET_SRC (PATTERN (insn))) == REG)
4171 Return 1 if dep_insn sets a register which insn uses as a base
4172 or index to reference memory.
4173 otherwise return 0 */
4176 agi_dependent (insn, dep_insn)
4179 if (GET_CODE (dep_insn) == INSN
4180 && GET_CODE (PATTERN (dep_insn)) == SET
4181 && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG)
4183 return (reg_mentioned_in_mem (SET_DEST (PATTERN (dep_insn)), insn));
4186 if (GET_CODE (dep_insn) == INSN && GET_CODE (PATTERN (dep_insn)) == SET
4187 && GET_CODE (SET_DEST (PATTERN (dep_insn))) == MEM
4188 && push_operand (SET_DEST (PATTERN (dep_insn)),
4189 GET_MODE (SET_DEST (PATTERN (dep_insn)))))
4191 return (reg_mentioned_in_mem (stack_pointer_rtx, insn));
4199 Return 1 if reg is used in rtl as a base or index for a memory ref
4200 otherwise return 0. */
4203 reg_mentioned_in_mem (reg, rtl)
4208 register enum rtx_code code;
4213 code = GET_CODE (rtl);
4231 if (code == MEM && reg_mentioned_p (reg, rtl))
4234 fmt = GET_RTX_FORMAT (code);
4235 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4240 for (j = XVECLEN (rtl, i) - 1; j >= 0; j--)
4242 if (reg_mentioned_in_mem (reg, XVECEXP (rtl, i, j)))
4247 else if (fmt[i] == 'e' && reg_mentioned_in_mem (reg, XEXP (rtl, i)))
4254 /* Output the approprate insns for doing strlen if not just doing repnz; scasb
4256 operands[0] = result, initialized with the startaddress
4257 operands[1] = alignment of the address.
4258 operands[2] = scratch register, initialized with the startaddress when
4259 not aligned, otherwise undefined
4261 This is just the body. It needs the initialisations mentioned above and
4262 some address computing at the end. These things are done in i386.md. */
4265 output_strlen_unroll (operands)
4270 xops[0] = operands[0]; /* Result */
4271 /* operands[1]; * Alignment */
4272 xops[1] = operands[2]; /* Scratch */
4273 xops[2] = GEN_INT (0);
4274 xops[3] = GEN_INT (2);
4275 xops[4] = GEN_INT (3);
4276 xops[5] = GEN_INT (4);
4277 /* xops[6] = gen_label_rtx (); * label when aligned to 3-byte */
4278 /* xops[7] = gen_label_rtx (); * label when aligned to 2-byte */
4279 xops[8] = gen_label_rtx (); /* label of main loop */
4280 if(TARGET_USE_Q_REG && QI_REG_P (xops[1]))
4281 xops[9] = gen_label_rtx (); /* pentium optimisation */
4282 xops[10] = gen_label_rtx (); /* end label 2 */
4283 xops[11] = gen_label_rtx (); /* end label 1 */
4284 xops[12] = gen_label_rtx (); /* end label */
4285 /* xops[13] * Temporary used */
4286 xops[14] = GEN_INT (0xff);
4287 xops[15] = GEN_INT (0xff00);
4288 xops[16] = GEN_INT (0xff0000);
4289 xops[17] = GEN_INT (0xff000000);
4291 /* Loop to check 1..3 bytes for null to get an aligned pointer */
4293 /* is there a known alignment and is it less then 4 */
4294 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) < 4)
4296 /* is there a known alignment and is it not 2 */
4297 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
4299 xops[6] = gen_label_rtx (); /* label when aligned to 3-byte */
4300 xops[7] = gen_label_rtx (); /* label when aligned to 2-byte */
4302 /* leave just the 3 lower bits */
4303 /* if this is a q-register, then the high part is used later */
4304 /* therefore user andl rather than andb */
4305 output_asm_insn (AS2 (and%L1,%4,%1), xops);
4306 /* is aligned to 4-byte adress when zero */
4307 output_asm_insn (AS1 (je,%l8), xops);
4308 /* side-effect even Parity when %eax == 3 */
4309 output_asm_insn (AS1 (jp,%6), xops);
4311 /* is it aligned to 2 bytes ? */
4312 if (QI_REG_P (xops[1]))
4313 output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
4315 output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
4316 output_asm_insn (AS1 (je,%7), xops);
4320 /* since the alignment is 2, we have to check 2 or 0 bytes */
4322 /* check if is aligned to 4 - byte */
4323 output_asm_insn (AS2 (and%L1,%3,%1), xops);
4324 /* is aligned to 4-byte adress when zero */
4325 output_asm_insn (AS1 (je,%l8), xops);
4328 xops[13] = gen_rtx (MEM, QImode, xops[0]);
4329 /* now, compare the bytes */
4330 /* compare with the high part of a q-reg gives shorter code */
4331 if (QI_REG_P (xops[1]))
4333 /* compare the first n unaligned byte on a byte per byte basis */
4334 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
4335 /* when zero we reached the end */
4336 output_asm_insn (AS1 (je,%l12), xops);
4337 /* increment the address */
4338 output_asm_insn (AS1 (inc%L0,%0), xops);
4340 /* not needed with an alignment of 2 */
4341 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
4343 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[7]));
4344 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
4345 output_asm_insn (AS1 (je,%l12), xops);
4346 output_asm_insn (AS1 (inc%L0,%0), xops);
4348 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[6]));
4350 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
4354 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
4355 output_asm_insn (AS1 (je,%l12), xops);
4356 output_asm_insn (AS1 (inc%L0,%0), xops);
4358 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[7]));
4359 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
4360 output_asm_insn (AS1 (je,%l12), xops);
4361 output_asm_insn (AS1 (inc%L0,%0), xops);
4363 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[6]));
4364 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
4366 output_asm_insn (AS1 (je,%l12), xops);
4367 output_asm_insn (AS1 (inc%L0,%0), xops);
4370 /* Generate loop to check 4 bytes at a time */
4371 /* IMHO it is not a good idea to align this loop. It gives only */
4372 /* huge programms, but does not help to speed up */
4373 /* ASM_OUTPUT_LOOP_ALIGN (asm_out_file); */
4374 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[8]));
4376 xops[13] = gen_rtx (MEM, SImode, xops[0]);
4377 output_asm_insn (AS2 (mov%L1,%13,%1), xops);
4379 if (QI_REG_P (xops[1]))
4381 /* on i586 it is faster to compare the hi- and lo- part */
4382 /* as a kind of lookahead. If xoring both is zero, then one */
4383 /* of both *could* be zero, otherwith none of both is zero */
4384 /* this saves one instruction, on i486 this is slower */
4385 /* testet with P-90, i486DX2-66, AMD486DX2-66 */
4388 output_asm_insn (AS2 (test%B1,%h1,%b1), xops);
4389 output_asm_insn (AS1 (jne,%l9), xops);
4392 /* check first byte */
4393 output_asm_insn (AS2 (test%B1,%b1,%b1), xops);
4394 output_asm_insn (AS1 (je,%l12), xops);
4396 /* check second byte */
4397 output_asm_insn (AS2 (test%B1,%h1,%h1), xops);
4398 output_asm_insn (AS1 (je,%l11), xops);
4401 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[9]));
4405 /* check first byte */
4406 output_asm_insn (AS2 (test%L1,%14,%1), xops);
4407 output_asm_insn (AS1 (je,%l12), xops);
4409 /* check second byte */
4410 output_asm_insn (AS2 (test%L1,%15,%1), xops);
4411 output_asm_insn (AS1 (je,%l11), xops);
4414 /* check third byte */
4415 output_asm_insn (AS2 (test%L1,%16,%1), xops);
4416 output_asm_insn (AS1 (je,%l10), xops);
4418 /* check fourth byte and increment address */
4419 output_asm_insn (AS2 (add%L0,%5,%0), xops);
4420 output_asm_insn (AS2 (test%L1,%17,%1), xops);
4421 output_asm_insn (AS1 (jne,%l8), xops);
4423 /* now generate fixups when the compare stops within a 4-byte word */
4424 output_asm_insn (AS2 (sub%L0,%4,%0), xops);
4426 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[10]));
4427 output_asm_insn (AS1 (inc%L0,%0), xops);
4429 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[11]));
4430 output_asm_insn (AS1 (inc%L0,%0), xops);
4432 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[12]));