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 || GET_RTX_CLASS (code) == 'c');
1625 /* Attempt to expand a unary operator. Make the expansion closer to the
1626 actual machine, then just general_operand, which will allow 2 separate
1627 memory references (one output, one input) in a single insn. Return
1628 whether the insn fails, or succeeds. */
1631 ix86_expand_unary_operator (code, mode, operands)
1633 enum machine_mode mode;
1638 /* If optimizing, copy to regs to improve CSE */
1641 && ((reload_in_progress | reload_completed) == 0)
1642 && GET_CODE (operands[1]) == MEM)
1644 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
1647 if (!ix86_unary_operator_ok (code, mode, operands))
1649 if ((!TARGET_PSEUDO || !optimize)
1650 && ((reload_in_progress | reload_completed) == 0)
1651 && GET_CODE (operands[1]) == MEM)
1653 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
1654 if (!ix86_unary_operator_ok (code, mode, operands))
1664 /* Return TRUE or FALSE depending on whether the unary operator meets the
1665 appropriate constraints. */
1668 ix86_unary_operator_ok (code, mode, operands)
1670 enum machine_mode mode;
1677 /* This function generates the assembly code for function entry.
1678 FILE is an stdio stream to output the code to.
1679 SIZE is an int: how many units of temporary storage to allocate. */
1682 function_prologue (file, size)
1689 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1690 || current_function_uses_const_pool);
1692 xops[0] = stack_pointer_rtx;
1693 xops[1] = frame_pointer_rtx;
1694 xops[2] = GEN_INT (size);
1695 if (frame_pointer_needed)
1697 output_asm_insn ("push%L1 %1", xops);
1698 output_asm_insn (AS2 (mov%L0,%0,%1), xops);
1702 output_asm_insn (AS2 (sub%L0,%2,%0), xops);
1704 /* Note If use enter it is NOT reversed args.
1705 This one is not reversed from intel!!
1706 I think enter is slower. Also sdb doesn't like it.
1707 But if you want it the code is:
1709 xops[3] = const0_rtx;
1710 output_asm_insn ("enter %2,%3", xops);
1713 limit = (frame_pointer_needed ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
1714 for (regno = limit - 1; regno >= 0; regno--)
1715 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1716 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1718 xops[0] = gen_rtx (REG, SImode, regno);
1719 output_asm_insn ("push%L0 %0", xops);
1724 xops[0] = pic_offset_table_rtx;
1725 xops[1] = (rtx) gen_label_rtx ();
1727 output_asm_insn (AS1 (call,%P1), xops);
1728 ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (xops[1]));
1729 output_asm_insn (AS1 (pop%L0,%0), xops);
1730 output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops);
1734 /* Return 1 if it is appropriate to emit `ret' instructions in the
1735 body of a function. Do this only if the epilogue is simple, needing a
1736 couple of insns. Prior to reloading, we can't tell how many registers
1737 must be saved, so return 0 then.
1739 If NON_SAVING_SETJMP is defined and true, then it is not possible
1740 for the epilogue to be simple, so return 0. This is a special case
1741 since NON_SAVING_SETJMP will not cause regs_ever_live to change until
1742 final, but jump_optimize may need to know sooner if a `return' is OK. */
1745 simple_386_epilogue ()
1749 int reglimit = (frame_pointer_needed
1750 ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
1751 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1752 || current_function_uses_const_pool);
1754 #ifdef NON_SAVING_SETJMP
1755 if (NON_SAVING_SETJMP && current_function_calls_setjmp)
1759 if (! reload_completed)
1762 for (regno = reglimit - 1; regno >= 0; regno--)
1763 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1764 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1767 return nregs == 0 || ! frame_pointer_needed;
1771 /* This function generates the assembly code for function exit.
1772 FILE is an stdio stream to output the code to.
1773 SIZE is an int: how many units of temporary storage to deallocate. */
1776 function_epilogue (file, size)
1781 register int nregs, limit;
1784 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1785 || current_function_uses_const_pool);
1787 /* Compute the number of registers to pop */
1789 limit = (frame_pointer_needed
1790 ? FRAME_POINTER_REGNUM
1791 : STACK_POINTER_REGNUM);
1795 for (regno = limit - 1; regno >= 0; regno--)
1796 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1797 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1800 /* sp is often unreliable so we must go off the frame pointer,
1803 /* In reality, we may not care if sp is unreliable, because we can
1804 restore the register relative to the frame pointer. In theory,
1805 since each move is the same speed as a pop, and we don't need the
1806 leal, this is faster. For now restore multiple registers the old
1809 offset = -size - (nregs * UNITS_PER_WORD);
1811 xops[2] = stack_pointer_rtx;
1813 if (nregs > 1 || ! frame_pointer_needed)
1815 if (frame_pointer_needed)
1817 xops[0] = adj_offsettable_operand (AT_BP (Pmode), offset);
1818 output_asm_insn (AS2 (lea%L2,%0,%2), xops);
1821 for (regno = 0; regno < limit; regno++)
1822 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1823 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1825 xops[0] = gen_rtx (REG, SImode, regno);
1826 output_asm_insn ("pop%L0 %0", xops);
1830 for (regno = 0; regno < limit; regno++)
1831 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1832 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1834 xops[0] = gen_rtx (REG, SImode, regno);
1835 xops[1] = adj_offsettable_operand (AT_BP (Pmode), offset);
1836 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
1840 if (frame_pointer_needed)
1842 /* If not an i386, mov & pop is faster than "leave". */
1844 if (TARGET_USE_LEAVE)
1845 output_asm_insn ("leave", xops);
1848 xops[0] = frame_pointer_rtx;
1849 output_asm_insn (AS2 (mov%L2,%0,%2), xops);
1850 output_asm_insn ("pop%L0 %0", xops);
1855 /* If there is no frame pointer, we must still release the frame. */
1857 xops[0] = GEN_INT (size);
1858 output_asm_insn (AS2 (add%L2,%0,%2), xops);
1861 #ifdef FUNCTION_BLOCK_PROFILER_EXIT
1862 if (profile_block_flag == 2)
1864 FUNCTION_BLOCK_PROFILER_EXIT(file);
1868 if (current_function_pops_args && current_function_args_size)
1870 xops[1] = GEN_INT (current_function_pops_args);
1872 /* i386 can only pop 32K bytes (maybe 64K? Is it signed?). If
1873 asked to pop more, pop return address, do explicit add, and jump
1874 indirectly to the caller. */
1876 if (current_function_pops_args >= 32768)
1878 /* ??? Which register to use here? */
1879 xops[0] = gen_rtx (REG, SImode, 2);
1880 output_asm_insn ("pop%L0 %0", xops);
1881 output_asm_insn (AS2 (add%L2,%1,%2), xops);
1882 output_asm_insn ("jmp %*%0", xops);
1885 output_asm_insn ("ret %1", xops);
1888 output_asm_insn ("ret", xops);
1892 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
1893 that is a valid memory address for an instruction.
1894 The MODE argument is the machine mode for the MEM expression
1895 that wants to use this address.
1897 On x86, legitimate addresses are:
1898 base movl (base),reg
1899 displacement movl disp,reg
1900 base + displacement movl disp(base),reg
1901 index + base movl (base,index),reg
1902 (index + base) + displacement movl disp(base,index),reg
1903 index*scale movl (,index,scale),reg
1904 index*scale + disp movl disp(,index,scale),reg
1905 index*scale + base movl (base,index,scale),reg
1906 (index*scale + base) + disp movl disp(base,index,scale),reg
1908 In each case, scale can be 1, 2, 4, 8. */
1910 /* This is exactly the same as print_operand_addr, except that
1911 it recognizes addresses instead of printing them.
1913 It only recognizes address in canonical form. LEGITIMIZE_ADDRESS should
1914 convert common non-canonical forms to canonical form so that they will
1917 #define ADDR_INVALID(msg,insn) \
1919 if (TARGET_DEBUG_ADDR) \
1921 fprintf (stderr, msg); \
1927 legitimate_address_p (mode, addr, strict)
1928 enum machine_mode mode;
1932 rtx base = NULL_RTX;
1933 rtx indx = NULL_RTX;
1934 rtx scale = NULL_RTX;
1935 rtx disp = NULL_RTX;
1937 if (TARGET_DEBUG_ADDR)
1940 "\n==========\nGO_IF_LEGITIMATE_ADDRESS, mode = %s, strict = %d\n",
1941 GET_MODE_NAME (mode), strict);
1946 if (GET_CODE (addr) == REG || GET_CODE (addr) == SUBREG)
1947 base = addr; /* base reg */
1949 else if (GET_CODE (addr) == PLUS)
1951 rtx op0 = XEXP (addr, 0);
1952 rtx op1 = XEXP (addr, 1);
1953 enum rtx_code code0 = GET_CODE (op0);
1954 enum rtx_code code1 = GET_CODE (op1);
1956 if (code0 == REG || code0 == SUBREG)
1958 if (code1 == REG || code1 == SUBREG)
1960 indx = op0; /* index + base */
1966 base = op0; /* base + displacement */
1971 else if (code0 == MULT)
1973 indx = XEXP (op0, 0);
1974 scale = XEXP (op0, 1);
1976 if (code1 == REG || code1 == SUBREG)
1977 base = op1; /* index*scale + base */
1980 disp = op1; /* index*scale + disp */
1983 else if (code0 == PLUS && GET_CODE (XEXP (op0, 0)) == MULT)
1985 indx = XEXP (XEXP (op0, 0), 0); /* index*scale + base + disp */
1986 scale = XEXP (XEXP (op0, 0), 1);
1987 base = XEXP (op0, 1);
1991 else if (code0 == PLUS)
1993 indx = XEXP (op0, 0); /* index + base + disp */
1994 base = XEXP (op0, 1);
2000 ADDR_INVALID ("PLUS subcode is not valid.\n", op0);
2005 else if (GET_CODE (addr) == MULT)
2007 indx = XEXP (addr, 0); /* index*scale */
2008 scale = XEXP (addr, 1);
2012 disp = addr; /* displacement */
2014 /* Allow arg pointer and stack pointer as index if there is not scaling */
2015 if (base && indx && !scale
2016 && (indx == arg_pointer_rtx || indx == stack_pointer_rtx))
2023 /* Validate base register */
2024 /* Don't allow SUBREG's here, it can lead to spill failures when the base
2025 is one word out of a two word structure, which is represented internally
2029 if (GET_CODE (base) != REG)
2031 ADDR_INVALID ("Base is not a register.\n", base);
2035 if ((strict && !REG_OK_FOR_BASE_STRICT_P (base))
2036 || (!strict && !REG_OK_FOR_BASE_NONSTRICT_P (base)))
2038 ADDR_INVALID ("Base is not valid.\n", base);
2043 /* Validate index register */
2044 /* Don't allow SUBREG's here, it can lead to spill failures when the index
2045 is one word out of a two word structure, which is represented internally
2049 if (GET_CODE (indx) != REG)
2051 ADDR_INVALID ("Index is not a register.\n", indx);
2055 if ((strict && !REG_OK_FOR_INDEX_STRICT_P (indx))
2056 || (!strict && !REG_OK_FOR_INDEX_NONSTRICT_P (indx)))
2058 ADDR_INVALID ("Index is not valid.\n", indx);
2063 abort (); /* scale w/o index invalid */
2065 /* Validate scale factor */
2068 HOST_WIDE_INT value;
2070 if (GET_CODE (scale) != CONST_INT)
2072 ADDR_INVALID ("Scale is not valid.\n", scale);
2076 value = INTVAL (scale);
2077 if (value != 1 && value != 2 && value != 4 && value != 8)
2079 ADDR_INVALID ("Scale is not a good multiplier.\n", scale);
2084 /* Validate displacement
2085 Constant pool addresses must be handled special. They are
2086 considered legitimate addresses, but only if not used with regs.
2087 When printed, the output routines know to print the reference with the
2088 PIC reg, even though the PIC reg doesn't appear in the RTL. */
2091 if (GET_CODE (disp) == SYMBOL_REF
2092 && CONSTANT_POOL_ADDRESS_P (disp)
2097 else if (!CONSTANT_ADDRESS_P (disp))
2099 ADDR_INVALID ("Displacement is not valid.\n", disp);
2103 else if (GET_CODE (disp) == CONST_DOUBLE)
2105 ADDR_INVALID ("Displacement is a const_double.\n", disp);
2109 else if (flag_pic && SYMBOLIC_CONST (disp)
2110 && base != pic_offset_table_rtx
2111 && (indx != pic_offset_table_rtx || scale != NULL_RTX))
2113 ADDR_INVALID ("Displacement is an invalid pic reference.\n", disp);
2117 else if (HALF_PIC_P () && HALF_PIC_ADDRESS_P (disp)
2118 && (base != NULL_RTX || indx != NULL_RTX))
2120 ADDR_INVALID ("Displacement is an invalid half-pic reference.\n", disp);
2125 if (TARGET_DEBUG_ADDR)
2126 fprintf (stderr, "Address is valid.\n");
2128 /* Everything looks valid, return true */
2133 /* Return a legitimate reference for ORIG (an address) using the
2134 register REG. If REG is 0, a new pseudo is generated.
2136 There are three types of references that must be handled:
2138 1. Global data references must load the address from the GOT, via
2139 the PIC reg. An insn is emitted to do this load, and the reg is
2142 2. Static data references must compute the address as an offset
2143 from the GOT, whose base is in the PIC reg. An insn is emitted to
2144 compute the address into a reg, and the reg is returned. Static
2145 data objects have SYMBOL_REF_FLAG set to differentiate them from
2146 global data objects.
2148 3. Constant pool addresses must be handled special. They are
2149 considered legitimate addresses, but only if not used with regs.
2150 When printed, the output routines know to print the reference with the
2151 PIC reg, even though the PIC reg doesn't appear in the RTL.
2153 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2154 reg also appears in the address (except for constant pool references,
2157 "switch" statements also require special handling when generating
2158 PIC code. See comments by the `casesi' insn in i386.md for details. */
2161 legitimize_pic_address (orig, reg)
2168 if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
2170 if (GET_CODE (addr) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (addr))
2175 reg = gen_reg_rtx (Pmode);
2177 if ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
2178 || GET_CODE (addr) == LABEL_REF)
2179 new = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig);
2181 new = gen_rtx (MEM, Pmode,
2182 gen_rtx (PLUS, Pmode,
2183 pic_offset_table_rtx, orig));
2185 emit_move_insn (reg, new);
2187 current_function_uses_pic_offset_table = 1;
2190 else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
2194 if (GET_CODE (addr) == CONST)
2196 addr = XEXP (addr, 0);
2197 if (GET_CODE (addr) != PLUS)
2201 if (XEXP (addr, 0) == pic_offset_table_rtx)
2205 reg = gen_reg_rtx (Pmode);
2207 base = legitimize_pic_address (XEXP (addr, 0), reg);
2208 addr = legitimize_pic_address (XEXP (addr, 1),
2209 base == reg ? NULL_RTX : reg);
2211 if (GET_CODE (addr) == CONST_INT)
2212 return plus_constant (base, INTVAL (addr));
2214 if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
2216 base = gen_rtx (PLUS, Pmode, base, XEXP (addr, 0));
2217 addr = XEXP (addr, 1);
2219 return gen_rtx (PLUS, Pmode, base, addr);
2225 /* Emit insns to move operands[1] into operands[0]. */
2228 emit_pic_move (operands, mode)
2230 enum machine_mode mode;
2232 rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
2234 if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
2235 operands[1] = (rtx) force_reg (SImode, operands[1]);
2237 operands[1] = legitimize_pic_address (operands[1], temp);
2241 /* Try machine-dependent ways of modifying an illegitimate address
2242 to be legitimate. If we find one, return the new, valid address.
2243 This macro is used in only one place: `memory_address' in explow.c.
2245 OLDX is the address as it was before break_out_memory_refs was called.
2246 In some cases it is useful to look at this to decide what needs to be done.
2248 MODE and WIN are passed so that this macro can use
2249 GO_IF_LEGITIMATE_ADDRESS.
2251 It is always safe for this macro to do nothing. It exists to recognize
2252 opportunities to optimize the output.
2254 For the 80386, we handle X+REG by loading X into a register R and
2255 using R+REG. R will go in a general reg and indexing will be used.
2256 However, if REG is a broken-out memory address or multiplication,
2257 nothing needs to be done because REG can certainly go in a general reg.
2259 When -fpic is used, special handling is needed for symbolic references.
2260 See comments by legitimize_pic_address in i386.c for details. */
2263 legitimize_address (x, oldx, mode)
2266 enum machine_mode mode;
2271 if (TARGET_DEBUG_ADDR)
2273 fprintf (stderr, "\n==========\nLEGITIMIZE_ADDRESS, mode = %s\n", GET_MODE_NAME (mode));
2277 if (flag_pic && SYMBOLIC_CONST (x))
2278 return legitimize_pic_address (x, 0);
2280 /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
2281 if (GET_CODE (x) == ASHIFT
2282 && GET_CODE (XEXP (x, 1)) == CONST_INT
2283 && (log = (unsigned)exact_log2 (INTVAL (XEXP (x, 1)))) < 4)
2286 x = gen_rtx (MULT, Pmode,
2287 force_reg (Pmode, XEXP (x, 0)),
2288 GEN_INT (1 << log));
2291 if (GET_CODE (x) == PLUS)
2293 /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
2294 if (GET_CODE (XEXP (x, 0)) == ASHIFT
2295 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
2296 && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) < 4)
2299 XEXP (x, 0) = gen_rtx (MULT, Pmode,
2300 force_reg (Pmode, XEXP (XEXP (x, 0), 0)),
2301 GEN_INT (1 << log));
2304 if (GET_CODE (XEXP (x, 1)) == ASHIFT
2305 && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
2306 && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 1), 1)))) < 4)
2309 XEXP (x, 1) = gen_rtx (MULT, Pmode,
2310 force_reg (Pmode, XEXP (XEXP (x, 1), 0)),
2311 GEN_INT (1 << log));
2314 /* Put multiply first if it isn't already */
2315 if (GET_CODE (XEXP (x, 1)) == MULT)
2317 rtx tmp = XEXP (x, 0);
2318 XEXP (x, 0) = XEXP (x, 1);
2323 /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
2324 into (plus (plus (mult (reg) (const)) (reg)) (const)). This can be
2325 created by virtual register instantiation, register elimination, and
2326 similar optimizations. */
2327 if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS)
2330 x = gen_rtx (PLUS, Pmode,
2331 gen_rtx (PLUS, Pmode, XEXP (x, 0), XEXP (XEXP (x, 1), 0)),
2332 XEXP (XEXP (x, 1), 1));
2335 /* Canonicalize (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
2336 into (plus (plus (mult (reg) (const)) (reg)) (const)). */
2337 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
2338 && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
2339 && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
2340 && CONSTANT_P (XEXP (x, 1)))
2342 rtx constant, other;
2344 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
2346 constant = XEXP (x, 1);
2347 other = XEXP (XEXP (XEXP (x, 0), 1), 1);
2349 else if (GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 1)) == CONST_INT)
2351 constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
2352 other = XEXP (x, 1);
2360 x = gen_rtx (PLUS, Pmode,
2361 gen_rtx (PLUS, Pmode, XEXP (XEXP (x, 0), 0),
2362 XEXP (XEXP (XEXP (x, 0), 1), 0)),
2363 plus_constant (other, INTVAL (constant)));
2367 if (changed && legitimate_address_p (mode, x, FALSE))
2370 if (GET_CODE (XEXP (x, 0)) == MULT)
2373 XEXP (x, 0) = force_operand (XEXP (x, 0), 0);
2376 if (GET_CODE (XEXP (x, 1)) == MULT)
2379 XEXP (x, 1) = force_operand (XEXP (x, 1), 0);
2383 && GET_CODE (XEXP (x, 1)) == REG
2384 && GET_CODE (XEXP (x, 0)) == REG)
2387 if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1)))
2390 x = legitimize_pic_address (x, 0);
2393 if (changed && legitimate_address_p (mode, x, FALSE))
2396 if (GET_CODE (XEXP (x, 0)) == REG)
2398 register rtx temp = gen_reg_rtx (Pmode);
2399 register rtx val = force_operand (XEXP (x, 1), temp);
2401 emit_move_insn (temp, val);
2407 else if (GET_CODE (XEXP (x, 1)) == REG)
2409 register rtx temp = gen_reg_rtx (Pmode);
2410 register rtx val = force_operand (XEXP (x, 0), temp);
2412 emit_move_insn (temp, val);
2423 /* Print an integer constant expression in assembler syntax. Addition
2424 and subtraction are the only arithmetic that may appear in these
2425 expressions. FILE is the stdio stream to write to, X is the rtx, and
2426 CODE is the operand print code from the output string. */
2429 output_pic_addr_const (file, x, code)
2436 switch (GET_CODE (x))
2447 if (GET_CODE (x) == SYMBOL_REF)
2448 assemble_name (file, XSTR (x, 0));
2451 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
2452 CODE_LABEL_NUMBER (XEXP (x, 0)));
2453 assemble_name (asm_out_file, buf);
2456 if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
2457 fprintf (file, "@GOTOFF(%%ebx)");
2458 else if (code == 'P')
2459 fprintf (file, "@PLT");
2460 else if (GET_CODE (x) == LABEL_REF)
2461 fprintf (file, "@GOTOFF");
2462 else if (! SYMBOL_REF_FLAG (x))
2463 fprintf (file, "@GOT");
2465 fprintf (file, "@GOTOFF");
2470 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
2471 assemble_name (asm_out_file, buf);
2475 fprintf (file, "%d", INTVAL (x));
2479 /* This used to output parentheses around the expression,
2480 but that does not work on the 386 (either ATT or BSD assembler). */
2481 output_pic_addr_const (file, XEXP (x, 0), code);
2485 if (GET_MODE (x) == VOIDmode)
2487 /* We can use %d if the number is <32 bits and positive. */
2488 if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
2489 fprintf (file, "0x%x%08x",
2490 CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
2492 fprintf (file, "%d", CONST_DOUBLE_LOW (x));
2495 /* We can't handle floating point constants;
2496 PRINT_OPERAND must handle them. */
2497 output_operand_lossage ("floating constant misused");
2501 /* Some assemblers need integer constants to appear last (eg masm). */
2502 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
2504 output_pic_addr_const (file, XEXP (x, 1), code);
2505 if (INTVAL (XEXP (x, 0)) >= 0)
2506 fprintf (file, "+");
2507 output_pic_addr_const (file, XEXP (x, 0), code);
2511 output_pic_addr_const (file, XEXP (x, 0), code);
2512 if (INTVAL (XEXP (x, 1)) >= 0)
2513 fprintf (file, "+");
2514 output_pic_addr_const (file, XEXP (x, 1), code);
2519 output_pic_addr_const (file, XEXP (x, 0), code);
2520 fprintf (file, "-");
2521 output_pic_addr_const (file, XEXP (x, 1), code);
2525 output_operand_lossage ("invalid expression as operand");
2530 f -- float insn (print a CONST_DOUBLE as a float rather than in hex).
2531 D,L,W,B,Q,S -- print the opcode suffix for specified size of operand.
2532 R -- print the prefix for register names.
2533 z -- print the opcode suffix for the size of the current operand.
2534 * -- print a star (in certain assembler syntax)
2535 w -- print the operand as if it's a "word" (HImode) even if it isn't.
2536 c -- don't print special prefixes before constant operands.
2537 J -- print the appropriate jump operand.
2541 print_operand (file, x, code)
2556 PUT_OP_SIZE (code, 'l', file);
2560 PUT_OP_SIZE (code, 'w', file);
2564 PUT_OP_SIZE (code, 'b', file);
2568 PUT_OP_SIZE (code, 'l', file);
2572 PUT_OP_SIZE (code, 's', file);
2576 PUT_OP_SIZE (code, 't', file);
2580 /* 387 opcodes don't get size suffixes if the operands are
2583 if (STACK_REG_P (x))
2586 /* this is the size of op from size of operand */
2587 switch (GET_MODE_SIZE (GET_MODE (x)))
2590 PUT_OP_SIZE ('B', 'b', file);
2594 PUT_OP_SIZE ('W', 'w', file);
2598 if (GET_MODE (x) == SFmode)
2600 PUT_OP_SIZE ('S', 's', file);
2604 PUT_OP_SIZE ('L', 'l', file);
2608 PUT_OP_SIZE ('T', 't', file);
2612 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
2614 #ifdef GAS_MNEMONICS
2615 PUT_OP_SIZE ('Q', 'q', file);
2618 PUT_OP_SIZE ('Q', 'l', file); /* Fall through */
2622 PUT_OP_SIZE ('Q', 'l', file);
2635 switch (GET_CODE (x))
2637 /* These conditions are appropriate for testing the result
2638 of an arithmetic operation, not for a compare operation.
2639 Cases GE, LT assume CC_NO_OVERFLOW true. All cases assume
2640 CC_Z_IN_NOT_C false and not floating point. */
2641 case NE: fputs ("jne", file); return;
2642 case EQ: fputs ("je", file); return;
2643 case GE: fputs ("jns", file); return;
2644 case LT: fputs ("js", file); return;
2645 case GEU: fputs ("jmp", file); return;
2646 case GTU: fputs ("jne", file); return;
2647 case LEU: fputs ("je", file); return;
2648 case LTU: fputs ("#branch never", file); return;
2650 /* no matching branches for GT nor LE */
2658 sprintf (str, "invalid operand code `%c'", code);
2659 output_operand_lossage (str);
2663 if (GET_CODE (x) == REG)
2665 PRINT_REG (x, code, file);
2667 else if (GET_CODE (x) == MEM)
2669 PRINT_PTR (x, file);
2670 if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
2673 output_pic_addr_const (file, XEXP (x, 0), code);
2675 output_addr_const (file, XEXP (x, 0));
2678 output_address (XEXP (x, 0));
2680 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
2682 REAL_VALUE_TYPE r; long l;
2683 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2684 REAL_VALUE_TO_TARGET_SINGLE (r, l);
2685 PRINT_IMMED_PREFIX (file);
2686 fprintf (file, "0x%x", l);
2688 /* These float cases don't actually occur as immediate operands. */
2689 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
2691 REAL_VALUE_TYPE r; char dstr[30];
2692 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2693 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
2694 fprintf (file, "%s", dstr);
2696 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == XFmode)
2698 REAL_VALUE_TYPE r; char dstr[30];
2699 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2700 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
2701 fprintf (file, "%s", dstr);
2707 if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
2708 PRINT_IMMED_PREFIX (file);
2709 else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
2710 || GET_CODE (x) == LABEL_REF)
2711 PRINT_OFFSET_PREFIX (file);
2714 output_pic_addr_const (file, x, code);
2716 output_addr_const (file, x);
2720 /* Print a memory operand whose address is ADDR. */
2723 print_operand_address (file, addr)
2727 register rtx reg1, reg2, breg, ireg;
2730 switch (GET_CODE (addr))
2734 fprintf (file, "%se", RP);
2735 fputs (hi_reg_name[REGNO (addr)], file);
2745 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
2747 offset = XEXP (addr, 0);
2748 addr = XEXP (addr, 1);
2750 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
2752 offset = XEXP (addr, 1);
2753 addr = XEXP (addr, 0);
2755 if (GET_CODE (addr) != PLUS) ;
2756 else if (GET_CODE (XEXP (addr, 0)) == MULT)
2758 reg1 = XEXP (addr, 0);
2759 addr = XEXP (addr, 1);
2761 else if (GET_CODE (XEXP (addr, 1)) == MULT)
2763 reg1 = XEXP (addr, 1);
2764 addr = XEXP (addr, 0);
2766 else if (GET_CODE (XEXP (addr, 0)) == REG)
2768 reg1 = XEXP (addr, 0);
2769 addr = XEXP (addr, 1);
2771 else if (GET_CODE (XEXP (addr, 1)) == REG)
2773 reg1 = XEXP (addr, 1);
2774 addr = XEXP (addr, 0);
2776 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
2778 if (reg1 == 0) reg1 = addr;
2784 if (addr != 0) abort ();
2787 if ((reg1 && GET_CODE (reg1) == MULT)
2788 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
2793 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
2799 if (ireg != 0 || breg != 0)
2806 output_pic_addr_const (file, addr, 0);
2808 else if (GET_CODE (addr) == LABEL_REF)
2809 output_asm_label (addr);
2812 output_addr_const (file, addr);
2815 if (ireg != 0 && GET_CODE (ireg) == MULT)
2817 scale = INTVAL (XEXP (ireg, 1));
2818 ireg = XEXP (ireg, 0);
2821 /* The stack pointer can only appear as a base register,
2822 never an index register, so exchange the regs if it is wrong. */
2824 if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM)
2833 /* output breg+ireg*scale */
2834 PRINT_B_I_S (breg, ireg, scale, file);
2841 if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
2843 scale = INTVAL (XEXP (addr, 0));
2844 ireg = XEXP (addr, 1);
2848 scale = INTVAL (XEXP (addr, 1));
2849 ireg = XEXP (addr, 0);
2851 output_addr_const (file, const0_rtx);
2852 PRINT_B_I_S ((rtx) 0, ireg, scale, file);
2857 if (GET_CODE (addr) == CONST_INT
2858 && INTVAL (addr) < 0x8000
2859 && INTVAL (addr) >= -0x8000)
2860 fprintf (file, "%d", INTVAL (addr));
2864 output_pic_addr_const (file, addr, 0);
2866 output_addr_const (file, addr);
2871 /* Set the cc_status for the results of an insn whose pattern is EXP.
2872 On the 80386, we assume that only test and compare insns, as well
2873 as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, ASHIFT,
2874 ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
2875 Also, we assume that jumps, moves and sCOND don't affect the condition
2876 codes. All else clobbers the condition codes, by assumption.
2878 We assume that ALL integer add, minus, etc. instructions effect the
2879 condition codes. This MUST be consistent with i386.md.
2881 We don't record any float test or compare - the redundant test &
2882 compare check in final.c does not handle stack-like regs correctly. */
2885 notice_update_cc (exp)
2888 if (GET_CODE (exp) == SET)
2890 /* Jumps do not alter the cc's. */
2891 if (SET_DEST (exp) == pc_rtx)
2893 #ifdef IS_STACK_MODE
2894 /* Moving into a memory of stack_mode may have been moved
2895 in between the use and set of cc0 by loop_spl(). So
2896 old value of cc.status must be retained */
2897 if(GET_CODE(SET_DEST(exp))==MEM
2898 && IS_STACK_MODE(GET_MODE(SET_DEST(exp))))
2903 /* Moving register or memory into a register:
2904 it doesn't alter the cc's, but it might invalidate
2905 the RTX's which we remember the cc's came from.
2906 (Note that moving a constant 0 or 1 MAY set the cc's). */
2907 if (REG_P (SET_DEST (exp))
2908 && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM
2909 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
2911 if (cc_status.value1
2912 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
2913 cc_status.value1 = 0;
2914 if (cc_status.value2
2915 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
2916 cc_status.value2 = 0;
2919 /* Moving register into memory doesn't alter the cc's.
2920 It may invalidate the RTX's which we remember the cc's came from. */
2921 if (GET_CODE (SET_DEST (exp)) == MEM
2922 && (REG_P (SET_SRC (exp))
2923 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
2925 if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
2926 cc_status.value1 = 0;
2927 if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
2928 cc_status.value2 = 0;
2931 /* Function calls clobber the cc's. */
2932 else if (GET_CODE (SET_SRC (exp)) == CALL)
2937 /* Tests and compares set the cc's in predictable ways. */
2938 else if (SET_DEST (exp) == cc0_rtx)
2941 cc_status.value1 = SET_SRC (exp);
2944 /* Certain instructions effect the condition codes. */
2945 else if (GET_MODE (SET_SRC (exp)) == SImode
2946 || GET_MODE (SET_SRC (exp)) == HImode
2947 || GET_MODE (SET_SRC (exp)) == QImode)
2948 switch (GET_CODE (SET_SRC (exp)))
2950 case ASHIFTRT: case LSHIFTRT:
2952 /* Shifts on the 386 don't set the condition codes if the
2953 shift count is zero. */
2954 if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
2959 /* We assume that the CONST_INT is non-zero (this rtx would
2960 have been deleted if it were zero. */
2962 case PLUS: case MINUS: case NEG:
2963 case AND: case IOR: case XOR:
2964 cc_status.flags = CC_NO_OVERFLOW;
2965 cc_status.value1 = SET_SRC (exp);
2966 cc_status.value2 = SET_DEST (exp);
2977 else if (GET_CODE (exp) == PARALLEL
2978 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
2980 if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
2982 if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
2985 if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
2986 cc_status.flags |= CC_IN_80387;
2988 cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
2999 /* Split one or more DImode RTL references into pairs of SImode
3000 references. The RTL can be REG, offsettable MEM, integer constant, or
3001 CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to
3002 split and "num" is its length. lo_half and hi_half are output arrays
3003 that parallel "operands". */
3006 split_di (operands, num, lo_half, hi_half)
3009 rtx lo_half[], hi_half[];
3013 if (GET_CODE (operands[num]) == REG)
3015 lo_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]));
3016 hi_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]) + 1);
3018 else if (CONSTANT_P (operands[num]))
3020 split_double (operands[num], &lo_half[num], &hi_half[num]);
3022 else if (offsettable_memref_p (operands[num]))
3024 lo_half[num] = operands[num];
3025 hi_half[num] = adj_offsettable_operand (operands[num], 4);
3032 /* Return 1 if this is a valid binary operation on a 387.
3033 OP is the expression matched, and MODE is its mode. */
3036 binary_387_op (op, mode)
3038 enum machine_mode mode;
3040 if (mode != VOIDmode && mode != GET_MODE (op))
3043 switch (GET_CODE (op))
3049 return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
3057 /* Return 1 if this is a valid shift or rotate operation on a 386.
3058 OP is the expression matched, and MODE is its mode. */
3063 enum machine_mode mode;
3065 rtx operand = XEXP (op, 0);
3067 if (mode != VOIDmode && mode != GET_MODE (op))
3070 if (GET_MODE (operand) != GET_MODE (op)
3071 || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
3074 return (GET_CODE (op) == ASHIFT
3075 || GET_CODE (op) == ASHIFTRT
3076 || GET_CODE (op) == LSHIFTRT
3077 || GET_CODE (op) == ROTATE
3078 || GET_CODE (op) == ROTATERT);
3081 /* Return 1 if OP is COMPARE rtx with mode VOIDmode.
3082 MODE is not used. */
3085 VOIDmode_compare_op (op, mode)
3087 enum machine_mode mode;
3089 return GET_CODE (op) == COMPARE && GET_MODE (op) == VOIDmode;
3092 /* Output code to perform a 387 binary operation in INSN, one of PLUS,
3093 MINUS, MULT or DIV. OPERANDS are the insn operands, where operands[3]
3094 is the expression of the binary operation. The output may either be
3095 emitted here, or returned to the caller, like all output_* functions.
3097 There is no guarantee that the operands are the same mode, as they
3098 might be within FLOAT or FLOAT_EXTEND expressions. */
3101 output_387_binary_op (insn, operands)
3107 static char buf[100];
3109 switch (GET_CODE (operands[3]))
3112 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3113 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3120 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3121 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3128 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3129 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3136 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3137 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3147 strcpy (buf, base_op);
3149 switch (GET_CODE (operands[3]))
3153 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
3156 operands[2] = operands[1];
3160 if (GET_CODE (operands[2]) == MEM)
3161 return strcat (buf, AS1 (%z2,%2));
3163 if (NON_STACK_REG_P (operands[1]))
3165 output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
3168 else if (NON_STACK_REG_P (operands[2]))
3170 output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
3174 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
3175 return strcat (buf, AS2 (p,%2,%0));
3177 if (STACK_TOP_P (operands[0]))
3178 return strcat (buf, AS2C (%y2,%0));
3180 return strcat (buf, AS2C (%2,%0));
3184 if (GET_CODE (operands[1]) == MEM)
3185 return strcat (buf, AS1 (r%z1,%1));
3187 if (GET_CODE (operands[2]) == MEM)
3188 return strcat (buf, AS1 (%z2,%2));
3190 if (NON_STACK_REG_P (operands[1]))
3192 output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1)));
3195 else if (NON_STACK_REG_P (operands[2]))
3197 output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
3201 if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
3204 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
3205 return strcat (buf, AS2 (rp,%2,%0));
3207 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3208 return strcat (buf, AS2 (p,%1,%0));
3210 if (STACK_TOP_P (operands[0]))
3212 if (STACK_TOP_P (operands[1]))
3213 return strcat (buf, AS2C (%y2,%0));
3215 return strcat (buf, AS2 (r,%y1,%0));
3217 else if (STACK_TOP_P (operands[1]))
3218 return strcat (buf, AS2C (%1,%0));
3220 return strcat (buf, AS2 (r,%2,%0));
3227 /* Output code for INSN to convert a float to a signed int. OPERANDS
3228 are the insn operands. The output may be SFmode or DFmode and the
3229 input operand may be SImode or DImode. As a special case, make sure
3230 that the 387 stack top dies if the output mode is DImode, because the
3231 hardware requires this. */
3234 output_fix_trunc (insn, operands)
3238 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
3241 if (! STACK_TOP_P (operands[1]) ||
3242 (GET_MODE (operands[0]) == DImode && ! stack_top_dies))
3245 xops[0] = GEN_INT (12);
3246 xops[1] = operands[4];
3248 output_asm_insn (AS1 (fnstc%W2,%2), operands);
3249 output_asm_insn (AS2 (mov%L2,%2,%4), operands);
3250 output_asm_insn (AS2 (mov%B1,%0,%h1), xops);
3251 output_asm_insn (AS2 (mov%L4,%4,%3), operands);
3252 output_asm_insn (AS1 (fldc%W3,%3), operands);
3254 if (NON_STACK_REG_P (operands[0]))
3255 output_to_reg (operands[0], stack_top_dies);
3256 else if (GET_CODE (operands[0]) == MEM)
3259 output_asm_insn (AS1 (fistp%z0,%0), operands);
3261 output_asm_insn (AS1 (fist%z0,%0), operands);
3266 return AS1 (fldc%W2,%2);
3269 /* Output code for INSN to compare OPERANDS. The two operands might
3270 not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
3271 expression. If the compare is in mode CCFPEQmode, use an opcode that
3272 will not fault if a qNaN is present. */
3275 output_float_compare (insn, operands)
3280 rtx body = XVECEXP (PATTERN (insn), 0, 0);
3281 int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
3284 if (! STACK_TOP_P (operands[0]))
3287 operands[0] = operands[1];
3289 cc_status.flags |= CC_REVERSED;
3292 if (! STACK_TOP_P (operands[0]))
3295 stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
3297 if (STACK_REG_P (operands[1])
3299 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3300 && REGNO (operands[1]) != FIRST_STACK_REG)
3302 /* If both the top of the 387 stack dies, and the other operand
3303 is also a stack register that dies, then this must be a
3304 `fcompp' float compare */
3306 if (unordered_compare)
3307 output_asm_insn ("fucompp", operands);
3309 output_asm_insn ("fcompp", operands);
3313 static char buf[100];
3315 /* Decide if this is the integer or float compare opcode, or the
3316 unordered float compare. */
3318 if (unordered_compare)
3319 strcpy (buf, "fucom");
3320 else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT)
3321 strcpy (buf, "fcom");
3323 strcpy (buf, "ficom");
3325 /* Modify the opcode if the 387 stack is to be popped. */
3330 if (NON_STACK_REG_P (operands[1]))
3331 output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
3333 output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
3336 /* Now retrieve the condition code. */
3338 return output_fp_cc0_set (insn);
3341 /* Output opcodes to transfer the results of FP compare or test INSN
3342 from the FPU to the CPU flags. If TARGET_IEEE_FP, ensure that if the
3343 result of the compare or test is unordered, no comparison operator
3344 succeeds except NE. Return an output template, if any. */
3347 output_fp_cc0_set (insn)
3351 rtx unordered_label;
3355 xops[0] = gen_rtx (REG, HImode, 0);
3356 output_asm_insn (AS1 (fnsts%W0,%0), xops);
3358 if (! TARGET_IEEE_FP)
3360 if (!(cc_status.flags & CC_REVERSED))
3362 next = next_cc0_user (insn);
3364 if (GET_CODE (next) == JUMP_INSN
3365 && GET_CODE (PATTERN (next)) == SET
3366 && SET_DEST (PATTERN (next)) == pc_rtx
3367 && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
3369 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
3371 else if (GET_CODE (PATTERN (next)) == SET)
3373 code = GET_CODE (SET_SRC (PATTERN (next)));
3379 if (code == GT || code == LT || code == EQ || code == NE
3380 || code == LE || code == GE)
3381 { /* We will test eax directly */
3382 cc_status.flags |= CC_TEST_AX;
3389 next = next_cc0_user (insn);
3390 if (next == NULL_RTX)
3393 if (GET_CODE (next) == JUMP_INSN
3394 && GET_CODE (PATTERN (next)) == SET
3395 && SET_DEST (PATTERN (next)) == pc_rtx
3396 && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
3398 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
3400 else if (GET_CODE (PATTERN (next)) == SET)
3402 code = GET_CODE (SET_SRC (PATTERN (next)));
3407 xops[0] = gen_rtx (REG, QImode, 0);
3412 xops[1] = GEN_INT (0x45);
3413 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3418 xops[1] = GEN_INT (0x45);
3419 xops[2] = GEN_INT (0x01);
3420 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3421 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
3426 xops[1] = GEN_INT (0x05);
3427 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3432 xops[1] = GEN_INT (0x45);
3433 xops[2] = GEN_INT (0x40);
3434 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3435 output_asm_insn (AS1 (dec%B0,%h0), xops);
3436 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
3441 xops[1] = GEN_INT (0x45);
3442 xops[2] = GEN_INT (0x40);
3443 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3444 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
3449 xops[1] = GEN_INT (0x44);
3450 xops[2] = GEN_INT (0x40);
3451 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3452 output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
3466 #define MAX_386_STACK_LOCALS 2
3468 static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
3470 /* Define the structure for the machine field in struct function. */
3471 struct machine_function
3473 rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
3476 /* Functions to save and restore i386_stack_locals.
3477 These will be called, via pointer variables,
3478 from push_function_context and pop_function_context. */
3481 save_386_machine_status (p)
3484 p->machine = (struct machine_function *) xmalloc (sizeof i386_stack_locals);
3485 bcopy ((char *) i386_stack_locals, (char *) p->machine->i386_stack_locals,
3486 sizeof i386_stack_locals);
3490 restore_386_machine_status (p)
3493 bcopy ((char *) p->machine->i386_stack_locals, (char *) i386_stack_locals,
3494 sizeof i386_stack_locals);
3498 /* Clear stack slot assignments remembered from previous functions.
3499 This is called from INIT_EXPANDERS once before RTL is emitted for each
3503 clear_386_stack_locals ()
3505 enum machine_mode mode;
3508 for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
3509 mode = (enum machine_mode) ((int) mode + 1))
3510 for (n = 0; n < MAX_386_STACK_LOCALS; n++)
3511 i386_stack_locals[(int) mode][n] = NULL_RTX;
3513 /* Arrange to save and restore i386_stack_locals around nested functions. */
3514 save_machine_status = save_386_machine_status;
3515 restore_machine_status = restore_386_machine_status;
3518 /* Return a MEM corresponding to a stack slot with mode MODE.
3519 Allocate a new slot if necessary.
3521 The RTL for a function can have several slots available: N is
3522 which slot to use. */
3525 assign_386_stack_local (mode, n)
3526 enum machine_mode mode;
3529 if (n < 0 || n >= MAX_386_STACK_LOCALS)
3532 if (i386_stack_locals[(int) mode][n] == NULL_RTX)
3533 i386_stack_locals[(int) mode][n]
3534 = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
3536 return i386_stack_locals[(int) mode][n];
3542 enum machine_mode mode;
3544 return (GET_CODE (op) == MULT);
3549 enum machine_mode mode;
3551 return (GET_CODE (op) == DIV);
3556 /* Create a new copy of an rtx.
3557 Recursively copies the operands of the rtx,
3558 except for those few rtx codes that are sharable.
3559 Doesn't share CONST */
3567 register RTX_CODE code;
3568 register char *format_ptr;
3570 code = GET_CODE (orig);
3583 /* SCRATCH must be shared because they represent distinct values. */
3588 /* CONST can be shared if it contains a SYMBOL_REF. If it contains
3589 a LABEL_REF, it isn't sharable. */
3590 if (GET_CODE (XEXP (orig, 0)) == PLUS
3591 && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
3592 && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
3596 /* A MEM with a constant address is not sharable. The problem is that
3597 the constant address may need to be reloaded. If the mem is shared,
3598 then reloading one copy of this mem will cause all copies to appear
3599 to have been reloaded. */
3602 copy = rtx_alloc (code);
3603 PUT_MODE (copy, GET_MODE (orig));
3604 copy->in_struct = orig->in_struct;
3605 copy->volatil = orig->volatil;
3606 copy->unchanging = orig->unchanging;
3607 copy->integrated = orig->integrated;
3609 copy->is_spill_rtx = orig->is_spill_rtx;
3611 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
3613 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
3615 switch (*format_ptr++)
3618 XEXP (copy, i) = XEXP (orig, i);
3619 if (XEXP (orig, i) != NULL)
3620 XEXP (copy, i) = copy_rtx (XEXP (orig, i));
3625 XEXP (copy, i) = XEXP (orig, i);
3630 XVEC (copy, i) = XVEC (orig, i);
3631 if (XVEC (orig, i) != NULL)
3633 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
3634 for (j = 0; j < XVECLEN (copy, i); j++)
3635 XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
3640 XWINT (copy, i) = XWINT (orig, i);
3644 XINT (copy, i) = XINT (orig, i);
3649 XSTR (copy, i) = XSTR (orig, i);
3660 /* try to rewrite a memory address to make it valid */
3662 rewrite_address (mem_rtx)
3665 rtx index_rtx, base_rtx, offset_rtx, scale_rtx, ret_rtx;
3667 int offset_adjust = 0;
3668 int was_only_offset = 0;
3669 rtx mem_addr = XEXP (mem_rtx, 0);
3670 char *storage = (char *) oballoc (0);
3672 int is_spill_rtx = 0;
3674 in_struct = MEM_IN_STRUCT_P (mem_rtx);
3675 is_spill_rtx = RTX_IS_SPILL_P (mem_rtx);
3677 if (GET_CODE (mem_addr) == PLUS &&
3678 GET_CODE (XEXP (mem_addr, 1)) == PLUS &&
3679 GET_CODE (XEXP (XEXP (mem_addr, 1), 0)) == REG)
3680 { /* this part is utilized by the combiner */
3682 gen_rtx (PLUS, GET_MODE (mem_addr),
3683 gen_rtx (PLUS, GET_MODE (XEXP (mem_addr, 1)),
3685 XEXP (XEXP (mem_addr, 1), 0)),
3686 XEXP (XEXP (mem_addr, 1), 1));
3687 if (memory_address_p (GET_MODE (mem_rtx), ret_rtx))
3689 XEXP (mem_rtx, 0) = ret_rtx;
3690 RTX_IS_SPILL_P (ret_rtx) = is_spill_rtx;
3696 /* this part is utilized by loop.c */
3697 /* If the address contains PLUS (reg,const) and this pattern is invalid
3698 in this case - try to rewrite the address to make it valid intel1
3700 storage = (char *) oballoc (0);
3701 index_rtx = base_rtx = offset_rtx = NULL;
3702 /* find the base index and offset elements of the memory address */
3703 if (GET_CODE (mem_addr) == PLUS)
3705 if (GET_CODE (XEXP (mem_addr, 0)) == REG)
3707 if (GET_CODE (XEXP (mem_addr, 1)) == REG)
3709 base_rtx = XEXP (mem_addr, 1);
3710 index_rtx = XEXP (mem_addr, 0);
3714 base_rtx = XEXP (mem_addr, 0);
3715 offset_rtx = XEXP (mem_addr, 1);
3718 else if (GET_CODE (XEXP (mem_addr, 0)) == MULT)
3720 index_rtx = XEXP (mem_addr, 0);
3721 if (GET_CODE (XEXP (mem_addr, 1)) == REG)
3723 base_rtx = XEXP (mem_addr, 1);
3727 offset_rtx = XEXP (mem_addr, 1);
3730 else if (GET_CODE (XEXP (mem_addr, 0)) == PLUS)
3733 if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == PLUS &&
3734 GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0)) == MULT &&
3735 GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 0)) == REG &&
3736 GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 1)) == CONST_INT &&
3737 GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1)) == CONST_INT &&
3738 GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == REG &&
3739 GET_CODE (XEXP (mem_addr, 1)) == SYMBOL_REF)
3741 index_rtx = XEXP (XEXP (XEXP (mem_addr, 0), 0), 0);
3742 offset_rtx = XEXP (mem_addr, 1);
3743 base_rtx = XEXP (XEXP (mem_addr, 0), 1);
3744 offset_adjust = INTVAL (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1));
3748 offset_rtx = XEXP (mem_addr, 1);
3749 index_rtx = XEXP (XEXP (mem_addr, 0), 0);
3750 base_rtx = XEXP (XEXP (mem_addr, 0), 1);
3753 else if (GET_CODE (XEXP (mem_addr, 0)) == CONST_INT)
3755 was_only_offset = 1;
3758 offset_rtx = XEXP (mem_addr, 1);
3759 offset_adjust = INTVAL (XEXP (mem_addr, 0));
3760 if (offset_adjust == 0)
3762 XEXP (mem_rtx, 0) = offset_rtx;
3763 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
3773 else if (GET_CODE (mem_addr) == MULT)
3775 index_rtx = mem_addr;
3782 if (index_rtx && GET_CODE (index_rtx) == MULT)
3784 if (GET_CODE (XEXP (index_rtx, 1)) != CONST_INT)
3789 scale_rtx = XEXP (index_rtx, 1);
3790 scale = INTVAL (scale_rtx);
3791 index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
3793 /* now find which of the elements are invalid and try to fix them */
3794 if (index_rtx && GET_CODE (index_rtx) == CONST_INT && base_rtx == NULL)
3796 offset_adjust = INTVAL (index_rtx) * scale;
3797 if (offset_rtx && GET_CODE (offset_rtx) == CONST &&
3798 GET_CODE (XEXP (offset_rtx, 0)) == PLUS)
3800 if (GET_CODE (XEXP (XEXP (offset_rtx, 0), 0)) == SYMBOL_REF &&
3801 GET_CODE (XEXP (XEXP (offset_rtx, 0), 1)) == CONST_INT)
3803 offset_rtx = copy_all_rtx (offset_rtx);
3804 XEXP (XEXP (offset_rtx, 0), 1) =
3805 gen_rtx (CONST_INT, 0, INTVAL (XEXP (XEXP (offset_rtx, 0), 1)) + offset_adjust);
3806 if (!CONSTANT_P (offset_rtx))
3813 else if (offset_rtx && GET_CODE (offset_rtx) == SYMBOL_REF)
3816 gen_rtx (CONST, GET_MODE (offset_rtx),
3817 gen_rtx (PLUS, GET_MODE (offset_rtx),
3819 gen_rtx (CONST_INT, 0, offset_adjust)));
3820 if (!CONSTANT_P (offset_rtx))
3826 else if (offset_rtx && GET_CODE (offset_rtx) == CONST_INT)
3828 offset_rtx = gen_rtx (CONST_INT, 0, INTVAL (offset_rtx) + offset_adjust);
3830 else if (!offset_rtx)
3832 offset_rtx = gen_rtx (CONST_INT, 0, 0);
3834 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
3835 XEXP (mem_rtx, 0) = offset_rtx;
3838 if (base_rtx && GET_CODE (base_rtx) == PLUS &&
3839 GET_CODE (XEXP (base_rtx, 0)) == REG &&
3840 GET_CODE (XEXP (base_rtx, 1)) == CONST_INT)
3842 offset_adjust += INTVAL (XEXP (base_rtx, 1));
3843 base_rtx = copy_all_rtx (XEXP (base_rtx, 0));
3845 else if (base_rtx && GET_CODE (base_rtx) == CONST_INT)
3847 offset_adjust += INTVAL (base_rtx);
3850 if (index_rtx && GET_CODE (index_rtx) == PLUS &&
3851 GET_CODE (XEXP (index_rtx, 0)) == REG &&
3852 GET_CODE (XEXP (index_rtx, 1)) == CONST_INT)
3854 offset_adjust += INTVAL (XEXP (index_rtx, 1)) * scale;
3855 index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
3859 if (!LEGITIMATE_INDEX_P (index_rtx)
3860 && !(index_rtx == stack_pointer_rtx && scale == 1 && base_rtx == NULL))
3868 if (!LEGITIMATE_INDEX_P (base_rtx) && GET_CODE (base_rtx) != REG)
3874 if (offset_adjust != 0)
3878 if (GET_CODE (offset_rtx) == CONST &&
3879 GET_CODE (XEXP (offset_rtx, 0)) == PLUS)
3881 if (GET_CODE (XEXP (XEXP (offset_rtx, 0), 0)) == SYMBOL_REF &&
3882 GET_CODE (XEXP (XEXP (offset_rtx, 0), 1)) == CONST_INT)
3884 offset_rtx = copy_all_rtx (offset_rtx);
3885 XEXP (XEXP (offset_rtx, 0), 1) =
3886 gen_rtx (CONST_INT, 0, INTVAL (XEXP (XEXP (offset_rtx, 0), 1)) + offset_adjust);
3887 if (!CONSTANT_P (offset_rtx))
3894 else if (GET_CODE (offset_rtx) == SYMBOL_REF)
3897 gen_rtx (CONST, GET_MODE (offset_rtx),
3898 gen_rtx (PLUS, GET_MODE (offset_rtx),
3900 gen_rtx (CONST_INT, 0, offset_adjust)));
3901 if (!CONSTANT_P (offset_rtx))
3907 else if (GET_CODE (offset_rtx) == CONST_INT)
3909 offset_rtx = gen_rtx (CONST_INT, 0, INTVAL (offset_rtx) + offset_adjust);
3919 offset_rtx = gen_rtx (CONST_INT, 0, offset_adjust);
3927 if (GET_CODE (offset_rtx) == CONST_INT &&
3928 INTVAL (offset_rtx) == 0)
3930 ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx),
3931 gen_rtx (MULT, GET_MODE (index_rtx), index_rtx,
3937 ret_rtx = gen_rtx (PLUS, GET_MODE (offset_rtx),
3938 gen_rtx (PLUS, GET_MODE (base_rtx),
3939 gen_rtx (MULT, GET_MODE (index_rtx), index_rtx,
3947 if (GET_CODE (offset_rtx) == CONST_INT &&
3948 INTVAL (offset_rtx) == 0)
3950 ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx), index_rtx, base_rtx);
3954 ret_rtx = gen_rtx (PLUS, GET_MODE (offset_rtx),
3955 gen_rtx (PLUS, GET_MODE (index_rtx), index_rtx,
3965 if (GET_CODE (offset_rtx) == CONST_INT &&
3966 INTVAL (offset_rtx) == 0)
3968 ret_rtx = gen_rtx (MULT, GET_MODE (index_rtx), index_rtx, scale_rtx);
3973 gen_rtx (PLUS, GET_MODE (offset_rtx),
3974 gen_rtx (MULT, GET_MODE (index_rtx), index_rtx,
3981 if (GET_CODE (offset_rtx) == CONST_INT &&
3982 INTVAL (offset_rtx) == 0)
3984 ret_rtx = index_rtx;
3988 ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx), index_rtx, offset_rtx);
3997 if (GET_CODE (offset_rtx) == CONST_INT &&
3998 INTVAL (offset_rtx) == 0)
4004 ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx), base_rtx, offset_rtx);
4007 else if (was_only_offset)
4009 ret_rtx = offset_rtx;
4017 XEXP (mem_rtx, 0) = ret_rtx;
4018 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4030 /* return 1 if the first insn to set cc before insn also sets the register
4031 reg_rtx - otherwise return 0 */
4033 last_to_set_cc (reg_rtx, insn)
4036 rtx prev_insn = PREV_INSN (insn);
4040 if (GET_CODE (prev_insn) == NOTE)
4043 else if (GET_CODE (prev_insn) == INSN)
4045 if (GET_CODE (PATTERN (prev_insn)) != SET)
4048 if (rtx_equal_p (SET_DEST (PATTERN (prev_insn)), reg_rtx))
4050 if (sets_condition_code (SET_SRC (PATTERN (prev_insn))))
4056 else if (!doesnt_set_condition_code (SET_SRC (PATTERN (prev_insn))))
4063 prev_insn = PREV_INSN (prev_insn);
4071 doesnt_set_condition_code (pat)
4074 switch (GET_CODE (pat))
4088 sets_condition_code (pat)
4091 switch (GET_CODE (pat))
4115 str_immediate_operand (op, mode)
4117 enum machine_mode mode;
4119 if (GET_CODE (op) == CONST_INT && INTVAL (op) <= 32 && INTVAL (op) >= 0)
4131 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4132 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4133 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4134 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode))
4143 Return 1 if the mode of the SET_DEST of insn is floating point
4144 and it is not an fld or a move from memory to memory.
4145 Otherwise return 0 */
4150 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4151 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4152 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4153 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
4154 && GET_CODE (SET_DEST (PATTERN (insn))) == REG
4155 && REGNO (SET_DEST (PATTERN (insn))) >= FIRST_FLOAT_REG
4156 && GET_CODE (SET_SRC (insn)) != MEM)
4165 Return 1 if the mode of the SET_DEST floating point and is memory
4166 and the source is a register.
4172 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4173 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4174 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4175 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
4176 && GET_CODE (SET_DEST (PATTERN (insn))) == MEM
4177 && GET_CODE (SET_SRC (PATTERN (insn))) == REG)
4187 Return 1 if dep_insn sets a register which insn uses as a base
4188 or index to reference memory.
4189 otherwise return 0 */
4192 agi_dependent (insn, dep_insn)
4195 if (GET_CODE (dep_insn) == INSN
4196 && GET_CODE (PATTERN (dep_insn)) == SET
4197 && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG)
4199 return (reg_mentioned_in_mem (SET_DEST (PATTERN (dep_insn)), insn));
4202 if (GET_CODE (dep_insn) == INSN && GET_CODE (PATTERN (dep_insn)) == SET
4203 && GET_CODE (SET_DEST (PATTERN (dep_insn))) == MEM
4204 && push_operand (SET_DEST (PATTERN (dep_insn)),
4205 GET_MODE (SET_DEST (PATTERN (dep_insn)))))
4207 return (reg_mentioned_in_mem (stack_pointer_rtx, insn));
4215 Return 1 if reg is used in rtl as a base or index for a memory ref
4216 otherwise return 0. */
4219 reg_mentioned_in_mem (reg, rtl)
4224 register enum rtx_code code;
4229 code = GET_CODE (rtl);
4247 if (code == MEM && reg_mentioned_p (reg, rtl))
4250 fmt = GET_RTX_FORMAT (code);
4251 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4256 for (j = XVECLEN (rtl, i) - 1; j >= 0; j--)
4258 if (reg_mentioned_in_mem (reg, XVECEXP (rtl, i, j)))
4263 else if (fmt[i] == 'e' && reg_mentioned_in_mem (reg, XEXP (rtl, i)))
4270 /* Output the approprate insns for doing strlen if not just doing repnz; scasb
4272 operands[0] = result, initialized with the startaddress
4273 operands[1] = alignment of the address.
4274 operands[2] = scratch register, initialized with the startaddress when
4275 not aligned, otherwise undefined
4277 This is just the body. It needs the initialisations mentioned above and
4278 some address computing at the end. These things are done in i386.md. */
4281 output_strlen_unroll (operands)
4286 xops[0] = operands[0]; /* Result */
4287 /* operands[1]; * Alignment */
4288 xops[1] = operands[2]; /* Scratch */
4289 xops[2] = GEN_INT (0);
4290 xops[3] = GEN_INT (2);
4291 xops[4] = GEN_INT (3);
4292 xops[5] = GEN_INT (4);
4293 /* xops[6] = gen_label_rtx (); * label when aligned to 3-byte */
4294 /* xops[7] = gen_label_rtx (); * label when aligned to 2-byte */
4295 xops[8] = gen_label_rtx (); /* label of main loop */
4296 if(TARGET_USE_Q_REG && QI_REG_P (xops[1]))
4297 xops[9] = gen_label_rtx (); /* pentium optimisation */
4298 xops[10] = gen_label_rtx (); /* end label 2 */
4299 xops[11] = gen_label_rtx (); /* end label 1 */
4300 xops[12] = gen_label_rtx (); /* end label */
4301 /* xops[13] * Temporary used */
4302 xops[14] = GEN_INT (0xff);
4303 xops[15] = GEN_INT (0xff00);
4304 xops[16] = GEN_INT (0xff0000);
4305 xops[17] = GEN_INT (0xff000000);
4307 /* Loop to check 1..3 bytes for null to get an aligned pointer */
4309 /* is there a known alignment and is it less then 4 */
4310 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) < 4)
4312 /* is there a known alignment and is it not 2 */
4313 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
4315 xops[6] = gen_label_rtx (); /* label when aligned to 3-byte */
4316 xops[7] = gen_label_rtx (); /* label when aligned to 2-byte */
4318 /* leave just the 3 lower bits */
4319 /* if this is a q-register, then the high part is used later */
4320 /* therefore user andl rather than andb */
4321 output_asm_insn (AS2 (and%L1,%4,%1), xops);
4322 /* is aligned to 4-byte adress when zero */
4323 output_asm_insn (AS1 (je,%l8), xops);
4324 /* side-effect even Parity when %eax == 3 */
4325 output_asm_insn (AS1 (jp,%6), xops);
4327 /* is it aligned to 2 bytes ? */
4328 if (QI_REG_P (xops[1]))
4329 output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
4331 output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
4332 output_asm_insn (AS1 (je,%7), xops);
4336 /* since the alignment is 2, we have to check 2 or 0 bytes */
4338 /* check if is aligned to 4 - byte */
4339 output_asm_insn (AS2 (and%L1,%3,%1), xops);
4340 /* is aligned to 4-byte adress when zero */
4341 output_asm_insn (AS1 (je,%l8), xops);
4344 xops[13] = gen_rtx (MEM, QImode, xops[0]);
4345 /* now, compare the bytes */
4346 /* compare with the high part of a q-reg gives shorter code */
4347 if (QI_REG_P (xops[1]))
4349 /* compare the first n unaligned byte on a byte per byte basis */
4350 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
4351 /* when zero we reached the end */
4352 output_asm_insn (AS1 (je,%l12), xops);
4353 /* increment the address */
4354 output_asm_insn (AS1 (inc%L0,%0), xops);
4356 /* not needed with an alignment of 2 */
4357 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
4359 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[7]));
4360 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
4361 output_asm_insn (AS1 (je,%l12), xops);
4362 output_asm_insn (AS1 (inc%L0,%0), xops);
4364 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[6]));
4366 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
4370 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
4371 output_asm_insn (AS1 (je,%l12), xops);
4372 output_asm_insn (AS1 (inc%L0,%0), xops);
4374 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[7]));
4375 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
4376 output_asm_insn (AS1 (je,%l12), xops);
4377 output_asm_insn (AS1 (inc%L0,%0), xops);
4379 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[6]));
4380 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
4382 output_asm_insn (AS1 (je,%l12), xops);
4383 output_asm_insn (AS1 (inc%L0,%0), xops);
4386 /* Generate loop to check 4 bytes at a time */
4387 /* IMHO it is not a good idea to align this loop. It gives only */
4388 /* huge programms, but does not help to speed up */
4389 /* ASM_OUTPUT_LOOP_ALIGN (asm_out_file); */
4390 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[8]));
4392 xops[13] = gen_rtx (MEM, SImode, xops[0]);
4393 output_asm_insn (AS2 (mov%L1,%13,%1), xops);
4395 if (QI_REG_P (xops[1]))
4397 /* on i586 it is faster to compare the hi- and lo- part */
4398 /* as a kind of lookahead. If xoring both is zero, then one */
4399 /* of both *could* be zero, otherwith none of both is zero */
4400 /* this saves one instruction, on i486 this is slower */
4401 /* testet with P-90, i486DX2-66, AMD486DX2-66 */
4404 output_asm_insn (AS2 (test%B1,%h1,%b1), xops);
4405 output_asm_insn (AS1 (jne,%l9), xops);
4408 /* check first byte */
4409 output_asm_insn (AS2 (test%B1,%b1,%b1), xops);
4410 output_asm_insn (AS1 (je,%l12), xops);
4412 /* check second byte */
4413 output_asm_insn (AS2 (test%B1,%h1,%h1), xops);
4414 output_asm_insn (AS1 (je,%l11), xops);
4417 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[9]));
4421 /* check first byte */
4422 output_asm_insn (AS2 (test%L1,%14,%1), xops);
4423 output_asm_insn (AS1 (je,%l12), xops);
4425 /* check second byte */
4426 output_asm_insn (AS2 (test%L1,%15,%1), xops);
4427 output_asm_insn (AS1 (je,%l11), xops);
4430 /* check third byte */
4431 output_asm_insn (AS2 (test%L1,%16,%1), xops);
4432 output_asm_insn (AS1 (je,%l10), xops);
4434 /* check fourth byte and increment address */
4435 output_asm_insn (AS2 (add%L0,%5,%0), xops);
4436 output_asm_insn (AS2 (test%L1,%17,%1), xops);
4437 output_asm_insn (AS1 (jne,%l8), xops);
4439 /* now generate fixups when the compare stops within a 4-byte word */
4440 output_asm_insn (AS2 (sub%L0,%4,%0), xops);
4442 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[10]));
4443 output_asm_insn (AS1 (inc%L0,%0), xops);
4445 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[11]));
4446 output_asm_insn (AS1 (inc%L0,%0), xops);
4448 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[12]));