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 = {
76 1, /* cost of an add instruction */
77 1, /* cost of a lea instruction */
78 3, /* variable shift costs */
79 1, /* constant shift costs */
80 12, /* cost of starting a multiply */
81 1, /* cost of multiply per each bit set */
82 25 /* 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;
1678 static rtx pic_label_rtx;
1680 /* This function generates code for -fpic that loads %ebx with
1681 with the return address of the caller and then returns. */
1683 asm_output_function_prefix (file, name)
1688 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1689 || current_function_uses_const_pool);
1690 xops[0] = pic_offset_table_rtx;
1691 xops[1] = stack_pointer_rtx;
1693 if (pic_reg_used && TARGET_DEEP_BRANCH_PREDICTION)
1695 pic_label_rtx = (rtx) gen_label_rtx ();
1696 ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (pic_label_rtx));
1697 output_asm_insn ("movl (%1),%0", xops);
1698 output_asm_insn ("ret", xops);
1702 /* This function generates the assembly code for function entry.
1703 FILE is an stdio stream to output the code to.
1704 SIZE is an int: how many units of temporary storage to allocate. */
1707 function_prologue (file, size)
1714 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1715 || current_function_uses_const_pool);
1717 xops[0] = stack_pointer_rtx;
1718 xops[1] = frame_pointer_rtx;
1719 xops[2] = GEN_INT (size);
1720 if (frame_pointer_needed)
1722 output_asm_insn ("push%L1 %1", xops);
1723 output_asm_insn (AS2 (mov%L0,%0,%1), xops);
1727 output_asm_insn (AS2 (sub%L0,%2,%0), xops);
1729 /* Note If use enter it is NOT reversed args.
1730 This one is not reversed from intel!!
1731 I think enter is slower. Also sdb doesn't like it.
1732 But if you want it the code is:
1734 xops[3] = const0_rtx;
1735 output_asm_insn ("enter %2,%3", xops);
1738 limit = (frame_pointer_needed ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
1739 for (regno = limit - 1; regno >= 0; regno--)
1740 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1741 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1743 xops[0] = gen_rtx (REG, SImode, regno);
1744 output_asm_insn ("push%L0 %0", xops);
1747 if (pic_reg_used && TARGET_PENTIUMPRO)
1749 xops[0] = pic_offset_table_rtx;
1750 xops[1] = pic_label_rtx;
1752 output_asm_insn (AS1 (call,%P1), xops);
1753 output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_,%0", xops);
1756 xops[0] = pic_offset_table_rtx;
1757 xops[1] = (rtx) gen_label_rtx ();
1759 output_asm_insn (AS1 (call,%P1), xops);
1760 ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (xops[1]));
1761 output_asm_insn (AS1 (pop%L0,%0), xops);
1762 output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops);
1766 /* Return 1 if it is appropriate to emit `ret' instructions in the
1767 body of a function. Do this only if the epilogue is simple, needing a
1768 couple of insns. Prior to reloading, we can't tell how many registers
1769 must be saved, so return 0 then.
1771 If NON_SAVING_SETJMP is defined and true, then it is not possible
1772 for the epilogue to be simple, so return 0. This is a special case
1773 since NON_SAVING_SETJMP will not cause regs_ever_live to change until
1774 final, but jump_optimize may need to know sooner if a `return' is OK. */
1777 simple_386_epilogue ()
1781 int reglimit = (frame_pointer_needed
1782 ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
1783 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1784 || current_function_uses_const_pool);
1786 #ifdef NON_SAVING_SETJMP
1787 if (NON_SAVING_SETJMP && current_function_calls_setjmp)
1791 if (! reload_completed)
1794 for (regno = reglimit - 1; regno >= 0; regno--)
1795 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1796 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1799 return nregs == 0 || ! frame_pointer_needed;
1803 /* This function generates the assembly code for function exit.
1804 FILE is an stdio stream to output the code to.
1805 SIZE is an int: how many units of temporary storage to deallocate. */
1808 function_epilogue (file, size)
1813 register int nregs, limit;
1816 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1817 || current_function_uses_const_pool);
1819 /* Compute the number of registers to pop */
1821 limit = (frame_pointer_needed
1822 ? FRAME_POINTER_REGNUM
1823 : STACK_POINTER_REGNUM);
1827 for (regno = limit - 1; regno >= 0; regno--)
1828 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1829 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1832 /* sp is often unreliable so we must go off the frame pointer,
1835 /* In reality, we may not care if sp is unreliable, because we can
1836 restore the register relative to the frame pointer. In theory,
1837 since each move is the same speed as a pop, and we don't need the
1838 leal, this is faster. For now restore multiple registers the old
1841 offset = -size - (nregs * UNITS_PER_WORD);
1843 xops[2] = stack_pointer_rtx;
1845 if (nregs > 1 || ! frame_pointer_needed)
1847 if (frame_pointer_needed)
1849 xops[0] = adj_offsettable_operand (AT_BP (Pmode), offset);
1850 output_asm_insn (AS2 (lea%L2,%0,%2), xops);
1853 for (regno = 0; regno < limit; regno++)
1854 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1855 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1857 xops[0] = gen_rtx (REG, SImode, regno);
1858 output_asm_insn ("pop%L0 %0", xops);
1862 for (regno = 0; regno < limit; regno++)
1863 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1864 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1866 xops[0] = gen_rtx (REG, SImode, regno);
1867 xops[1] = adj_offsettable_operand (AT_BP (Pmode), offset);
1868 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
1872 if (frame_pointer_needed)
1874 /* If not an i386, mov & pop is faster than "leave". */
1876 if (TARGET_USE_LEAVE)
1877 output_asm_insn ("leave", xops);
1880 xops[0] = frame_pointer_rtx;
1881 output_asm_insn (AS2 (mov%L2,%0,%2), xops);
1882 output_asm_insn ("pop%L0 %0", xops);
1887 /* If there is no frame pointer, we must still release the frame. */
1889 xops[0] = GEN_INT (size);
1890 output_asm_insn (AS2 (add%L2,%0,%2), xops);
1893 #ifdef FUNCTION_BLOCK_PROFILER_EXIT
1894 if (profile_block_flag == 2)
1896 FUNCTION_BLOCK_PROFILER_EXIT(file);
1900 if (current_function_pops_args && current_function_args_size)
1902 xops[1] = GEN_INT (current_function_pops_args);
1904 /* i386 can only pop 32K bytes (maybe 64K? Is it signed?). If
1905 asked to pop more, pop return address, do explicit add, and jump
1906 indirectly to the caller. */
1908 if (current_function_pops_args >= 32768)
1910 /* ??? Which register to use here? */
1911 xops[0] = gen_rtx (REG, SImode, 2);
1912 output_asm_insn ("pop%L0 %0", xops);
1913 output_asm_insn (AS2 (add%L2,%1,%2), xops);
1914 output_asm_insn ("jmp %*%0", xops);
1917 output_asm_insn ("ret %1", xops);
1920 output_asm_insn ("ret", xops);
1924 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
1925 that is a valid memory address for an instruction.
1926 The MODE argument is the machine mode for the MEM expression
1927 that wants to use this address.
1929 On x86, legitimate addresses are:
1930 base movl (base),reg
1931 displacement movl disp,reg
1932 base + displacement movl disp(base),reg
1933 index + base movl (base,index),reg
1934 (index + base) + displacement movl disp(base,index),reg
1935 index*scale movl (,index,scale),reg
1936 index*scale + disp movl disp(,index,scale),reg
1937 index*scale + base movl (base,index,scale),reg
1938 (index*scale + base) + disp movl disp(base,index,scale),reg
1940 In each case, scale can be 1, 2, 4, 8. */
1942 /* This is exactly the same as print_operand_addr, except that
1943 it recognizes addresses instead of printing them.
1945 It only recognizes address in canonical form. LEGITIMIZE_ADDRESS should
1946 convert common non-canonical forms to canonical form so that they will
1949 #define ADDR_INVALID(msg,insn) \
1951 if (TARGET_DEBUG_ADDR) \
1953 fprintf (stderr, msg); \
1959 legitimate_address_p (mode, addr, strict)
1960 enum machine_mode mode;
1964 rtx base = NULL_RTX;
1965 rtx indx = NULL_RTX;
1966 rtx scale = NULL_RTX;
1967 rtx disp = NULL_RTX;
1969 if (TARGET_DEBUG_ADDR)
1972 "\n==========\nGO_IF_LEGITIMATE_ADDRESS, mode = %s, strict = %d\n",
1973 GET_MODE_NAME (mode), strict);
1978 if (GET_CODE (addr) == REG || GET_CODE (addr) == SUBREG)
1979 base = addr; /* base reg */
1981 else if (GET_CODE (addr) == PLUS)
1983 rtx op0 = XEXP (addr, 0);
1984 rtx op1 = XEXP (addr, 1);
1985 enum rtx_code code0 = GET_CODE (op0);
1986 enum rtx_code code1 = GET_CODE (op1);
1988 if (code0 == REG || code0 == SUBREG)
1990 if (code1 == REG || code1 == SUBREG)
1992 indx = op0; /* index + base */
1998 base = op0; /* base + displacement */
2003 else if (code0 == MULT)
2005 indx = XEXP (op0, 0);
2006 scale = XEXP (op0, 1);
2008 if (code1 == REG || code1 == SUBREG)
2009 base = op1; /* index*scale + base */
2012 disp = op1; /* index*scale + disp */
2015 else if (code0 == PLUS && GET_CODE (XEXP (op0, 0)) == MULT)
2017 indx = XEXP (XEXP (op0, 0), 0); /* index*scale + base + disp */
2018 scale = XEXP (XEXP (op0, 0), 1);
2019 base = XEXP (op0, 1);
2023 else if (code0 == PLUS)
2025 indx = XEXP (op0, 0); /* index + base + disp */
2026 base = XEXP (op0, 1);
2032 ADDR_INVALID ("PLUS subcode is not valid.\n", op0);
2037 else if (GET_CODE (addr) == MULT)
2039 indx = XEXP (addr, 0); /* index*scale */
2040 scale = XEXP (addr, 1);
2044 disp = addr; /* displacement */
2046 /* Allow arg pointer and stack pointer as index if there is not scaling */
2047 if (base && indx && !scale
2048 && (indx == arg_pointer_rtx || indx == stack_pointer_rtx))
2055 /* Validate base register */
2056 /* Don't allow SUBREG's here, it can lead to spill failures when the base
2057 is one word out of a two word structure, which is represented internally
2061 if (GET_CODE (base) != REG)
2063 ADDR_INVALID ("Base is not a register.\n", base);
2067 if ((strict && !REG_OK_FOR_BASE_STRICT_P (base))
2068 || (!strict && !REG_OK_FOR_BASE_NONSTRICT_P (base)))
2070 ADDR_INVALID ("Base is not valid.\n", base);
2075 /* Validate index register */
2076 /* Don't allow SUBREG's here, it can lead to spill failures when the index
2077 is one word out of a two word structure, which is represented internally
2081 if (GET_CODE (indx) != REG)
2083 ADDR_INVALID ("Index is not a register.\n", indx);
2087 if ((strict && !REG_OK_FOR_INDEX_STRICT_P (indx))
2088 || (!strict && !REG_OK_FOR_INDEX_NONSTRICT_P (indx)))
2090 ADDR_INVALID ("Index is not valid.\n", indx);
2095 abort (); /* scale w/o index invalid */
2097 /* Validate scale factor */
2100 HOST_WIDE_INT value;
2102 if (GET_CODE (scale) != CONST_INT)
2104 ADDR_INVALID ("Scale is not valid.\n", scale);
2108 value = INTVAL (scale);
2109 if (value != 1 && value != 2 && value != 4 && value != 8)
2111 ADDR_INVALID ("Scale is not a good multiplier.\n", scale);
2116 /* Validate displacement
2117 Constant pool addresses must be handled special. They are
2118 considered legitimate addresses, but only if not used with regs.
2119 When printed, the output routines know to print the reference with the
2120 PIC reg, even though the PIC reg doesn't appear in the RTL. */
2123 if (GET_CODE (disp) == SYMBOL_REF
2124 && CONSTANT_POOL_ADDRESS_P (disp)
2129 else if (!CONSTANT_ADDRESS_P (disp))
2131 ADDR_INVALID ("Displacement is not valid.\n", disp);
2135 else if (GET_CODE (disp) == CONST_DOUBLE)
2137 ADDR_INVALID ("Displacement is a const_double.\n", disp);
2141 else if (flag_pic && SYMBOLIC_CONST (disp)
2142 && base != pic_offset_table_rtx
2143 && (indx != pic_offset_table_rtx || scale != NULL_RTX))
2145 ADDR_INVALID ("Displacement is an invalid pic reference.\n", disp);
2149 else if (HALF_PIC_P () && HALF_PIC_ADDRESS_P (disp)
2150 && (base != NULL_RTX || indx != NULL_RTX))
2152 ADDR_INVALID ("Displacement is an invalid half-pic reference.\n", disp);
2157 if (TARGET_DEBUG_ADDR)
2158 fprintf (stderr, "Address is valid.\n");
2160 /* Everything looks valid, return true */
2165 /* Return a legitimate reference for ORIG (an address) using the
2166 register REG. If REG is 0, a new pseudo is generated.
2168 There are three types of references that must be handled:
2170 1. Global data references must load the address from the GOT, via
2171 the PIC reg. An insn is emitted to do this load, and the reg is
2174 2. Static data references must compute the address as an offset
2175 from the GOT, whose base is in the PIC reg. An insn is emitted to
2176 compute the address into a reg, and the reg is returned. Static
2177 data objects have SYMBOL_REF_FLAG set to differentiate them from
2178 global data objects.
2180 3. Constant pool addresses must be handled special. They are
2181 considered legitimate addresses, but only if not used with regs.
2182 When printed, the output routines know to print the reference with the
2183 PIC reg, even though the PIC reg doesn't appear in the RTL.
2185 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2186 reg also appears in the address (except for constant pool references,
2189 "switch" statements also require special handling when generating
2190 PIC code. See comments by the `casesi' insn in i386.md for details. */
2193 legitimize_pic_address (orig, reg)
2200 if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
2202 if (GET_CODE (addr) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (addr))
2207 reg = gen_reg_rtx (Pmode);
2209 if ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
2210 || GET_CODE (addr) == LABEL_REF)
2211 new = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig);
2213 new = gen_rtx (MEM, Pmode,
2214 gen_rtx (PLUS, Pmode,
2215 pic_offset_table_rtx, orig));
2217 emit_move_insn (reg, new);
2219 current_function_uses_pic_offset_table = 1;
2222 else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
2226 if (GET_CODE (addr) == CONST)
2228 addr = XEXP (addr, 0);
2229 if (GET_CODE (addr) != PLUS)
2233 if (XEXP (addr, 0) == pic_offset_table_rtx)
2237 reg = gen_reg_rtx (Pmode);
2239 base = legitimize_pic_address (XEXP (addr, 0), reg);
2240 addr = legitimize_pic_address (XEXP (addr, 1),
2241 base == reg ? NULL_RTX : reg);
2243 if (GET_CODE (addr) == CONST_INT)
2244 return plus_constant (base, INTVAL (addr));
2246 if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
2248 base = gen_rtx (PLUS, Pmode, base, XEXP (addr, 0));
2249 addr = XEXP (addr, 1);
2251 return gen_rtx (PLUS, Pmode, base, addr);
2257 /* Emit insns to move operands[1] into operands[0]. */
2260 emit_pic_move (operands, mode)
2262 enum machine_mode mode;
2264 rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
2266 if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
2267 operands[1] = (rtx) force_reg (SImode, operands[1]);
2269 operands[1] = legitimize_pic_address (operands[1], temp);
2273 /* Try machine-dependent ways of modifying an illegitimate address
2274 to be legitimate. If we find one, return the new, valid address.
2275 This macro is used in only one place: `memory_address' in explow.c.
2277 OLDX is the address as it was before break_out_memory_refs was called.
2278 In some cases it is useful to look at this to decide what needs to be done.
2280 MODE and WIN are passed so that this macro can use
2281 GO_IF_LEGITIMATE_ADDRESS.
2283 It is always safe for this macro to do nothing. It exists to recognize
2284 opportunities to optimize the output.
2286 For the 80386, we handle X+REG by loading X into a register R and
2287 using R+REG. R will go in a general reg and indexing will be used.
2288 However, if REG is a broken-out memory address or multiplication,
2289 nothing needs to be done because REG can certainly go in a general reg.
2291 When -fpic is used, special handling is needed for symbolic references.
2292 See comments by legitimize_pic_address in i386.c for details. */
2295 legitimize_address (x, oldx, mode)
2298 enum machine_mode mode;
2303 if (TARGET_DEBUG_ADDR)
2305 fprintf (stderr, "\n==========\nLEGITIMIZE_ADDRESS, mode = %s\n", GET_MODE_NAME (mode));
2309 if (flag_pic && SYMBOLIC_CONST (x))
2310 return legitimize_pic_address (x, 0);
2312 /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
2313 if (GET_CODE (x) == ASHIFT
2314 && GET_CODE (XEXP (x, 1)) == CONST_INT
2315 && (log = (unsigned)exact_log2 (INTVAL (XEXP (x, 1)))) < 4)
2318 x = gen_rtx (MULT, Pmode,
2319 force_reg (Pmode, XEXP (x, 0)),
2320 GEN_INT (1 << log));
2323 if (GET_CODE (x) == PLUS)
2325 /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
2326 if (GET_CODE (XEXP (x, 0)) == ASHIFT
2327 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
2328 && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) < 4)
2331 XEXP (x, 0) = gen_rtx (MULT, Pmode,
2332 force_reg (Pmode, XEXP (XEXP (x, 0), 0)),
2333 GEN_INT (1 << log));
2336 if (GET_CODE (XEXP (x, 1)) == ASHIFT
2337 && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
2338 && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 1), 1)))) < 4)
2341 XEXP (x, 1) = gen_rtx (MULT, Pmode,
2342 force_reg (Pmode, XEXP (XEXP (x, 1), 0)),
2343 GEN_INT (1 << log));
2346 /* Put multiply first if it isn't already */
2347 if (GET_CODE (XEXP (x, 1)) == MULT)
2349 rtx tmp = XEXP (x, 0);
2350 XEXP (x, 0) = XEXP (x, 1);
2355 /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
2356 into (plus (plus (mult (reg) (const)) (reg)) (const)). This can be
2357 created by virtual register instantiation, register elimination, and
2358 similar optimizations. */
2359 if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS)
2362 x = gen_rtx (PLUS, Pmode,
2363 gen_rtx (PLUS, Pmode, XEXP (x, 0), XEXP (XEXP (x, 1), 0)),
2364 XEXP (XEXP (x, 1), 1));
2367 /* Canonicalize (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
2368 into (plus (plus (mult (reg) (const)) (reg)) (const)). */
2369 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
2370 && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
2371 && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
2372 && CONSTANT_P (XEXP (x, 1)))
2374 rtx constant, other;
2376 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
2378 constant = XEXP (x, 1);
2379 other = XEXP (XEXP (XEXP (x, 0), 1), 1);
2381 else if (GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 1)) == CONST_INT)
2383 constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
2384 other = XEXP (x, 1);
2392 x = gen_rtx (PLUS, Pmode,
2393 gen_rtx (PLUS, Pmode, XEXP (XEXP (x, 0), 0),
2394 XEXP (XEXP (XEXP (x, 0), 1), 0)),
2395 plus_constant (other, INTVAL (constant)));
2399 if (changed && legitimate_address_p (mode, x, FALSE))
2402 if (GET_CODE (XEXP (x, 0)) == MULT)
2405 XEXP (x, 0) = force_operand (XEXP (x, 0), 0);
2408 if (GET_CODE (XEXP (x, 1)) == MULT)
2411 XEXP (x, 1) = force_operand (XEXP (x, 1), 0);
2415 && GET_CODE (XEXP (x, 1)) == REG
2416 && GET_CODE (XEXP (x, 0)) == REG)
2419 if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1)))
2422 x = legitimize_pic_address (x, 0);
2425 if (changed && legitimate_address_p (mode, x, FALSE))
2428 if (GET_CODE (XEXP (x, 0)) == REG)
2430 register rtx temp = gen_reg_rtx (Pmode);
2431 register rtx val = force_operand (XEXP (x, 1), temp);
2433 emit_move_insn (temp, val);
2439 else if (GET_CODE (XEXP (x, 1)) == REG)
2441 register rtx temp = gen_reg_rtx (Pmode);
2442 register rtx val = force_operand (XEXP (x, 0), temp);
2444 emit_move_insn (temp, val);
2455 /* Print an integer constant expression in assembler syntax. Addition
2456 and subtraction are the only arithmetic that may appear in these
2457 expressions. FILE is the stdio stream to write to, X is the rtx, and
2458 CODE is the operand print code from the output string. */
2461 output_pic_addr_const (file, x, code)
2468 switch (GET_CODE (x))
2479 if (GET_CODE (x) == SYMBOL_REF)
2480 assemble_name (file, XSTR (x, 0));
2483 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
2484 CODE_LABEL_NUMBER (XEXP (x, 0)));
2485 assemble_name (asm_out_file, buf);
2488 if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
2489 fprintf (file, "@GOTOFF(%%ebx)");
2490 else if (code == 'P')
2491 fprintf (file, "@PLT");
2492 else if (GET_CODE (x) == LABEL_REF)
2493 fprintf (file, "@GOTOFF");
2494 else if (! SYMBOL_REF_FLAG (x))
2495 fprintf (file, "@GOT");
2497 fprintf (file, "@GOTOFF");
2502 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
2503 assemble_name (asm_out_file, buf);
2507 fprintf (file, "%d", INTVAL (x));
2511 /* This used to output parentheses around the expression,
2512 but that does not work on the 386 (either ATT or BSD assembler). */
2513 output_pic_addr_const (file, XEXP (x, 0), code);
2517 if (GET_MODE (x) == VOIDmode)
2519 /* We can use %d if the number is <32 bits and positive. */
2520 if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
2521 fprintf (file, "0x%x%08x",
2522 CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
2524 fprintf (file, "%d", CONST_DOUBLE_LOW (x));
2527 /* We can't handle floating point constants;
2528 PRINT_OPERAND must handle them. */
2529 output_operand_lossage ("floating constant misused");
2533 /* Some assemblers need integer constants to appear last (eg masm). */
2534 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
2536 output_pic_addr_const (file, XEXP (x, 1), code);
2537 if (INTVAL (XEXP (x, 0)) >= 0)
2538 fprintf (file, "+");
2539 output_pic_addr_const (file, XEXP (x, 0), code);
2543 output_pic_addr_const (file, XEXP (x, 0), code);
2544 if (INTVAL (XEXP (x, 1)) >= 0)
2545 fprintf (file, "+");
2546 output_pic_addr_const (file, XEXP (x, 1), code);
2551 output_pic_addr_const (file, XEXP (x, 0), code);
2552 fprintf (file, "-");
2553 output_pic_addr_const (file, XEXP (x, 1), code);
2557 output_operand_lossage ("invalid expression as operand");
2562 /* Append the correct conditional move suffix which corresponds to CODE */
2565 put_condition_code (code, file)
2572 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
2578 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
2584 fputs ("ge", file); return;
2586 fputs ("g", file); return;
2588 fputs ("le", file); return;
2590 fputs ("l", file); return;
2592 fputs ("ae", file); return;
2594 fputs ("a", file); return;
2596 fputs ("be", file); return;
2598 fputs ("b", file); return;
2599 default: output_operand_lossage ("Invalid %%C operand");
2604 f -- float insn (print a CONST_DOUBLE as a float rather than in hex).
2605 D,L,W,B,Q,S -- print the opcode suffix for specified size of operand.
2606 C -- print opcode suffix for set/cmov insn.
2607 N -- like C, but print reversed condition
2608 R -- print the prefix for register names.
2609 z -- print the opcode suffix for the size of the current operand.
2610 * -- print a star (in certain assembler syntax)
2611 w -- print the operand as if it's a "word" (HImode) even if it isn't.
2612 c -- don't print special prefixes before constant operands.
2613 J -- print the appropriate jump operand.
2617 print_operand (file, x, code)
2632 PUT_OP_SIZE (code, 'l', file);
2636 PUT_OP_SIZE (code, 'w', file);
2640 PUT_OP_SIZE (code, 'b', file);
2644 PUT_OP_SIZE (code, 'l', file);
2648 PUT_OP_SIZE (code, 's', file);
2652 PUT_OP_SIZE (code, 't', file);
2656 /* 387 opcodes don't get size suffixes if the operands are
2659 if (STACK_REG_P (x))
2662 /* this is the size of op from size of operand */
2663 switch (GET_MODE_SIZE (GET_MODE (x)))
2666 PUT_OP_SIZE ('B', 'b', file);
2670 PUT_OP_SIZE ('W', 'w', file);
2674 if (GET_MODE (x) == SFmode)
2676 PUT_OP_SIZE ('S', 's', file);
2680 PUT_OP_SIZE ('L', 'l', file);
2684 PUT_OP_SIZE ('T', 't', file);
2688 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
2690 #ifdef GAS_MNEMONICS
2691 PUT_OP_SIZE ('Q', 'q', file);
2694 PUT_OP_SIZE ('Q', 'l', file); /* Fall through */
2698 PUT_OP_SIZE ('Q', 'l', file);
2711 switch (GET_CODE (x))
2713 /* These conditions are appropriate for testing the result
2714 of an arithmetic operation, not for a compare operation.
2715 Cases GE, LT assume CC_NO_OVERFLOW true. All cases assume
2716 CC_Z_IN_NOT_C false and not floating point. */
2717 case NE: fputs ("jne", file); return;
2718 case EQ: fputs ("je", file); return;
2719 case GE: fputs ("jns", file); return;
2720 case LT: fputs ("js", file); return;
2721 case GEU: fputs ("jmp", file); return;
2722 case GTU: fputs ("jne", file); return;
2723 case LEU: fputs ("je", file); return;
2724 case LTU: fputs ("#branch never", file); return;
2726 /* no matching branches for GT nor LE */
2730 /* This is used by the conditional move instructions. */
2732 put_condition_code (GET_CODE (x), file);
2734 /* like above but reverse condition */
2736 put_condition_code (reverse_condition (GET_CODE (x)), file);
2743 sprintf (str, "invalid operand code `%c'", code);
2744 output_operand_lossage (str);
2748 if (GET_CODE (x) == REG)
2750 PRINT_REG (x, code, file);
2752 else if (GET_CODE (x) == MEM)
2754 PRINT_PTR (x, file);
2755 if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
2758 output_pic_addr_const (file, XEXP (x, 0), code);
2760 output_addr_const (file, XEXP (x, 0));
2763 output_address (XEXP (x, 0));
2765 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
2767 REAL_VALUE_TYPE r; long l;
2768 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2769 REAL_VALUE_TO_TARGET_SINGLE (r, l);
2770 PRINT_IMMED_PREFIX (file);
2771 fprintf (file, "0x%x", l);
2773 /* These float cases don't actually occur as immediate operands. */
2774 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
2776 REAL_VALUE_TYPE r; char dstr[30];
2777 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2778 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
2779 fprintf (file, "%s", dstr);
2781 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == XFmode)
2783 REAL_VALUE_TYPE r; char dstr[30];
2784 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2785 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
2786 fprintf (file, "%s", dstr);
2792 if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
2793 PRINT_IMMED_PREFIX (file);
2794 else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
2795 || GET_CODE (x) == LABEL_REF)
2796 PRINT_OFFSET_PREFIX (file);
2799 output_pic_addr_const (file, x, code);
2801 output_addr_const (file, x);
2805 /* Print a memory operand whose address is ADDR. */
2808 print_operand_address (file, addr)
2812 register rtx reg1, reg2, breg, ireg;
2815 switch (GET_CODE (addr))
2819 fprintf (file, "%se", RP);
2820 fputs (hi_reg_name[REGNO (addr)], file);
2830 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
2832 offset = XEXP (addr, 0);
2833 addr = XEXP (addr, 1);
2835 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
2837 offset = XEXP (addr, 1);
2838 addr = XEXP (addr, 0);
2840 if (GET_CODE (addr) != PLUS) ;
2841 else if (GET_CODE (XEXP (addr, 0)) == MULT)
2843 reg1 = XEXP (addr, 0);
2844 addr = XEXP (addr, 1);
2846 else if (GET_CODE (XEXP (addr, 1)) == MULT)
2848 reg1 = XEXP (addr, 1);
2849 addr = XEXP (addr, 0);
2851 else if (GET_CODE (XEXP (addr, 0)) == REG)
2853 reg1 = XEXP (addr, 0);
2854 addr = XEXP (addr, 1);
2856 else if (GET_CODE (XEXP (addr, 1)) == REG)
2858 reg1 = XEXP (addr, 1);
2859 addr = XEXP (addr, 0);
2861 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
2863 if (reg1 == 0) reg1 = addr;
2869 if (addr != 0) abort ();
2872 if ((reg1 && GET_CODE (reg1) == MULT)
2873 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
2878 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
2884 if (ireg != 0 || breg != 0)
2891 output_pic_addr_const (file, addr, 0);
2893 else if (GET_CODE (addr) == LABEL_REF)
2894 output_asm_label (addr);
2897 output_addr_const (file, addr);
2900 if (ireg != 0 && GET_CODE (ireg) == MULT)
2902 scale = INTVAL (XEXP (ireg, 1));
2903 ireg = XEXP (ireg, 0);
2906 /* The stack pointer can only appear as a base register,
2907 never an index register, so exchange the regs if it is wrong. */
2909 if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM)
2918 /* output breg+ireg*scale */
2919 PRINT_B_I_S (breg, ireg, scale, file);
2926 if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
2928 scale = INTVAL (XEXP (addr, 0));
2929 ireg = XEXP (addr, 1);
2933 scale = INTVAL (XEXP (addr, 1));
2934 ireg = XEXP (addr, 0);
2936 output_addr_const (file, const0_rtx);
2937 PRINT_B_I_S ((rtx) 0, ireg, scale, file);
2942 if (GET_CODE (addr) == CONST_INT
2943 && INTVAL (addr) < 0x8000
2944 && INTVAL (addr) >= -0x8000)
2945 fprintf (file, "%d", INTVAL (addr));
2949 output_pic_addr_const (file, addr, 0);
2951 output_addr_const (file, addr);
2956 /* Set the cc_status for the results of an insn whose pattern is EXP.
2957 On the 80386, we assume that only test and compare insns, as well
2958 as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, ASHIFT,
2959 ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
2960 Also, we assume that jumps, moves and sCOND don't affect the condition
2961 codes. All else clobbers the condition codes, by assumption.
2963 We assume that ALL integer add, minus, etc. instructions effect the
2964 condition codes. This MUST be consistent with i386.md.
2966 We don't record any float test or compare - the redundant test &
2967 compare check in final.c does not handle stack-like regs correctly. */
2970 notice_update_cc (exp)
2973 if (GET_CODE (exp) == SET)
2975 /* Jumps do not alter the cc's. */
2976 if (SET_DEST (exp) == pc_rtx)
2978 #ifdef IS_STACK_MODE
2979 /* Moving into a memory of stack_mode may have been moved
2980 in between the use and set of cc0 by loop_spl(). So
2981 old value of cc.status must be retained */
2982 if(GET_CODE(SET_DEST(exp))==MEM
2983 && IS_STACK_MODE(GET_MODE(SET_DEST(exp))))
2988 /* Moving register or memory into a register:
2989 it doesn't alter the cc's, but it might invalidate
2990 the RTX's which we remember the cc's came from.
2991 (Note that moving a constant 0 or 1 MAY set the cc's). */
2992 if (REG_P (SET_DEST (exp))
2993 && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM
2994 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
2996 if (cc_status.value1
2997 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
2998 cc_status.value1 = 0;
2999 if (cc_status.value2
3000 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
3001 cc_status.value2 = 0;
3004 /* Moving register into memory doesn't alter the cc's.
3005 It may invalidate the RTX's which we remember the cc's came from. */
3006 if (GET_CODE (SET_DEST (exp)) == MEM
3007 && (REG_P (SET_SRC (exp))
3008 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
3010 if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM
3011 || reg_mentioned_p (SET_DEST (exp), cc_status.value1))
3012 cc_status.value1 = 0;
3013 if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM
3014 || reg_mentioned_p (SET_DEST (exp), cc_status.value2))
3015 cc_status.value2 = 0;
3018 /* Function calls clobber the cc's. */
3019 else if (GET_CODE (SET_SRC (exp)) == CALL)
3024 /* Tests and compares set the cc's in predictable ways. */
3025 else if (SET_DEST (exp) == cc0_rtx)
3028 cc_status.value1 = SET_SRC (exp);
3031 /* Certain instructions effect the condition codes. */
3032 else if (GET_MODE (SET_SRC (exp)) == SImode
3033 || GET_MODE (SET_SRC (exp)) == HImode
3034 || GET_MODE (SET_SRC (exp)) == QImode)
3035 switch (GET_CODE (SET_SRC (exp)))
3037 case ASHIFTRT: case LSHIFTRT:
3039 /* Shifts on the 386 don't set the condition codes if the
3040 shift count is zero. */
3041 if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
3046 /* We assume that the CONST_INT is non-zero (this rtx would
3047 have been deleted if it were zero. */
3049 case PLUS: case MINUS: case NEG:
3050 case AND: case IOR: case XOR:
3051 cc_status.flags = CC_NO_OVERFLOW;
3052 cc_status.value1 = SET_SRC (exp);
3053 cc_status.value2 = SET_DEST (exp);
3064 else if (GET_CODE (exp) == PARALLEL
3065 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
3067 if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
3069 if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
3072 if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
3073 cc_status.flags |= CC_IN_80387;
3075 cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
3086 /* Split one or more DImode RTL references into pairs of SImode
3087 references. The RTL can be REG, offsettable MEM, integer constant, or
3088 CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to
3089 split and "num" is its length. lo_half and hi_half are output arrays
3090 that parallel "operands". */
3093 split_di (operands, num, lo_half, hi_half)
3096 rtx lo_half[], hi_half[];
3100 if (GET_CODE (operands[num]) == REG)
3102 lo_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]));
3103 hi_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]) + 1);
3105 else if (CONSTANT_P (operands[num]))
3107 split_double (operands[num], &lo_half[num], &hi_half[num]);
3109 else if (offsettable_memref_p (operands[num]))
3111 lo_half[num] = operands[num];
3112 hi_half[num] = adj_offsettable_operand (operands[num], 4);
3119 /* Return 1 if this is a valid binary operation on a 387.
3120 OP is the expression matched, and MODE is its mode. */
3123 binary_387_op (op, mode)
3125 enum machine_mode mode;
3127 if (mode != VOIDmode && mode != GET_MODE (op))
3130 switch (GET_CODE (op))
3136 return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
3144 /* Return 1 if this is a valid shift or rotate operation on a 386.
3145 OP is the expression matched, and MODE is its mode. */
3150 enum machine_mode mode;
3152 rtx operand = XEXP (op, 0);
3154 if (mode != VOIDmode && mode != GET_MODE (op))
3157 if (GET_MODE (operand) != GET_MODE (op)
3158 || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
3161 return (GET_CODE (op) == ASHIFT
3162 || GET_CODE (op) == ASHIFTRT
3163 || GET_CODE (op) == LSHIFTRT
3164 || GET_CODE (op) == ROTATE
3165 || GET_CODE (op) == ROTATERT);
3168 /* Return 1 if OP is COMPARE rtx with mode VOIDmode.
3169 MODE is not used. */
3172 VOIDmode_compare_op (op, mode)
3174 enum machine_mode mode;
3176 return GET_CODE (op) == COMPARE && GET_MODE (op) == VOIDmode;
3179 /* Output code to perform a 387 binary operation in INSN, one of PLUS,
3180 MINUS, MULT or DIV. OPERANDS are the insn operands, where operands[3]
3181 is the expression of the binary operation. The output may either be
3182 emitted here, or returned to the caller, like all output_* functions.
3184 There is no guarantee that the operands are the same mode, as they
3185 might be within FLOAT or FLOAT_EXTEND expressions. */
3188 output_387_binary_op (insn, operands)
3194 static char buf[100];
3196 switch (GET_CODE (operands[3]))
3199 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3200 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3207 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3208 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3215 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3216 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3223 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3224 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3234 strcpy (buf, base_op);
3236 switch (GET_CODE (operands[3]))
3240 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
3243 operands[2] = operands[1];
3247 if (GET_CODE (operands[2]) == MEM)
3248 return strcat (buf, AS1 (%z2,%2));
3250 if (NON_STACK_REG_P (operands[1]))
3252 output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
3255 else if (NON_STACK_REG_P (operands[2]))
3257 output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
3261 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
3262 return strcat (buf, AS2 (p,%2,%0));
3264 if (STACK_TOP_P (operands[0]))
3265 return strcat (buf, AS2C (%y2,%0));
3267 return strcat (buf, AS2C (%2,%0));
3271 if (GET_CODE (operands[1]) == MEM)
3272 return strcat (buf, AS1 (r%z1,%1));
3274 if (GET_CODE (operands[2]) == MEM)
3275 return strcat (buf, AS1 (%z2,%2));
3277 if (NON_STACK_REG_P (operands[1]))
3279 output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1)));
3282 else if (NON_STACK_REG_P (operands[2]))
3284 output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
3288 if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
3291 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
3292 return strcat (buf, AS2 (rp,%2,%0));
3294 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3295 return strcat (buf, AS2 (p,%1,%0));
3297 if (STACK_TOP_P (operands[0]))
3299 if (STACK_TOP_P (operands[1]))
3300 return strcat (buf, AS2C (%y2,%0));
3302 return strcat (buf, AS2 (r,%y1,%0));
3304 else if (STACK_TOP_P (operands[1]))
3305 return strcat (buf, AS2C (%1,%0));
3307 return strcat (buf, AS2 (r,%2,%0));
3314 /* Output code for INSN to convert a float to a signed int. OPERANDS
3315 are the insn operands. The output may be SFmode or DFmode and the
3316 input operand may be SImode or DImode. As a special case, make sure
3317 that the 387 stack top dies if the output mode is DImode, because the
3318 hardware requires this. */
3321 output_fix_trunc (insn, operands)
3325 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
3328 if (! STACK_TOP_P (operands[1]) ||
3329 (GET_MODE (operands[0]) == DImode && ! stack_top_dies))
3332 xops[0] = GEN_INT (12);
3333 xops[1] = operands[4];
3335 output_asm_insn (AS1 (fnstc%W2,%2), operands);
3336 output_asm_insn (AS2 (mov%L2,%2,%4), operands);
3337 output_asm_insn (AS2 (mov%B1,%0,%h1), xops);
3338 output_asm_insn (AS2 (mov%L4,%4,%3), operands);
3339 output_asm_insn (AS1 (fldc%W3,%3), operands);
3341 if (NON_STACK_REG_P (operands[0]))
3342 output_to_reg (operands[0], stack_top_dies);
3343 else if (GET_CODE (operands[0]) == MEM)
3346 output_asm_insn (AS1 (fistp%z0,%0), operands);
3348 output_asm_insn (AS1 (fist%z0,%0), operands);
3353 return AS1 (fldc%W2,%2);
3356 /* Output code for INSN to compare OPERANDS. The two operands might
3357 not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
3358 expression. If the compare is in mode CCFPEQmode, use an opcode that
3359 will not fault if a qNaN is present. */
3362 output_float_compare (insn, operands)
3367 rtx body = XVECEXP (PATTERN (insn), 0, 0);
3368 int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
3371 if (! STACK_TOP_P (operands[0]))
3374 operands[0] = operands[1];
3376 cc_status.flags |= CC_REVERSED;
3379 if (! STACK_TOP_P (operands[0]))
3382 stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
3384 if (STACK_REG_P (operands[1])
3386 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3387 && REGNO (operands[1]) != FIRST_STACK_REG)
3389 /* If both the top of the 387 stack dies, and the other operand
3390 is also a stack register that dies, then this must be a
3391 `fcompp' float compare */
3393 if (unordered_compare)
3394 output_asm_insn ("fucompp", operands);
3396 output_asm_insn ("fcompp", operands);
3400 static char buf[100];
3402 /* Decide if this is the integer or float compare opcode, or the
3403 unordered float compare. */
3405 if (unordered_compare)
3406 strcpy (buf, "fucom");
3407 else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT)
3408 strcpy (buf, "fcom");
3410 strcpy (buf, "ficom");
3412 /* Modify the opcode if the 387 stack is to be popped. */
3417 if (NON_STACK_REG_P (operands[1]))
3418 output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
3420 output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
3423 /* Now retrieve the condition code. */
3425 return output_fp_cc0_set (insn);
3428 /* Output opcodes to transfer the results of FP compare or test INSN
3429 from the FPU to the CPU flags. If TARGET_IEEE_FP, ensure that if the
3430 result of the compare or test is unordered, no comparison operator
3431 succeeds except NE. Return an output template, if any. */
3434 output_fp_cc0_set (insn)
3438 rtx unordered_label;
3442 xops[0] = gen_rtx (REG, HImode, 0);
3443 output_asm_insn (AS1 (fnsts%W0,%0), xops);
3445 if (! TARGET_IEEE_FP)
3447 if (!(cc_status.flags & CC_REVERSED))
3449 next = next_cc0_user (insn);
3451 if (GET_CODE (next) == JUMP_INSN
3452 && GET_CODE (PATTERN (next)) == SET
3453 && SET_DEST (PATTERN (next)) == pc_rtx
3454 && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
3456 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
3458 else if (GET_CODE (PATTERN (next)) == SET)
3460 code = GET_CODE (SET_SRC (PATTERN (next)));
3466 if (code == GT || code == LT || code == EQ || code == NE
3467 || code == LE || code == GE)
3468 { /* We will test eax directly */
3469 cc_status.flags |= CC_TEST_AX;
3476 next = next_cc0_user (insn);
3477 if (next == NULL_RTX)
3480 if (GET_CODE (next) == JUMP_INSN
3481 && GET_CODE (PATTERN (next)) == SET
3482 && SET_DEST (PATTERN (next)) == pc_rtx
3483 && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
3485 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
3487 else if (GET_CODE (PATTERN (next)) == SET)
3489 code = GET_CODE (SET_SRC (PATTERN (next)));
3494 xops[0] = gen_rtx (REG, QImode, 0);
3499 xops[1] = GEN_INT (0x45);
3500 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3505 xops[1] = GEN_INT (0x45);
3506 xops[2] = GEN_INT (0x01);
3507 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3508 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
3513 xops[1] = GEN_INT (0x05);
3514 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3519 xops[1] = GEN_INT (0x45);
3520 xops[2] = GEN_INT (0x40);
3521 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3522 output_asm_insn (AS1 (dec%B0,%h0), xops);
3523 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
3528 xops[1] = GEN_INT (0x45);
3529 xops[2] = GEN_INT (0x40);
3530 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3531 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
3536 xops[1] = GEN_INT (0x44);
3537 xops[2] = GEN_INT (0x40);
3538 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3539 output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
3553 #define MAX_386_STACK_LOCALS 2
3555 static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
3557 /* Define the structure for the machine field in struct function. */
3558 struct machine_function
3560 rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
3563 /* Functions to save and restore i386_stack_locals.
3564 These will be called, via pointer variables,
3565 from push_function_context and pop_function_context. */
3568 save_386_machine_status (p)
3571 p->machine = (struct machine_function *) xmalloc (sizeof i386_stack_locals);
3572 bcopy ((char *) i386_stack_locals, (char *) p->machine->i386_stack_locals,
3573 sizeof i386_stack_locals);
3577 restore_386_machine_status (p)
3580 bcopy ((char *) p->machine->i386_stack_locals, (char *) i386_stack_locals,
3581 sizeof i386_stack_locals);
3585 /* Clear stack slot assignments remembered from previous functions.
3586 This is called from INIT_EXPANDERS once before RTL is emitted for each
3590 clear_386_stack_locals ()
3592 enum machine_mode mode;
3595 for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
3596 mode = (enum machine_mode) ((int) mode + 1))
3597 for (n = 0; n < MAX_386_STACK_LOCALS; n++)
3598 i386_stack_locals[(int) mode][n] = NULL_RTX;
3600 /* Arrange to save and restore i386_stack_locals around nested functions. */
3601 save_machine_status = save_386_machine_status;
3602 restore_machine_status = restore_386_machine_status;
3605 /* Return a MEM corresponding to a stack slot with mode MODE.
3606 Allocate a new slot if necessary.
3608 The RTL for a function can have several slots available: N is
3609 which slot to use. */
3612 assign_386_stack_local (mode, n)
3613 enum machine_mode mode;
3616 if (n < 0 || n >= MAX_386_STACK_LOCALS)
3619 if (i386_stack_locals[(int) mode][n] == NULL_RTX)
3620 i386_stack_locals[(int) mode][n]
3621 = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
3623 return i386_stack_locals[(int) mode][n];
3629 enum machine_mode mode;
3631 return (GET_CODE (op) == MULT);
3636 enum machine_mode mode;
3638 return (GET_CODE (op) == DIV);
3643 /* Create a new copy of an rtx.
3644 Recursively copies the operands of the rtx,
3645 except for those few rtx codes that are sharable.
3646 Doesn't share CONST */
3654 register RTX_CODE code;
3655 register char *format_ptr;
3657 code = GET_CODE (orig);
3670 /* SCRATCH must be shared because they represent distinct values. */
3675 /* CONST can be shared if it contains a SYMBOL_REF. If it contains
3676 a LABEL_REF, it isn't sharable. */
3677 if (GET_CODE (XEXP (orig, 0)) == PLUS
3678 && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
3679 && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
3683 /* A MEM with a constant address is not sharable. The problem is that
3684 the constant address may need to be reloaded. If the mem is shared,
3685 then reloading one copy of this mem will cause all copies to appear
3686 to have been reloaded. */
3689 copy = rtx_alloc (code);
3690 PUT_MODE (copy, GET_MODE (orig));
3691 copy->in_struct = orig->in_struct;
3692 copy->volatil = orig->volatil;
3693 copy->unchanging = orig->unchanging;
3694 copy->integrated = orig->integrated;
3696 copy->is_spill_rtx = orig->is_spill_rtx;
3698 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
3700 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
3702 switch (*format_ptr++)
3705 XEXP (copy, i) = XEXP (orig, i);
3706 if (XEXP (orig, i) != NULL)
3707 XEXP (copy, i) = copy_rtx (XEXP (orig, i));
3712 XEXP (copy, i) = XEXP (orig, i);
3717 XVEC (copy, i) = XVEC (orig, i);
3718 if (XVEC (orig, i) != NULL)
3720 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
3721 for (j = 0; j < XVECLEN (copy, i); j++)
3722 XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
3727 XWINT (copy, i) = XWINT (orig, i);
3731 XINT (copy, i) = XINT (orig, i);
3736 XSTR (copy, i) = XSTR (orig, i);
3747 /* try to rewrite a memory address to make it valid */
3749 rewrite_address (mem_rtx)
3752 rtx index_rtx, base_rtx, offset_rtx, scale_rtx, ret_rtx;
3754 int offset_adjust = 0;
3755 int was_only_offset = 0;
3756 rtx mem_addr = XEXP (mem_rtx, 0);
3757 char *storage = (char *) oballoc (0);
3759 int is_spill_rtx = 0;
3761 in_struct = MEM_IN_STRUCT_P (mem_rtx);
3762 is_spill_rtx = RTX_IS_SPILL_P (mem_rtx);
3764 if (GET_CODE (mem_addr) == PLUS &&
3765 GET_CODE (XEXP (mem_addr, 1)) == PLUS &&
3766 GET_CODE (XEXP (XEXP (mem_addr, 1), 0)) == REG)
3767 { /* this part is utilized by the combiner */
3769 gen_rtx (PLUS, GET_MODE (mem_addr),
3770 gen_rtx (PLUS, GET_MODE (XEXP (mem_addr, 1)),
3772 XEXP (XEXP (mem_addr, 1), 0)),
3773 XEXP (XEXP (mem_addr, 1), 1));
3774 if (memory_address_p (GET_MODE (mem_rtx), ret_rtx))
3776 XEXP (mem_rtx, 0) = ret_rtx;
3777 RTX_IS_SPILL_P (ret_rtx) = is_spill_rtx;
3783 /* this part is utilized by loop.c */
3784 /* If the address contains PLUS (reg,const) and this pattern is invalid
3785 in this case - try to rewrite the address to make it valid intel1
3787 storage = (char *) oballoc (0);
3788 index_rtx = base_rtx = offset_rtx = NULL;
3789 /* find the base index and offset elements of the memory address */
3790 if (GET_CODE (mem_addr) == PLUS)
3792 if (GET_CODE (XEXP (mem_addr, 0)) == REG)
3794 if (GET_CODE (XEXP (mem_addr, 1)) == REG)
3796 base_rtx = XEXP (mem_addr, 1);
3797 index_rtx = XEXP (mem_addr, 0);
3801 base_rtx = XEXP (mem_addr, 0);
3802 offset_rtx = XEXP (mem_addr, 1);
3805 else if (GET_CODE (XEXP (mem_addr, 0)) == MULT)
3807 index_rtx = XEXP (mem_addr, 0);
3808 if (GET_CODE (XEXP (mem_addr, 1)) == REG)
3810 base_rtx = XEXP (mem_addr, 1);
3814 offset_rtx = XEXP (mem_addr, 1);
3817 else if (GET_CODE (XEXP (mem_addr, 0)) == PLUS)
3820 if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == PLUS &&
3821 GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0)) == MULT &&
3822 GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 0)) == REG &&
3823 GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 1)) == CONST_INT &&
3824 GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1)) == CONST_INT &&
3825 GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == REG &&
3826 GET_CODE (XEXP (mem_addr, 1)) == SYMBOL_REF)
3828 index_rtx = XEXP (XEXP (XEXP (mem_addr, 0), 0), 0);
3829 offset_rtx = XEXP (mem_addr, 1);
3830 base_rtx = XEXP (XEXP (mem_addr, 0), 1);
3831 offset_adjust = INTVAL (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1));
3835 offset_rtx = XEXP (mem_addr, 1);
3836 index_rtx = XEXP (XEXP (mem_addr, 0), 0);
3837 base_rtx = XEXP (XEXP (mem_addr, 0), 1);
3840 else if (GET_CODE (XEXP (mem_addr, 0)) == CONST_INT)
3842 was_only_offset = 1;
3845 offset_rtx = XEXP (mem_addr, 1);
3846 offset_adjust = INTVAL (XEXP (mem_addr, 0));
3847 if (offset_adjust == 0)
3849 XEXP (mem_rtx, 0) = offset_rtx;
3850 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
3860 else if (GET_CODE (mem_addr) == MULT)
3862 index_rtx = mem_addr;
3869 if (index_rtx && GET_CODE (index_rtx) == MULT)
3871 if (GET_CODE (XEXP (index_rtx, 1)) != CONST_INT)
3876 scale_rtx = XEXP (index_rtx, 1);
3877 scale = INTVAL (scale_rtx);
3878 index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
3880 /* now find which of the elements are invalid and try to fix them */
3881 if (index_rtx && GET_CODE (index_rtx) == CONST_INT && base_rtx == NULL)
3883 offset_adjust = INTVAL (index_rtx) * scale;
3884 if (offset_rtx && GET_CODE (offset_rtx) == CONST &&
3885 GET_CODE (XEXP (offset_rtx, 0)) == PLUS)
3887 if (GET_CODE (XEXP (XEXP (offset_rtx, 0), 0)) == SYMBOL_REF &&
3888 GET_CODE (XEXP (XEXP (offset_rtx, 0), 1)) == CONST_INT)
3890 offset_rtx = copy_all_rtx (offset_rtx);
3891 XEXP (XEXP (offset_rtx, 0), 1) =
3892 gen_rtx (CONST_INT, 0, INTVAL (XEXP (XEXP (offset_rtx, 0), 1)) + offset_adjust);
3893 if (!CONSTANT_P (offset_rtx))
3900 else if (offset_rtx && GET_CODE (offset_rtx) == SYMBOL_REF)
3903 gen_rtx (CONST, GET_MODE (offset_rtx),
3904 gen_rtx (PLUS, GET_MODE (offset_rtx),
3906 gen_rtx (CONST_INT, 0, offset_adjust)));
3907 if (!CONSTANT_P (offset_rtx))
3913 else if (offset_rtx && GET_CODE (offset_rtx) == CONST_INT)
3915 offset_rtx = gen_rtx (CONST_INT, 0, INTVAL (offset_rtx) + offset_adjust);
3917 else if (!offset_rtx)
3919 offset_rtx = gen_rtx (CONST_INT, 0, 0);
3921 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
3922 XEXP (mem_rtx, 0) = offset_rtx;
3925 if (base_rtx && GET_CODE (base_rtx) == PLUS &&
3926 GET_CODE (XEXP (base_rtx, 0)) == REG &&
3927 GET_CODE (XEXP (base_rtx, 1)) == CONST_INT)
3929 offset_adjust += INTVAL (XEXP (base_rtx, 1));
3930 base_rtx = copy_all_rtx (XEXP (base_rtx, 0));
3932 else if (base_rtx && GET_CODE (base_rtx) == CONST_INT)
3934 offset_adjust += INTVAL (base_rtx);
3937 if (index_rtx && GET_CODE (index_rtx) == PLUS &&
3938 GET_CODE (XEXP (index_rtx, 0)) == REG &&
3939 GET_CODE (XEXP (index_rtx, 1)) == CONST_INT)
3941 offset_adjust += INTVAL (XEXP (index_rtx, 1)) * scale;
3942 index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
3946 if (!LEGITIMATE_INDEX_P (index_rtx)
3947 && !(index_rtx == stack_pointer_rtx && scale == 1 && base_rtx == NULL))
3955 if (!LEGITIMATE_INDEX_P (base_rtx) && GET_CODE (base_rtx) != REG)
3961 if (offset_adjust != 0)
3965 if (GET_CODE (offset_rtx) == CONST &&
3966 GET_CODE (XEXP (offset_rtx, 0)) == PLUS)
3968 if (GET_CODE (XEXP (XEXP (offset_rtx, 0), 0)) == SYMBOL_REF &&
3969 GET_CODE (XEXP (XEXP (offset_rtx, 0), 1)) == CONST_INT)
3971 offset_rtx = copy_all_rtx (offset_rtx);
3972 XEXP (XEXP (offset_rtx, 0), 1) =
3973 gen_rtx (CONST_INT, 0, INTVAL (XEXP (XEXP (offset_rtx, 0), 1)) + offset_adjust);
3974 if (!CONSTANT_P (offset_rtx))
3981 else if (GET_CODE (offset_rtx) == SYMBOL_REF)
3984 gen_rtx (CONST, GET_MODE (offset_rtx),
3985 gen_rtx (PLUS, GET_MODE (offset_rtx),
3987 gen_rtx (CONST_INT, 0, offset_adjust)));
3988 if (!CONSTANT_P (offset_rtx))
3994 else if (GET_CODE (offset_rtx) == CONST_INT)
3996 offset_rtx = gen_rtx (CONST_INT, 0, INTVAL (offset_rtx) + offset_adjust);
4006 offset_rtx = gen_rtx (CONST_INT, 0, offset_adjust);
4014 if (GET_CODE (offset_rtx) == CONST_INT &&
4015 INTVAL (offset_rtx) == 0)
4017 ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx),
4018 gen_rtx (MULT, GET_MODE (index_rtx), index_rtx,
4024 ret_rtx = gen_rtx (PLUS, GET_MODE (offset_rtx),
4025 gen_rtx (PLUS, GET_MODE (base_rtx),
4026 gen_rtx (MULT, GET_MODE (index_rtx), index_rtx,
4034 if (GET_CODE (offset_rtx) == CONST_INT &&
4035 INTVAL (offset_rtx) == 0)
4037 ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx), index_rtx, base_rtx);
4041 ret_rtx = gen_rtx (PLUS, GET_MODE (offset_rtx),
4042 gen_rtx (PLUS, GET_MODE (index_rtx), index_rtx,
4052 if (GET_CODE (offset_rtx) == CONST_INT &&
4053 INTVAL (offset_rtx) == 0)
4055 ret_rtx = gen_rtx (MULT, GET_MODE (index_rtx), index_rtx, scale_rtx);
4060 gen_rtx (PLUS, GET_MODE (offset_rtx),
4061 gen_rtx (MULT, GET_MODE (index_rtx), index_rtx,
4068 if (GET_CODE (offset_rtx) == CONST_INT &&
4069 INTVAL (offset_rtx) == 0)
4071 ret_rtx = index_rtx;
4075 ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx), index_rtx, offset_rtx);
4084 if (GET_CODE (offset_rtx) == CONST_INT &&
4085 INTVAL (offset_rtx) == 0)
4091 ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx), base_rtx, offset_rtx);
4094 else if (was_only_offset)
4096 ret_rtx = offset_rtx;
4104 XEXP (mem_rtx, 0) = ret_rtx;
4105 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4117 /* return 1 if the first insn to set cc before insn also sets the register
4118 reg_rtx - otherwise return 0 */
4120 last_to_set_cc (reg_rtx, insn)
4123 rtx prev_insn = PREV_INSN (insn);
4127 if (GET_CODE (prev_insn) == NOTE)
4130 else if (GET_CODE (prev_insn) == INSN)
4132 if (GET_CODE (PATTERN (prev_insn)) != SET)
4135 if (rtx_equal_p (SET_DEST (PATTERN (prev_insn)), reg_rtx))
4137 if (sets_condition_code (SET_SRC (PATTERN (prev_insn))))
4143 else if (!doesnt_set_condition_code (SET_SRC (PATTERN (prev_insn))))
4150 prev_insn = PREV_INSN (prev_insn);
4158 doesnt_set_condition_code (pat)
4161 switch (GET_CODE (pat))
4175 sets_condition_code (pat)
4178 switch (GET_CODE (pat))
4202 str_immediate_operand (op, mode)
4204 enum machine_mode mode;
4206 if (GET_CODE (op) == CONST_INT && INTVAL (op) <= 32 && INTVAL (op) >= 0)
4218 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4219 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4220 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4221 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode))
4230 Return 1 if the mode of the SET_DEST of insn is floating point
4231 and it is not an fld or a move from memory to memory.
4232 Otherwise return 0 */
4237 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4238 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4239 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4240 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
4241 && GET_CODE (SET_DEST (PATTERN (insn))) == REG
4242 && REGNO (SET_DEST (PATTERN (insn))) >= FIRST_FLOAT_REG
4243 && GET_CODE (SET_SRC (insn)) != MEM)
4252 Return 1 if the mode of the SET_DEST floating point and is memory
4253 and the source is a register.
4259 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4260 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4261 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4262 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
4263 && GET_CODE (SET_DEST (PATTERN (insn))) == MEM
4264 && GET_CODE (SET_SRC (PATTERN (insn))) == REG)
4274 Return 1 if dep_insn sets a register which insn uses as a base
4275 or index to reference memory.
4276 otherwise return 0 */
4279 agi_dependent (insn, dep_insn)
4282 if (GET_CODE (dep_insn) == INSN
4283 && GET_CODE (PATTERN (dep_insn)) == SET
4284 && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG)
4286 return (reg_mentioned_in_mem (SET_DEST (PATTERN (dep_insn)), insn));
4289 if (GET_CODE (dep_insn) == INSN && GET_CODE (PATTERN (dep_insn)) == SET
4290 && GET_CODE (SET_DEST (PATTERN (dep_insn))) == MEM
4291 && push_operand (SET_DEST (PATTERN (dep_insn)),
4292 GET_MODE (SET_DEST (PATTERN (dep_insn)))))
4294 return (reg_mentioned_in_mem (stack_pointer_rtx, insn));
4302 Return 1 if reg is used in rtl as a base or index for a memory ref
4303 otherwise return 0. */
4306 reg_mentioned_in_mem (reg, rtl)
4311 register enum rtx_code code;
4316 code = GET_CODE (rtl);
4334 if (code == MEM && reg_mentioned_p (reg, rtl))
4337 fmt = GET_RTX_FORMAT (code);
4338 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4343 for (j = XVECLEN (rtl, i) - 1; j >= 0; j--)
4345 if (reg_mentioned_in_mem (reg, XVECEXP (rtl, i, j)))
4350 else if (fmt[i] == 'e' && reg_mentioned_in_mem (reg, XEXP (rtl, i)))
4357 /* Output the approprate insns for doing strlen if not just doing repnz; scasb
4359 operands[0] = result, initialized with the startaddress
4360 operands[1] = alignment of the address.
4361 operands[2] = scratch register, initialized with the startaddress when
4362 not aligned, otherwise undefined
4364 This is just the body. It needs the initialisations mentioned above and
4365 some address computing at the end. These things are done in i386.md. */
4368 output_strlen_unroll (operands)
4373 xops[0] = operands[0]; /* Result */
4374 /* operands[1]; * Alignment */
4375 xops[1] = operands[2]; /* Scratch */
4376 xops[2] = GEN_INT (0);
4377 xops[3] = GEN_INT (2);
4378 xops[4] = GEN_INT (3);
4379 xops[5] = GEN_INT (4);
4380 /* xops[6] = gen_label_rtx (); * label when aligned to 3-byte */
4381 /* xops[7] = gen_label_rtx (); * label when aligned to 2-byte */
4382 xops[8] = gen_label_rtx (); /* label of main loop */
4383 if(TARGET_USE_Q_REG && QI_REG_P (xops[1]))
4384 xops[9] = gen_label_rtx (); /* pentium optimisation */
4385 xops[10] = gen_label_rtx (); /* end label 2 */
4386 xops[11] = gen_label_rtx (); /* end label 1 */
4387 xops[12] = gen_label_rtx (); /* end label */
4388 /* xops[13] * Temporary used */
4389 xops[14] = GEN_INT (0xff);
4390 xops[15] = GEN_INT (0xff00);
4391 xops[16] = GEN_INT (0xff0000);
4392 xops[17] = GEN_INT (0xff000000);
4394 /* Loop to check 1..3 bytes for null to get an aligned pointer */
4396 /* is there a known alignment and is it less then 4 */
4397 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) < 4)
4399 /* is there a known alignment and is it not 2 */
4400 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
4402 xops[6] = gen_label_rtx (); /* label when aligned to 3-byte */
4403 xops[7] = gen_label_rtx (); /* label when aligned to 2-byte */
4405 /* leave just the 3 lower bits */
4406 /* if this is a q-register, then the high part is used later */
4407 /* therefore user andl rather than andb */
4408 output_asm_insn (AS2 (and%L1,%4,%1), xops);
4409 /* is aligned to 4-byte adress when zero */
4410 output_asm_insn (AS1 (je,%l8), xops);
4411 /* side-effect even Parity when %eax == 3 */
4412 output_asm_insn (AS1 (jp,%6), xops);
4414 /* is it aligned to 2 bytes ? */
4415 if (QI_REG_P (xops[1]))
4416 output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
4418 output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
4419 output_asm_insn (AS1 (je,%7), xops);
4423 /* since the alignment is 2, we have to check 2 or 0 bytes */
4425 /* check if is aligned to 4 - byte */
4426 output_asm_insn (AS2 (and%L1,%3,%1), xops);
4427 /* is aligned to 4-byte adress when zero */
4428 output_asm_insn (AS1 (je,%l8), xops);
4431 xops[13] = gen_rtx (MEM, QImode, xops[0]);
4432 /* now, compare the bytes */
4433 /* compare with the high part of a q-reg gives shorter code */
4434 if (QI_REG_P (xops[1]))
4436 /* compare the first n unaligned byte on a byte per byte basis */
4437 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
4438 /* when zero we reached the end */
4439 output_asm_insn (AS1 (je,%l12), xops);
4440 /* increment the address */
4441 output_asm_insn (AS1 (inc%L0,%0), xops);
4443 /* not needed with an alignment of 2 */
4444 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
4446 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[7]));
4447 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
4448 output_asm_insn (AS1 (je,%l12), xops);
4449 output_asm_insn (AS1 (inc%L0,%0), xops);
4451 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[6]));
4453 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
4457 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
4458 output_asm_insn (AS1 (je,%l12), xops);
4459 output_asm_insn (AS1 (inc%L0,%0), xops);
4461 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[7]));
4462 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
4463 output_asm_insn (AS1 (je,%l12), xops);
4464 output_asm_insn (AS1 (inc%L0,%0), xops);
4466 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[6]));
4467 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
4469 output_asm_insn (AS1 (je,%l12), xops);
4470 output_asm_insn (AS1 (inc%L0,%0), xops);
4473 /* Generate loop to check 4 bytes at a time */
4474 /* IMHO it is not a good idea to align this loop. It gives only */
4475 /* huge programms, but does not help to speed up */
4476 /* ASM_OUTPUT_LOOP_ALIGN (asm_out_file); */
4477 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[8]));
4479 xops[13] = gen_rtx (MEM, SImode, xops[0]);
4480 output_asm_insn (AS2 (mov%L1,%13,%1), xops);
4482 if (QI_REG_P (xops[1]))
4484 /* on i586 it is faster to compare the hi- and lo- part */
4485 /* as a kind of lookahead. If xoring both is zero, then one */
4486 /* of both *could* be zero, otherwith none of both is zero */
4487 /* this saves one instruction, on i486 this is slower */
4488 /* testet with P-90, i486DX2-66, AMD486DX2-66 */
4491 output_asm_insn (AS2 (test%B1,%h1,%b1), xops);
4492 output_asm_insn (AS1 (jne,%l9), xops);
4495 /* check first byte */
4496 output_asm_insn (AS2 (test%B1,%b1,%b1), xops);
4497 output_asm_insn (AS1 (je,%l12), xops);
4499 /* check second byte */
4500 output_asm_insn (AS2 (test%B1,%h1,%h1), xops);
4501 output_asm_insn (AS1 (je,%l11), xops);
4504 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[9]));
4508 /* check first byte */
4509 output_asm_insn (AS2 (test%L1,%14,%1), xops);
4510 output_asm_insn (AS1 (je,%l12), xops);
4512 /* check second byte */
4513 output_asm_insn (AS2 (test%L1,%15,%1), xops);
4514 output_asm_insn (AS1 (je,%l11), xops);
4517 /* check third byte */
4518 output_asm_insn (AS2 (test%L1,%16,%1), xops);
4519 output_asm_insn (AS1 (je,%l10), xops);
4521 /* check fourth byte and increment address */
4522 output_asm_insn (AS2 (add%L0,%5,%0), xops);
4523 output_asm_insn (AS2 (test%L1,%17,%1), xops);
4524 output_asm_insn (AS1 (jne,%l8), xops);
4526 /* now generate fixups when the compare stops within a 4-byte word */
4527 output_asm_insn (AS2 (sub%L0,%4,%0), xops);
4529 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[10]));
4530 output_asm_insn (AS1 (inc%L0,%0), xops);
4532 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[11]));
4533 output_asm_insn (AS1 (inc%L0,%0), xops);
4535 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[12]));