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))) {
472 /* Stdcall functions will pop the stack if not variable args */
473 if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype)))
477 && (TYPE_ARG_TYPES (funtype) == NULL_TREE
478 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (funtype))) == void_type_node)))
482 /* Lose any fake structure return argument */
483 if (aggregate_value_p (TREE_TYPE (funtype)))
484 return GET_MODE_SIZE (Pmode);
490 /* Argument support functions. */
492 /* Initialize a variable CUM of type CUMULATIVE_ARGS
493 for a call to a function whose data type is FNTYPE.
494 For a library call, FNTYPE is 0. */
497 init_cumulative_args (cum, fntype, libname)
498 CUMULATIVE_ARGS *cum; /* argument info to initialize */
499 tree fntype; /* tree ptr for function decl */
500 rtx libname; /* SYMBOL_REF of library name or 0 */
502 static CUMULATIVE_ARGS zero_cum;
503 tree param, next_param;
505 if (TARGET_DEBUG_ARG)
507 fprintf (stderr, "\ninit_cumulative_args (");
510 tree ret_type = TREE_TYPE (fntype);
511 fprintf (stderr, "fntype code = %s, ret code = %s",
512 tree_code_name[ (int)TREE_CODE (fntype) ],
513 tree_code_name[ (int)TREE_CODE (ret_type) ]);
516 fprintf (stderr, "no fntype");
519 fprintf (stderr, ", libname = %s", XSTR (libname, 0));
524 /* Set up the number of registers to use for passing arguments. */
525 cum->nregs = i386_regparm;
528 tree attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (fntype));
530 cum->nregs = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
533 /* Determine if this function has variable arguments. This is
534 indicated by the last argument being 'void_type_mode' if there
535 are no variable arguments. If there are variable arguments, then
536 we won't pass anything in registers */
540 for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
544 next_param = TREE_CHAIN (param);
545 if (next_param == (tree)0 && TREE_VALUE (param) != void_type_node)
550 if (TARGET_DEBUG_ARG)
551 fprintf (stderr, ", nregs=%d )\n", cum->nregs);
556 /* Update the data in CUM to advance over an argument
557 of mode MODE and data type TYPE.
558 (TYPE is null for libcalls where that information may not be available.) */
561 function_arg_advance (cum, mode, type, named)
562 CUMULATIVE_ARGS *cum; /* current arg information */
563 enum machine_mode mode; /* current arg mode */
564 tree type; /* type of the argument or 0 if lib support */
565 int named; /* whether or not the argument was named */
567 int bytes = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
568 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
570 if (TARGET_DEBUG_ARG)
572 "function_adv( size=%d, words=%2d, nregs=%d, mode=%4s, named=%d )\n\n",
573 words, cum->words, cum->nregs, GET_MODE_NAME (mode), named);
588 /* Define where to put the arguments to a function.
589 Value is zero to push the argument on the stack,
590 or a hard register in which to store the argument.
592 MODE is the argument's machine mode.
593 TYPE is the data type of the argument (as a tree).
594 This is null for libcalls where that information may
596 CUM is a variable of type CUMULATIVE_ARGS which gives info about
597 the preceding args and about the function being called.
598 NAMED is nonzero if this argument is a named parameter
599 (otherwise it is an extra parameter matching an ellipsis). */
602 function_arg (cum, mode, type, named)
603 CUMULATIVE_ARGS *cum; /* current arg information */
604 enum machine_mode mode; /* current arg mode */
605 tree type; /* type of the argument or 0 if lib support */
606 int named; /* != 0 for normal args, == 0 for ... args */
609 int bytes = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
610 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
614 default: /* for now, pass fp/complex values on the stack */
622 if (words <= cum->nregs)
623 ret = gen_rtx (REG, mode, cum->regno);
627 if (TARGET_DEBUG_ARG)
630 "function_arg( size=%d, words=%2d, nregs=%d, mode=%4s, named=%d",
631 words, cum->words, cum->nregs, GET_MODE_NAME (mode), named);
634 fprintf (stderr, ", reg=%%e%s", reg_names[ REGNO(ret) ]);
636 fprintf (stderr, ", stack");
638 fprintf (stderr, " )\n");
644 /* For an arg passed partly in registers and partly in memory,
645 this is the number of registers used.
646 For args passed entirely in registers or entirely in memory, zero. */
649 function_arg_partial_nregs (cum, mode, type, named)
650 CUMULATIVE_ARGS *cum; /* current arg information */
651 enum machine_mode mode; /* current arg mode */
652 tree type; /* type of the argument or 0 if lib support */
653 int named; /* != 0 for normal args, == 0 for ... args */
659 /* Output an insn whose source is a 386 integer register. SRC is the
660 rtx for the register, and TEMPLATE is the op-code template. SRC may
661 be either SImode or DImode.
663 The template will be output with operands[0] as SRC, and operands[1]
664 as a pointer to the top of the 386 stack. So a call from floatsidf2
665 would look like this:
667 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
669 where %z0 corresponds to the caller's operands[1], and is used to
670 emit the proper size suffix.
672 ??? Extend this to handle HImode - a 387 can load and store HImode
676 output_op_from_reg (src, template)
681 int size = GET_MODE_SIZE (GET_MODE (src));
684 xops[1] = AT_SP (Pmode);
685 xops[2] = GEN_INT (size);
686 xops[3] = stack_pointer_rtx;
688 if (size > UNITS_PER_WORD)
691 if (size > 2 * UNITS_PER_WORD)
693 high = gen_rtx (REG, SImode, REGNO (src) + 2);
694 output_asm_insn (AS1 (push%L0,%0), &high);
696 high = gen_rtx (REG, SImode, REGNO (src) + 1);
697 output_asm_insn (AS1 (push%L0,%0), &high);
699 output_asm_insn (AS1 (push%L0,%0), &src);
701 output_asm_insn (template, xops);
703 output_asm_insn (AS2 (add%L3,%2,%3), xops);
706 /* Output an insn to pop an value from the 387 top-of-stack to 386
707 register DEST. The 387 register stack is popped if DIES is true. If
708 the mode of DEST is an integer mode, a `fist' integer store is done,
709 otherwise a `fst' float store is done. */
712 output_to_reg (dest, dies)
717 int size = GET_MODE_SIZE (GET_MODE (dest));
719 xops[0] = AT_SP (Pmode);
720 xops[1] = stack_pointer_rtx;
721 xops[2] = GEN_INT (size);
724 output_asm_insn (AS2 (sub%L1,%2,%1), xops);
726 if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_INT)
729 output_asm_insn (AS1 (fistp%z3,%y0), xops);
731 output_asm_insn (AS1 (fist%z3,%y0), xops);
733 else if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_FLOAT)
736 output_asm_insn (AS1 (fstp%z3,%y0), xops);
739 if (GET_MODE (dest) == XFmode)
741 output_asm_insn (AS1 (fstp%z3,%y0), xops);
742 output_asm_insn (AS1 (fld%z3,%y0), xops);
745 output_asm_insn (AS1 (fst%z3,%y0), xops);
751 output_asm_insn (AS1 (pop%L0,%0), &dest);
753 if (size > UNITS_PER_WORD)
755 dest = gen_rtx (REG, SImode, REGNO (dest) + 1);
756 output_asm_insn (AS1 (pop%L0,%0), &dest);
757 if (size > 2 * UNITS_PER_WORD)
759 dest = gen_rtx (REG, SImode, REGNO (dest) + 1);
760 output_asm_insn (AS1 (pop%L0,%0), &dest);
766 singlemove_string (operands)
770 if (GET_CODE (operands[0]) == MEM
771 && GET_CODE (x = XEXP (operands[0], 0)) == PRE_DEC)
773 if (XEXP (x, 0) != stack_pointer_rtx)
777 else if (GET_CODE (operands[1]) == CONST_DOUBLE)
779 return output_move_const_single (operands);
781 else if (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == REG)
782 return AS2 (mov%L0,%1,%0);
783 else if (CONSTANT_P (operands[1]))
784 return AS2 (mov%L0,%1,%0);
787 output_asm_insn ("push%L1 %1", operands);
792 /* Return a REG that occurs in ADDR with coefficient 1.
793 ADDR can be effectively incremented by incrementing REG. */
799 while (GET_CODE (addr) == PLUS)
801 if (GET_CODE (XEXP (addr, 0)) == REG)
802 addr = XEXP (addr, 0);
803 else if (GET_CODE (XEXP (addr, 1)) == REG)
804 addr = XEXP (addr, 1);
805 else if (CONSTANT_P (XEXP (addr, 0)))
806 addr = XEXP (addr, 1);
807 else if (CONSTANT_P (XEXP (addr, 1)))
808 addr = XEXP (addr, 0);
812 if (GET_CODE (addr) == REG)
818 /* Output an insn to add the constant N to the register X. */
829 output_asm_insn (AS1 (dec%L0,%0), xops);
831 output_asm_insn (AS1 (inc%L0,%0), xops);
834 xops[1] = GEN_INT (-n);
835 output_asm_insn (AS2 (sub%L0,%1,%0), xops);
839 xops[1] = GEN_INT (n);
840 output_asm_insn (AS2 (add%L0,%1,%0), xops);
845 /* Output assembler code to perform a doubleword move insn
846 with operands OPERANDS. */
849 output_move_double (operands)
852 enum {REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
856 rtx addreg0 = 0, addreg1 = 0;
857 int dest_overlapped_low = 0;
858 int size = GET_MODE_SIZE (GET_MODE (operands[0]));
863 /* First classify both operands. */
865 if (REG_P (operands[0]))
867 else if (offsettable_memref_p (operands[0]))
869 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
871 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
873 else if (GET_CODE (operands[0]) == MEM)
878 if (REG_P (operands[1]))
880 else if (CONSTANT_P (operands[1]))
882 else if (offsettable_memref_p (operands[1]))
884 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
886 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
888 else if (GET_CODE (operands[1]) == MEM)
893 /* Check for the cases that the operand constraints are not
894 supposed to allow to happen. Abort if we get one,
895 because generating code for these cases is painful. */
897 if (optype0 == RNDOP || optype1 == RNDOP)
900 /* If one operand is decrementing and one is incrementing
901 decrement the former register explicitly
902 and change that operand into ordinary indexing. */
904 if (optype0 == PUSHOP && optype1 == POPOP)
906 /* ??? Can this ever happen on i386? */
907 operands[0] = XEXP (XEXP (operands[0], 0), 0);
908 asm_add (-size, operands[0]);
909 if (GET_MODE (operands[1]) == XFmode)
910 operands[0] = gen_rtx (MEM, XFmode, operands[0]);
911 else if (GET_MODE (operands[0]) == DFmode)
912 operands[0] = gen_rtx (MEM, DFmode, operands[0]);
914 operands[0] = gen_rtx (MEM, DImode, operands[0]);
918 if (optype0 == POPOP && optype1 == PUSHOP)
920 /* ??? Can this ever happen on i386? */
921 operands[1] = XEXP (XEXP (operands[1], 0), 0);
922 asm_add (-size, operands[1]);
923 if (GET_MODE (operands[1]) == XFmode)
924 operands[1] = gen_rtx (MEM, XFmode, operands[1]);
925 else if (GET_MODE (operands[1]) == DFmode)
926 operands[1] = gen_rtx (MEM, DFmode, operands[1]);
928 operands[1] = gen_rtx (MEM, DImode, operands[1]);
932 /* If an operand is an unoffsettable memory ref, find a register
933 we can increment temporarily to make it refer to the second word. */
935 if (optype0 == MEMOP)
936 addreg0 = find_addr_reg (XEXP (operands[0], 0));
938 if (optype1 == MEMOP)
939 addreg1 = find_addr_reg (XEXP (operands[1], 0));
941 /* Ok, we can do one word at a time.
942 Normally we do the low-numbered word first,
943 but if either operand is autodecrementing then we
944 do the high-numbered word first.
946 In either case, set up in LATEHALF the operands to use
947 for the high-numbered word and in some cases alter the
948 operands in OPERANDS to be suitable for the low-numbered word. */
952 if (optype0 == REGOP)
954 middlehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
955 latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 2);
957 else if (optype0 == OFFSOP)
959 middlehalf[0] = adj_offsettable_operand (operands[0], 4);
960 latehalf[0] = adj_offsettable_operand (operands[0], 8);
964 middlehalf[0] = operands[0];
965 latehalf[0] = operands[0];
968 if (optype1 == REGOP)
970 middlehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
971 latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2);
973 else if (optype1 == OFFSOP)
975 middlehalf[1] = adj_offsettable_operand (operands[1], 4);
976 latehalf[1] = adj_offsettable_operand (operands[1], 8);
978 else if (optype1 == CNSTOP)
980 if (GET_CODE (operands[1]) == CONST_DOUBLE)
982 REAL_VALUE_TYPE r; long l[3];
984 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
985 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
986 operands[1] = GEN_INT (l[0]);
987 middlehalf[1] = GEN_INT (l[1]);
988 latehalf[1] = GEN_INT (l[2]);
990 else if (CONSTANT_P (operands[1]))
991 /* No non-CONST_DOUBLE constant should ever appear here. */
996 middlehalf[1] = operands[1];
997 latehalf[1] = operands[1];
1000 else /* size is not 12: */
1002 if (optype0 == REGOP)
1003 latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
1004 else if (optype0 == OFFSOP)
1005 latehalf[0] = adj_offsettable_operand (operands[0], 4);
1007 latehalf[0] = operands[0];
1009 if (optype1 == REGOP)
1010 latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
1011 else if (optype1 == OFFSOP)
1012 latehalf[1] = adj_offsettable_operand (operands[1], 4);
1013 else if (optype1 == CNSTOP)
1014 split_double (operands[1], &operands[1], &latehalf[1]);
1016 latehalf[1] = operands[1];
1019 /* If insn is effectively movd N (sp),-(sp) then we will do the
1020 high word first. We should use the adjusted operand 1
1021 (which is N+4 (sp) or N+8 (sp))
1022 for the low word and middle word as well,
1023 to compensate for the first decrement of sp. */
1024 if (optype0 == PUSHOP
1025 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
1026 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
1027 middlehalf[1] = operands[1] = latehalf[1];
1029 /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
1030 if the upper part of reg N does not appear in the MEM, arrange to
1031 emit the move late-half first. Otherwise, compute the MEM address
1032 into the upper part of N and use that as a pointer to the memory
1034 if (optype0 == REGOP
1035 && (optype1 == OFFSOP || optype1 == MEMOP))
1037 if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))
1038 && reg_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
1040 /* If both halves of dest are used in the src memory address,
1041 compute the address into latehalf of dest. */
1043 xops[0] = latehalf[0];
1044 xops[1] = XEXP (operands[1], 0);
1045 output_asm_insn (AS2 (lea%L0,%a1,%0), xops);
1046 if( GET_MODE (operands[1]) == XFmode )
1049 operands[1] = gen_rtx (MEM, XFmode, latehalf[0]);
1050 middlehalf[1] = adj_offsettable_operand (operands[1], size-8);
1051 latehalf[1] = adj_offsettable_operand (operands[1], size-4);
1055 operands[1] = gen_rtx (MEM, DImode, latehalf[0]);
1056 latehalf[1] = adj_offsettable_operand (operands[1], size-4);
1060 && reg_mentioned_p (middlehalf[0], XEXP (operands[1], 0)))
1062 /* Check for two regs used by both source and dest. */
1063 if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))
1064 || reg_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
1067 /* JRV says this can't happen: */
1068 if (addreg0 || addreg1)
1071 /* Only the middle reg conflicts; simply put it last. */
1072 output_asm_insn (singlemove_string (operands), operands);
1073 output_asm_insn (singlemove_string (latehalf), latehalf);
1074 output_asm_insn (singlemove_string (middlehalf), middlehalf);
1077 else if (reg_mentioned_p (operands[0], XEXP (operands[1], 0)))
1078 /* If the low half of dest is mentioned in the source memory
1079 address, the arrange to emit the move late half first. */
1080 dest_overlapped_low = 1;
1083 /* If one or both operands autodecrementing,
1084 do the two words, high-numbered first. */
1086 /* Likewise, the first move would clobber the source of the second one,
1087 do them in the other order. This happens only for registers;
1088 such overlap can't happen in memory unless the user explicitly
1089 sets it up, and that is an undefined circumstance. */
1092 if (optype0 == PUSHOP || optype1 == PUSHOP
1093 || (optype0 == REGOP && optype1 == REGOP
1094 && REGNO (operands[0]) == REGNO (latehalf[1]))
1095 || dest_overlapped_low)
1097 if (optype0 == PUSHOP || optype1 == PUSHOP
1098 || (optype0 == REGOP && optype1 == REGOP
1099 && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1]))
1100 || REGNO (operands[0]) == REGNO (latehalf[1])))
1101 || dest_overlapped_low)
1103 /* Make any unoffsettable addresses point at high-numbered word. */
1105 asm_add (size-4, addreg0);
1107 asm_add (size-4, addreg1);
1110 output_asm_insn (singlemove_string (latehalf), latehalf);
1112 /* Undo the adds we just did. */
1114 asm_add (-4, addreg0);
1116 asm_add (-4, addreg1);
1120 output_asm_insn (singlemove_string (middlehalf), middlehalf);
1122 asm_add (-4, addreg0);
1124 asm_add (-4, addreg1);
1127 /* Do low-numbered word. */
1128 return singlemove_string (operands);
1131 /* Normal case: do the two words, low-numbered first. */
1133 output_asm_insn (singlemove_string (operands), operands);
1135 /* Do the middle one of the three words for long double */
1139 asm_add (4, addreg0);
1141 asm_add (4, addreg1);
1143 output_asm_insn (singlemove_string (middlehalf), middlehalf);
1146 /* Make any unoffsettable addresses point at high-numbered word. */
1148 asm_add (4, addreg0);
1150 asm_add (4, addreg1);
1153 output_asm_insn (singlemove_string (latehalf), latehalf);
1155 /* Undo the adds we just did. */
1157 asm_add (4-size, addreg0);
1159 asm_add (4-size, addreg1);
1165 #define MAX_TMPS 2 /* max temporary registers used */
1167 /* Output the appropriate code to move push memory on the stack */
1170 output_move_pushmem (operands, insn, length, tmp_start, n_operands)
1182 } tmp_info[MAX_TMPS];
1184 rtx src = operands[1];
1187 int stack_p = reg_overlap_mentioned_p (stack_pointer_rtx, src);
1188 int stack_offset = 0;
1192 if (!offsettable_memref_p (src))
1193 fatal_insn ("Source is not offsettable", insn);
1195 if ((length & 3) != 0)
1196 fatal_insn ("Pushing non-word aligned size", insn);
1198 /* Figure out which temporary registers we have available */
1199 for (i = tmp_start; i < n_operands; i++)
1201 if (GET_CODE (operands[i]) == REG)
1203 if (reg_overlap_mentioned_p (operands[i], src))
1206 tmp_info[ max_tmps++ ].xops[1] = operands[i];
1207 if (max_tmps == MAX_TMPS)
1213 for (offset = length - 4; offset >= 0; offset -= 4)
1215 xops[0] = adj_offsettable_operand (src, offset + stack_offset);
1216 output_asm_insn (AS1(push%L0,%0), xops);
1222 for (offset = length - 4; offset >= 0; )
1224 for (num_tmps = 0; num_tmps < max_tmps && offset >= 0; num_tmps++)
1226 tmp_info[num_tmps].load = AS2(mov%L0,%0,%1);
1227 tmp_info[num_tmps].push = AS1(push%L0,%1);
1228 tmp_info[num_tmps].xops[0] = adj_offsettable_operand (src, offset + stack_offset);
1232 for (i = 0; i < num_tmps; i++)
1233 output_asm_insn (tmp_info[i].load, tmp_info[i].xops);
1235 for (i = 0; i < num_tmps; i++)
1236 output_asm_insn (tmp_info[i].push, tmp_info[i].xops);
1239 stack_offset += 4*num_tmps;
1247 /* Output the appropriate code to move data between two memory locations */
1250 output_move_memory (operands, insn, length, tmp_start, n_operands)
1261 } tmp_info[MAX_TMPS];
1263 rtx dest = operands[0];
1264 rtx src = operands[1];
1265 rtx qi_tmp = NULL_RTX;
1271 if (GET_CODE (dest) == MEM
1272 && GET_CODE (XEXP (dest, 0)) == PRE_INC
1273 && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx)
1274 return output_move_pushmem (operands, insn, length, tmp_start, n_operands);
1276 if (!offsettable_memref_p (src))
1277 fatal_insn ("Source is not offsettable", insn);
1279 if (!offsettable_memref_p (dest))
1280 fatal_insn ("Destination is not offsettable", insn);
1282 /* Figure out which temporary registers we have available */
1283 for (i = tmp_start; i < n_operands; i++)
1285 if (GET_CODE (operands[i]) == REG)
1287 if ((length & 1) != 0 && !qi_tmp && QI_REG_P (operands[i]))
1288 qi_tmp = operands[i];
1290 if (reg_overlap_mentioned_p (operands[i], dest))
1291 fatal_insn ("Temporary register overlaps the destination", insn);
1293 if (reg_overlap_mentioned_p (operands[i], src))
1294 fatal_insn ("Temporary register overlaps the source", insn);
1296 tmp_info[ max_tmps++ ].xops[2] = operands[i];
1297 if (max_tmps == MAX_TMPS)
1303 fatal_insn ("No scratch registers were found to do memory->memory moves", insn);
1305 if ((length & 1) != 0)
1308 fatal_insn ("No byte register found when moving odd # of bytes.", insn);
1313 for (num_tmps = 0; num_tmps < max_tmps; num_tmps++)
1317 tmp_info[num_tmps].load = AS2(mov%L0,%1,%2);
1318 tmp_info[num_tmps].store = AS2(mov%L0,%2,%0);
1319 tmp_info[num_tmps].xops[0] = adj_offsettable_operand (dest, offset);
1320 tmp_info[num_tmps].xops[1] = adj_offsettable_operand (src, offset);
1324 else if (length >= 2)
1326 tmp_info[num_tmps].load = AS2(mov%W0,%1,%2);
1327 tmp_info[num_tmps].store = AS2(mov%W0,%2,%0);
1328 tmp_info[num_tmps].xops[0] = adj_offsettable_operand (dest, offset);
1329 tmp_info[num_tmps].xops[1] = adj_offsettable_operand (src, offset);
1337 for (i = 0; i < num_tmps; i++)
1338 output_asm_insn (tmp_info[i].load, tmp_info[i].xops);
1340 for (i = 0; i < num_tmps; i++)
1341 output_asm_insn (tmp_info[i].store, tmp_info[i].xops);
1346 xops[0] = adj_offsettable_operand (dest, offset);
1347 xops[1] = adj_offsettable_operand (src, offset);
1349 output_asm_insn (AS2(mov%B0,%1,%2), xops);
1350 output_asm_insn (AS2(mov%B0,%2,%0), xops);
1358 standard_80387_constant_p (x)
1361 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
1366 if (setjmp (handler))
1369 set_float_handler (handler);
1370 REAL_VALUE_FROM_CONST_DOUBLE (d, x);
1371 is0 = REAL_VALUES_EQUAL (d, dconst0);
1372 is1 = REAL_VALUES_EQUAL (d, dconst1);
1373 set_float_handler (NULL_PTR);
1381 /* Note that on the 80387, other constants, such as pi,
1382 are much slower to load as standard constants
1383 than to load from doubles in memory! */
1390 output_move_const_single (operands)
1393 if (FP_REG_P (operands[0]))
1395 int conval = standard_80387_constant_p (operands[1]);
1403 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1405 REAL_VALUE_TYPE r; long l;
1407 if (GET_MODE (operands[1]) == XFmode)
1410 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1411 REAL_VALUE_TO_TARGET_SINGLE (r, l);
1412 operands[1] = GEN_INT (l);
1414 return singlemove_string (operands);
1417 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
1418 reference and a constant. */
1421 symbolic_operand (op, mode)
1423 enum machine_mode mode;
1425 switch (GET_CODE (op))
1432 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
1433 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
1434 && GET_CODE (XEXP (op, 1)) == CONST_INT);
1440 /* Test for a valid operand for a call instruction.
1441 Don't allow the arg pointer register or virtual regs
1442 since they may change into reg + const, which the patterns
1443 can't handle yet. */
1446 call_insn_operand (op, mode)
1448 enum machine_mode mode;
1450 if (GET_CODE (op) == MEM
1451 && ((CONSTANT_ADDRESS_P (XEXP (op, 0))
1452 /* This makes a difference for PIC. */
1453 && general_operand (XEXP (op, 0), Pmode))
1454 || (GET_CODE (XEXP (op, 0)) == REG
1455 && XEXP (op, 0) != arg_pointer_rtx
1456 && !(REGNO (XEXP (op, 0)) >= FIRST_PSEUDO_REGISTER
1457 && REGNO (XEXP (op, 0)) <= LAST_VIRTUAL_REGISTER))))
1462 /* Like call_insn_operand but allow (mem (symbol_ref ...))
1466 expander_call_insn_operand (op, mode)
1468 enum machine_mode mode;
1470 if (GET_CODE (op) == MEM
1471 && (CONSTANT_ADDRESS_P (XEXP (op, 0))
1472 || (GET_CODE (XEXP (op, 0)) == REG
1473 && XEXP (op, 0) != arg_pointer_rtx
1474 && !(REGNO (XEXP (op, 0)) >= FIRST_PSEUDO_REGISTER
1475 && REGNO (XEXP (op, 0)) <= LAST_VIRTUAL_REGISTER))))
1480 /* Return 1 if OP is a comparison operator that can use the condition code
1481 generated by an arithmetic operation. */
1484 arithmetic_comparison_operator (op, mode)
1486 enum machine_mode mode;
1490 if (mode != VOIDmode && mode != GET_MODE (op))
1492 code = GET_CODE (op);
1493 if (GET_RTX_CLASS (code) != '<')
1496 return (code != GT && code != LE);
1499 /* Returns 1 if OP contains a symbol reference */
1502 symbolic_reference_mentioned_p (op)
1508 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
1511 fmt = GET_RTX_FORMAT (GET_CODE (op));
1512 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
1518 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
1519 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
1522 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
1529 /* Attempt to expand a binary operator. Make the expansion closer to the
1530 actual machine, then just general_operand, which will allow 3 separate
1531 memory references (one output, two input) in a single insn. Return
1532 whether the insn fails, or succeeds. */
1535 ix86_expand_binary_operator (code, mode, operands)
1537 enum machine_mode mode;
1544 /* Recognize <var1> = <value> <op> <var1> for commutative operators */
1545 if (GET_RTX_CLASS (code) == 'c'
1546 && (rtx_equal_p (operands[0], operands[2])
1547 || immediate_operand (operands[1], mode)))
1549 rtx temp = operands[1];
1550 operands[1] = operands[2];
1554 /* If optimizing, copy to regs to improve CSE */
1555 if (TARGET_PSEUDO && optimize && ((reload_in_progress | reload_completed) == 0))
1557 if (GET_CODE (operands[1]) == MEM && !rtx_equal_p (operands[0], operands[1]))
1558 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
1560 if (GET_CODE (operands[2]) == MEM)
1561 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
1563 if (GET_CODE (operands[1]) == CONST_INT && code == MINUS)
1565 rtx temp = gen_reg_rtx (GET_MODE (operands[0]));
1566 emit_move_insn (temp, operands[1]);
1572 if (!ix86_binary_operator_ok (code, mode, operands))
1574 /* If not optimizing, try to make a valid insn (optimize code previously did
1575 this above to improve chances of CSE) */
1577 if ((!TARGET_PSEUDO || !optimize)
1578 && ((reload_in_progress | reload_completed) == 0)
1579 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM))
1582 if (GET_CODE (operands[1]) == MEM && !rtx_equal_p (operands[0], operands[1]))
1584 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
1588 if (GET_CODE (operands[2]) == MEM)
1590 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
1594 if (GET_CODE (operands[1]) == CONST_INT && code == MINUS)
1596 rtx temp = gen_reg_rtx (GET_MODE (operands[0]));
1597 emit_move_insn (temp, operands[1]);
1602 if (modified && !ix86_binary_operator_ok (code, mode, operands))
1612 /* Return TRUE or FALSE depending on whether the binary operator meets the
1613 appropriate constraints. */
1616 ix86_binary_operator_ok (code, mode, operands)
1618 enum machine_mode mode;
1621 return (GET_CODE (operands[1]) != MEM && GET_CODE (operands[2]) != MEM
1622 && GET_CODE (operands[1]) != CONST_INT)
1623 || GET_RTX_CLASS (code) == 'c';
1626 /* Attempt to expand a unary operator. Make the expansion closer to the
1627 actual machine, then just general_operand, which will allow 2 separate
1628 memory references (one output, one input) in a single insn. Return
1629 whether the insn fails, or succeeds. */
1632 ix86_expand_unary_operator (code, mode, operands)
1634 enum machine_mode mode;
1639 /* If optimizing, copy to regs to improve CSE */
1642 && ((reload_in_progress | reload_completed) == 0)
1643 && GET_CODE (operands[1]) == MEM)
1645 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
1648 if (!ix86_unary_operator_ok (code, mode, operands))
1650 if ((!TARGET_PSEUDO || !optimize)
1651 && ((reload_in_progress | reload_completed) == 0)
1652 && GET_CODE (operands[1]) == MEM)
1654 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
1655 if (!ix86_unary_operator_ok (code, mode, operands))
1665 /* Return TRUE or FALSE depending on whether the unary operator meets the
1666 appropriate constraints. */
1669 ix86_unary_operator_ok (code, mode, operands)
1671 enum machine_mode mode;
1678 /* This function generates the assembly code for function entry.
1679 FILE is an stdio stream to output the code to.
1680 SIZE is an int: how many units of temporary storage to allocate. */
1683 function_prologue (file, size)
1690 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1691 || current_function_uses_const_pool);
1693 xops[0] = stack_pointer_rtx;
1694 xops[1] = frame_pointer_rtx;
1695 xops[2] = GEN_INT (size);
1696 if (frame_pointer_needed)
1698 output_asm_insn ("push%L1 %1", xops);
1699 output_asm_insn (AS2 (mov%L0,%0,%1), xops);
1703 output_asm_insn (AS2 (sub%L0,%2,%0), xops);
1705 /* Note If use enter it is NOT reversed args.
1706 This one is not reversed from intel!!
1707 I think enter is slower. Also sdb doesn't like it.
1708 But if you want it the code is:
1710 xops[3] = const0_rtx;
1711 output_asm_insn ("enter %2,%3", xops);
1714 limit = (frame_pointer_needed ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
1715 for (regno = limit - 1; regno >= 0; regno--)
1716 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1717 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1719 xops[0] = gen_rtx (REG, SImode, regno);
1720 output_asm_insn ("push%L0 %0", xops);
1725 xops[0] = pic_offset_table_rtx;
1726 xops[1] = (rtx) gen_label_rtx ();
1728 output_asm_insn (AS1 (call,%P1), xops);
1729 ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (xops[1]));
1730 output_asm_insn (AS1 (pop%L0,%0), xops);
1731 output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops);
1735 /* Return 1 if it is appropriate to emit `ret' instructions in the
1736 body of a function. Do this only if the epilogue is simple, needing a
1737 couple of insns. Prior to reloading, we can't tell how many registers
1738 must be saved, so return 0 then.
1740 If NON_SAVING_SETJMP is defined and true, then it is not possible
1741 for the epilogue to be simple, so return 0. This is a special case
1742 since NON_SAVING_SETJMP will not cause regs_ever_live to change until
1743 final, but jump_optimize may need to know sooner if a `return' is OK. */
1746 simple_386_epilogue ()
1750 int reglimit = (frame_pointer_needed
1751 ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
1752 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1753 || current_function_uses_const_pool);
1755 #ifdef NON_SAVING_SETJMP
1756 if (NON_SAVING_SETJMP && current_function_calls_setjmp)
1760 if (! reload_completed)
1763 for (regno = reglimit - 1; regno >= 0; regno--)
1764 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1765 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1768 return nregs == 0 || ! frame_pointer_needed;
1772 /* This function generates the assembly code for function exit.
1773 FILE is an stdio stream to output the code to.
1774 SIZE is an int: how many units of temporary storage to deallocate. */
1777 function_epilogue (file, size)
1782 register int nregs, limit;
1785 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1786 || current_function_uses_const_pool);
1788 /* Compute the number of registers to pop */
1790 limit = (frame_pointer_needed
1791 ? FRAME_POINTER_REGNUM
1792 : STACK_POINTER_REGNUM);
1796 for (regno = limit - 1; regno >= 0; regno--)
1797 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1798 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1801 /* sp is often unreliable so we must go off the frame pointer,
1804 /* In reality, we may not care if sp is unreliable, because we can
1805 restore the register relative to the frame pointer. In theory,
1806 since each move is the same speed as a pop, and we don't need the
1807 leal, this is faster. For now restore multiple registers the old
1810 offset = -size - (nregs * UNITS_PER_WORD);
1812 xops[2] = stack_pointer_rtx;
1814 if (nregs > 1 || ! frame_pointer_needed)
1816 if (frame_pointer_needed)
1818 xops[0] = adj_offsettable_operand (AT_BP (Pmode), offset);
1819 output_asm_insn (AS2 (lea%L2,%0,%2), xops);
1822 for (regno = 0; regno < limit; regno++)
1823 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1824 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1826 xops[0] = gen_rtx (REG, SImode, regno);
1827 output_asm_insn ("pop%L0 %0", xops);
1831 for (regno = 0; regno < limit; regno++)
1832 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1833 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1835 xops[0] = gen_rtx (REG, SImode, regno);
1836 xops[1] = adj_offsettable_operand (AT_BP (Pmode), offset);
1837 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
1841 if (frame_pointer_needed)
1843 /* If not an i386, mov & pop is faster than "leave". */
1845 if (TARGET_USE_LEAVE)
1846 output_asm_insn ("leave", xops);
1849 xops[0] = frame_pointer_rtx;
1850 output_asm_insn (AS2 (mov%L2,%0,%2), xops);
1851 output_asm_insn ("pop%L0 %0", xops);
1856 /* If there is no frame pointer, we must still release the frame. */
1858 xops[0] = GEN_INT (size);
1859 output_asm_insn (AS2 (add%L2,%0,%2), xops);
1862 #ifdef FUNCTION_BLOCK_PROFILER_EXIT
1863 if (profile_block_flag == 2)
1865 FUNCTION_BLOCK_PROFILER_EXIT(file);
1869 if (current_function_pops_args && current_function_args_size)
1871 xops[1] = GEN_INT (current_function_pops_args);
1873 /* i386 can only pop 32K bytes (maybe 64K? Is it signed?). If
1874 asked to pop more, pop return address, do explicit add, and jump
1875 indirectly to the caller. */
1877 if (current_function_pops_args >= 32768)
1879 /* ??? Which register to use here? */
1880 xops[0] = gen_rtx (REG, SImode, 2);
1881 output_asm_insn ("pop%L0 %0", xops);
1882 output_asm_insn (AS2 (add%L2,%1,%2), xops);
1883 output_asm_insn ("jmp %*%0", xops);
1886 output_asm_insn ("ret %1", xops);
1889 output_asm_insn ("ret", xops);
1893 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
1894 that is a valid memory address for an instruction.
1895 The MODE argument is the machine mode for the MEM expression
1896 that wants to use this address.
1898 On x86, legitimate addresses are:
1899 base movl (base),reg
1900 displacement movl disp,reg
1901 base + displacement movl disp(base),reg
1902 index + base movl (base,index),reg
1903 (index + base) + displacement movl disp(base,index),reg
1904 index*scale movl (,index,scale),reg
1905 index*scale + disp movl disp(,index,scale),reg
1906 index*scale + base movl (base,index,scale),reg
1907 (index*scale + base) + disp movl disp(base,index,scale),reg
1909 In each case, scale can be 1, 2, 4, 8. */
1911 /* This is exactly the same as print_operand_addr, except that
1912 it recognizes addresses instead of printing them.
1914 It only recognizes address in canonical form. LEGITIMIZE_ADDRESS should
1915 convert common non-canonical forms to canonical form so that they will
1918 #define ADDR_INVALID(msg,insn) \
1920 if (TARGET_DEBUG_ADDR) \
1922 fprintf (stderr, msg); \
1928 legitimate_address_p (mode, addr, strict)
1929 enum machine_mode mode;
1933 rtx base = NULL_RTX;
1934 rtx indx = NULL_RTX;
1935 rtx scale = NULL_RTX;
1936 rtx disp = NULL_RTX;
1938 if (TARGET_DEBUG_ADDR)
1941 "\n==========\nGO_IF_LEGITIMATE_ADDRESS, mode = %s, strict = %d\n",
1942 GET_MODE_NAME (mode), strict);
1947 if (GET_CODE (addr) == REG || GET_CODE (addr) == SUBREG)
1948 base = addr; /* base reg */
1950 else if (GET_CODE (addr) == PLUS)
1952 rtx op0 = XEXP (addr, 0);
1953 rtx op1 = XEXP (addr, 1);
1954 enum rtx_code code0 = GET_CODE (op0);
1955 enum rtx_code code1 = GET_CODE (op1);
1957 if (code0 == REG || code0 == SUBREG)
1959 if (code1 == REG || code1 == SUBREG)
1961 indx = op0; /* index + base */
1967 base = op0; /* base + displacement */
1972 else if (code0 == MULT)
1974 indx = XEXP (op0, 0);
1975 scale = XEXP (op0, 1);
1977 if (code1 == REG || code1 == SUBREG)
1978 base = op1; /* index*scale + base */
1981 disp = op1; /* index*scale + disp */
1984 else if (code0 == PLUS && GET_CODE (XEXP (op0, 0)) == MULT)
1986 indx = XEXP (XEXP (op0, 0), 0); /* index*scale + base + disp */
1987 scale = XEXP (XEXP (op0, 0), 1);
1988 base = XEXP (op0, 1);
1992 else if (code0 == PLUS)
1994 indx = XEXP (op0, 0); /* index + base + disp */
1995 base = XEXP (op0, 1);
2001 ADDR_INVALID ("PLUS subcode is not valid.\n", op0);
2006 else if (GET_CODE (addr) == MULT)
2008 indx = XEXP (addr, 0); /* index*scale */
2009 scale = XEXP (addr, 1);
2013 disp = addr; /* displacement */
2015 /* Allow arg pointer and stack pointer as index if there is not scaling */
2016 if (base && indx && !scale
2017 && (indx == arg_pointer_rtx || indx == stack_pointer_rtx))
2024 /* Validate base register */
2025 /* Don't allow SUBREG's here, it can lead to spill failures when the base
2026 is one word out of a two word structure, which is represented internally
2030 if (GET_CODE (base) != REG)
2032 ADDR_INVALID ("Base is not a register.\n", base);
2036 if ((strict && !REG_OK_FOR_BASE_STRICT_P (base))
2037 || (!strict && !REG_OK_FOR_BASE_NONSTRICT_P (base)))
2039 ADDR_INVALID ("Base is not valid.\n", base);
2044 /* Validate index register */
2045 /* Don't allow SUBREG's here, it can lead to spill failures when the index
2046 is one word out of a two word structure, which is represented internally
2050 if (GET_CODE (indx) != REG)
2052 ADDR_INVALID ("Index is not a register.\n", indx);
2056 if ((strict && !REG_OK_FOR_INDEX_STRICT_P (indx))
2057 || (!strict && !REG_OK_FOR_INDEX_NONSTRICT_P (indx)))
2059 ADDR_INVALID ("Index is not valid.\n", indx);
2064 abort (); /* scale w/o index invalid */
2066 /* Validate scale factor */
2069 HOST_WIDE_INT value;
2071 if (GET_CODE (scale) != CONST_INT)
2073 ADDR_INVALID ("Scale is not valid.\n", scale);
2077 value = INTVAL (scale);
2078 if (value != 1 && value != 2 && value != 4 && value != 8)
2080 ADDR_INVALID ("Scale is not a good multiplier.\n", scale);
2085 /* Validate displacement
2086 Constant pool addresses must be handled special. They are
2087 considered legitimate addresses, but only if not used with regs.
2088 When printed, the output routines know to print the reference with the
2089 PIC reg, even though the PIC reg doesn't appear in the RTL. */
2092 if (GET_CODE (disp) == SYMBOL_REF
2093 && CONSTANT_POOL_ADDRESS_P (disp)
2098 else if (!CONSTANT_ADDRESS_P (disp))
2100 ADDR_INVALID ("Displacement is not valid.\n", disp);
2104 else if (GET_CODE (disp) == CONST_DOUBLE)
2106 ADDR_INVALID ("Displacement is a const_double.\n", disp);
2110 else if (flag_pic && SYMBOLIC_CONST (disp)
2111 && base != pic_offset_table_rtx
2112 && (indx != pic_offset_table_rtx || scale != NULL_RTX))
2114 ADDR_INVALID ("Displacement is an invalid pic reference.\n", disp);
2118 else if (HALF_PIC_P () && HALF_PIC_ADDRESS_P (disp)
2119 && (base != NULL_RTX || indx != NULL_RTX))
2121 ADDR_INVALID ("Displacement is an invalid half-pic reference.\n", disp);
2126 if (TARGET_DEBUG_ADDR)
2127 fprintf (stderr, "Address is valid.\n");
2129 /* Everything looks valid, return true */
2134 /* Return a legitimate reference for ORIG (an address) using the
2135 register REG. If REG is 0, a new pseudo is generated.
2137 There are three types of references that must be handled:
2139 1. Global data references must load the address from the GOT, via
2140 the PIC reg. An insn is emitted to do this load, and the reg is
2143 2. Static data references must compute the address as an offset
2144 from the GOT, whose base is in the PIC reg. An insn is emitted to
2145 compute the address into a reg, and the reg is returned. Static
2146 data objects have SYMBOL_REF_FLAG set to differentiate them from
2147 global data objects.
2149 3. Constant pool addresses must be handled special. They are
2150 considered legitimate addresses, but only if not used with regs.
2151 When printed, the output routines know to print the reference with the
2152 PIC reg, even though the PIC reg doesn't appear in the RTL.
2154 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2155 reg also appears in the address (except for constant pool references,
2158 "switch" statements also require special handling when generating
2159 PIC code. See comments by the `casesi' insn in i386.md for details. */
2162 legitimize_pic_address (orig, reg)
2169 if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
2171 if (GET_CODE (addr) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (addr))
2176 reg = gen_reg_rtx (Pmode);
2178 if ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
2179 || GET_CODE (addr) == LABEL_REF)
2180 new = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig);
2182 new = gen_rtx (MEM, Pmode,
2183 gen_rtx (PLUS, Pmode,
2184 pic_offset_table_rtx, orig));
2186 emit_move_insn (reg, new);
2188 current_function_uses_pic_offset_table = 1;
2191 else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
2195 if (GET_CODE (addr) == CONST)
2197 addr = XEXP (addr, 0);
2198 if (GET_CODE (addr) != PLUS)
2202 if (XEXP (addr, 0) == pic_offset_table_rtx)
2206 reg = gen_reg_rtx (Pmode);
2208 base = legitimize_pic_address (XEXP (addr, 0), reg);
2209 addr = legitimize_pic_address (XEXP (addr, 1),
2210 base == reg ? NULL_RTX : reg);
2212 if (GET_CODE (addr) == CONST_INT)
2213 return plus_constant (base, INTVAL (addr));
2215 if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
2217 base = gen_rtx (PLUS, Pmode, base, XEXP (addr, 0));
2218 addr = XEXP (addr, 1);
2220 return gen_rtx (PLUS, Pmode, base, addr);
2226 /* Emit insns to move operands[1] into operands[0]. */
2229 emit_pic_move (operands, mode)
2231 enum machine_mode mode;
2233 rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
2235 if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
2236 operands[1] = (rtx) force_reg (SImode, operands[1]);
2238 operands[1] = legitimize_pic_address (operands[1], temp);
2242 /* Try machine-dependent ways of modifying an illegitimate address
2243 to be legitimate. If we find one, return the new, valid address.
2244 This macro is used in only one place: `memory_address' in explow.c.
2246 OLDX is the address as it was before break_out_memory_refs was called.
2247 In some cases it is useful to look at this to decide what needs to be done.
2249 MODE and WIN are passed so that this macro can use
2250 GO_IF_LEGITIMATE_ADDRESS.
2252 It is always safe for this macro to do nothing. It exists to recognize
2253 opportunities to optimize the output.
2255 For the 80386, we handle X+REG by loading X into a register R and
2256 using R+REG. R will go in a general reg and indexing will be used.
2257 However, if REG is a broken-out memory address or multiplication,
2258 nothing needs to be done because REG can certainly go in a general reg.
2260 When -fpic is used, special handling is needed for symbolic references.
2261 See comments by legitimize_pic_address in i386.c for details. */
2264 legitimize_address (x, oldx, mode)
2267 enum machine_mode mode;
2272 if (TARGET_DEBUG_ADDR)
2274 fprintf (stderr, "\n==========\nLEGITIMIZE_ADDRESS, mode = %s\n", GET_MODE_NAME (mode));
2278 if (flag_pic && SYMBOLIC_CONST (x))
2279 return legitimize_pic_address (x, 0);
2281 /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
2282 if (GET_CODE (x) == ASHIFT
2283 && GET_CODE (XEXP (x, 1)) == CONST_INT
2284 && (log = (unsigned)exact_log2 (INTVAL (XEXP (x, 1)))) < 4)
2287 x = gen_rtx (MULT, Pmode,
2288 force_reg (Pmode, XEXP (x, 0)),
2289 GEN_INT (1 << log));
2292 if (GET_CODE (x) == PLUS)
2294 /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
2295 if (GET_CODE (XEXP (x, 0)) == ASHIFT
2296 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
2297 && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) < 4)
2300 XEXP (x, 0) = gen_rtx (MULT, Pmode,
2301 force_reg (Pmode, XEXP (XEXP (x, 0), 0)),
2302 GEN_INT (1 << log));
2305 if (GET_CODE (XEXP (x, 1)) == ASHIFT
2306 && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
2307 && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 1), 1)))) < 4)
2310 XEXP (x, 1) = gen_rtx (MULT, Pmode,
2311 force_reg (Pmode, XEXP (XEXP (x, 1), 0)),
2312 GEN_INT (1 << log));
2315 /* Put multiply first if it isn't already */
2316 if (GET_CODE (XEXP (x, 1)) == MULT)
2318 rtx tmp = XEXP (x, 0);
2319 XEXP (x, 0) = XEXP (x, 1);
2324 /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
2325 into (plus (plus (mult (reg) (const)) (reg)) (const)). This can be
2326 created by virtual register instantiation, register elimination, and
2327 similar optimizations. */
2328 if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS)
2331 x = gen_rtx (PLUS, Pmode,
2332 gen_rtx (PLUS, Pmode, XEXP (x, 0), XEXP (XEXP (x, 1), 0)),
2333 XEXP (XEXP (x, 1), 1));
2336 /* Canonicalize (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
2337 into (plus (plus (mult (reg) (const)) (reg)) (const)). */
2338 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
2339 && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
2340 && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
2341 && CONSTANT_P (XEXP (x, 1)))
2343 rtx constant, other;
2345 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
2347 constant = XEXP (x, 1);
2348 other = XEXP (XEXP (XEXP (x, 0), 1), 1);
2350 else if (GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 1)) == CONST_INT)
2352 constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
2353 other = XEXP (x, 1);
2361 x = gen_rtx (PLUS, Pmode,
2362 gen_rtx (PLUS, Pmode, XEXP (XEXP (x, 0), 0),
2363 XEXP (XEXP (XEXP (x, 0), 1), 0)),
2364 plus_constant (other, INTVAL (constant)));
2368 if (changed && legitimate_address_p (mode, x, FALSE))
2371 if (GET_CODE (XEXP (x, 0)) == MULT)
2374 XEXP (x, 0) = force_operand (XEXP (x, 0), 0);
2377 if (GET_CODE (XEXP (x, 1)) == MULT)
2380 XEXP (x, 1) = force_operand (XEXP (x, 1), 0);
2384 && GET_CODE (XEXP (x, 1)) == REG
2385 && GET_CODE (XEXP (x, 0)) == REG)
2388 if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1)))
2391 x = legitimize_pic_address (x, 0);
2394 if (changed && legitimate_address_p (mode, x, FALSE))
2397 if (GET_CODE (XEXP (x, 0)) == REG)
2399 register rtx temp = gen_reg_rtx (Pmode);
2400 register rtx val = force_operand (XEXP (x, 1), temp);
2402 emit_move_insn (temp, val);
2408 else if (GET_CODE (XEXP (x, 1)) == REG)
2410 register rtx temp = gen_reg_rtx (Pmode);
2411 register rtx val = force_operand (XEXP (x, 0), temp);
2413 emit_move_insn (temp, val);
2424 /* Print an integer constant expression in assembler syntax. Addition
2425 and subtraction are the only arithmetic that may appear in these
2426 expressions. FILE is the stdio stream to write to, X is the rtx, and
2427 CODE is the operand print code from the output string. */
2430 output_pic_addr_const (file, x, code)
2437 switch (GET_CODE (x))
2448 if (GET_CODE (x) == SYMBOL_REF)
2449 assemble_name (file, XSTR (x, 0));
2452 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
2453 CODE_LABEL_NUMBER (XEXP (x, 0)));
2454 assemble_name (asm_out_file, buf);
2457 if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
2458 fprintf (file, "@GOTOFF(%%ebx)");
2459 else if (code == 'P')
2460 fprintf (file, "@PLT");
2461 else if (GET_CODE (x) == LABEL_REF)
2462 fprintf (file, "@GOTOFF");
2463 else if (! SYMBOL_REF_FLAG (x))
2464 fprintf (file, "@GOT");
2466 fprintf (file, "@GOTOFF");
2471 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
2472 assemble_name (asm_out_file, buf);
2476 fprintf (file, "%d", INTVAL (x));
2480 /* This used to output parentheses around the expression,
2481 but that does not work on the 386 (either ATT or BSD assembler). */
2482 output_pic_addr_const (file, XEXP (x, 0), code);
2486 if (GET_MODE (x) == VOIDmode)
2488 /* We can use %d if the number is <32 bits and positive. */
2489 if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
2490 fprintf (file, "0x%x%08x",
2491 CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
2493 fprintf (file, "%d", CONST_DOUBLE_LOW (x));
2496 /* We can't handle floating point constants;
2497 PRINT_OPERAND must handle them. */
2498 output_operand_lossage ("floating constant misused");
2502 /* Some assemblers need integer constants to appear last (eg masm). */
2503 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
2505 output_pic_addr_const (file, XEXP (x, 1), code);
2506 if (INTVAL (XEXP (x, 0)) >= 0)
2507 fprintf (file, "+");
2508 output_pic_addr_const (file, XEXP (x, 0), code);
2512 output_pic_addr_const (file, XEXP (x, 0), code);
2513 if (INTVAL (XEXP (x, 1)) >= 0)
2514 fprintf (file, "+");
2515 output_pic_addr_const (file, XEXP (x, 1), code);
2520 output_pic_addr_const (file, XEXP (x, 0), code);
2521 fprintf (file, "-");
2522 output_pic_addr_const (file, XEXP (x, 1), code);
2526 output_operand_lossage ("invalid expression as operand");
2531 f -- float insn (print a CONST_DOUBLE as a float rather than in hex).
2532 D,L,W,B,Q,S -- print the opcode suffix for specified size of operand.
2533 R -- print the prefix for register names.
2534 z -- print the opcode suffix for the size of the current operand.
2535 * -- print a star (in certain assembler syntax)
2536 w -- print the operand as if it's a "word" (HImode) even if it isn't.
2537 c -- don't print special prefixes before constant operands.
2538 J -- print the appropriate jump operand.
2542 print_operand (file, x, code)
2557 PUT_OP_SIZE (code, 'l', file);
2561 PUT_OP_SIZE (code, 'w', file);
2565 PUT_OP_SIZE (code, 'b', file);
2569 PUT_OP_SIZE (code, 'l', file);
2573 PUT_OP_SIZE (code, 's', file);
2577 PUT_OP_SIZE (code, 't', file);
2581 /* 387 opcodes don't get size suffixes if the operands are
2584 if (STACK_REG_P (x))
2587 /* this is the size of op from size of operand */
2588 switch (GET_MODE_SIZE (GET_MODE (x)))
2591 PUT_OP_SIZE ('B', 'b', file);
2595 PUT_OP_SIZE ('W', 'w', file);
2599 if (GET_MODE (x) == SFmode)
2601 PUT_OP_SIZE ('S', 's', file);
2605 PUT_OP_SIZE ('L', 'l', file);
2609 PUT_OP_SIZE ('T', 't', file);
2613 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
2615 #ifdef GAS_MNEMONICS
2616 PUT_OP_SIZE ('Q', 'q', file);
2619 PUT_OP_SIZE ('Q', 'l', file); /* Fall through */
2623 PUT_OP_SIZE ('Q', 'l', file);
2636 switch (GET_CODE (x))
2638 /* These conditions are appropriate for testing the result
2639 of an arithmetic operation, not for a compare operation.
2640 Cases GE, LT assume CC_NO_OVERFLOW true. All cases assume
2641 CC_Z_IN_NOT_C false and not floating point. */
2642 case NE: fputs ("jne", file); return;
2643 case EQ: fputs ("je", file); return;
2644 case GE: fputs ("jns", file); return;
2645 case LT: fputs ("js", file); return;
2646 case GEU: fputs ("jmp", file); return;
2647 case GTU: fputs ("jne", file); return;
2648 case LEU: fputs ("je", file); return;
2649 case LTU: fputs ("#branch never", file); return;
2651 /* no matching branches for GT nor LE */
2659 sprintf (str, "invalid operand code `%c'", code);
2660 output_operand_lossage (str);
2664 if (GET_CODE (x) == REG)
2666 PRINT_REG (x, code, file);
2668 else if (GET_CODE (x) == MEM)
2670 PRINT_PTR (x, file);
2671 if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
2674 output_pic_addr_const (file, XEXP (x, 0), code);
2676 output_addr_const (file, XEXP (x, 0));
2679 output_address (XEXP (x, 0));
2681 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
2683 REAL_VALUE_TYPE r; long l;
2684 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2685 REAL_VALUE_TO_TARGET_SINGLE (r, l);
2686 PRINT_IMMED_PREFIX (file);
2687 fprintf (file, "0x%x", l);
2689 /* These float cases don't actually occur as immediate operands. */
2690 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
2692 REAL_VALUE_TYPE r; char dstr[30];
2693 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2694 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
2695 fprintf (file, "%s", dstr);
2697 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == XFmode)
2699 REAL_VALUE_TYPE r; char dstr[30];
2700 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2701 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
2702 fprintf (file, "%s", dstr);
2708 if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
2709 PRINT_IMMED_PREFIX (file);
2710 else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
2711 || GET_CODE (x) == LABEL_REF)
2712 PRINT_OFFSET_PREFIX (file);
2715 output_pic_addr_const (file, x, code);
2717 output_addr_const (file, x);
2721 /* Print a memory operand whose address is ADDR. */
2724 print_operand_address (file, addr)
2728 register rtx reg1, reg2, breg, ireg;
2731 switch (GET_CODE (addr))
2735 fprintf (file, "%se", RP);
2736 fputs (hi_reg_name[REGNO (addr)], file);
2746 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
2748 offset = XEXP (addr, 0);
2749 addr = XEXP (addr, 1);
2751 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
2753 offset = XEXP (addr, 1);
2754 addr = XEXP (addr, 0);
2756 if (GET_CODE (addr) != PLUS) ;
2757 else if (GET_CODE (XEXP (addr, 0)) == MULT)
2759 reg1 = XEXP (addr, 0);
2760 addr = XEXP (addr, 1);
2762 else if (GET_CODE (XEXP (addr, 1)) == MULT)
2764 reg1 = XEXP (addr, 1);
2765 addr = XEXP (addr, 0);
2767 else if (GET_CODE (XEXP (addr, 0)) == REG)
2769 reg1 = XEXP (addr, 0);
2770 addr = XEXP (addr, 1);
2772 else if (GET_CODE (XEXP (addr, 1)) == REG)
2774 reg1 = XEXP (addr, 1);
2775 addr = XEXP (addr, 0);
2777 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
2779 if (reg1 == 0) reg1 = addr;
2785 if (addr != 0) abort ();
2788 if ((reg1 && GET_CODE (reg1) == MULT)
2789 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
2794 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
2800 if (ireg != 0 || breg != 0)
2807 output_pic_addr_const (file, addr, 0);
2809 else if (GET_CODE (addr) == LABEL_REF)
2810 output_asm_label (addr);
2813 output_addr_const (file, addr);
2816 if (ireg != 0 && GET_CODE (ireg) == MULT)
2818 scale = INTVAL (XEXP (ireg, 1));
2819 ireg = XEXP (ireg, 0);
2822 /* The stack pointer can only appear as a base register,
2823 never an index register, so exchange the regs if it is wrong. */
2825 if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM)
2834 /* output breg+ireg*scale */
2835 PRINT_B_I_S (breg, ireg, scale, file);
2842 if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
2844 scale = INTVAL (XEXP (addr, 0));
2845 ireg = XEXP (addr, 1);
2849 scale = INTVAL (XEXP (addr, 1));
2850 ireg = XEXP (addr, 0);
2852 output_addr_const (file, const0_rtx);
2853 PRINT_B_I_S ((rtx) 0, ireg, scale, file);
2858 if (GET_CODE (addr) == CONST_INT
2859 && INTVAL (addr) < 0x8000
2860 && INTVAL (addr) >= -0x8000)
2861 fprintf (file, "%d", INTVAL (addr));
2865 output_pic_addr_const (file, addr, 0);
2867 output_addr_const (file, addr);
2872 /* Set the cc_status for the results of an insn whose pattern is EXP.
2873 On the 80386, we assume that only test and compare insns, as well
2874 as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, ASHIFT,
2875 ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
2876 Also, we assume that jumps, moves and sCOND don't affect the condition
2877 codes. All else clobbers the condition codes, by assumption.
2879 We assume that ALL integer add, minus, etc. instructions effect the
2880 condition codes. This MUST be consistent with i386.md.
2882 We don't record any float test or compare - the redundant test &
2883 compare check in final.c does not handle stack-like regs correctly. */
2886 notice_update_cc (exp)
2889 if (GET_CODE (exp) == SET)
2891 /* Jumps do not alter the cc's. */
2892 if (SET_DEST (exp) == pc_rtx)
2894 #ifdef IS_STACK_MODE
2895 /* Moving into a memory of stack_mode may have been moved
2896 in between the use and set of cc0 by loop_spl(). So
2897 old value of cc.status must be retained */
2898 if(GET_CODE(SET_DEST(exp))==MEM
2899 && IS_STACK_MODE(GET_MODE(SET_DEST(exp))))
2904 /* Moving register or memory into a register:
2905 it doesn't alter the cc's, but it might invalidate
2906 the RTX's which we remember the cc's came from.
2907 (Note that moving a constant 0 or 1 MAY set the cc's). */
2908 if (REG_P (SET_DEST (exp))
2909 && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM
2910 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
2912 if (cc_status.value1
2913 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
2914 cc_status.value1 = 0;
2915 if (cc_status.value2
2916 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
2917 cc_status.value2 = 0;
2920 /* Moving register into memory doesn't alter the cc's.
2921 It may invalidate the RTX's which we remember the cc's came from. */
2922 if (GET_CODE (SET_DEST (exp)) == MEM
2923 && (REG_P (SET_SRC (exp))
2924 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
2926 if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
2927 cc_status.value1 = 0;
2928 if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
2929 cc_status.value2 = 0;
2932 /* Function calls clobber the cc's. */
2933 else if (GET_CODE (SET_SRC (exp)) == CALL)
2938 /* Tests and compares set the cc's in predictable ways. */
2939 else if (SET_DEST (exp) == cc0_rtx)
2942 cc_status.value1 = SET_SRC (exp);
2945 /* Certain instructions effect the condition codes. */
2946 else if (GET_MODE (SET_SRC (exp)) == SImode
2947 || GET_MODE (SET_SRC (exp)) == HImode
2948 || GET_MODE (SET_SRC (exp)) == QImode)
2949 switch (GET_CODE (SET_SRC (exp)))
2951 case ASHIFTRT: case LSHIFTRT:
2953 /* Shifts on the 386 don't set the condition codes if the
2954 shift count is zero. */
2955 if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
2960 /* We assume that the CONST_INT is non-zero (this rtx would
2961 have been deleted if it were zero. */
2963 case PLUS: case MINUS: case NEG:
2964 case AND: case IOR: case XOR:
2965 cc_status.flags = CC_NO_OVERFLOW;
2966 cc_status.value1 = SET_SRC (exp);
2967 cc_status.value2 = SET_DEST (exp);
2978 else if (GET_CODE (exp) == PARALLEL
2979 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
2981 if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
2983 if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
2986 if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
2987 cc_status.flags |= CC_IN_80387;
2989 cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
3000 /* Split one or more DImode RTL references into pairs of SImode
3001 references. The RTL can be REG, offsettable MEM, integer constant, or
3002 CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to
3003 split and "num" is its length. lo_half and hi_half are output arrays
3004 that parallel "operands". */
3007 split_di (operands, num, lo_half, hi_half)
3010 rtx lo_half[], hi_half[];
3014 if (GET_CODE (operands[num]) == REG)
3016 lo_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]));
3017 hi_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]) + 1);
3019 else if (CONSTANT_P (operands[num]))
3021 split_double (operands[num], &lo_half[num], &hi_half[num]);
3023 else if (offsettable_memref_p (operands[num]))
3025 lo_half[num] = operands[num];
3026 hi_half[num] = adj_offsettable_operand (operands[num], 4);
3033 /* Return 1 if this is a valid binary operation on a 387.
3034 OP is the expression matched, and MODE is its mode. */
3037 binary_387_op (op, mode)
3039 enum machine_mode mode;
3041 if (mode != VOIDmode && mode != GET_MODE (op))
3044 switch (GET_CODE (op))
3050 return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
3058 /* Return 1 if this is a valid shift or rotate operation on a 386.
3059 OP is the expression matched, and MODE is its mode. */
3064 enum machine_mode mode;
3066 rtx operand = XEXP (op, 0);
3068 if (mode != VOIDmode && mode != GET_MODE (op))
3071 if (GET_MODE (operand) != GET_MODE (op)
3072 || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
3075 return (GET_CODE (op) == ASHIFT
3076 || GET_CODE (op) == ASHIFTRT
3077 || GET_CODE (op) == LSHIFTRT
3078 || GET_CODE (op) == ROTATE
3079 || GET_CODE (op) == ROTATERT);
3082 /* Return 1 if OP is COMPARE rtx with mode VOIDmode.
3083 MODE is not used. */
3086 VOIDmode_compare_op (op, mode)
3088 enum machine_mode mode;
3090 return GET_CODE (op) == COMPARE && GET_MODE (op) == VOIDmode;
3093 /* Output code to perform a 387 binary operation in INSN, one of PLUS,
3094 MINUS, MULT or DIV. OPERANDS are the insn operands, where operands[3]
3095 is the expression of the binary operation. The output may either be
3096 emitted here, or returned to the caller, like all output_* functions.
3098 There is no guarantee that the operands are the same mode, as they
3099 might be within FLOAT or FLOAT_EXTEND expressions. */
3102 output_387_binary_op (insn, operands)
3108 static char buf[100];
3110 switch (GET_CODE (operands[3]))
3113 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3114 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3121 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3122 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3129 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3130 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3137 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3138 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3148 strcpy (buf, base_op);
3150 switch (GET_CODE (operands[3]))
3154 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
3157 operands[2] = operands[1];
3161 if (GET_CODE (operands[2]) == MEM)
3162 return strcat (buf, AS1 (%z2,%2));
3164 if (NON_STACK_REG_P (operands[1]))
3166 output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
3169 else if (NON_STACK_REG_P (operands[2]))
3171 output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
3175 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
3176 return strcat (buf, AS2 (p,%2,%0));
3178 if (STACK_TOP_P (operands[0]))
3179 return strcat (buf, AS2C (%y2,%0));
3181 return strcat (buf, AS2C (%2,%0));
3185 if (GET_CODE (operands[1]) == MEM)
3186 return strcat (buf, AS1 (r%z1,%1));
3188 if (GET_CODE (operands[2]) == MEM)
3189 return strcat (buf, AS1 (%z2,%2));
3191 if (NON_STACK_REG_P (operands[1]))
3193 output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1)));
3196 else if (NON_STACK_REG_P (operands[2]))
3198 output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
3202 if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
3205 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
3206 return strcat (buf, AS2 (rp,%2,%0));
3208 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3209 return strcat (buf, AS2 (p,%1,%0));
3211 if (STACK_TOP_P (operands[0]))
3213 if (STACK_TOP_P (operands[1]))
3214 return strcat (buf, AS2C (%y2,%0));
3216 return strcat (buf, AS2 (r,%y1,%0));
3218 else if (STACK_TOP_P (operands[1]))
3219 return strcat (buf, AS2C (%1,%0));
3221 return strcat (buf, AS2 (r,%2,%0));
3228 /* Output code for INSN to convert a float to a signed int. OPERANDS
3229 are the insn operands. The output may be SFmode or DFmode and the
3230 input operand may be SImode or DImode. As a special case, make sure
3231 that the 387 stack top dies if the output mode is DImode, because the
3232 hardware requires this. */
3235 output_fix_trunc (insn, operands)
3239 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
3242 if (! STACK_TOP_P (operands[1]) ||
3243 (GET_MODE (operands[0]) == DImode && ! stack_top_dies))
3246 xops[0] = GEN_INT (12);
3247 xops[1] = operands[4];
3249 output_asm_insn (AS1 (fnstc%W2,%2), operands);
3250 output_asm_insn (AS2 (mov%L2,%2,%4), operands);
3251 output_asm_insn (AS2 (mov%B1,%0,%h1), xops);
3252 output_asm_insn (AS2 (mov%L4,%4,%3), operands);
3253 output_asm_insn (AS1 (fldc%W3,%3), operands);
3255 if (NON_STACK_REG_P (operands[0]))
3256 output_to_reg (operands[0], stack_top_dies);
3257 else if (GET_CODE (operands[0]) == MEM)
3260 output_asm_insn (AS1 (fistp%z0,%0), operands);
3262 output_asm_insn (AS1 (fist%z0,%0), operands);
3267 return AS1 (fldc%W2,%2);
3270 /* Output code for INSN to compare OPERANDS. The two operands might
3271 not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
3272 expression. If the compare is in mode CCFPEQmode, use an opcode that
3273 will not fault if a qNaN is present. */
3276 output_float_compare (insn, operands)
3281 rtx body = XVECEXP (PATTERN (insn), 0, 0);
3282 int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
3285 if (! STACK_TOP_P (operands[0]))
3288 operands[0] = operands[1];
3290 cc_status.flags |= CC_REVERSED;
3293 if (! STACK_TOP_P (operands[0]))
3296 stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
3298 if (STACK_REG_P (operands[1])
3300 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3301 && REGNO (operands[1]) != FIRST_STACK_REG)
3303 /* If both the top of the 387 stack dies, and the other operand
3304 is also a stack register that dies, then this must be a
3305 `fcompp' float compare */
3307 if (unordered_compare)
3308 output_asm_insn ("fucompp", operands);
3310 output_asm_insn ("fcompp", operands);
3314 static char buf[100];
3316 /* Decide if this is the integer or float compare opcode, or the
3317 unordered float compare. */
3319 if (unordered_compare)
3320 strcpy (buf, "fucom");
3321 else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT)
3322 strcpy (buf, "fcom");
3324 strcpy (buf, "ficom");
3326 /* Modify the opcode if the 387 stack is to be popped. */
3331 if (NON_STACK_REG_P (operands[1]))
3332 output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
3334 output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
3337 /* Now retrieve the condition code. */
3339 return output_fp_cc0_set (insn);
3342 /* Output opcodes to transfer the results of FP compare or test INSN
3343 from the FPU to the CPU flags. If TARGET_IEEE_FP, ensure that if the
3344 result of the compare or test is unordered, no comparison operator
3345 succeeds except NE. Return an output template, if any. */
3348 output_fp_cc0_set (insn)
3352 rtx unordered_label;
3356 xops[0] = gen_rtx (REG, HImode, 0);
3357 output_asm_insn (AS1 (fnsts%W0,%0), xops);
3359 if (! TARGET_IEEE_FP)
3361 if (!(cc_status.flags & CC_REVERSED))
3363 next = next_cc0_user (insn);
3365 if (GET_CODE (next) == JUMP_INSN
3366 && GET_CODE (PATTERN (next)) == SET
3367 && SET_DEST (PATTERN (next)) == pc_rtx
3368 && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
3370 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
3372 else if (GET_CODE (PATTERN (next)) == SET)
3374 code = GET_CODE (SET_SRC (PATTERN (next)));
3380 if (code == GT || code == LT || code == EQ || code == NE
3381 || code == LE || code == GE)
3382 { /* We will test eax directly */
3383 cc_status.flags |= CC_TEST_AX;
3390 next = next_cc0_user (insn);
3391 if (next == NULL_RTX)
3394 if (GET_CODE (next) == JUMP_INSN
3395 && GET_CODE (PATTERN (next)) == SET
3396 && SET_DEST (PATTERN (next)) == pc_rtx
3397 && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
3399 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
3401 else if (GET_CODE (PATTERN (next)) == SET)
3403 code = GET_CODE (SET_SRC (PATTERN (next)));
3408 xops[0] = gen_rtx (REG, QImode, 0);
3413 xops[1] = GEN_INT (0x45);
3414 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3419 xops[1] = GEN_INT (0x45);
3420 xops[2] = GEN_INT (0x01);
3421 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3422 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
3427 xops[1] = GEN_INT (0x05);
3428 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3433 xops[1] = GEN_INT (0x45);
3434 xops[2] = GEN_INT (0x40);
3435 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3436 output_asm_insn (AS1 (dec%B0,%h0), xops);
3437 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
3442 xops[1] = GEN_INT (0x45);
3443 xops[2] = GEN_INT (0x40);
3444 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3445 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
3450 xops[1] = GEN_INT (0x44);
3451 xops[2] = GEN_INT (0x40);
3452 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3453 output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
3467 #define MAX_386_STACK_LOCALS 2
3469 static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
3471 /* Define the structure for the machine field in struct function. */
3472 struct machine_function
3474 rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
3477 /* Functions to save and restore i386_stack_locals.
3478 These will be called, via pointer variables,
3479 from push_function_context and pop_function_context. */
3482 save_386_machine_status (p)
3485 p->machine = (struct machine_function *) xmalloc (sizeof i386_stack_locals);
3486 bcopy ((char *) i386_stack_locals, (char *) p->machine->i386_stack_locals,
3487 sizeof i386_stack_locals);
3491 restore_386_machine_status (p)
3494 bcopy ((char *) p->machine->i386_stack_locals, (char *) i386_stack_locals,
3495 sizeof i386_stack_locals);
3499 /* Clear stack slot assignments remembered from previous functions.
3500 This is called from INIT_EXPANDERS once before RTL is emitted for each
3504 clear_386_stack_locals ()
3506 enum machine_mode mode;
3509 for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
3510 mode = (enum machine_mode) ((int) mode + 1))
3511 for (n = 0; n < MAX_386_STACK_LOCALS; n++)
3512 i386_stack_locals[(int) mode][n] = NULL_RTX;
3514 /* Arrange to save and restore i386_stack_locals around nested functions. */
3515 save_machine_status = save_386_machine_status;
3516 restore_machine_status = restore_386_machine_status;
3519 /* Return a MEM corresponding to a stack slot with mode MODE.
3520 Allocate a new slot if necessary.
3522 The RTL for a function can have several slots available: N is
3523 which slot to use. */
3526 assign_386_stack_local (mode, n)
3527 enum machine_mode mode;
3530 if (n < 0 || n >= MAX_386_STACK_LOCALS)
3533 if (i386_stack_locals[(int) mode][n] == NULL_RTX)
3534 i386_stack_locals[(int) mode][n]
3535 = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
3537 return i386_stack_locals[(int) mode][n];
3543 enum machine_mode mode;
3545 return (GET_CODE (op) == MULT);
3550 enum machine_mode mode;
3552 return (GET_CODE (op) == DIV);
3557 /* Create a new copy of an rtx.
3558 Recursively copies the operands of the rtx,
3559 except for those few rtx codes that are sharable.
3560 Doesn't share CONST */
3568 register RTX_CODE code;
3569 register char *format_ptr;
3571 code = GET_CODE (orig);
3584 /* SCRATCH must be shared because they represent distinct values. */
3589 /* CONST can be shared if it contains a SYMBOL_REF. If it contains
3590 a LABEL_REF, it isn't sharable. */
3591 if (GET_CODE (XEXP (orig, 0)) == PLUS
3592 && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
3593 && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
3597 /* A MEM with a constant address is not sharable. The problem is that
3598 the constant address may need to be reloaded. If the mem is shared,
3599 then reloading one copy of this mem will cause all copies to appear
3600 to have been reloaded. */
3603 copy = rtx_alloc (code);
3604 PUT_MODE (copy, GET_MODE (orig));
3605 copy->in_struct = orig->in_struct;
3606 copy->volatil = orig->volatil;
3607 copy->unchanging = orig->unchanging;
3608 copy->integrated = orig->integrated;
3610 copy->is_spill_rtx = orig->is_spill_rtx;
3612 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
3614 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
3616 switch (*format_ptr++)
3619 XEXP (copy, i) = XEXP (orig, i);
3620 if (XEXP (orig, i) != NULL)
3621 XEXP (copy, i) = copy_rtx (XEXP (orig, i));
3626 XEXP (copy, i) = XEXP (orig, i);
3631 XVEC (copy, i) = XVEC (orig, i);
3632 if (XVEC (orig, i) != NULL)
3634 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
3635 for (j = 0; j < XVECLEN (copy, i); j++)
3636 XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
3641 XWINT (copy, i) = XWINT (orig, i);
3645 XINT (copy, i) = XINT (orig, i);
3650 XSTR (copy, i) = XSTR (orig, i);
3661 /* try to rewrite a memory address to make it valid */
3663 rewrite_address (mem_rtx)
3666 rtx index_rtx, base_rtx, offset_rtx, scale_rtx, ret_rtx;
3668 int offset_adjust = 0;
3669 int was_only_offset = 0;
3670 rtx mem_addr = XEXP (mem_rtx, 0);
3671 char *storage = (char *) oballoc (0);
3673 int is_spill_rtx = 0;
3675 in_struct = MEM_IN_STRUCT_P (mem_rtx);
3676 is_spill_rtx = RTX_IS_SPILL_P (mem_rtx);
3678 if (GET_CODE (mem_addr) == PLUS &&
3679 GET_CODE (XEXP (mem_addr, 1)) == PLUS &&
3680 GET_CODE (XEXP (XEXP (mem_addr, 1), 0)) == REG)
3681 { /* this part is utilized by the combiner */
3683 gen_rtx (PLUS, GET_MODE (mem_addr),
3684 gen_rtx (PLUS, GET_MODE (XEXP (mem_addr, 1)),
3686 XEXP (XEXP (mem_addr, 1), 0)),
3687 XEXP (XEXP (mem_addr, 1), 1));
3688 if (memory_address_p (GET_MODE (mem_rtx), ret_rtx))
3690 XEXP (mem_rtx, 0) = ret_rtx;
3691 RTX_IS_SPILL_P (ret_rtx) = is_spill_rtx;
3697 /* this part is utilized by loop.c */
3698 /* If the address contains PLUS (reg,const) and this pattern is invalid
3699 in this case - try to rewrite the address to make it valid intel1
3701 storage = (char *) oballoc (0);
3702 index_rtx = base_rtx = offset_rtx = NULL;
3703 /* find the base index and offset elements of the memory address */
3704 if (GET_CODE (mem_addr) == PLUS)
3706 if (GET_CODE (XEXP (mem_addr, 0)) == REG)
3708 if (GET_CODE (XEXP (mem_addr, 1)) == REG)
3710 base_rtx = XEXP (mem_addr, 1);
3711 index_rtx = XEXP (mem_addr, 0);
3715 base_rtx = XEXP (mem_addr, 0);
3716 offset_rtx = XEXP (mem_addr, 1);
3719 else if (GET_CODE (XEXP (mem_addr, 0)) == MULT)
3721 index_rtx = XEXP (mem_addr, 0);
3722 if (GET_CODE (XEXP (mem_addr, 1)) == REG)
3724 base_rtx = XEXP (mem_addr, 1);
3728 offset_rtx = XEXP (mem_addr, 1);
3731 else if (GET_CODE (XEXP (mem_addr, 0)) == PLUS)
3734 if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == PLUS &&
3735 GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0)) == MULT &&
3736 GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 0)) == REG &&
3737 GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 1)) == CONST_INT &&
3738 GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1)) == CONST_INT &&
3739 GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == REG &&
3740 GET_CODE (XEXP (mem_addr, 1)) == SYMBOL_REF)
3742 index_rtx = XEXP (XEXP (XEXP (mem_addr, 0), 0), 0);
3743 offset_rtx = XEXP (mem_addr, 1);
3744 base_rtx = XEXP (XEXP (mem_addr, 0), 1);
3745 offset_adjust = INTVAL (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1));
3749 offset_rtx = XEXP (mem_addr, 1);
3750 index_rtx = XEXP (XEXP (mem_addr, 0), 0);
3751 base_rtx = XEXP (XEXP (mem_addr, 0), 1);
3754 else if (GET_CODE (XEXP (mem_addr, 0)) == CONST_INT)
3756 was_only_offset = 1;
3759 offset_rtx = XEXP (mem_addr, 1);
3760 offset_adjust = INTVAL (XEXP (mem_addr, 0));
3761 if (offset_adjust == 0)
3763 XEXP (mem_rtx, 0) = offset_rtx;
3764 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
3774 else if (GET_CODE (mem_addr) == MULT)
3776 index_rtx = mem_addr;
3783 if (index_rtx && GET_CODE (index_rtx) == MULT)
3785 if (GET_CODE (XEXP (index_rtx, 1)) != CONST_INT)
3790 scale_rtx = XEXP (index_rtx, 1);
3791 scale = INTVAL (scale_rtx);
3792 index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
3794 /* now find which of the elements are invalid and try to fix them */
3795 if (index_rtx && GET_CODE (index_rtx) == CONST_INT && base_rtx == NULL)
3797 offset_adjust = INTVAL (index_rtx) * scale;
3798 if (offset_rtx && GET_CODE (offset_rtx) == CONST &&
3799 GET_CODE (XEXP (offset_rtx, 0)) == PLUS)
3801 if (GET_CODE (XEXP (XEXP (offset_rtx, 0), 0)) == SYMBOL_REF &&
3802 GET_CODE (XEXP (XEXP (offset_rtx, 0), 1)) == CONST_INT)
3804 offset_rtx = copy_all_rtx (offset_rtx);
3805 XEXP (XEXP (offset_rtx, 0), 1) =
3806 gen_rtx (CONST_INT, 0, INTVAL (XEXP (XEXP (offset_rtx, 0), 1)) + offset_adjust);
3807 if (!CONSTANT_P (offset_rtx))
3814 else if (offset_rtx && GET_CODE (offset_rtx) == SYMBOL_REF)
3817 gen_rtx (CONST, GET_MODE (offset_rtx),
3818 gen_rtx (PLUS, GET_MODE (offset_rtx),
3820 gen_rtx (CONST_INT, 0, offset_adjust)));
3821 if (!CONSTANT_P (offset_rtx))
3827 else if (offset_rtx && GET_CODE (offset_rtx) == CONST_INT)
3829 offset_rtx = gen_rtx (CONST_INT, 0, INTVAL (offset_rtx) + offset_adjust);
3831 else if (!offset_rtx)
3833 offset_rtx = gen_rtx (CONST_INT, 0, 0);
3835 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
3836 XEXP (mem_rtx, 0) = offset_rtx;
3839 if (base_rtx && GET_CODE (base_rtx) == PLUS &&
3840 GET_CODE (XEXP (base_rtx, 0)) == REG &&
3841 GET_CODE (XEXP (base_rtx, 1)) == CONST_INT)
3843 offset_adjust += INTVAL (XEXP (base_rtx, 1));
3844 base_rtx = copy_all_rtx (XEXP (base_rtx, 0));
3846 else if (base_rtx && GET_CODE (base_rtx) == CONST_INT)
3848 offset_adjust += INTVAL (base_rtx);
3851 if (index_rtx && GET_CODE (index_rtx) == PLUS &&
3852 GET_CODE (XEXP (index_rtx, 0)) == REG &&
3853 GET_CODE (XEXP (index_rtx, 1)) == CONST_INT)
3855 offset_adjust += INTVAL (XEXP (index_rtx, 1)) * scale;
3856 index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
3860 if (!LEGITIMATE_INDEX_P (index_rtx)
3861 && !(index_rtx == stack_pointer_rtx && scale == 1 && base_rtx == NULL))
3869 if (!LEGITIMATE_INDEX_P (base_rtx) && GET_CODE (base_rtx) != REG)
3875 if (offset_adjust != 0)
3879 if (GET_CODE (offset_rtx) == CONST &&
3880 GET_CODE (XEXP (offset_rtx, 0)) == PLUS)
3882 if (GET_CODE (XEXP (XEXP (offset_rtx, 0), 0)) == SYMBOL_REF &&
3883 GET_CODE (XEXP (XEXP (offset_rtx, 0), 1)) == CONST_INT)
3885 offset_rtx = copy_all_rtx (offset_rtx);
3886 XEXP (XEXP (offset_rtx, 0), 1) =
3887 gen_rtx (CONST_INT, 0, INTVAL (XEXP (XEXP (offset_rtx, 0), 1)) + offset_adjust);
3888 if (!CONSTANT_P (offset_rtx))
3895 else if (GET_CODE (offset_rtx) == SYMBOL_REF)
3898 gen_rtx (CONST, GET_MODE (offset_rtx),
3899 gen_rtx (PLUS, GET_MODE (offset_rtx),
3901 gen_rtx (CONST_INT, 0, offset_adjust)));
3902 if (!CONSTANT_P (offset_rtx))
3908 else if (GET_CODE (offset_rtx) == CONST_INT)
3910 offset_rtx = gen_rtx (CONST_INT, 0, INTVAL (offset_rtx) + offset_adjust);
3920 offset_rtx = gen_rtx (CONST_INT, 0, offset_adjust);
3928 if (GET_CODE (offset_rtx) == CONST_INT &&
3929 INTVAL (offset_rtx) == 0)
3931 ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx),
3932 gen_rtx (MULT, GET_MODE (index_rtx), index_rtx,
3938 ret_rtx = gen_rtx (PLUS, GET_MODE (offset_rtx),
3939 gen_rtx (PLUS, GET_MODE (base_rtx),
3940 gen_rtx (MULT, GET_MODE (index_rtx), index_rtx,
3948 if (GET_CODE (offset_rtx) == CONST_INT &&
3949 INTVAL (offset_rtx) == 0)
3951 ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx), index_rtx, base_rtx);
3955 ret_rtx = gen_rtx (PLUS, GET_MODE (offset_rtx),
3956 gen_rtx (PLUS, GET_MODE (index_rtx), index_rtx,
3966 if (GET_CODE (offset_rtx) == CONST_INT &&
3967 INTVAL (offset_rtx) == 0)
3969 ret_rtx = gen_rtx (MULT, GET_MODE (index_rtx), index_rtx, scale_rtx);
3974 gen_rtx (PLUS, GET_MODE (offset_rtx),
3975 gen_rtx (MULT, GET_MODE (index_rtx), index_rtx,
3982 if (GET_CODE (offset_rtx) == CONST_INT &&
3983 INTVAL (offset_rtx) == 0)
3985 ret_rtx = index_rtx;
3989 ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx), index_rtx, offset_rtx);
3998 if (GET_CODE (offset_rtx) == CONST_INT &&
3999 INTVAL (offset_rtx) == 0)
4005 ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx), base_rtx, offset_rtx);
4008 else if (was_only_offset)
4010 ret_rtx = offset_rtx;
4018 XEXP (mem_rtx, 0) = ret_rtx;
4019 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4031 /* return 1 if the first insn to set cc before insn also sets the register
4032 reg_rtx - otherwise return 0 */
4034 last_to_set_cc (reg_rtx, insn)
4037 rtx prev_insn = PREV_INSN (insn);
4041 if (GET_CODE (prev_insn) == NOTE)
4044 else if (GET_CODE (prev_insn) == INSN)
4046 if (GET_CODE (PATTERN (prev_insn)) != SET)
4049 if (rtx_equal_p (SET_DEST (PATTERN (prev_insn)), reg_rtx))
4051 if (sets_condition_code (SET_SRC (PATTERN (prev_insn))))
4057 else if (!doesnt_set_condition_code (SET_SRC (PATTERN (prev_insn))))
4064 prev_insn = PREV_INSN (prev_insn);
4072 doesnt_set_condition_code (pat)
4075 switch (GET_CODE (pat))
4089 sets_condition_code (pat)
4092 switch (GET_CODE (pat))
4116 str_immediate_operand (op, mode)
4118 enum machine_mode mode;
4120 if (GET_CODE (op) == CONST_INT && INTVAL (op) <= 32 && INTVAL (op) >= 0)
4132 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4133 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4134 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4135 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode))
4144 Return 1 if the mode of the SET_DEST of insn is floating point
4145 and it is not an fld or a move from memory to memory.
4146 Otherwise return 0 */
4151 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4152 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4153 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4154 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
4155 && GET_CODE (SET_DEST (PATTERN (insn))) == REG
4156 && REGNO (SET_DEST (PATTERN (insn))) >= FIRST_FLOAT_REG
4157 && GET_CODE (SET_SRC (insn)) != MEM)
4166 Return 1 if the mode of the SET_DEST floating point and is memory
4167 and the source is a register.
4173 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4174 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4175 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4176 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
4177 && GET_CODE (SET_DEST (PATTERN (insn))) == MEM
4178 && GET_CODE (SET_SRC (PATTERN (insn))) == REG)
4188 Return 1 if dep_insn sets a register which insn uses as a base
4189 or index to reference memory.
4190 otherwise return 0 */
4193 agi_dependent (insn, dep_insn)
4196 if (GET_CODE (dep_insn) == INSN
4197 && GET_CODE (PATTERN (dep_insn)) == SET
4198 && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG)
4200 return (reg_mentioned_in_mem (SET_DEST (PATTERN (dep_insn)), insn));
4203 if (GET_CODE (dep_insn) == INSN && GET_CODE (PATTERN (dep_insn)) == SET
4204 && GET_CODE (SET_DEST (PATTERN (dep_insn))) == MEM
4205 && push_operand (SET_DEST (PATTERN (dep_insn)),
4206 GET_MODE (SET_DEST (PATTERN (dep_insn)))))
4208 return (reg_mentioned_in_mem (stack_pointer_rtx, insn));
4216 Return 1 if reg is used in rtl as a base or index for a memory ref
4217 otherwise return 0. */
4220 reg_mentioned_in_mem (reg, rtl)
4225 register enum rtx_code code;
4230 code = GET_CODE (rtl);
4248 if (code == MEM && reg_mentioned_p (reg, rtl))
4251 fmt = GET_RTX_FORMAT (code);
4252 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4257 for (j = XVECLEN (rtl, i) - 1; j >= 0; j--)
4259 if (reg_mentioned_in_mem (reg, XVECEXP (rtl, i, j)))
4264 else if (fmt[i] == 'e' && reg_mentioned_in_mem (reg, XEXP (rtl, i)))
4271 /* Output the approprate insns for doing strlen if not just doing repnz; scasb
4273 operands[0] = result, initialized with the startaddress
4274 operands[1] = alignment of the address.
4275 operands[2] = scratch register, initialized with the startaddress when
4276 not aligned, otherwise undefined
4278 This is just the body. It needs the initialisations mentioned above and
4279 some address computing at the end. These things are done in i386.md. */
4282 output_strlen_unroll (operands)
4287 xops[0] = operands[0]; /* Result */
4288 /* operands[1]; * Alignment */
4289 xops[1] = operands[2]; /* Scratch */
4290 xops[2] = GEN_INT (0);
4291 xops[3] = GEN_INT (2);
4292 xops[4] = GEN_INT (3);
4293 xops[5] = GEN_INT (4);
4294 /* xops[6] = gen_label_rtx (); * label when aligned to 3-byte */
4295 /* xops[7] = gen_label_rtx (); * label when aligned to 2-byte */
4296 xops[8] = gen_label_rtx (); /* label of main loop */
4297 if(TARGET_USE_Q_REG && QI_REG_P (xops[1]))
4298 xops[9] = gen_label_rtx (); /* pentium optimisation */
4299 xops[10] = gen_label_rtx (); /* end label 2 */
4300 xops[11] = gen_label_rtx (); /* end label 1 */
4301 xops[12] = gen_label_rtx (); /* end label */
4302 /* xops[13] * Temporary used */
4303 xops[14] = GEN_INT (0xff);
4304 xops[15] = GEN_INT (0xff00);
4305 xops[16] = GEN_INT (0xff0000);
4306 xops[17] = GEN_INT (0xff000000);
4308 /* Loop to check 1..3 bytes for null to get an aligned pointer */
4310 /* is there a known alignment and is it less then 4 */
4311 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) < 4)
4313 /* is there a known alignment and is it not 2 */
4314 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
4316 xops[6] = gen_label_rtx (); /* label when aligned to 3-byte */
4317 xops[7] = gen_label_rtx (); /* label when aligned to 2-byte */
4319 /* leave just the 3 lower bits */
4320 /* if this is a q-register, then the high part is used later */
4321 /* therefore user andl rather than andb */
4322 output_asm_insn (AS2 (and%L1,%4,%1), xops);
4323 /* is aligned to 4-byte adress when zero */
4324 output_asm_insn (AS1 (je,%l8), xops);
4325 /* side-effect even Parity when %eax == 3 */
4326 output_asm_insn (AS1 (jp,%6), xops);
4328 /* is it aligned to 2 bytes ? */
4329 if (QI_REG_P (xops[1]))
4330 output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
4332 output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
4333 output_asm_insn (AS1 (je,%7), xops);
4337 /* since the alignment is 2, we have to check 2 or 0 bytes */
4339 /* check if is aligned to 4 - byte */
4340 output_asm_insn (AS2 (and%L1,%3,%1), xops);
4341 /* is aligned to 4-byte adress when zero */
4342 output_asm_insn (AS1 (je,%l8), xops);
4345 xops[13] = gen_rtx (MEM, QImode, xops[0]);
4346 /* now, compare the bytes */
4347 /* compare with the high part of a q-reg gives shorter code */
4348 if (QI_REG_P (xops[1]))
4350 /* compare the first n unaligned byte on a byte per byte basis */
4351 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
4352 /* when zero we reached the end */
4353 output_asm_insn (AS1 (je,%l12), xops);
4354 /* increment the address */
4355 output_asm_insn (AS1 (inc%L0,%0), xops);
4357 /* not needed with an alignment of 2 */
4358 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
4360 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[7]));
4361 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
4362 output_asm_insn (AS1 (je,%l12), xops);
4363 output_asm_insn (AS1 (inc%L0,%0), xops);
4365 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[6]));
4367 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
4371 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
4372 output_asm_insn (AS1 (je,%l12), xops);
4373 output_asm_insn (AS1 (inc%L0,%0), xops);
4375 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[7]));
4376 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
4377 output_asm_insn (AS1 (je,%l12), xops);
4378 output_asm_insn (AS1 (inc%L0,%0), xops);
4380 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[6]));
4381 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
4383 output_asm_insn (AS1 (je,%l12), xops);
4384 output_asm_insn (AS1 (inc%L0,%0), xops);
4387 /* Generate loop to check 4 bytes at a time */
4388 /* IMHO it is not a good idea to align this loop. It gives only */
4389 /* huge programms, but does not help to speed up */
4390 /* ASM_OUTPUT_LOOP_ALIGN (asm_out_file); */
4391 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[8]));
4393 xops[13] = gen_rtx (MEM, SImode, xops[0]);
4394 output_asm_insn (AS2 (mov%L1,%13,%1), xops);
4396 if (QI_REG_P (xops[1]))
4398 /* on i586 it is faster to compare the hi- and lo- part */
4399 /* as a kind of lookahead. If xoring both is zero, then one */
4400 /* of both *could* be zero, otherwith none of both is zero */
4401 /* this saves one instruction, on i486 this is slower */
4402 /* testet with P-90, i486DX2-66, AMD486DX2-66 */
4405 output_asm_insn (AS2 (test%B1,%h1,%b1), xops);
4406 output_asm_insn (AS1 (jne,%l9), xops);
4409 /* check first byte */
4410 output_asm_insn (AS2 (test%B1,%b1,%b1), xops);
4411 output_asm_insn (AS1 (je,%l12), xops);
4413 /* check second byte */
4414 output_asm_insn (AS2 (test%B1,%h1,%h1), xops);
4415 output_asm_insn (AS1 (je,%l11), xops);
4418 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[9]));
4422 /* check first byte */
4423 output_asm_insn (AS2 (test%L1,%14,%1), xops);
4424 output_asm_insn (AS1 (je,%l12), xops);
4426 /* check second byte */
4427 output_asm_insn (AS2 (test%L1,%15,%1), xops);
4428 output_asm_insn (AS1 (je,%l11), xops);
4431 /* check third byte */
4432 output_asm_insn (AS2 (test%L1,%16,%1), xops);
4433 output_asm_insn (AS1 (je,%l10), xops);
4435 /* check fourth byte and increment address */
4436 output_asm_insn (AS2 (add%L0,%5,%0), xops);
4437 output_asm_insn (AS2 (test%L1,%17,%1), xops);
4438 output_asm_insn (AS1 (jne,%l8), xops);
4440 /* now generate fixups when the compare stops within a 4-byte word */
4441 output_asm_insn (AS2 (sub%L0,%4,%0), xops);
4443 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[10]));
4444 output_asm_insn (AS1 (inc%L0,%0), xops);
4446 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[11]));
4447 output_asm_insn (AS1 (inc%L0,%0), xops);
4449 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[12]));