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) && !REAL_VALUE_MINUS_ZERO (d);
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 || reg_mentioned_p (SET_DEST (exp), cc_status.value1))
2927 cc_status.value1 = 0;
2928 if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM
2929 || reg_mentioned_p (SET_DEST (exp), cc_status.value2))
2930 cc_status.value2 = 0;
2933 /* Function calls clobber the cc's. */
2934 else if (GET_CODE (SET_SRC (exp)) == CALL)
2939 /* Tests and compares set the cc's in predictable ways. */
2940 else if (SET_DEST (exp) == cc0_rtx)
2943 cc_status.value1 = SET_SRC (exp);
2946 /* Certain instructions effect the condition codes. */
2947 else if (GET_MODE (SET_SRC (exp)) == SImode
2948 || GET_MODE (SET_SRC (exp)) == HImode
2949 || GET_MODE (SET_SRC (exp)) == QImode)
2950 switch (GET_CODE (SET_SRC (exp)))
2952 case ASHIFTRT: case LSHIFTRT:
2954 /* Shifts on the 386 don't set the condition codes if the
2955 shift count is zero. */
2956 if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
2961 /* We assume that the CONST_INT is non-zero (this rtx would
2962 have been deleted if it were zero. */
2964 case PLUS: case MINUS: case NEG:
2965 case AND: case IOR: case XOR:
2966 cc_status.flags = CC_NO_OVERFLOW;
2967 cc_status.value1 = SET_SRC (exp);
2968 cc_status.value2 = SET_DEST (exp);
2979 else if (GET_CODE (exp) == PARALLEL
2980 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
2982 if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
2984 if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
2987 if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
2988 cc_status.flags |= CC_IN_80387;
2990 cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
3001 /* Split one or more DImode RTL references into pairs of SImode
3002 references. The RTL can be REG, offsettable MEM, integer constant, or
3003 CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to
3004 split and "num" is its length. lo_half and hi_half are output arrays
3005 that parallel "operands". */
3008 split_di (operands, num, lo_half, hi_half)
3011 rtx lo_half[], hi_half[];
3015 if (GET_CODE (operands[num]) == REG)
3017 lo_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]));
3018 hi_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]) + 1);
3020 else if (CONSTANT_P (operands[num]))
3022 split_double (operands[num], &lo_half[num], &hi_half[num]);
3024 else if (offsettable_memref_p (operands[num]))
3026 lo_half[num] = operands[num];
3027 hi_half[num] = adj_offsettable_operand (operands[num], 4);
3034 /* Return 1 if this is a valid binary operation on a 387.
3035 OP is the expression matched, and MODE is its mode. */
3038 binary_387_op (op, mode)
3040 enum machine_mode mode;
3042 if (mode != VOIDmode && mode != GET_MODE (op))
3045 switch (GET_CODE (op))
3051 return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
3059 /* Return 1 if this is a valid shift or rotate operation on a 386.
3060 OP is the expression matched, and MODE is its mode. */
3065 enum machine_mode mode;
3067 rtx operand = XEXP (op, 0);
3069 if (mode != VOIDmode && mode != GET_MODE (op))
3072 if (GET_MODE (operand) != GET_MODE (op)
3073 || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
3076 return (GET_CODE (op) == ASHIFT
3077 || GET_CODE (op) == ASHIFTRT
3078 || GET_CODE (op) == LSHIFTRT
3079 || GET_CODE (op) == ROTATE
3080 || GET_CODE (op) == ROTATERT);
3083 /* Return 1 if OP is COMPARE rtx with mode VOIDmode.
3084 MODE is not used. */
3087 VOIDmode_compare_op (op, mode)
3089 enum machine_mode mode;
3091 return GET_CODE (op) == COMPARE && GET_MODE (op) == VOIDmode;
3094 /* Output code to perform a 387 binary operation in INSN, one of PLUS,
3095 MINUS, MULT or DIV. OPERANDS are the insn operands, where operands[3]
3096 is the expression of the binary operation. The output may either be
3097 emitted here, or returned to the caller, like all output_* functions.
3099 There is no guarantee that the operands are the same mode, as they
3100 might be within FLOAT or FLOAT_EXTEND expressions. */
3103 output_387_binary_op (insn, operands)
3109 static char buf[100];
3111 switch (GET_CODE (operands[3]))
3114 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3115 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3122 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3123 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3130 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3131 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3138 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3139 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3149 strcpy (buf, base_op);
3151 switch (GET_CODE (operands[3]))
3155 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
3158 operands[2] = operands[1];
3162 if (GET_CODE (operands[2]) == MEM)
3163 return strcat (buf, AS1 (%z2,%2));
3165 if (NON_STACK_REG_P (operands[1]))
3167 output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
3170 else if (NON_STACK_REG_P (operands[2]))
3172 output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
3176 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
3177 return strcat (buf, AS2 (p,%2,%0));
3179 if (STACK_TOP_P (operands[0]))
3180 return strcat (buf, AS2C (%y2,%0));
3182 return strcat (buf, AS2C (%2,%0));
3186 if (GET_CODE (operands[1]) == MEM)
3187 return strcat (buf, AS1 (r%z1,%1));
3189 if (GET_CODE (operands[2]) == MEM)
3190 return strcat (buf, AS1 (%z2,%2));
3192 if (NON_STACK_REG_P (operands[1]))
3194 output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1)));
3197 else if (NON_STACK_REG_P (operands[2]))
3199 output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
3203 if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
3206 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
3207 return strcat (buf, AS2 (rp,%2,%0));
3209 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3210 return strcat (buf, AS2 (p,%1,%0));
3212 if (STACK_TOP_P (operands[0]))
3214 if (STACK_TOP_P (operands[1]))
3215 return strcat (buf, AS2C (%y2,%0));
3217 return strcat (buf, AS2 (r,%y1,%0));
3219 else if (STACK_TOP_P (operands[1]))
3220 return strcat (buf, AS2C (%1,%0));
3222 return strcat (buf, AS2 (r,%2,%0));
3229 /* Output code for INSN to convert a float to a signed int. OPERANDS
3230 are the insn operands. The output may be SFmode or DFmode and the
3231 input operand may be SImode or DImode. As a special case, make sure
3232 that the 387 stack top dies if the output mode is DImode, because the
3233 hardware requires this. */
3236 output_fix_trunc (insn, operands)
3240 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
3243 if (! STACK_TOP_P (operands[1]) ||
3244 (GET_MODE (operands[0]) == DImode && ! stack_top_dies))
3247 xops[0] = GEN_INT (12);
3248 xops[1] = operands[4];
3250 output_asm_insn (AS1 (fnstc%W2,%2), operands);
3251 output_asm_insn (AS2 (mov%L2,%2,%4), operands);
3252 output_asm_insn (AS2 (mov%B1,%0,%h1), xops);
3253 output_asm_insn (AS2 (mov%L4,%4,%3), operands);
3254 output_asm_insn (AS1 (fldc%W3,%3), operands);
3256 if (NON_STACK_REG_P (operands[0]))
3257 output_to_reg (operands[0], stack_top_dies);
3258 else if (GET_CODE (operands[0]) == MEM)
3261 output_asm_insn (AS1 (fistp%z0,%0), operands);
3263 output_asm_insn (AS1 (fist%z0,%0), operands);
3268 return AS1 (fldc%W2,%2);
3271 /* Output code for INSN to compare OPERANDS. The two operands might
3272 not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
3273 expression. If the compare is in mode CCFPEQmode, use an opcode that
3274 will not fault if a qNaN is present. */
3277 output_float_compare (insn, operands)
3282 rtx body = XVECEXP (PATTERN (insn), 0, 0);
3283 int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
3286 if (! STACK_TOP_P (operands[0]))
3289 operands[0] = operands[1];
3291 cc_status.flags |= CC_REVERSED;
3294 if (! STACK_TOP_P (operands[0]))
3297 stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
3299 if (STACK_REG_P (operands[1])
3301 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3302 && REGNO (operands[1]) != FIRST_STACK_REG)
3304 /* If both the top of the 387 stack dies, and the other operand
3305 is also a stack register that dies, then this must be a
3306 `fcompp' float compare */
3308 if (unordered_compare)
3309 output_asm_insn ("fucompp", operands);
3311 output_asm_insn ("fcompp", operands);
3315 static char buf[100];
3317 /* Decide if this is the integer or float compare opcode, or the
3318 unordered float compare. */
3320 if (unordered_compare)
3321 strcpy (buf, "fucom");
3322 else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT)
3323 strcpy (buf, "fcom");
3325 strcpy (buf, "ficom");
3327 /* Modify the opcode if the 387 stack is to be popped. */
3332 if (NON_STACK_REG_P (operands[1]))
3333 output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
3335 output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
3338 /* Now retrieve the condition code. */
3340 return output_fp_cc0_set (insn);
3343 /* Output opcodes to transfer the results of FP compare or test INSN
3344 from the FPU to the CPU flags. If TARGET_IEEE_FP, ensure that if the
3345 result of the compare or test is unordered, no comparison operator
3346 succeeds except NE. Return an output template, if any. */
3349 output_fp_cc0_set (insn)
3353 rtx unordered_label;
3357 xops[0] = gen_rtx (REG, HImode, 0);
3358 output_asm_insn (AS1 (fnsts%W0,%0), xops);
3360 if (! TARGET_IEEE_FP)
3362 if (!(cc_status.flags & CC_REVERSED))
3364 next = next_cc0_user (insn);
3366 if (GET_CODE (next) == JUMP_INSN
3367 && GET_CODE (PATTERN (next)) == SET
3368 && SET_DEST (PATTERN (next)) == pc_rtx
3369 && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
3371 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
3373 else if (GET_CODE (PATTERN (next)) == SET)
3375 code = GET_CODE (SET_SRC (PATTERN (next)));
3381 if (code == GT || code == LT || code == EQ || code == NE
3382 || code == LE || code == GE)
3383 { /* We will test eax directly */
3384 cc_status.flags |= CC_TEST_AX;
3391 next = next_cc0_user (insn);
3392 if (next == NULL_RTX)
3395 if (GET_CODE (next) == JUMP_INSN
3396 && GET_CODE (PATTERN (next)) == SET
3397 && SET_DEST (PATTERN (next)) == pc_rtx
3398 && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
3400 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
3402 else if (GET_CODE (PATTERN (next)) == SET)
3404 code = GET_CODE (SET_SRC (PATTERN (next)));
3409 xops[0] = gen_rtx (REG, QImode, 0);
3414 xops[1] = GEN_INT (0x45);
3415 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3420 xops[1] = GEN_INT (0x45);
3421 xops[2] = GEN_INT (0x01);
3422 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3423 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
3428 xops[1] = GEN_INT (0x05);
3429 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3434 xops[1] = GEN_INT (0x45);
3435 xops[2] = GEN_INT (0x40);
3436 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3437 output_asm_insn (AS1 (dec%B0,%h0), xops);
3438 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
3443 xops[1] = GEN_INT (0x45);
3444 xops[2] = GEN_INT (0x40);
3445 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3446 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
3451 xops[1] = GEN_INT (0x44);
3452 xops[2] = GEN_INT (0x40);
3453 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3454 output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
3468 #define MAX_386_STACK_LOCALS 2
3470 static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
3472 /* Define the structure for the machine field in struct function. */
3473 struct machine_function
3475 rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
3478 /* Functions to save and restore i386_stack_locals.
3479 These will be called, via pointer variables,
3480 from push_function_context and pop_function_context. */
3483 save_386_machine_status (p)
3486 p->machine = (struct machine_function *) xmalloc (sizeof i386_stack_locals);
3487 bcopy ((char *) i386_stack_locals, (char *) p->machine->i386_stack_locals,
3488 sizeof i386_stack_locals);
3492 restore_386_machine_status (p)
3495 bcopy ((char *) p->machine->i386_stack_locals, (char *) i386_stack_locals,
3496 sizeof i386_stack_locals);
3500 /* Clear stack slot assignments remembered from previous functions.
3501 This is called from INIT_EXPANDERS once before RTL is emitted for each
3505 clear_386_stack_locals ()
3507 enum machine_mode mode;
3510 for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
3511 mode = (enum machine_mode) ((int) mode + 1))
3512 for (n = 0; n < MAX_386_STACK_LOCALS; n++)
3513 i386_stack_locals[(int) mode][n] = NULL_RTX;
3515 /* Arrange to save and restore i386_stack_locals around nested functions. */
3516 save_machine_status = save_386_machine_status;
3517 restore_machine_status = restore_386_machine_status;
3520 /* Return a MEM corresponding to a stack slot with mode MODE.
3521 Allocate a new slot if necessary.
3523 The RTL for a function can have several slots available: N is
3524 which slot to use. */
3527 assign_386_stack_local (mode, n)
3528 enum machine_mode mode;
3531 if (n < 0 || n >= MAX_386_STACK_LOCALS)
3534 if (i386_stack_locals[(int) mode][n] == NULL_RTX)
3535 i386_stack_locals[(int) mode][n]
3536 = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
3538 return i386_stack_locals[(int) mode][n];
3544 enum machine_mode mode;
3546 return (GET_CODE (op) == MULT);
3551 enum machine_mode mode;
3553 return (GET_CODE (op) == DIV);
3558 /* Create a new copy of an rtx.
3559 Recursively copies the operands of the rtx,
3560 except for those few rtx codes that are sharable.
3561 Doesn't share CONST */
3569 register RTX_CODE code;
3570 register char *format_ptr;
3572 code = GET_CODE (orig);
3585 /* SCRATCH must be shared because they represent distinct values. */
3590 /* CONST can be shared if it contains a SYMBOL_REF. If it contains
3591 a LABEL_REF, it isn't sharable. */
3592 if (GET_CODE (XEXP (orig, 0)) == PLUS
3593 && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
3594 && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
3598 /* A MEM with a constant address is not sharable. The problem is that
3599 the constant address may need to be reloaded. If the mem is shared,
3600 then reloading one copy of this mem will cause all copies to appear
3601 to have been reloaded. */
3604 copy = rtx_alloc (code);
3605 PUT_MODE (copy, GET_MODE (orig));
3606 copy->in_struct = orig->in_struct;
3607 copy->volatil = orig->volatil;
3608 copy->unchanging = orig->unchanging;
3609 copy->integrated = orig->integrated;
3611 copy->is_spill_rtx = orig->is_spill_rtx;
3613 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
3615 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
3617 switch (*format_ptr++)
3620 XEXP (copy, i) = XEXP (orig, i);
3621 if (XEXP (orig, i) != NULL)
3622 XEXP (copy, i) = copy_rtx (XEXP (orig, i));
3627 XEXP (copy, i) = XEXP (orig, i);
3632 XVEC (copy, i) = XVEC (orig, i);
3633 if (XVEC (orig, i) != NULL)
3635 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
3636 for (j = 0; j < XVECLEN (copy, i); j++)
3637 XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
3642 XWINT (copy, i) = XWINT (orig, i);
3646 XINT (copy, i) = XINT (orig, i);
3651 XSTR (copy, i) = XSTR (orig, i);
3662 /* try to rewrite a memory address to make it valid */
3664 rewrite_address (mem_rtx)
3667 rtx index_rtx, base_rtx, offset_rtx, scale_rtx, ret_rtx;
3669 int offset_adjust = 0;
3670 int was_only_offset = 0;
3671 rtx mem_addr = XEXP (mem_rtx, 0);
3672 char *storage = (char *) oballoc (0);
3674 int is_spill_rtx = 0;
3676 in_struct = MEM_IN_STRUCT_P (mem_rtx);
3677 is_spill_rtx = RTX_IS_SPILL_P (mem_rtx);
3679 if (GET_CODE (mem_addr) == PLUS &&
3680 GET_CODE (XEXP (mem_addr, 1)) == PLUS &&
3681 GET_CODE (XEXP (XEXP (mem_addr, 1), 0)) == REG)
3682 { /* this part is utilized by the combiner */
3684 gen_rtx (PLUS, GET_MODE (mem_addr),
3685 gen_rtx (PLUS, GET_MODE (XEXP (mem_addr, 1)),
3687 XEXP (XEXP (mem_addr, 1), 0)),
3688 XEXP (XEXP (mem_addr, 1), 1));
3689 if (memory_address_p (GET_MODE (mem_rtx), ret_rtx))
3691 XEXP (mem_rtx, 0) = ret_rtx;
3692 RTX_IS_SPILL_P (ret_rtx) = is_spill_rtx;
3698 /* this part is utilized by loop.c */
3699 /* If the address contains PLUS (reg,const) and this pattern is invalid
3700 in this case - try to rewrite the address to make it valid intel1
3702 storage = (char *) oballoc (0);
3703 index_rtx = base_rtx = offset_rtx = NULL;
3704 /* find the base index and offset elements of the memory address */
3705 if (GET_CODE (mem_addr) == PLUS)
3707 if (GET_CODE (XEXP (mem_addr, 0)) == REG)
3709 if (GET_CODE (XEXP (mem_addr, 1)) == REG)
3711 base_rtx = XEXP (mem_addr, 1);
3712 index_rtx = XEXP (mem_addr, 0);
3716 base_rtx = XEXP (mem_addr, 0);
3717 offset_rtx = XEXP (mem_addr, 1);
3720 else if (GET_CODE (XEXP (mem_addr, 0)) == MULT)
3722 index_rtx = XEXP (mem_addr, 0);
3723 if (GET_CODE (XEXP (mem_addr, 1)) == REG)
3725 base_rtx = XEXP (mem_addr, 1);
3729 offset_rtx = XEXP (mem_addr, 1);
3732 else if (GET_CODE (XEXP (mem_addr, 0)) == PLUS)
3735 if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == PLUS &&
3736 GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0)) == MULT &&
3737 GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 0)) == REG &&
3738 GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 1)) == CONST_INT &&
3739 GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1)) == CONST_INT &&
3740 GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == REG &&
3741 GET_CODE (XEXP (mem_addr, 1)) == SYMBOL_REF)
3743 index_rtx = XEXP (XEXP (XEXP (mem_addr, 0), 0), 0);
3744 offset_rtx = XEXP (mem_addr, 1);
3745 base_rtx = XEXP (XEXP (mem_addr, 0), 1);
3746 offset_adjust = INTVAL (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1));
3750 offset_rtx = XEXP (mem_addr, 1);
3751 index_rtx = XEXP (XEXP (mem_addr, 0), 0);
3752 base_rtx = XEXP (XEXP (mem_addr, 0), 1);
3755 else if (GET_CODE (XEXP (mem_addr, 0)) == CONST_INT)
3757 was_only_offset = 1;
3760 offset_rtx = XEXP (mem_addr, 1);
3761 offset_adjust = INTVAL (XEXP (mem_addr, 0));
3762 if (offset_adjust == 0)
3764 XEXP (mem_rtx, 0) = offset_rtx;
3765 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
3775 else if (GET_CODE (mem_addr) == MULT)
3777 index_rtx = mem_addr;
3784 if (index_rtx && GET_CODE (index_rtx) == MULT)
3786 if (GET_CODE (XEXP (index_rtx, 1)) != CONST_INT)
3791 scale_rtx = XEXP (index_rtx, 1);
3792 scale = INTVAL (scale_rtx);
3793 index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
3795 /* now find which of the elements are invalid and try to fix them */
3796 if (index_rtx && GET_CODE (index_rtx) == CONST_INT && base_rtx == NULL)
3798 offset_adjust = INTVAL (index_rtx) * scale;
3799 if (offset_rtx && GET_CODE (offset_rtx) == CONST &&
3800 GET_CODE (XEXP (offset_rtx, 0)) == PLUS)
3802 if (GET_CODE (XEXP (XEXP (offset_rtx, 0), 0)) == SYMBOL_REF &&
3803 GET_CODE (XEXP (XEXP (offset_rtx, 0), 1)) == CONST_INT)
3805 offset_rtx = copy_all_rtx (offset_rtx);
3806 XEXP (XEXP (offset_rtx, 0), 1) =
3807 gen_rtx (CONST_INT, 0, INTVAL (XEXP (XEXP (offset_rtx, 0), 1)) + offset_adjust);
3808 if (!CONSTANT_P (offset_rtx))
3815 else if (offset_rtx && GET_CODE (offset_rtx) == SYMBOL_REF)
3818 gen_rtx (CONST, GET_MODE (offset_rtx),
3819 gen_rtx (PLUS, GET_MODE (offset_rtx),
3821 gen_rtx (CONST_INT, 0, offset_adjust)));
3822 if (!CONSTANT_P (offset_rtx))
3828 else if (offset_rtx && GET_CODE (offset_rtx) == CONST_INT)
3830 offset_rtx = gen_rtx (CONST_INT, 0, INTVAL (offset_rtx) + offset_adjust);
3832 else if (!offset_rtx)
3834 offset_rtx = gen_rtx (CONST_INT, 0, 0);
3836 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
3837 XEXP (mem_rtx, 0) = offset_rtx;
3840 if (base_rtx && GET_CODE (base_rtx) == PLUS &&
3841 GET_CODE (XEXP (base_rtx, 0)) == REG &&
3842 GET_CODE (XEXP (base_rtx, 1)) == CONST_INT)
3844 offset_adjust += INTVAL (XEXP (base_rtx, 1));
3845 base_rtx = copy_all_rtx (XEXP (base_rtx, 0));
3847 else if (base_rtx && GET_CODE (base_rtx) == CONST_INT)
3849 offset_adjust += INTVAL (base_rtx);
3852 if (index_rtx && GET_CODE (index_rtx) == PLUS &&
3853 GET_CODE (XEXP (index_rtx, 0)) == REG &&
3854 GET_CODE (XEXP (index_rtx, 1)) == CONST_INT)
3856 offset_adjust += INTVAL (XEXP (index_rtx, 1)) * scale;
3857 index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
3861 if (!LEGITIMATE_INDEX_P (index_rtx)
3862 && !(index_rtx == stack_pointer_rtx && scale == 1 && base_rtx == NULL))
3870 if (!LEGITIMATE_INDEX_P (base_rtx) && GET_CODE (base_rtx) != REG)
3876 if (offset_adjust != 0)
3880 if (GET_CODE (offset_rtx) == CONST &&
3881 GET_CODE (XEXP (offset_rtx, 0)) == PLUS)
3883 if (GET_CODE (XEXP (XEXP (offset_rtx, 0), 0)) == SYMBOL_REF &&
3884 GET_CODE (XEXP (XEXP (offset_rtx, 0), 1)) == CONST_INT)
3886 offset_rtx = copy_all_rtx (offset_rtx);
3887 XEXP (XEXP (offset_rtx, 0), 1) =
3888 gen_rtx (CONST_INT, 0, INTVAL (XEXP (XEXP (offset_rtx, 0), 1)) + offset_adjust);
3889 if (!CONSTANT_P (offset_rtx))
3896 else if (GET_CODE (offset_rtx) == SYMBOL_REF)
3899 gen_rtx (CONST, GET_MODE (offset_rtx),
3900 gen_rtx (PLUS, GET_MODE (offset_rtx),
3902 gen_rtx (CONST_INT, 0, offset_adjust)));
3903 if (!CONSTANT_P (offset_rtx))
3909 else if (GET_CODE (offset_rtx) == CONST_INT)
3911 offset_rtx = gen_rtx (CONST_INT, 0, INTVAL (offset_rtx) + offset_adjust);
3921 offset_rtx = gen_rtx (CONST_INT, 0, offset_adjust);
3929 if (GET_CODE (offset_rtx) == CONST_INT &&
3930 INTVAL (offset_rtx) == 0)
3932 ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx),
3933 gen_rtx (MULT, GET_MODE (index_rtx), index_rtx,
3939 ret_rtx = gen_rtx (PLUS, GET_MODE (offset_rtx),
3940 gen_rtx (PLUS, GET_MODE (base_rtx),
3941 gen_rtx (MULT, GET_MODE (index_rtx), index_rtx,
3949 if (GET_CODE (offset_rtx) == CONST_INT &&
3950 INTVAL (offset_rtx) == 0)
3952 ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx), index_rtx, base_rtx);
3956 ret_rtx = gen_rtx (PLUS, GET_MODE (offset_rtx),
3957 gen_rtx (PLUS, GET_MODE (index_rtx), index_rtx,
3967 if (GET_CODE (offset_rtx) == CONST_INT &&
3968 INTVAL (offset_rtx) == 0)
3970 ret_rtx = gen_rtx (MULT, GET_MODE (index_rtx), index_rtx, scale_rtx);
3975 gen_rtx (PLUS, GET_MODE (offset_rtx),
3976 gen_rtx (MULT, GET_MODE (index_rtx), index_rtx,
3983 if (GET_CODE (offset_rtx) == CONST_INT &&
3984 INTVAL (offset_rtx) == 0)
3986 ret_rtx = index_rtx;
3990 ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx), index_rtx, offset_rtx);
3999 if (GET_CODE (offset_rtx) == CONST_INT &&
4000 INTVAL (offset_rtx) == 0)
4006 ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx), base_rtx, offset_rtx);
4009 else if (was_only_offset)
4011 ret_rtx = offset_rtx;
4019 XEXP (mem_rtx, 0) = ret_rtx;
4020 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4032 /* return 1 if the first insn to set cc before insn also sets the register
4033 reg_rtx - otherwise return 0 */
4035 last_to_set_cc (reg_rtx, insn)
4038 rtx prev_insn = PREV_INSN (insn);
4042 if (GET_CODE (prev_insn) == NOTE)
4045 else if (GET_CODE (prev_insn) == INSN)
4047 if (GET_CODE (PATTERN (prev_insn)) != SET)
4050 if (rtx_equal_p (SET_DEST (PATTERN (prev_insn)), reg_rtx))
4052 if (sets_condition_code (SET_SRC (PATTERN (prev_insn))))
4058 else if (!doesnt_set_condition_code (SET_SRC (PATTERN (prev_insn))))
4065 prev_insn = PREV_INSN (prev_insn);
4073 doesnt_set_condition_code (pat)
4076 switch (GET_CODE (pat))
4090 sets_condition_code (pat)
4093 switch (GET_CODE (pat))
4117 str_immediate_operand (op, mode)
4119 enum machine_mode mode;
4121 if (GET_CODE (op) == CONST_INT && INTVAL (op) <= 32 && INTVAL (op) >= 0)
4133 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4134 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4135 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4136 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode))
4145 Return 1 if the mode of the SET_DEST of insn is floating point
4146 and it is not an fld or a move from memory to memory.
4147 Otherwise return 0 */
4152 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4153 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4154 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4155 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
4156 && GET_CODE (SET_DEST (PATTERN (insn))) == REG
4157 && REGNO (SET_DEST (PATTERN (insn))) >= FIRST_FLOAT_REG
4158 && GET_CODE (SET_SRC (insn)) != MEM)
4167 Return 1 if the mode of the SET_DEST floating point and is memory
4168 and the source is a register.
4174 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4175 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4176 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4177 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
4178 && GET_CODE (SET_DEST (PATTERN (insn))) == MEM
4179 && GET_CODE (SET_SRC (PATTERN (insn))) == REG)
4189 Return 1 if dep_insn sets a register which insn uses as a base
4190 or index to reference memory.
4191 otherwise return 0 */
4194 agi_dependent (insn, dep_insn)
4197 if (GET_CODE (dep_insn) == INSN
4198 && GET_CODE (PATTERN (dep_insn)) == SET
4199 && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG)
4201 return (reg_mentioned_in_mem (SET_DEST (PATTERN (dep_insn)), insn));
4204 if (GET_CODE (dep_insn) == INSN && GET_CODE (PATTERN (dep_insn)) == SET
4205 && GET_CODE (SET_DEST (PATTERN (dep_insn))) == MEM
4206 && push_operand (SET_DEST (PATTERN (dep_insn)),
4207 GET_MODE (SET_DEST (PATTERN (dep_insn)))))
4209 return (reg_mentioned_in_mem (stack_pointer_rtx, insn));
4217 Return 1 if reg is used in rtl as a base or index for a memory ref
4218 otherwise return 0. */
4221 reg_mentioned_in_mem (reg, rtl)
4226 register enum rtx_code code;
4231 code = GET_CODE (rtl);
4249 if (code == MEM && reg_mentioned_p (reg, rtl))
4252 fmt = GET_RTX_FORMAT (code);
4253 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4258 for (j = XVECLEN (rtl, i) - 1; j >= 0; j--)
4260 if (reg_mentioned_in_mem (reg, XVECEXP (rtl, i, j)))
4265 else if (fmt[i] == 'e' && reg_mentioned_in_mem (reg, XEXP (rtl, i)))
4272 /* Output the approprate insns for doing strlen if not just doing repnz; scasb
4274 operands[0] = result, initialized with the startaddress
4275 operands[1] = alignment of the address.
4276 operands[2] = scratch register, initialized with the startaddress when
4277 not aligned, otherwise undefined
4279 This is just the body. It needs the initialisations mentioned above and
4280 some address computing at the end. These things are done in i386.md. */
4283 output_strlen_unroll (operands)
4288 xops[0] = operands[0]; /* Result */
4289 /* operands[1]; * Alignment */
4290 xops[1] = operands[2]; /* Scratch */
4291 xops[2] = GEN_INT (0);
4292 xops[3] = GEN_INT (2);
4293 xops[4] = GEN_INT (3);
4294 xops[5] = GEN_INT (4);
4295 /* xops[6] = gen_label_rtx (); * label when aligned to 3-byte */
4296 /* xops[7] = gen_label_rtx (); * label when aligned to 2-byte */
4297 xops[8] = gen_label_rtx (); /* label of main loop */
4298 if(TARGET_USE_Q_REG && QI_REG_P (xops[1]))
4299 xops[9] = gen_label_rtx (); /* pentium optimisation */
4300 xops[10] = gen_label_rtx (); /* end label 2 */
4301 xops[11] = gen_label_rtx (); /* end label 1 */
4302 xops[12] = gen_label_rtx (); /* end label */
4303 /* xops[13] * Temporary used */
4304 xops[14] = GEN_INT (0xff);
4305 xops[15] = GEN_INT (0xff00);
4306 xops[16] = GEN_INT (0xff0000);
4307 xops[17] = GEN_INT (0xff000000);
4309 /* Loop to check 1..3 bytes for null to get an aligned pointer */
4311 /* is there a known alignment and is it less then 4 */
4312 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) < 4)
4314 /* is there a known alignment and is it not 2 */
4315 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
4317 xops[6] = gen_label_rtx (); /* label when aligned to 3-byte */
4318 xops[7] = gen_label_rtx (); /* label when aligned to 2-byte */
4320 /* leave just the 3 lower bits */
4321 /* if this is a q-register, then the high part is used later */
4322 /* therefore user andl rather than andb */
4323 output_asm_insn (AS2 (and%L1,%4,%1), xops);
4324 /* is aligned to 4-byte adress when zero */
4325 output_asm_insn (AS1 (je,%l8), xops);
4326 /* side-effect even Parity when %eax == 3 */
4327 output_asm_insn (AS1 (jp,%6), xops);
4329 /* is it aligned to 2 bytes ? */
4330 if (QI_REG_P (xops[1]))
4331 output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
4333 output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
4334 output_asm_insn (AS1 (je,%7), xops);
4338 /* since the alignment is 2, we have to check 2 or 0 bytes */
4340 /* check if is aligned to 4 - byte */
4341 output_asm_insn (AS2 (and%L1,%3,%1), xops);
4342 /* is aligned to 4-byte adress when zero */
4343 output_asm_insn (AS1 (je,%l8), xops);
4346 xops[13] = gen_rtx (MEM, QImode, xops[0]);
4347 /* now, compare the bytes */
4348 /* compare with the high part of a q-reg gives shorter code */
4349 if (QI_REG_P (xops[1]))
4351 /* compare the first n unaligned byte on a byte per byte basis */
4352 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
4353 /* when zero we reached the end */
4354 output_asm_insn (AS1 (je,%l12), xops);
4355 /* increment the address */
4356 output_asm_insn (AS1 (inc%L0,%0), xops);
4358 /* not needed with an alignment of 2 */
4359 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
4361 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[7]));
4362 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
4363 output_asm_insn (AS1 (je,%l12), xops);
4364 output_asm_insn (AS1 (inc%L0,%0), xops);
4366 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[6]));
4368 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
4372 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
4373 output_asm_insn (AS1 (je,%l12), xops);
4374 output_asm_insn (AS1 (inc%L0,%0), xops);
4376 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[7]));
4377 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
4378 output_asm_insn (AS1 (je,%l12), xops);
4379 output_asm_insn (AS1 (inc%L0,%0), xops);
4381 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[6]));
4382 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
4384 output_asm_insn (AS1 (je,%l12), xops);
4385 output_asm_insn (AS1 (inc%L0,%0), xops);
4388 /* Generate loop to check 4 bytes at a time */
4389 /* IMHO it is not a good idea to align this loop. It gives only */
4390 /* huge programms, but does not help to speed up */
4391 /* ASM_OUTPUT_LOOP_ALIGN (asm_out_file); */
4392 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[8]));
4394 xops[13] = gen_rtx (MEM, SImode, xops[0]);
4395 output_asm_insn (AS2 (mov%L1,%13,%1), xops);
4397 if (QI_REG_P (xops[1]))
4399 /* on i586 it is faster to compare the hi- and lo- part */
4400 /* as a kind of lookahead. If xoring both is zero, then one */
4401 /* of both *could* be zero, otherwith none of both is zero */
4402 /* this saves one instruction, on i486 this is slower */
4403 /* testet with P-90, i486DX2-66, AMD486DX2-66 */
4406 output_asm_insn (AS2 (test%B1,%h1,%b1), xops);
4407 output_asm_insn (AS1 (jne,%l9), xops);
4410 /* check first byte */
4411 output_asm_insn (AS2 (test%B1,%b1,%b1), xops);
4412 output_asm_insn (AS1 (je,%l12), xops);
4414 /* check second byte */
4415 output_asm_insn (AS2 (test%B1,%h1,%h1), xops);
4416 output_asm_insn (AS1 (je,%l11), xops);
4419 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[9]));
4423 /* check first byte */
4424 output_asm_insn (AS2 (test%L1,%14,%1), xops);
4425 output_asm_insn (AS1 (je,%l12), xops);
4427 /* check second byte */
4428 output_asm_insn (AS2 (test%L1,%15,%1), xops);
4429 output_asm_insn (AS1 (je,%l11), xops);
4432 /* check third byte */
4433 output_asm_insn (AS2 (test%L1,%16,%1), xops);
4434 output_asm_insn (AS1 (je,%l10), xops);
4436 /* check fourth byte and increment address */
4437 output_asm_insn (AS2 (add%L0,%5,%0), xops);
4438 output_asm_insn (AS2 (test%L1,%17,%1), xops);
4439 output_asm_insn (AS1 (jne,%l8), xops);
4441 /* now generate fixups when the compare stops within a 4-byte word */
4442 output_asm_insn (AS2 (sub%L0,%4,%0), xops);
4444 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[10]));
4445 output_asm_insn (AS1 (inc%L0,%0), xops);
4447 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[11]));
4448 output_asm_insn (AS1 (inc%L0,%0), xops);
4450 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[12]));