1 /* Subroutines for insn-output.c for Intel X86.
2 Copyright (C) 1988, 92, 94, 95, 96, 97, 1998 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. */
26 #include "hard-reg-set.h"
28 #include "insn-config.h"
29 #include "conditions.h"
30 #include "insn-flags.h"
32 #include "insn-attr.h"
41 #ifdef EXTRA_CONSTRAINT
42 /* If EXTRA_CONSTRAINT is defined, then the 'S'
43 constraint in REG_CLASS_FROM_LETTER will no longer work, and various
44 asm statements that need 'S' for class SIREG will break. */
45 error EXTRA_CONSTRAINT conflicts with S constraint letter
46 /* The previous line used to be #error, but some compilers barf
47 even if the conditional was untrue. */
50 #ifndef CHECK_STACK_LIMIT
51 #define CHECK_STACK_LIMIT -1
54 /* Type of an operand for ix86_{binary,unary}_operator_ok */
62 /* Processor costs (relative to an add) */
63 struct processor_costs i386_cost
= { /* 386 specific costs */
64 1, /* cost of an add instruction */
65 1, /* cost of a lea instruction */
66 3, /* variable shift costs */
67 2, /* constant shift costs */
68 6, /* cost of starting a multiply */
69 1, /* cost of multiply per each bit set */
70 23 /* cost of a divide/mod */
73 struct processor_costs i486_cost
= { /* 486 specific costs */
74 1, /* cost of an add instruction */
75 1, /* cost of a lea instruction */
76 3, /* variable shift costs */
77 2, /* constant shift costs */
78 12, /* cost of starting a multiply */
79 1, /* cost of multiply per each bit set */
80 40 /* cost of a divide/mod */
83 struct processor_costs pentium_cost
= {
84 1, /* cost of an add instruction */
85 1, /* cost of a lea instruction */
86 4, /* variable shift costs */
87 1, /* constant shift costs */
88 11, /* cost of starting a multiply */
89 0, /* cost of multiply per each bit set */
90 25 /* cost of a divide/mod */
93 struct processor_costs pentiumpro_cost
= {
94 1, /* cost of an add instruction */
95 1, /* cost of a lea instruction */
96 3, /* variable shift costs */
97 1, /* constant shift costs */
98 4, /* cost of starting a multiply */
99 0, /* cost of multiply per each bit set */
100 17 /* cost of a divide/mod */
103 struct processor_costs
*ix86_cost
= &pentium_cost
;
105 #define AT_BP(mode) (gen_rtx_MEM ((mode), frame_pointer_rtx))
107 extern FILE *asm_out_file
;
108 extern char *strcat ();
110 static void ix86_epilogue
PROTO((int));
111 static void ix86_prologue
PROTO((int));
113 char *singlemove_string ();
114 char *output_move_const_single ();
115 char *output_fp_cc0_set ();
117 char *hi_reg_name
[] = HI_REGISTER_NAMES
;
118 char *qi_reg_name
[] = QI_REGISTER_NAMES
;
119 char *qi_high_reg_name
[] = QI_HIGH_REGISTER_NAMES
;
121 /* Array of the smallest class containing reg number REGNO, indexed by
122 REGNO. Used by REGNO_REG_CLASS in i386.h. */
124 enum reg_class regclass_map
[FIRST_PSEUDO_REGISTER
] =
127 AREG
, DREG
, CREG
, BREG
,
129 SIREG
, DIREG
, INDEX_REGS
, GENERAL_REGS
,
131 FP_TOP_REG
, FP_SECOND_REG
, FLOAT_REGS
, FLOAT_REGS
,
132 FLOAT_REGS
, FLOAT_REGS
, FLOAT_REGS
, FLOAT_REGS
,
137 /* Test and compare insns in i386.md store the information needed to
138 generate branch and scc insns here. */
140 struct rtx_def
*i386_compare_op0
= NULL_RTX
;
141 struct rtx_def
*i386_compare_op1
= NULL_RTX
;
142 struct rtx_def
*(*i386_compare_gen
)(), *(*i386_compare_gen_eq
)();
144 /* which cpu are we scheduling for */
145 enum processor_type ix86_cpu
;
147 /* which instruction set architecture to use. */
150 /* Strings to hold which cpu and instruction set architecture to use. */
151 char *ix86_cpu_string
; /* for -mcpu=<xxx> */
152 char *ix86_arch_string
; /* for -march=<xxx> */
154 /* Register allocation order */
155 char *i386_reg_alloc_order
;
156 static char regs_allocated
[FIRST_PSEUDO_REGISTER
];
158 /* # of registers to use to pass arguments. */
159 char *i386_regparm_string
;
161 /* i386_regparm_string as a number */
164 /* Alignment to use for loops and jumps: */
166 /* Power of two alignment for loops. */
167 char *i386_align_loops_string
;
169 /* Power of two alignment for non-loop jumps. */
170 char *i386_align_jumps_string
;
172 /* Values 1-5: see jump.c */
173 int i386_branch_cost
;
174 char *i386_branch_cost_string
;
176 /* Power of two alignment for functions. */
177 int i386_align_funcs
;
178 char *i386_align_funcs_string
;
180 /* Power of two alignment for loops. */
181 int i386_align_loops
;
183 /* Power of two alignment for non-loop jumps. */
184 int i386_align_jumps
;
186 /* Sometimes certain combinations of command options do not make
187 sense on a particular target machine. You can define a macro
188 `OVERRIDE_OPTIONS' to take account of this. This macro, if
189 defined, is executed once just after all the command options have
192 Don't use this macro to turn on various extra optimizations for
193 `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
203 char *name
; /* Canonical processor name. */
204 enum processor_type processor
; /* Processor type enum value. */
205 struct processor_costs
*cost
; /* Processor costs */
206 int target_enable
; /* Target flags to enable. */
207 int target_disable
; /* Target flags to disable. */
208 } processor_target_table
[]
209 = {{PROCESSOR_I386_STRING
, PROCESSOR_I386
, &i386_cost
, 0, 0},
210 {PROCESSOR_I486_STRING
, PROCESSOR_I486
, &i486_cost
, 0, 0},
211 {PROCESSOR_I586_STRING
, PROCESSOR_PENTIUM
, &pentium_cost
, 0, 0},
212 {PROCESSOR_PENTIUM_STRING
, PROCESSOR_PENTIUM
, &pentium_cost
, 0, 0},
213 {PROCESSOR_I686_STRING
, PROCESSOR_PENTIUMPRO
, &pentiumpro_cost
,
215 {PROCESSOR_PENTIUMPRO_STRING
, PROCESSOR_PENTIUMPRO
,
216 &pentiumpro_cost
, 0, 0}};
218 int ptt_size
= sizeof (processor_target_table
) / sizeof (struct ptt
);
220 #ifdef SUBTARGET_OVERRIDE_OPTIONS
221 SUBTARGET_OVERRIDE_OPTIONS
;
224 /* Validate registers in register allocation order. */
225 if (i386_reg_alloc_order
)
227 for (i
= 0; (ch
= i386_reg_alloc_order
[i
]) != '\0'; i
++)
233 case 'a': regno
= 0; break;
234 case 'd': regno
= 1; break;
235 case 'c': regno
= 2; break;
236 case 'b': regno
= 3; break;
237 case 'S': regno
= 4; break;
238 case 'D': regno
= 5; break;
239 case 'B': regno
= 6; break;
241 default: fatal ("Register '%c' is unknown", ch
);
244 if (regs_allocated
[regno
])
245 fatal ("Register '%c' already specified in allocation order", ch
);
247 regs_allocated
[regno
] = 1;
251 if (ix86_arch_string
== 0)
253 ix86_arch_string
= PROCESSOR_PENTIUM_STRING
;
254 if (ix86_cpu_string
== 0)
255 ix86_cpu_string
= PROCESSOR_DEFAULT_STRING
;
258 for (i
= 0; i
< ptt_size
; i
++)
259 if (! strcmp (ix86_arch_string
, processor_target_table
[i
].name
))
261 ix86_arch
= processor_target_table
[i
].processor
;
262 if (ix86_cpu_string
== 0)
263 ix86_cpu_string
= processor_target_table
[i
].name
;
269 error ("bad value (%s) for -march= switch", ix86_arch_string
);
270 ix86_arch_string
= PROCESSOR_PENTIUM_STRING
;
271 ix86_arch
= PROCESSOR_DEFAULT
;
274 if (ix86_cpu_string
== 0)
275 ix86_cpu_string
= PROCESSOR_DEFAULT_STRING
;
277 for (j
= 0; j
< ptt_size
; j
++)
278 if (! strcmp (ix86_cpu_string
, processor_target_table
[j
].name
))
280 ix86_cpu
= processor_target_table
[j
].processor
;
281 ix86_cost
= processor_target_table
[j
].cost
;
282 if (i
> j
&& (int) ix86_arch
>= (int) PROCESSOR_PENTIUMPRO
)
283 error ("-mcpu=%s does not support -march=%s",
284 ix86_cpu_string
, ix86_arch_string
);
286 target_flags
|= processor_target_table
[j
].target_enable
;
287 target_flags
&= ~processor_target_table
[j
].target_disable
;
293 error ("bad value (%s) for -mcpu= switch", ix86_cpu_string
);
294 ix86_cpu_string
= PROCESSOR_DEFAULT_STRING
;
295 ix86_cpu
= PROCESSOR_DEFAULT
;
298 /* Validate -mregparm= value. */
299 if (i386_regparm_string
)
301 i386_regparm
= atoi (i386_regparm_string
);
302 if (i386_regparm
< 0 || i386_regparm
> REGPARM_MAX
)
303 fatal ("-mregparm=%d is not between 0 and %d",
304 i386_regparm
, REGPARM_MAX
);
307 /* The 486 suffers more from non-aligned cache line fills, and the
308 larger code size results in a larger cache foot-print and more misses.
309 The 486 has a 16 byte cache line, pentium and pentiumpro have a 32 byte
311 def_align
= (TARGET_486
) ? 4 : 2;
313 /* Validate -malign-loops= value, or provide default. */
314 if (i386_align_loops_string
)
316 i386_align_loops
= atoi (i386_align_loops_string
);
317 if (i386_align_loops
< 0 || i386_align_loops
> MAX_CODE_ALIGN
)
318 fatal ("-malign-loops=%d is not between 0 and %d",
319 i386_align_loops
, MAX_CODE_ALIGN
);
322 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
323 i386_align_loops
= 4;
325 i386_align_loops
= 2;
328 /* Validate -malign-jumps= value, or provide default. */
329 if (i386_align_jumps_string
)
331 i386_align_jumps
= atoi (i386_align_jumps_string
);
332 if (i386_align_jumps
< 0 || i386_align_jumps
> MAX_CODE_ALIGN
)
333 fatal ("-malign-jumps=%d is not between 0 and %d",
334 i386_align_jumps
, MAX_CODE_ALIGN
);
337 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
338 i386_align_jumps
= 4;
340 i386_align_jumps
= def_align
;
343 /* Validate -malign-functions= value, or provide default. */
344 if (i386_align_funcs_string
)
346 i386_align_funcs
= atoi (i386_align_funcs_string
);
347 if (i386_align_funcs
< 0 || i386_align_funcs
> MAX_CODE_ALIGN
)
348 fatal ("-malign-functions=%d is not between 0 and %d",
349 i386_align_funcs
, MAX_CODE_ALIGN
);
352 i386_align_funcs
= def_align
;
354 /* Validate -mbranch-cost= value, or provide default. */
355 if (i386_branch_cost_string
)
357 i386_branch_cost
= atoi (i386_branch_cost_string
);
358 if (i386_branch_cost
< 0 || i386_branch_cost
> 5)
359 fatal ("-mbranch-cost=%d is not between 0 and 5",
363 i386_branch_cost
= 1;
365 /* Keep nonleaf frame pointers. */
366 if (TARGET_OMIT_LEAF_FRAME_POINTER
)
367 flag_omit_frame_pointer
= 1;
370 /* A C statement (sans semicolon) to choose the order in which to
371 allocate hard registers for pseudo-registers local to a basic
374 Store the desired register order in the array `reg_alloc_order'.
375 Element 0 should be the register to allocate first; element 1, the
376 next register; and so on.
378 The macro body should not assume anything about the contents of
379 `reg_alloc_order' before execution of the macro.
381 On most machines, it is not necessary to define this macro. */
384 order_regs_for_local_alloc ()
388 /* User specified the register allocation order. */
390 if (i386_reg_alloc_order
)
392 for (i
= order
= 0; (ch
= i386_reg_alloc_order
[i
]) != '\0'; i
++)
398 case 'a': regno
= 0; break;
399 case 'd': regno
= 1; break;
400 case 'c': regno
= 2; break;
401 case 'b': regno
= 3; break;
402 case 'S': regno
= 4; break;
403 case 'D': regno
= 5; break;
404 case 'B': regno
= 6; break;
407 reg_alloc_order
[order
++] = regno
;
410 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
412 if (! regs_allocated
[i
])
413 reg_alloc_order
[order
++] = i
;
417 /* If user did not specify a register allocation order, use natural order. */
420 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
421 reg_alloc_order
[i
] = i
;
426 optimization_options (level
, size
)
428 int size ATTRIBUTE_UNUSED
;
430 /* For -O2 and beyond, turn off -fschedule-insns by default. It tends to
431 make the problem with not enough registers even worse. */
432 #ifdef INSN_SCHEDULING
434 flag_schedule_insns
= 0;
438 /* Sign-extend a 16-bit constant */
441 i386_sext16_if_const (op
)
444 if (GET_CODE (op
) == CONST_INT
)
446 HOST_WIDE_INT val
= INTVAL (op
);
447 HOST_WIDE_INT sext_val
;
449 sext_val
= val
| ~0xffff;
451 sext_val
= val
& 0xffff;
453 op
= GEN_INT (sext_val
);
458 /* Return nonzero if the rtx is aligned */
461 i386_aligned_reg_p (regno
)
464 return (regno
== STACK_POINTER_REGNUM
465 || (! flag_omit_frame_pointer
&& regno
== FRAME_POINTER_REGNUM
));
472 /* Registers and immediate operands are always "aligned". */
473 if (GET_CODE (op
) != MEM
)
476 /* Don't even try to do any aligned optimizations with volatiles. */
477 if (MEM_VOLATILE_P (op
))
480 /* Get address of memory operand. */
483 switch (GET_CODE (op
))
490 /* Match "reg + offset" */
492 if (GET_CODE (XEXP (op
, 1)) != CONST_INT
)
494 if (INTVAL (XEXP (op
, 1)) & 3)
498 if (GET_CODE (op
) != REG
)
501 /* ... fall through ... */
504 return i386_aligned_reg_p (REGNO (op
));
513 /* Return nonzero if INSN looks like it won't compute useful cc bits
514 as a side effect. This information is only a hint. */
517 i386_cc_probably_useless_p (insn
)
520 return ! next_cc0_user (insn
);
523 /* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
524 attribute for DECL. The attributes in ATTRIBUTES have previously been
528 i386_valid_decl_attribute_p (decl
, attributes
, identifier
, args
)
529 tree decl ATTRIBUTE_UNUSED
;
530 tree attributes ATTRIBUTE_UNUSED
;
531 tree identifier ATTRIBUTE_UNUSED
;
532 tree args ATTRIBUTE_UNUSED
;
537 /* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
538 attribute for TYPE. The attributes in ATTRIBUTES have previously been
542 i386_valid_type_attribute_p (type
, attributes
, identifier
, args
)
544 tree attributes ATTRIBUTE_UNUSED
;
548 if (TREE_CODE (type
) != FUNCTION_TYPE
549 && TREE_CODE (type
) != FIELD_DECL
550 && TREE_CODE (type
) != TYPE_DECL
)
553 /* Stdcall attribute says callee is responsible for popping arguments
554 if they are not variable. */
555 if (is_attribute_p ("stdcall", identifier
))
556 return (args
== NULL_TREE
);
558 /* Cdecl attribute says the callee is a normal C declaration. */
559 if (is_attribute_p ("cdecl", identifier
))
560 return (args
== NULL_TREE
);
562 /* Regparm attribute specifies how many integer arguments are to be
563 passed in registers. */
564 if (is_attribute_p ("regparm", identifier
))
568 if (! args
|| TREE_CODE (args
) != TREE_LIST
569 || TREE_CHAIN (args
) != NULL_TREE
570 || TREE_VALUE (args
) == NULL_TREE
)
573 cst
= TREE_VALUE (args
);
574 if (TREE_CODE (cst
) != INTEGER_CST
)
577 if (TREE_INT_CST_HIGH (cst
) != 0
578 || TREE_INT_CST_LOW (cst
) < 0
579 || TREE_INT_CST_LOW (cst
) > REGPARM_MAX
)
588 /* Return 0 if the attributes for two types are incompatible, 1 if they
589 are compatible, and 2 if they are nearly compatible (which causes a
590 warning to be generated). */
593 i386_comp_type_attributes (type1
, type2
)
594 tree type1 ATTRIBUTE_UNUSED
;
595 tree type2 ATTRIBUTE_UNUSED
;
601 /* Value is the number of bytes of arguments automatically
602 popped when returning from a subroutine call.
603 FUNDECL is the declaration node of the function (as a tree),
604 FUNTYPE is the data type of the function (as a tree),
605 or for a library call it is an identifier node for the subroutine name.
606 SIZE is the number of bytes of arguments passed on the stack.
608 On the 80386, the RTD insn may be used to pop them if the number
609 of args is fixed, but if the number is variable then the caller
610 must pop them all. RTD can't be used for library calls now
611 because the library is compiled with the Unix compiler.
612 Use of RTD is a selectable option, since it is incompatible with
613 standard Unix calling sequences. If the option is not selected,
614 the caller must always pop the args.
616 The attribute stdcall is equivalent to RTD on a per module basis. */
619 i386_return_pops_args (fundecl
, funtype
, size
)
624 int rtd
= TARGET_RTD
&& (!fundecl
|| TREE_CODE (fundecl
) != IDENTIFIER_NODE
);
626 /* Cdecl functions override -mrtd, and never pop the stack. */
627 if (! lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype
))) {
629 /* Stdcall functions will pop the stack if not variable args. */
630 if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype
)))
634 && (TYPE_ARG_TYPES (funtype
) == NULL_TREE
635 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (funtype
)))
640 /* Lose any fake structure return argument. */
641 if (aggregate_value_p (TREE_TYPE (funtype
)))
642 return GET_MODE_SIZE (Pmode
);
648 /* Argument support functions. */
650 /* Initialize a variable CUM of type CUMULATIVE_ARGS
651 for a call to a function whose data type is FNTYPE.
652 For a library call, FNTYPE is 0. */
655 init_cumulative_args (cum
, fntype
, libname
)
656 CUMULATIVE_ARGS
*cum
; /* Argument info to initialize */
657 tree fntype
; /* tree ptr for function decl */
658 rtx libname
; /* SYMBOL_REF of library name or 0 */
660 static CUMULATIVE_ARGS zero_cum
;
661 tree param
, next_param
;
663 if (TARGET_DEBUG_ARG
)
665 fprintf (stderr
, "\ninit_cumulative_args (");
667 fprintf (stderr
, "fntype code = %s, ret code = %s",
668 tree_code_name
[(int) TREE_CODE (fntype
)],
669 tree_code_name
[(int) TREE_CODE (TREE_TYPE (fntype
))]);
671 fprintf (stderr
, "no fntype");
674 fprintf (stderr
, ", libname = %s", XSTR (libname
, 0));
679 /* Set up the number of registers to use for passing arguments. */
680 cum
->nregs
= i386_regparm
;
683 tree attr
= lookup_attribute ("regparm", TYPE_ATTRIBUTES (fntype
));
686 cum
->nregs
= TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr
)));
689 /* Determine if this function has variable arguments. This is
690 indicated by the last argument being 'void_type_mode' if there
691 are no variable arguments. If there are variable arguments, then
692 we won't pass anything in registers */
696 for (param
= (fntype
) ? TYPE_ARG_TYPES (fntype
) : 0;
697 param
!= 0; param
= next_param
)
699 next_param
= TREE_CHAIN (param
);
700 if (next_param
== 0 && TREE_VALUE (param
) != void_type_node
)
705 if (TARGET_DEBUG_ARG
)
706 fprintf (stderr
, ", nregs=%d )\n", cum
->nregs
);
711 /* Update the data in CUM to advance over an argument
712 of mode MODE and data type TYPE.
713 (TYPE is null for libcalls where that information may not be available.) */
716 function_arg_advance (cum
, mode
, type
, named
)
717 CUMULATIVE_ARGS
*cum
; /* current arg information */
718 enum machine_mode mode
; /* current arg mode */
719 tree type
; /* type of the argument or 0 if lib support */
720 int named
; /* whether or not the argument was named */
723 = (mode
== BLKmode
) ? int_size_in_bytes (type
) : GET_MODE_SIZE (mode
);
724 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
726 if (TARGET_DEBUG_ARG
)
728 "function_adv (sz=%d, wds=%2d, nregs=%d, mode=%s, named=%d)\n\n",
729 words
, cum
->words
, cum
->nregs
, GET_MODE_NAME (mode
), named
);
744 /* Define where to put the arguments to a function.
745 Value is zero to push the argument on the stack,
746 or a hard register in which to store the argument.
748 MODE is the argument's machine mode.
749 TYPE is the data type of the argument (as a tree).
750 This is null for libcalls where that information may
752 CUM is a variable of type CUMULATIVE_ARGS which gives info about
753 the preceding args and about the function being called.
754 NAMED is nonzero if this argument is a named parameter
755 (otherwise it is an extra parameter matching an ellipsis). */
758 function_arg (cum
, mode
, type
, named
)
759 CUMULATIVE_ARGS
*cum
; /* current arg information */
760 enum machine_mode mode
; /* current arg mode */
761 tree type
; /* type of the argument or 0 if lib support */
762 int named
; /* != 0 for normal args, == 0 for ... args */
766 = (mode
== BLKmode
) ? int_size_in_bytes (type
) : GET_MODE_SIZE (mode
);
767 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
771 /* For now, pass fp/complex values on the stack. */
780 if (words
<= cum
->nregs
)
781 ret
= gen_rtx_REG (mode
, cum
->regno
);
785 if (TARGET_DEBUG_ARG
)
788 "function_arg (size=%d, wds=%2d, nregs=%d, mode=%4s, named=%d",
789 words
, cum
->words
, cum
->nregs
, GET_MODE_NAME (mode
), named
);
792 fprintf (stderr
, ", reg=%%e%s", reg_names
[ REGNO(ret
) ]);
794 fprintf (stderr
, ", stack");
796 fprintf (stderr
, " )\n");
802 /* For an arg passed partly in registers and partly in memory,
803 this is the number of registers used.
804 For args passed entirely in registers or entirely in memory, zero. */
807 function_arg_partial_nregs (cum
, mode
, type
, named
)
808 CUMULATIVE_ARGS
*cum ATTRIBUTE_UNUSED
; /* current arg information */
809 enum machine_mode mode ATTRIBUTE_UNUSED
; /* current arg mode */
810 tree type ATTRIBUTE_UNUSED
; /* type of the argument or 0 if lib support */
811 int named ATTRIBUTE_UNUSED
; /* != 0 for normal args, == 0 for ... args */
816 /* Output an insn whose source is a 386 integer register. SRC is the
817 rtx for the register, and TEMPLATE is the op-code template. SRC may
818 be either SImode or DImode.
820 The template will be output with operands[0] as SRC, and operands[1]
821 as a pointer to the top of the 386 stack. So a call from floatsidf2
822 would look like this:
824 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
826 where %z0 corresponds to the caller's operands[1], and is used to
827 emit the proper size suffix.
829 ??? Extend this to handle HImode - a 387 can load and store HImode
833 output_op_from_reg (src
, template)
838 int size
= GET_MODE_SIZE (GET_MODE (src
));
841 xops
[1] = AT_SP (Pmode
);
842 xops
[2] = GEN_INT (size
);
843 xops
[3] = stack_pointer_rtx
;
845 if (size
> UNITS_PER_WORD
)
849 if (size
> 2 * UNITS_PER_WORD
)
851 high
= gen_rtx_REG (SImode
, REGNO (src
) + 2);
852 output_asm_insn (AS1 (push
%L0
,%0), &high
);
855 high
= gen_rtx_REG (SImode
, REGNO (src
) + 1);
856 output_asm_insn (AS1 (push
%L0
,%0), &high
);
859 output_asm_insn (AS1 (push
%L0
,%0), &src
);
860 output_asm_insn (template, xops
);
861 output_asm_insn (AS2 (add
%L3
,%2,%3), xops
);
864 /* Output an insn to pop an value from the 387 top-of-stack to 386
865 register DEST. The 387 register stack is popped if DIES is true. If
866 the mode of DEST is an integer mode, a `fist' integer store is done,
867 otherwise a `fst' float store is done. */
870 output_to_reg (dest
, dies
, scratch_mem
)
876 int size
= GET_MODE_SIZE (GET_MODE (dest
));
879 xops
[0] = AT_SP (Pmode
);
881 xops
[0] = scratch_mem
;
883 xops
[1] = stack_pointer_rtx
;
884 xops
[2] = GEN_INT (size
);
888 output_asm_insn (AS2 (sub
%L1
,%2,%1), xops
);
890 if (GET_MODE_CLASS (GET_MODE (dest
)) == MODE_INT
)
893 output_asm_insn (AS1 (fistp
%z3
,%y0
), xops
);
895 output_asm_insn (AS1 (fist
%z3
,%y0
), xops
);
898 else if (GET_MODE_CLASS (GET_MODE (dest
)) == MODE_FLOAT
)
901 output_asm_insn (AS1 (fstp
%z3
,%y0
), xops
);
904 if (GET_MODE (dest
) == XFmode
)
906 output_asm_insn (AS1 (fstp
%z3
,%y0
), xops
);
907 output_asm_insn (AS1 (fld
%z3
,%y0
), xops
);
910 output_asm_insn (AS1 (fst
%z3
,%y0
), xops
);
918 output_asm_insn (AS1 (pop
%L0
,%0), &dest
);
920 output_asm_insn (AS2 (mov
%L0
,%0,%3), xops
);
923 if (size
> UNITS_PER_WORD
)
925 dest
= gen_rtx_REG (SImode
, REGNO (dest
) + 1);
927 output_asm_insn (AS1 (pop
%L0
,%0), &dest
);
930 xops
[0] = adj_offsettable_operand (xops
[0], 4);
932 output_asm_insn (AS2 (mov
%L0
,%0,%3), xops
);
935 if (size
> 2 * UNITS_PER_WORD
)
937 dest
= gen_rtx_REG (SImode
, REGNO (dest
) + 1);
939 output_asm_insn (AS1 (pop
%L0
,%0), &dest
);
942 xops
[0] = adj_offsettable_operand (xops
[0], 4);
943 output_asm_insn (AS2 (mov
%L0
,%0,%3), xops
);
950 singlemove_string (operands
)
954 if (GET_CODE (operands
[0]) == MEM
955 && GET_CODE (x
= XEXP (operands
[0], 0)) == PRE_DEC
)
957 if (XEXP (x
, 0) != stack_pointer_rtx
)
961 else if (GET_CODE (operands
[1]) == CONST_DOUBLE
)
962 return output_move_const_single (operands
);
963 else if (GET_CODE (operands
[0]) == REG
|| GET_CODE (operands
[1]) == REG
)
964 return AS2 (mov
%L0
,%1,%0);
965 else if (CONSTANT_P (operands
[1]))
966 return AS2 (mov
%L0
,%1,%0);
969 output_asm_insn ("push%L1 %1", operands
);
974 /* Return a REG that occurs in ADDR with coefficient 1.
975 ADDR can be effectively incremented by incrementing REG. */
981 while (GET_CODE (addr
) == PLUS
)
983 if (GET_CODE (XEXP (addr
, 0)) == REG
)
984 addr
= XEXP (addr
, 0);
985 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
986 addr
= XEXP (addr
, 1);
987 else if (CONSTANT_P (XEXP (addr
, 0)))
988 addr
= XEXP (addr
, 1);
989 else if (CONSTANT_P (XEXP (addr
, 1)))
990 addr
= XEXP (addr
, 0);
995 if (GET_CODE (addr
) == REG
)
1000 /* Output an insn to add the constant N to the register X. */
1011 output_asm_insn (AS1 (dec
%L0
,%0), xops
);
1013 output_asm_insn (AS1 (inc
%L0
,%0), xops
);
1014 else if (n
< 0 || n
== 128)
1016 xops
[1] = GEN_INT (-n
);
1017 output_asm_insn (AS2 (sub
%L0
,%1,%0), xops
);
1021 xops
[1] = GEN_INT (n
);
1022 output_asm_insn (AS2 (add
%L0
,%1,%0), xops
);
1026 /* Output assembler code to perform a doubleword move insn
1027 with operands OPERANDS. */
1030 output_move_double (operands
)
1033 enum {REGOP
, OFFSOP
, MEMOP
, PUSHOP
, POPOP
, CNSTOP
, RNDOP
} optype0
, optype1
;
1037 rtx addreg0
= 0, addreg1
= 0;
1038 int dest_overlapped_low
= 0;
1039 int size
= GET_MODE_SIZE (GET_MODE (operands
[0]));
1044 /* First classify both operands. */
1046 if (REG_P (operands
[0]))
1048 else if (offsettable_memref_p (operands
[0]))
1050 else if (GET_CODE (XEXP (operands
[0], 0)) == POST_INC
)
1052 else if (GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
)
1054 else if (GET_CODE (operands
[0]) == MEM
)
1059 if (REG_P (operands
[1]))
1061 else if (CONSTANT_P (operands
[1]))
1063 else if (offsettable_memref_p (operands
[1]))
1065 else if (GET_CODE (XEXP (operands
[1], 0)) == POST_INC
)
1067 else if (GET_CODE (XEXP (operands
[1], 0)) == PRE_DEC
)
1069 else if (GET_CODE (operands
[1]) == MEM
)
1074 /* Check for the cases that the operand constraints are not
1075 supposed to allow to happen. Abort if we get one,
1076 because generating code for these cases is painful. */
1078 if (optype0
== RNDOP
|| optype1
== RNDOP
)
1081 /* If one operand is decrementing and one is incrementing
1082 decrement the former register explicitly
1083 and change that operand into ordinary indexing. */
1085 if (optype0
== PUSHOP
&& optype1
== POPOP
)
1087 /* ??? Can this ever happen on i386? */
1088 operands
[0] = XEXP (XEXP (operands
[0], 0), 0);
1089 asm_add (-size
, operands
[0]);
1090 if (GET_MODE (operands
[1]) == XFmode
)
1091 operands
[0] = gen_rtx_MEM (XFmode
, operands
[0]);
1092 else if (GET_MODE (operands
[0]) == DFmode
)
1093 operands
[0] = gen_rtx_MEM (DFmode
, operands
[0]);
1095 operands
[0] = gen_rtx_MEM (DImode
, operands
[0]);
1099 if (optype0
== POPOP
&& optype1
== PUSHOP
)
1101 /* ??? Can this ever happen on i386? */
1102 operands
[1] = XEXP (XEXP (operands
[1], 0), 0);
1103 asm_add (-size
, operands
[1]);
1104 if (GET_MODE (operands
[1]) == XFmode
)
1105 operands
[1] = gen_rtx_MEM (XFmode
, operands
[1]);
1106 else if (GET_MODE (operands
[1]) == DFmode
)
1107 operands
[1] = gen_rtx_MEM (DFmode
, operands
[1]);
1109 operands
[1] = gen_rtx_MEM (DImode
, operands
[1]);
1113 /* If an operand is an unoffsettable memory ref, find a register
1114 we can increment temporarily to make it refer to the second word. */
1116 if (optype0
== MEMOP
)
1117 addreg0
= find_addr_reg (XEXP (operands
[0], 0));
1119 if (optype1
== MEMOP
)
1120 addreg1
= find_addr_reg (XEXP (operands
[1], 0));
1122 /* Ok, we can do one word at a time.
1123 Normally we do the low-numbered word first,
1124 but if either operand is autodecrementing then we
1125 do the high-numbered word first.
1127 In either case, set up in LATEHALF the operands to use
1128 for the high-numbered word and in some cases alter the
1129 operands in OPERANDS to be suitable for the low-numbered word. */
1133 if (optype0
== REGOP
)
1135 middlehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
1136 latehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 2);
1138 else if (optype0
== OFFSOP
)
1140 middlehalf
[0] = adj_offsettable_operand (operands
[0], 4);
1141 latehalf
[0] = adj_offsettable_operand (operands
[0], 8);
1145 middlehalf
[0] = operands
[0];
1146 latehalf
[0] = operands
[0];
1149 if (optype1
== REGOP
)
1151 middlehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 1);
1152 latehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 2);
1154 else if (optype1
== OFFSOP
)
1156 middlehalf
[1] = adj_offsettable_operand (operands
[1], 4);
1157 latehalf
[1] = adj_offsettable_operand (operands
[1], 8);
1159 else if (optype1
== CNSTOP
)
1161 if (GET_CODE (operands
[1]) == CONST_DOUBLE
)
1163 REAL_VALUE_TYPE r
; long l
[3];
1165 REAL_VALUE_FROM_CONST_DOUBLE (r
, operands
[1]);
1166 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r
, l
);
1167 operands
[1] = GEN_INT (l
[0]);
1168 middlehalf
[1] = GEN_INT (l
[1]);
1169 latehalf
[1] = GEN_INT (l
[2]);
1171 else if (CONSTANT_P (operands
[1]))
1172 /* No non-CONST_DOUBLE constant should ever appear here. */
1177 middlehalf
[1] = operands
[1];
1178 latehalf
[1] = operands
[1];
1184 /* Size is not 12. */
1186 if (optype0
== REGOP
)
1187 latehalf
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
1188 else if (optype0
== OFFSOP
)
1189 latehalf
[0] = adj_offsettable_operand (operands
[0], 4);
1191 latehalf
[0] = operands
[0];
1193 if (optype1
== REGOP
)
1194 latehalf
[1] = gen_rtx_REG (SImode
, REGNO (operands
[1]) + 1);
1195 else if (optype1
== OFFSOP
)
1196 latehalf
[1] = adj_offsettable_operand (operands
[1], 4);
1197 else if (optype1
== CNSTOP
)
1198 split_double (operands
[1], &operands
[1], &latehalf
[1]);
1200 latehalf
[1] = operands
[1];
1203 /* If insn is effectively movd N (sp),-(sp) then we will do the
1204 high word first. We should use the adjusted operand 1
1205 (which is N+4 (sp) or N+8 (sp))
1206 for the low word and middle word as well,
1207 to compensate for the first decrement of sp. */
1208 if (optype0
== PUSHOP
1209 && REGNO (XEXP (XEXP (operands
[0], 0), 0)) == STACK_POINTER_REGNUM
1210 && reg_overlap_mentioned_p (stack_pointer_rtx
, operands
[1]))
1211 middlehalf
[1] = operands
[1] = latehalf
[1];
1213 /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
1214 if the upper part of reg N does not appear in the MEM, arrange to
1215 emit the move late-half first. Otherwise, compute the MEM address
1216 into the upper part of N and use that as a pointer to the memory
1218 if (optype0
== REGOP
1219 && (optype1
== OFFSOP
|| optype1
== MEMOP
))
1221 if (reg_mentioned_p (operands
[0], XEXP (operands
[1], 0))
1222 && reg_mentioned_p (latehalf
[0], XEXP (operands
[1], 0)))
1224 /* If both halves of dest are used in the src memory address,
1225 compute the address into latehalf of dest. */
1227 xops
[0] = latehalf
[0];
1228 xops
[1] = XEXP (operands
[1], 0);
1229 output_asm_insn (AS2 (lea
%L0
,%a1
,%0), xops
);
1230 if (GET_MODE (operands
[1]) == XFmode
)
1232 operands
[1] = gen_rtx_MEM (XFmode
, latehalf
[0]);
1233 middlehalf
[1] = adj_offsettable_operand (operands
[1], size
-8);
1234 latehalf
[1] = adj_offsettable_operand (operands
[1], size
-4);
1238 operands
[1] = gen_rtx_MEM (DImode
, latehalf
[0]);
1239 latehalf
[1] = adj_offsettable_operand (operands
[1], size
-4);
1244 && reg_mentioned_p (middlehalf
[0], XEXP (operands
[1], 0)))
1246 /* Check for two regs used by both source and dest. */
1247 if (reg_mentioned_p (operands
[0], XEXP (operands
[1], 0))
1248 || reg_mentioned_p (latehalf
[0], XEXP (operands
[1], 0)))
1251 /* JRV says this can't happen: */
1252 if (addreg0
|| addreg1
)
1255 /* Only the middle reg conflicts; simply put it last. */
1256 output_asm_insn (singlemove_string (operands
), operands
);
1257 output_asm_insn (singlemove_string (latehalf
), latehalf
);
1258 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
1262 else if (reg_mentioned_p (operands
[0], XEXP (operands
[1], 0)))
1263 /* If the low half of dest is mentioned in the source memory
1264 address, the arrange to emit the move late half first. */
1265 dest_overlapped_low
= 1;
1268 /* If one or both operands autodecrementing,
1269 do the two words, high-numbered first. */
1271 /* Likewise, the first move would clobber the source of the second one,
1272 do them in the other order. This happens only for registers;
1273 such overlap can't happen in memory unless the user explicitly
1274 sets it up, and that is an undefined circumstance. */
1277 if (optype0
== PUSHOP
|| optype1
== PUSHOP
1278 || (optype0
== REGOP
&& optype1
== REGOP
1279 && REGNO (operands
[0]) == REGNO (latehalf
[1]))
1280 || dest_overlapped_low
)
1283 if (optype0
== PUSHOP
|| optype1
== PUSHOP
1284 || (optype0
== REGOP
&& optype1
== REGOP
1285 && ((middlehalf
[1] && REGNO (operands
[0]) == REGNO (middlehalf
[1]))
1286 || REGNO (operands
[0]) == REGNO (latehalf
[1])))
1287 || dest_overlapped_low
)
1289 /* Make any unoffsettable addresses point at high-numbered word. */
1291 asm_add (size
-4, addreg0
);
1293 asm_add (size
-4, addreg1
);
1296 output_asm_insn (singlemove_string (latehalf
), latehalf
);
1298 /* Undo the adds we just did. */
1300 asm_add (-4, addreg0
);
1302 asm_add (-4, addreg1
);
1306 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
1308 asm_add (-4, addreg0
);
1310 asm_add (-4, addreg1
);
1313 /* Do low-numbered word. */
1314 return singlemove_string (operands
);
1317 /* Normal case: do the two words, low-numbered first. */
1319 output_asm_insn (singlemove_string (operands
), operands
);
1321 /* Do the middle one of the three words for long double */
1325 asm_add (4, addreg0
);
1327 asm_add (4, addreg1
);
1329 output_asm_insn (singlemove_string (middlehalf
), middlehalf
);
1332 /* Make any unoffsettable addresses point at high-numbered word. */
1334 asm_add (4, addreg0
);
1336 asm_add (4, addreg1
);
1339 output_asm_insn (singlemove_string (latehalf
), latehalf
);
1341 /* Undo the adds we just did. */
1343 asm_add (4-size
, addreg0
);
1345 asm_add (4-size
, addreg1
);
1350 #define MAX_TMPS 2 /* max temporary registers used */
1352 /* Output the appropriate code to move push memory on the stack */
1355 output_move_pushmem (operands
, insn
, length
, tmp_start
, n_operands
)
1367 } tmp_info
[MAX_TMPS
];
1369 rtx src
= operands
[1];
1372 int stack_p
= reg_overlap_mentioned_p (stack_pointer_rtx
, src
);
1373 int stack_offset
= 0;
1377 if (! offsettable_memref_p (src
))
1378 fatal_insn ("Source is not offsettable", insn
);
1380 if ((length
& 3) != 0)
1381 fatal_insn ("Pushing non-word aligned size", insn
);
1383 /* Figure out which temporary registers we have available */
1384 for (i
= tmp_start
; i
< n_operands
; i
++)
1386 if (GET_CODE (operands
[i
]) == REG
)
1388 if (reg_overlap_mentioned_p (operands
[i
], src
))
1391 tmp_info
[ max_tmps
++ ].xops
[1] = operands
[i
];
1392 if (max_tmps
== MAX_TMPS
)
1398 for (offset
= length
- 4; offset
>= 0; offset
-= 4)
1400 xops
[0] = adj_offsettable_operand (src
, offset
+ stack_offset
);
1401 output_asm_insn (AS1(push
%L0
,%0), xops
);
1407 for (offset
= length
- 4; offset
>= 0; )
1409 for (num_tmps
= 0; num_tmps
< max_tmps
&& offset
>= 0; num_tmps
++)
1411 tmp_info
[num_tmps
].load
= AS2(mov
%L0
,%0,%1);
1412 tmp_info
[num_tmps
].push
= AS1(push
%L0
,%1);
1413 tmp_info
[num_tmps
].xops
[0]
1414 = adj_offsettable_operand (src
, offset
+ stack_offset
);
1418 for (i
= 0; i
< num_tmps
; i
++)
1419 output_asm_insn (tmp_info
[i
].load
, tmp_info
[i
].xops
);
1421 for (i
= 0; i
< num_tmps
; i
++)
1422 output_asm_insn (tmp_info
[i
].push
, tmp_info
[i
].xops
);
1425 stack_offset
+= 4*num_tmps
;
1431 /* Output the appropriate code to move data between two memory locations */
1434 output_move_memory (operands
, insn
, length
, tmp_start
, n_operands
)
1446 } tmp_info
[MAX_TMPS
];
1448 rtx dest
= operands
[0];
1449 rtx src
= operands
[1];
1450 rtx qi_tmp
= NULL_RTX
;
1456 if (GET_CODE (dest
) == MEM
1457 && GET_CODE (XEXP (dest
, 0)) == PRE_INC
1458 && XEXP (XEXP (dest
, 0), 0) == stack_pointer_rtx
)
1459 return output_move_pushmem (operands
, insn
, length
, tmp_start
, n_operands
);
1461 if (! offsettable_memref_p (src
))
1462 fatal_insn ("Source is not offsettable", insn
);
1464 if (! offsettable_memref_p (dest
))
1465 fatal_insn ("Destination is not offsettable", insn
);
1467 /* Figure out which temporary registers we have available */
1468 for (i
= tmp_start
; i
< n_operands
; i
++)
1470 if (GET_CODE (operands
[i
]) == REG
)
1472 if ((length
& 1) != 0 && qi_tmp
== 0 && QI_REG_P (operands
[i
]))
1473 qi_tmp
= operands
[i
];
1475 if (reg_overlap_mentioned_p (operands
[i
], dest
))
1476 fatal_insn ("Temporary register overlaps the destination", insn
);
1478 if (reg_overlap_mentioned_p (operands
[i
], src
))
1479 fatal_insn ("Temporary register overlaps the source", insn
);
1481 tmp_info
[max_tmps
++].xops
[2] = operands
[i
];
1482 if (max_tmps
== MAX_TMPS
)
1488 fatal_insn ("No scratch registers were found to do memory->memory moves",
1491 if ((length
& 1) != 0)
1494 fatal_insn ("No byte register found when moving odd # of bytes.",
1500 for (num_tmps
= 0; num_tmps
< max_tmps
; num_tmps
++)
1504 tmp_info
[num_tmps
].load
= AS2(mov
%L0
,%1,%2);
1505 tmp_info
[num_tmps
].store
= AS2(mov
%L0
,%2,%0);
1506 tmp_info
[num_tmps
].xops
[0]
1507 = adj_offsettable_operand (dest
, offset
);
1508 tmp_info
[num_tmps
].xops
[1]
1509 = adj_offsettable_operand (src
, offset
);
1515 else if (length
>= 2)
1517 tmp_info
[num_tmps
].load
= AS2(mov
%W0
,%1,%2);
1518 tmp_info
[num_tmps
].store
= AS2(mov
%W0
,%2,%0);
1519 tmp_info
[num_tmps
].xops
[0]
1520 = adj_offsettable_operand (dest
, offset
);
1521 tmp_info
[num_tmps
].xops
[1]
1522 = adj_offsettable_operand (src
, offset
);
1531 for (i
= 0; i
< num_tmps
; i
++)
1532 output_asm_insn (tmp_info
[i
].load
, tmp_info
[i
].xops
);
1534 for (i
= 0; i
< num_tmps
; i
++)
1535 output_asm_insn (tmp_info
[i
].store
, tmp_info
[i
].xops
);
1540 xops
[0] = adj_offsettable_operand (dest
, offset
);
1541 xops
[1] = adj_offsettable_operand (src
, offset
);
1543 output_asm_insn (AS2(mov
%B0
,%1,%2), xops
);
1544 output_asm_insn (AS2(mov
%B0
,%2,%0), xops
);
1551 standard_80387_constant_p (x
)
1554 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
1559 if (setjmp (handler
))
1562 set_float_handler (handler
);
1563 REAL_VALUE_FROM_CONST_DOUBLE (d
, x
);
1564 is0
= REAL_VALUES_EQUAL (d
, dconst0
) && !REAL_VALUE_MINUS_ZERO (d
);
1565 is1
= REAL_VALUES_EQUAL (d
, dconst1
);
1566 set_float_handler (NULL_PTR
);
1574 /* Note that on the 80387, other constants, such as pi,
1575 are much slower to load as standard constants
1576 than to load from doubles in memory! */
1583 output_move_const_single (operands
)
1586 if (FP_REG_P (operands
[0]))
1588 int conval
= standard_80387_constant_p (operands
[1]);
1597 if (GET_CODE (operands
[1]) == CONST_DOUBLE
)
1599 REAL_VALUE_TYPE r
; long l
;
1601 if (GET_MODE (operands
[1]) == XFmode
)
1604 REAL_VALUE_FROM_CONST_DOUBLE (r
, operands
[1]);
1605 REAL_VALUE_TO_TARGET_SINGLE (r
, l
);
1606 operands
[1] = GEN_INT (l
);
1609 return singlemove_string (operands
);
1612 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
1613 reference and a constant. */
1616 symbolic_operand (op
, mode
)
1618 enum machine_mode mode ATTRIBUTE_UNUSED
;
1620 switch (GET_CODE (op
))
1628 return ((GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
1629 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
)
1630 && GET_CODE (XEXP (op
, 1)) == CONST_INT
);
1637 /* Test for a valid operand for a call instruction.
1638 Don't allow the arg pointer register or virtual regs
1639 since they may change into reg + const, which the patterns
1640 can't handle yet. */
1643 call_insn_operand (op
, mode
)
1645 enum machine_mode mode ATTRIBUTE_UNUSED
;
1647 if (GET_CODE (op
) == MEM
1648 && ((CONSTANT_ADDRESS_P (XEXP (op
, 0))
1649 /* This makes a difference for PIC. */
1650 && general_operand (XEXP (op
, 0), Pmode
))
1651 || (GET_CODE (XEXP (op
, 0)) == REG
1652 && XEXP (op
, 0) != arg_pointer_rtx
1653 && ! (REGNO (XEXP (op
, 0)) >= FIRST_PSEUDO_REGISTER
1654 && REGNO (XEXP (op
, 0)) <= LAST_VIRTUAL_REGISTER
))))
1660 /* Like call_insn_operand but allow (mem (symbol_ref ...))
1664 expander_call_insn_operand (op
, mode
)
1666 enum machine_mode mode ATTRIBUTE_UNUSED
;
1668 if (GET_CODE (op
) == MEM
1669 && (CONSTANT_ADDRESS_P (XEXP (op
, 0))
1670 || (GET_CODE (XEXP (op
, 0)) == REG
1671 && XEXP (op
, 0) != arg_pointer_rtx
1672 && ! (REGNO (XEXP (op
, 0)) >= FIRST_PSEUDO_REGISTER
1673 && REGNO (XEXP (op
, 0)) <= LAST_VIRTUAL_REGISTER
))))
1679 /* Return 1 if OP is a comparison operator that can use the condition code
1680 generated by an arithmetic operation. */
1683 arithmetic_comparison_operator (op
, mode
)
1685 enum machine_mode mode
;
1689 if (mode
!= VOIDmode
&& mode
!= GET_MODE (op
))
1692 code
= GET_CODE (op
);
1693 if (GET_RTX_CLASS (code
) != '<')
1696 return (code
!= GT
&& code
!= LE
);
1700 ix86_logical_operator (op
, mode
)
1702 enum machine_mode mode ATTRIBUTE_UNUSED
;
1704 return GET_CODE (op
) == AND
|| GET_CODE (op
) == IOR
|| GET_CODE (op
) == XOR
;
1708 /* Returns 1 if OP contains a symbol reference */
1711 symbolic_reference_mentioned_p (op
)
1717 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
1720 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
1721 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
1727 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
1728 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
1732 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
1739 /* Attempt to expand a binary operator. Make the expansion closer to the
1740 actual machine, then just general_operand, which will allow 3 separate
1741 memory references (one output, two input) in a single insn. Return
1742 whether the insn fails, or succeeds. */
1745 ix86_expand_binary_operator (code
, mode
, operands
)
1747 enum machine_mode mode
;
1752 /* Recognize <var1> = <value> <op> <var1> for commutative operators */
1753 if (GET_RTX_CLASS (code
) == 'c'
1754 && (rtx_equal_p (operands
[0], operands
[2])
1755 || immediate_operand (operands
[1], mode
)))
1757 rtx temp
= operands
[1];
1758 operands
[1] = operands
[2];
1762 /* If optimizing, copy to regs to improve CSE */
1763 if (TARGET_PSEUDO
&& optimize
1764 && ((reload_in_progress
| reload_completed
) == 0))
1766 if (GET_CODE (operands
[1]) == MEM
1767 && ! rtx_equal_p (operands
[0], operands
[1]))
1768 operands
[1] = force_reg (GET_MODE (operands
[1]), operands
[1]);
1770 if (GET_CODE (operands
[2]) == MEM
)
1771 operands
[2] = force_reg (GET_MODE (operands
[2]), operands
[2]);
1773 if (GET_CODE (operands
[1]) == CONST_INT
&& code
== MINUS
)
1775 rtx temp
= gen_reg_rtx (GET_MODE (operands
[0]));
1777 emit_move_insn (temp
, operands
[1]);
1783 if (!ix86_binary_operator_ok (code
, mode
, operands
))
1785 /* If not optimizing, try to make a valid insn (optimize code
1786 previously did this above to improve chances of CSE) */
1788 if ((! TARGET_PSEUDO
|| !optimize
)
1789 && ((reload_in_progress
| reload_completed
) == 0)
1790 && (GET_CODE (operands
[1]) == MEM
|| GET_CODE (operands
[2]) == MEM
))
1793 if (GET_CODE (operands
[1]) == MEM
1794 && ! rtx_equal_p (operands
[0], operands
[1]))
1796 operands
[1] = force_reg (GET_MODE (operands
[1]), operands
[1]);
1800 if (GET_CODE (operands
[2]) == MEM
)
1802 operands
[2] = force_reg (GET_MODE (operands
[2]), operands
[2]);
1806 if (GET_CODE (operands
[1]) == CONST_INT
&& code
== MINUS
)
1808 rtx temp
= gen_reg_rtx (GET_MODE (operands
[0]));
1810 emit_move_insn (temp
, operands
[1]);
1815 if (modified
&& ! ix86_binary_operator_ok (code
, mode
, operands
))
1825 /* Return TRUE or FALSE depending on whether the binary operator meets the
1826 appropriate constraints. */
1829 ix86_binary_operator_ok (code
, mode
, operands
)
1831 enum machine_mode mode ATTRIBUTE_UNUSED
;
1834 return (GET_CODE (operands
[1]) != MEM
|| GET_CODE (operands
[2]) != MEM
)
1835 && (GET_CODE (operands
[1]) != CONST_INT
|| GET_RTX_CLASS (code
) == 'c');
1838 /* Attempt to expand a unary operator. Make the expansion closer to the
1839 actual machine, then just general_operand, which will allow 2 separate
1840 memory references (one output, one input) in a single insn. Return
1841 whether the insn fails, or succeeds. */
1844 ix86_expand_unary_operator (code
, mode
, operands
)
1846 enum machine_mode mode
;
1849 /* If optimizing, copy to regs to improve CSE */
1852 && ((reload_in_progress
| reload_completed
) == 0)
1853 && GET_CODE (operands
[1]) == MEM
)
1854 operands
[1] = force_reg (GET_MODE (operands
[1]), operands
[1]);
1856 if (! ix86_unary_operator_ok (code
, mode
, operands
))
1858 if ((! TARGET_PSEUDO
|| optimize
== 0)
1859 && ((reload_in_progress
| reload_completed
) == 0)
1860 && GET_CODE (operands
[1]) == MEM
)
1862 operands
[1] = force_reg (GET_MODE (operands
[1]), operands
[1]);
1863 if (! ix86_unary_operator_ok (code
, mode
, operands
))
1873 /* Return TRUE or FALSE depending on whether the unary operator meets the
1874 appropriate constraints. */
1877 ix86_unary_operator_ok (code
, mode
, operands
)
1878 enum rtx_code code ATTRIBUTE_UNUSED
;
1879 enum machine_mode mode ATTRIBUTE_UNUSED
;
1880 rtx operands
[2] ATTRIBUTE_UNUSED
;
1885 static rtx pic_label_rtx
;
1886 static char pic_label_name
[256];
1887 static int pic_label_no
= 0;
1889 /* This function generates code for -fpic that loads %ebx with
1890 the return address of the caller and then returns. */
1893 asm_output_function_prefix (file
, name
)
1895 char *name ATTRIBUTE_UNUSED
;
1898 int pic_reg_used
= flag_pic
&& (current_function_uses_pic_offset_table
1899 || current_function_uses_const_pool
);
1900 xops
[0] = pic_offset_table_rtx
;
1901 xops
[1] = stack_pointer_rtx
;
1903 /* Deep branch prediction favors having a return for every call. */
1904 if (pic_reg_used
&& TARGET_DEEP_BRANCH_PREDICTION
)
1908 if (pic_label_rtx
== 0)
1910 pic_label_rtx
= gen_label_rtx ();
1911 ASM_GENERATE_INTERNAL_LABEL (pic_label_name
, "LPR", pic_label_no
++);
1912 LABEL_NAME (pic_label_rtx
) = pic_label_name
;
1915 prologue_node
= make_node (FUNCTION_DECL
);
1916 DECL_RESULT (prologue_node
) = 0;
1917 #ifdef ASM_DECLARE_FUNCTION_NAME
1918 ASM_DECLARE_FUNCTION_NAME (file
, pic_label_name
, prologue_node
);
1920 output_asm_insn ("movl (%1),%0", xops
);
1921 output_asm_insn ("ret", xops
);
1925 /* Generate the assembly code for function entry.
1926 FILE is an stdio stream to output the code to.
1927 SIZE is an int: how many units of temporary storage to allocate. */
1930 function_prologue (file
, size
)
1931 FILE *file ATTRIBUTE_UNUSED
;
1932 int size ATTRIBUTE_UNUSED
;
1934 if (TARGET_SCHEDULE_PROLOGUE
)
1943 /* Expand the prologue into a bunch of separate insns. */
1946 ix86_expand_prologue ()
1948 if (! TARGET_SCHEDULE_PROLOGUE
)
1955 load_pic_register (do_rtl
)
1960 if (TARGET_DEEP_BRANCH_PREDICTION
)
1962 xops
[0] = pic_offset_table_rtx
;
1963 if (pic_label_rtx
== 0)
1965 pic_label_rtx
= gen_label_rtx ();
1966 ASM_GENERATE_INTERNAL_LABEL (pic_label_name
, "LPR", pic_label_no
++);
1967 LABEL_NAME (pic_label_rtx
) = pic_label_name
;
1970 xops
[1] = gen_rtx_MEM (QImode
,
1971 gen_rtx (SYMBOL_REF
, Pmode
,
1972 LABEL_NAME (pic_label_rtx
)));
1976 emit_insn (gen_prologue_get_pc (xops
[0], xops
[1]));
1977 emit_insn (gen_prologue_set_got (xops
[0],
1978 gen_rtx (SYMBOL_REF
, Pmode
,
1979 "$_GLOBAL_OFFSET_TABLE_"),
1984 output_asm_insn (AS1 (call
,%X1
), xops
);
1985 output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_,%0", xops
);
1992 xops
[0] = pic_offset_table_rtx
;
1993 xops
[1] = gen_label_rtx ();
1997 /* We can't put a raw CODE_LABEL into the RTL, and we can't emit
1998 a new CODE_LABEL after reload, so we need a single pattern to
1999 emit the 3 necessary instructions. */
2000 emit_insn (gen_prologue_get_pc_and_set_got (xops
[0]));
2004 output_asm_insn (AS1 (call
,%P1
), xops
);
2005 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
2006 CODE_LABEL_NUMBER (xops
[1]));
2007 output_asm_insn (AS1 (pop
%L0
,%0), xops
);
2008 output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops
);
2012 /* When -fpic, we must emit a scheduling barrier, so that the instruction
2013 that restores %ebx (which is PIC_OFFSET_TABLE_REGNUM), does not get
2014 moved before any instruction which implicitly uses the got. */
2017 emit_insn (gen_blockage ());
2021 ix86_prologue (do_rtl
)
2027 int pic_reg_used
= flag_pic
&& (current_function_uses_pic_offset_table
2028 || current_function_uses_const_pool
);
2029 long tsize
= get_frame_size ();
2031 int cfa_offset
= INCOMING_FRAME_SP_OFFSET
, cfa_store_offset
= cfa_offset
;
2033 xops
[0] = stack_pointer_rtx
;
2034 xops
[1] = frame_pointer_rtx
;
2035 xops
[2] = GEN_INT (tsize
);
2037 if (frame_pointer_needed
)
2041 insn
= emit_insn (gen_rtx (SET
, VOIDmode
,
2042 gen_rtx_MEM (SImode
,
2043 gen_rtx (PRE_DEC
, SImode
,
2044 stack_pointer_rtx
)),
2045 frame_pointer_rtx
));
2047 RTX_FRAME_RELATED_P (insn
) = 1;
2048 insn
= emit_move_insn (xops
[1], xops
[0]);
2049 RTX_FRAME_RELATED_P (insn
) = 1;
2054 output_asm_insn ("push%L1 %1", xops
);
2055 #ifdef INCOMING_RETURN_ADDR_RTX
2056 if (dwarf2out_do_frame ())
2058 char *l
= dwarf2out_cfi_label ();
2060 cfa_store_offset
+= 4;
2061 cfa_offset
= cfa_store_offset
;
2062 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
2063 dwarf2out_reg_save (l
, FRAME_POINTER_REGNUM
, - cfa_store_offset
);
2067 output_asm_insn (AS2 (mov
%L0
,%0,%1), xops
);
2068 #ifdef INCOMING_RETURN_ADDR_RTX
2069 if (dwarf2out_do_frame ())
2070 dwarf2out_def_cfa ("", FRAME_POINTER_REGNUM
, cfa_offset
);
2077 else if (! TARGET_STACK_PROBE
|| tsize
< CHECK_STACK_LIMIT
)
2081 insn
= emit_insn (gen_prologue_set_stack_ptr (xops
[2]));
2082 RTX_FRAME_RELATED_P (insn
) = 1;
2086 output_asm_insn (AS2 (sub
%L0
,%2,%0), xops
);
2087 #ifdef INCOMING_RETURN_ADDR_RTX
2088 if (dwarf2out_do_frame ())
2090 cfa_store_offset
+= tsize
;
2091 if (! frame_pointer_needed
)
2093 cfa_offset
= cfa_store_offset
;
2094 dwarf2out_def_cfa ("", STACK_POINTER_REGNUM
, cfa_offset
);
2102 xops
[3] = gen_rtx_REG (SImode
, 0);
2104 emit_move_insn (xops
[3], xops
[2]);
2106 output_asm_insn (AS2 (mov
%L0
,%2,%3), xops
);
2108 xops
[3] = gen_rtx_MEM (FUNCTION_MODE
,
2109 gen_rtx (SYMBOL_REF
, Pmode
, "_alloca"));
2112 emit_call_insn (gen_rtx (CALL
, VOIDmode
, xops
[3], const0_rtx
));
2114 output_asm_insn (AS1 (call
,%P3
), xops
);
2117 /* Note If use enter it is NOT reversed args.
2118 This one is not reversed from intel!!
2119 I think enter is slower. Also sdb doesn't like it.
2120 But if you want it the code is:
2122 xops[3] = const0_rtx;
2123 output_asm_insn ("enter %2,%3", xops);
2127 limit
= (frame_pointer_needed
? FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
);
2128 for (regno
= limit
- 1; regno
>= 0; regno
--)
2129 if ((regs_ever_live
[regno
] && ! call_used_regs
[regno
])
2130 || (regno
== PIC_OFFSET_TABLE_REGNUM
&& pic_reg_used
))
2132 xops
[0] = gen_rtx_REG (SImode
, regno
);
2135 insn
= emit_insn (gen_rtx (SET
, VOIDmode
,
2136 gen_rtx_MEM (SImode
,
2137 gen_rtx (PRE_DEC
, SImode
,
2138 stack_pointer_rtx
)),
2141 RTX_FRAME_RELATED_P (insn
) = 1;
2145 output_asm_insn ("push%L0 %0", xops
);
2146 #ifdef INCOMING_RETURN_ADDR_RTX
2147 if (dwarf2out_do_frame ())
2149 char *l
= dwarf2out_cfi_label ();
2151 cfa_store_offset
+= 4;
2152 if (! frame_pointer_needed
)
2154 cfa_offset
= cfa_store_offset
;
2155 dwarf2out_def_cfa (l
, STACK_POINTER_REGNUM
, cfa_offset
);
2158 dwarf2out_reg_save (l
, regno
, - cfa_store_offset
);
2165 load_pic_register (do_rtl
);
2167 /* If we are profiling, make sure no instructions are scheduled before
2168 the call to mcount. However, if -fpic, the above call will have
2170 if ((profile_flag
|| profile_block_flag
)
2171 && ! pic_reg_used
&& do_rtl
)
2172 emit_insn (gen_blockage ());
2175 /* Return 1 if it is appropriate to emit `ret' instructions in the
2176 body of a function. Do this only if the epilogue is simple, needing a
2177 couple of insns. Prior to reloading, we can't tell how many registers
2178 must be saved, so return 0 then. Return 0 if there is no frame
2179 marker to de-allocate.
2181 If NON_SAVING_SETJMP is defined and true, then it is not possible
2182 for the epilogue to be simple, so return 0. This is a special case
2183 since NON_SAVING_SETJMP will not cause regs_ever_live to change
2184 until final, but jump_optimize may need to know sooner if a
2188 ix86_can_use_return_insn_p ()
2192 int reglimit
= (frame_pointer_needed
2193 ? FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
);
2194 int pic_reg_used
= flag_pic
&& (current_function_uses_pic_offset_table
2195 || current_function_uses_const_pool
);
2197 #ifdef NON_SAVING_SETJMP
2198 if (NON_SAVING_SETJMP
&& current_function_calls_setjmp
)
2202 if (! reload_completed
)
2205 for (regno
= reglimit
- 1; regno
>= 0; regno
--)
2206 if ((regs_ever_live
[regno
] && ! call_used_regs
[regno
])
2207 || (regno
== PIC_OFFSET_TABLE_REGNUM
&& pic_reg_used
))
2210 return nregs
== 0 || ! frame_pointer_needed
;
2213 /* This function generates the assembly code for function exit.
2214 FILE is an stdio stream to output the code to.
2215 SIZE is an int: how many units of temporary storage to deallocate. */
2218 function_epilogue (file
, size
)
2219 FILE *file ATTRIBUTE_UNUSED
;
2220 int size ATTRIBUTE_UNUSED
;
2225 /* Restore function stack, frame, and registers. */
2228 ix86_expand_epilogue ()
2234 ix86_epilogue (do_rtl
)
2238 register int nregs
, limit
;
2241 int pic_reg_used
= flag_pic
&& (current_function_uses_pic_offset_table
2242 || current_function_uses_const_pool
);
2243 long tsize
= get_frame_size ();
2245 /* Compute the number of registers to pop */
2247 limit
= (frame_pointer_needed
? FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
);
2251 for (regno
= limit
- 1; regno
>= 0; regno
--)
2252 if ((regs_ever_live
[regno
] && ! call_used_regs
[regno
])
2253 || (regno
== PIC_OFFSET_TABLE_REGNUM
&& pic_reg_used
))
2256 /* sp is often unreliable so we must go off the frame pointer.
2258 In reality, we may not care if sp is unreliable, because we can restore
2259 the register relative to the frame pointer. In theory, since each move
2260 is the same speed as a pop, and we don't need the leal, this is faster.
2261 For now restore multiple registers the old way. */
2263 offset
= - tsize
- (nregs
* UNITS_PER_WORD
);
2265 xops
[2] = stack_pointer_rtx
;
2267 /* When -fpic, we must emit a scheduling barrier, so that the instruction
2268 that restores %ebx (which is PIC_OFFSET_TABLE_REGNUM), does not get
2269 moved before any instruction which implicitly uses the got. This
2270 includes any instruction which uses a SYMBOL_REF or a LABEL_REF.
2272 Alternatively, this could be fixed by making the dependence on the
2273 PIC_OFFSET_TABLE_REGNUM explicit in the RTL. */
2275 if (flag_pic
|| profile_flag
|| profile_block_flag
)
2276 emit_insn (gen_blockage ());
2278 if (nregs
> 1 || ! frame_pointer_needed
)
2280 if (frame_pointer_needed
)
2282 xops
[0] = adj_offsettable_operand (AT_BP (QImode
), offset
);
2284 emit_insn (gen_movsi_lea (xops
[2], XEXP (xops
[0], 0)));
2286 output_asm_insn (AS2 (lea
%L2
,%0,%2), xops
);
2289 for (regno
= 0; regno
< limit
; regno
++)
2290 if ((regs_ever_live
[regno
] && ! call_used_regs
[regno
])
2291 || (regno
== PIC_OFFSET_TABLE_REGNUM
&& pic_reg_used
))
2293 xops
[0] = gen_rtx_REG (SImode
, regno
);
2296 emit_insn (gen_pop (xops
[0]));
2298 output_asm_insn ("pop%L0 %0", xops
);
2303 for (regno
= 0; regno
< limit
; regno
++)
2304 if ((regs_ever_live
[regno
] && ! call_used_regs
[regno
])
2305 || (regno
== PIC_OFFSET_TABLE_REGNUM
&& pic_reg_used
))
2307 xops
[0] = gen_rtx_REG (SImode
, regno
);
2308 xops
[1] = adj_offsettable_operand (AT_BP (Pmode
), offset
);
2311 emit_move_insn (xops
[0], xops
[1]);
2313 output_asm_insn (AS2 (mov
%L0
,%1,%0), xops
);
2318 if (frame_pointer_needed
)
2320 /* If not an i386, mov & pop is faster than "leave". */
2322 if (TARGET_USE_LEAVE
)
2325 emit_insn (gen_leave());
2327 output_asm_insn ("leave", xops
);
2331 xops
[0] = frame_pointer_rtx
;
2332 xops
[1] = stack_pointer_rtx
;
2336 emit_insn (gen_epilogue_set_stack_ptr());
2337 emit_insn (gen_pop (xops
[0]));
2341 output_asm_insn (AS2 (mov
%L2
,%0,%2), xops
);
2342 output_asm_insn ("pop%L0 %0", xops
);
2349 /* If there is no frame pointer, we must still release the frame. */
2350 xops
[0] = GEN_INT (tsize
);
2353 emit_insn (gen_rtx (SET
, VOIDmode
, xops
[2],
2354 gen_rtx (PLUS
, SImode
, xops
[2], xops
[0])));
2356 output_asm_insn (AS2 (add
%L2
,%0,%2), xops
);
2359 #ifdef FUNCTION_BLOCK_PROFILER_EXIT
2360 if (profile_block_flag
== 2)
2362 FUNCTION_BLOCK_PROFILER_EXIT(file
);
2366 if (current_function_pops_args
&& current_function_args_size
)
2368 xops
[1] = GEN_INT (current_function_pops_args
);
2370 /* i386 can only pop 32K bytes (maybe 64K? Is it signed?). If
2371 asked to pop more, pop return address, do explicit add, and jump
2372 indirectly to the caller. */
2374 if (current_function_pops_args
>= 32768)
2376 /* ??? Which register to use here? */
2377 xops
[0] = gen_rtx_REG (SImode
, 2);
2381 emit_insn (gen_pop (xops
[0]));
2382 emit_insn (gen_rtx (SET
, VOIDmode
, xops
[2],
2383 gen_rtx (PLUS
, SImode
, xops
[1], xops
[2])));
2384 emit_jump_insn (xops
[0]);
2388 output_asm_insn ("pop%L0 %0", xops
);
2389 output_asm_insn (AS2 (add
%L2
,%1,%2), xops
);
2390 output_asm_insn ("jmp %*%0", xops
);
2396 emit_jump_insn (gen_return_pop_internal (xops
[1]));
2398 output_asm_insn ("ret %1", xops
);
2404 emit_jump_insn (gen_return_internal ());
2406 output_asm_insn ("ret", xops
);
2410 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
2411 that is a valid memory address for an instruction.
2412 The MODE argument is the machine mode for the MEM expression
2413 that wants to use this address.
2415 On x86, legitimate addresses are:
2416 base movl (base),reg
2417 displacement movl disp,reg
2418 base + displacement movl disp(base),reg
2419 index + base movl (base,index),reg
2420 (index + base) + displacement movl disp(base,index),reg
2421 index*scale movl (,index,scale),reg
2422 index*scale + disp movl disp(,index,scale),reg
2423 index*scale + base movl (base,index,scale),reg
2424 (index*scale + base) + disp movl disp(base,index,scale),reg
2426 In each case, scale can be 1, 2, 4, 8. */
2428 /* This is exactly the same as print_operand_addr, except that
2429 it recognizes addresses instead of printing them.
2431 It only recognizes address in canonical form. LEGITIMIZE_ADDRESS should
2432 convert common non-canonical forms to canonical form so that they will
2435 #define ADDR_INVALID(msg,insn) \
2437 if (TARGET_DEBUG_ADDR) \
2439 fprintf (stderr, msg); \
2445 legitimate_address_p (mode
, addr
, strict
)
2446 enum machine_mode mode
;
2450 rtx base
= NULL_RTX
;
2451 rtx indx
= NULL_RTX
;
2452 rtx scale
= NULL_RTX
;
2453 rtx disp
= NULL_RTX
;
2455 if (TARGET_DEBUG_ADDR
)
2458 "\n======\nGO_IF_LEGITIMATE_ADDRESS, mode = %s, strict = %d\n",
2459 GET_MODE_NAME (mode
), strict
);
2464 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == SUBREG
)
2467 else if (GET_CODE (addr
) == PLUS
)
2469 rtx op0
= XEXP (addr
, 0);
2470 rtx op1
= XEXP (addr
, 1);
2471 enum rtx_code code0
= GET_CODE (op0
);
2472 enum rtx_code code1
= GET_CODE (op1
);
2474 if (code0
== REG
|| code0
== SUBREG
)
2476 if (code1
== REG
|| code1
== SUBREG
)
2478 indx
= op0
; /* index + base */
2484 base
= op0
; /* base + displacement */
2489 else if (code0
== MULT
)
2491 indx
= XEXP (op0
, 0);
2492 scale
= XEXP (op0
, 1);
2494 if (code1
== REG
|| code1
== SUBREG
)
2495 base
= op1
; /* index*scale + base */
2498 disp
= op1
; /* index*scale + disp */
2501 else if (code0
== PLUS
&& GET_CODE (XEXP (op0
, 0)) == MULT
)
2503 indx
= XEXP (XEXP (op0
, 0), 0); /* index*scale + base + disp */
2504 scale
= XEXP (XEXP (op0
, 0), 1);
2505 base
= XEXP (op0
, 1);
2509 else if (code0
== PLUS
)
2511 indx
= XEXP (op0
, 0); /* index + base + disp */
2512 base
= XEXP (op0
, 1);
2518 ADDR_INVALID ("PLUS subcode is not valid.\n", op0
);
2523 else if (GET_CODE (addr
) == MULT
)
2525 indx
= XEXP (addr
, 0); /* index*scale */
2526 scale
= XEXP (addr
, 1);
2530 disp
= addr
; /* displacement */
2532 /* Allow arg pointer and stack pointer as index if there is not scaling */
2533 if (base
&& indx
&& !scale
2534 && (indx
== arg_pointer_rtx
|| indx
== stack_pointer_rtx
))
2541 /* Validate base register:
2543 Don't allow SUBREG's here, it can lead to spill failures when the base
2544 is one word out of a two word structure, which is represented internally
2549 if (GET_CODE (base
) != REG
)
2551 ADDR_INVALID ("Base is not a register.\n", base
);
2555 if ((strict
&& ! REG_OK_FOR_BASE_STRICT_P (base
))
2556 || (! strict
&& ! REG_OK_FOR_BASE_NONSTRICT_P (base
)))
2558 ADDR_INVALID ("Base is not valid.\n", base
);
2563 /* Validate index register:
2565 Don't allow SUBREG's here, it can lead to spill failures when the index
2566 is one word out of a two word structure, which is represented internally
2570 if (GET_CODE (indx
) != REG
)
2572 ADDR_INVALID ("Index is not a register.\n", indx
);
2576 if ((strict
&& ! REG_OK_FOR_INDEX_STRICT_P (indx
))
2577 || (! strict
&& ! REG_OK_FOR_INDEX_NONSTRICT_P (indx
)))
2579 ADDR_INVALID ("Index is not valid.\n", indx
);
2584 abort (); /* scale w/o index invalid */
2586 /* Validate scale factor: */
2589 HOST_WIDE_INT value
;
2591 if (GET_CODE (scale
) != CONST_INT
)
2593 ADDR_INVALID ("Scale is not valid.\n", scale
);
2597 value
= INTVAL (scale
);
2598 if (value
!= 1 && value
!= 2 && value
!= 4 && value
!= 8)
2600 ADDR_INVALID ("Scale is not a good multiplier.\n", scale
);
2605 /* Validate displacement
2606 Constant pool addresses must be handled special. They are
2607 considered legitimate addresses, but only if not used with regs.
2608 When printed, the output routines know to print the reference with the
2609 PIC reg, even though the PIC reg doesn't appear in the RTL. */
2612 if (GET_CODE (disp
) == SYMBOL_REF
2613 && CONSTANT_POOL_ADDRESS_P (disp
)
2618 else if (!CONSTANT_ADDRESS_P (disp
))
2620 ADDR_INVALID ("Displacement is not valid.\n", disp
);
2624 else if (GET_CODE (disp
) == CONST_DOUBLE
)
2626 ADDR_INVALID ("Displacement is a const_double.\n", disp
);
2630 else if (flag_pic
&& SYMBOLIC_CONST (disp
)
2631 && base
!= pic_offset_table_rtx
2632 && (indx
!= pic_offset_table_rtx
|| scale
!= NULL_RTX
))
2634 ADDR_INVALID ("Displacement is an invalid pic reference.\n", disp
);
2638 else if (HALF_PIC_P () && HALF_PIC_ADDRESS_P (disp
)
2639 && (base
!= NULL_RTX
|| indx
!= NULL_RTX
))
2641 ADDR_INVALID ("Displacement is an invalid half-pic reference.\n",
2647 if (TARGET_DEBUG_ADDR
)
2648 fprintf (stderr
, "Address is valid.\n");
2650 /* Everything looks valid, return true */
2654 /* Return a legitimate reference for ORIG (an address) using the
2655 register REG. If REG is 0, a new pseudo is generated.
2657 There are three types of references that must be handled:
2659 1. Global data references must load the address from the GOT, via
2660 the PIC reg. An insn is emitted to do this load, and the reg is
2663 2. Static data references must compute the address as an offset
2664 from the GOT, whose base is in the PIC reg. An insn is emitted to
2665 compute the address into a reg, and the reg is returned. Static
2666 data objects have SYMBOL_REF_FLAG set to differentiate them from
2667 global data objects.
2669 3. Constant pool addresses must be handled special. They are
2670 considered legitimate addresses, but only if not used with regs.
2671 When printed, the output routines know to print the reference with the
2672 PIC reg, even though the PIC reg doesn't appear in the RTL.
2674 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2675 reg also appears in the address (except for constant pool references,
2678 "switch" statements also require special handling when generating
2679 PIC code. See comments by the `casesi' insn in i386.md for details. */
2682 legitimize_pic_address (orig
, reg
)
2689 if (GET_CODE (addr
) == SYMBOL_REF
|| GET_CODE (addr
) == LABEL_REF
)
2691 if (GET_CODE (addr
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (addr
))
2696 reg
= gen_reg_rtx (Pmode
);
2698 if ((GET_CODE (addr
) == SYMBOL_REF
&& SYMBOL_REF_FLAG (addr
))
2699 || GET_CODE (addr
) == LABEL_REF
)
2700 new = gen_rtx (PLUS
, Pmode
, pic_offset_table_rtx
, orig
);
2702 new = gen_rtx_MEM (Pmode
,
2703 gen_rtx (PLUS
, Pmode
, pic_offset_table_rtx
, orig
));
2705 emit_move_insn (reg
, new);
2707 current_function_uses_pic_offset_table
= 1;
2711 else if (GET_CODE (addr
) == CONST
|| GET_CODE (addr
) == PLUS
)
2715 if (GET_CODE (addr
) == CONST
)
2717 addr
= XEXP (addr
, 0);
2718 if (GET_CODE (addr
) != PLUS
)
2722 if (XEXP (addr
, 0) == pic_offset_table_rtx
)
2726 reg
= gen_reg_rtx (Pmode
);
2728 base
= legitimize_pic_address (XEXP (addr
, 0), reg
);
2729 addr
= legitimize_pic_address (XEXP (addr
, 1),
2730 base
== reg
? NULL_RTX
: reg
);
2732 if (GET_CODE (addr
) == CONST_INT
)
2733 return plus_constant (base
, INTVAL (addr
));
2735 if (GET_CODE (addr
) == PLUS
&& CONSTANT_P (XEXP (addr
, 1)))
2737 base
= gen_rtx (PLUS
, Pmode
, base
, XEXP (addr
, 0));
2738 addr
= XEXP (addr
, 1);
2741 return gen_rtx (PLUS
, Pmode
, base
, addr
);
2746 /* Emit insns to move operands[1] into operands[0]. */
2749 emit_pic_move (operands
, mode
)
2751 enum machine_mode mode ATTRIBUTE_UNUSED
;
2753 rtx temp
= reload_in_progress
? operands
[0] : gen_reg_rtx (Pmode
);
2755 if (GET_CODE (operands
[0]) == MEM
&& SYMBOLIC_CONST (operands
[1]))
2756 operands
[1] = force_reg (SImode
, operands
[1]);
2758 operands
[1] = legitimize_pic_address (operands
[1], temp
);
2761 /* Try machine-dependent ways of modifying an illegitimate address
2762 to be legitimate. If we find one, return the new, valid address.
2763 This macro is used in only one place: `memory_address' in explow.c.
2765 OLDX is the address as it was before break_out_memory_refs was called.
2766 In some cases it is useful to look at this to decide what needs to be done.
2768 MODE and WIN are passed so that this macro can use
2769 GO_IF_LEGITIMATE_ADDRESS.
2771 It is always safe for this macro to do nothing. It exists to recognize
2772 opportunities to optimize the output.
2774 For the 80386, we handle X+REG by loading X into a register R and
2775 using R+REG. R will go in a general reg and indexing will be used.
2776 However, if REG is a broken-out memory address or multiplication,
2777 nothing needs to be done because REG can certainly go in a general reg.
2779 When -fpic is used, special handling is needed for symbolic references.
2780 See comments by legitimize_pic_address in i386.c for details. */
2783 legitimize_address (x
, oldx
, mode
)
2785 register rtx oldx ATTRIBUTE_UNUSED
;
2786 enum machine_mode mode
;
2791 if (TARGET_DEBUG_ADDR
)
2793 fprintf (stderr
, "\n==========\nLEGITIMIZE_ADDRESS, mode = %s\n",
2794 GET_MODE_NAME (mode
));
2798 if (flag_pic
&& SYMBOLIC_CONST (x
))
2799 return legitimize_pic_address (x
, 0);
2801 /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
2802 if (GET_CODE (x
) == ASHIFT
2803 && GET_CODE (XEXP (x
, 1)) == CONST_INT
2804 && (log
= (unsigned)exact_log2 (INTVAL (XEXP (x
, 1)))) < 4)
2807 x
= gen_rtx (MULT
, Pmode
, force_reg (Pmode
, XEXP (x
, 0)),
2808 GEN_INT (1 << log
));
2811 if (GET_CODE (x
) == PLUS
)
2813 /* Canonicalize shifts by 0, 1, 2, 3 into multiply. */
2815 if (GET_CODE (XEXP (x
, 0)) == ASHIFT
2816 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
2817 && (log
= (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x
, 0), 1)))) < 4)
2820 XEXP (x
, 0) = gen_rtx (MULT
, Pmode
,
2821 force_reg (Pmode
, XEXP (XEXP (x
, 0), 0)),
2822 GEN_INT (1 << log
));
2825 if (GET_CODE (XEXP (x
, 1)) == ASHIFT
2826 && GET_CODE (XEXP (XEXP (x
, 1), 1)) == CONST_INT
2827 && (log
= (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x
, 1), 1)))) < 4)
2830 XEXP (x
, 1) = gen_rtx (MULT
, Pmode
,
2831 force_reg (Pmode
, XEXP (XEXP (x
, 1), 0)),
2832 GEN_INT (1 << log
));
2835 /* Put multiply first if it isn't already. */
2836 if (GET_CODE (XEXP (x
, 1)) == MULT
)
2838 rtx tmp
= XEXP (x
, 0);
2839 XEXP (x
, 0) = XEXP (x
, 1);
2844 /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
2845 into (plus (plus (mult (reg) (const)) (reg)) (const)). This can be
2846 created by virtual register instantiation, register elimination, and
2847 similar optimizations. */
2848 if (GET_CODE (XEXP (x
, 0)) == MULT
&& GET_CODE (XEXP (x
, 1)) == PLUS
)
2851 x
= gen_rtx (PLUS
, Pmode
,
2852 gen_rtx (PLUS
, Pmode
, XEXP (x
, 0),
2853 XEXP (XEXP (x
, 1), 0)),
2854 XEXP (XEXP (x
, 1), 1));
2858 (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
2859 into (plus (plus (mult (reg) (const)) (reg)) (const)). */
2860 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 0)) == PLUS
2861 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == MULT
2862 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == PLUS
2863 && CONSTANT_P (XEXP (x
, 1)))
2866 rtx other
= NULL_RTX
;
2868 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
2870 constant
= XEXP (x
, 1);
2871 other
= XEXP (XEXP (XEXP (x
, 0), 1), 1);
2873 else if (GET_CODE (XEXP (XEXP (XEXP (x
, 0), 1), 1)) == CONST_INT
)
2875 constant
= XEXP (XEXP (XEXP (x
, 0), 1), 1);
2876 other
= XEXP (x
, 1);
2884 x
= gen_rtx (PLUS
, Pmode
,
2885 gen_rtx (PLUS
, Pmode
, XEXP (XEXP (x
, 0), 0),
2886 XEXP (XEXP (XEXP (x
, 0), 1), 0)),
2887 plus_constant (other
, INTVAL (constant
)));
2891 if (changed
&& legitimate_address_p (mode
, x
, FALSE
))
2894 if (GET_CODE (XEXP (x
, 0)) == MULT
)
2897 XEXP (x
, 0) = force_operand (XEXP (x
, 0), 0);
2900 if (GET_CODE (XEXP (x
, 1)) == MULT
)
2903 XEXP (x
, 1) = force_operand (XEXP (x
, 1), 0);
2907 && GET_CODE (XEXP (x
, 1)) == REG
2908 && GET_CODE (XEXP (x
, 0)) == REG
)
2911 if (flag_pic
&& SYMBOLIC_CONST (XEXP (x
, 1)))
2914 x
= legitimize_pic_address (x
, 0);
2917 if (changed
&& legitimate_address_p (mode
, x
, FALSE
))
2920 if (GET_CODE (XEXP (x
, 0)) == REG
)
2922 register rtx temp
= gen_reg_rtx (Pmode
);
2923 register rtx val
= force_operand (XEXP (x
, 1), temp
);
2925 emit_move_insn (temp
, val
);
2931 else if (GET_CODE (XEXP (x
, 1)) == REG
)
2933 register rtx temp
= gen_reg_rtx (Pmode
);
2934 register rtx val
= force_operand (XEXP (x
, 0), temp
);
2936 emit_move_insn (temp
, val
);
2946 /* Print an integer constant expression in assembler syntax. Addition
2947 and subtraction are the only arithmetic that may appear in these
2948 expressions. FILE is the stdio stream to write to, X is the rtx, and
2949 CODE is the operand print code from the output string. */
2952 output_pic_addr_const (file
, x
, code
)
2959 switch (GET_CODE (x
))
2970 if (GET_CODE (x
) == SYMBOL_REF
)
2971 assemble_name (file
, XSTR (x
, 0));
2974 ASM_GENERATE_INTERNAL_LABEL (buf
, "L",
2975 CODE_LABEL_NUMBER (XEXP (x
, 0)));
2976 assemble_name (asm_out_file
, buf
);
2980 ; /* No suffix, dammit. */
2981 else if (GET_CODE (x
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (x
))
2982 fprintf (file
, "@GOTOFF(%%ebx)");
2983 else if (code
== 'P')
2984 fprintf (file
, "@PLT");
2985 else if (GET_CODE (x
) == LABEL_REF
)
2986 fprintf (file
, "@GOTOFF");
2987 else if (! SYMBOL_REF_FLAG (x
))
2988 fprintf (file
, "@GOT");
2990 fprintf (file
, "@GOTOFF");
2995 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (x
));
2996 assemble_name (asm_out_file
, buf
);
3000 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
3004 /* This used to output parentheses around the expression,
3005 but that does not work on the 386 (either ATT or BSD assembler). */
3006 output_pic_addr_const (file
, XEXP (x
, 0), code
);
3010 if (GET_MODE (x
) == VOIDmode
)
3012 /* We can use %d if the number is <32 bits and positive. */
3013 if (CONST_DOUBLE_HIGH (x
) || CONST_DOUBLE_LOW (x
) < 0)
3014 fprintf (file
, "0x%lx%08lx",
3015 (unsigned long) CONST_DOUBLE_HIGH (x
),
3016 (unsigned long) CONST_DOUBLE_LOW (x
));
3018 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
));
3021 /* We can't handle floating point constants;
3022 PRINT_OPERAND must handle them. */
3023 output_operand_lossage ("floating constant misused");
3027 /* Some assemblers need integer constants to appear first. */
3028 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
3030 output_pic_addr_const (file
, XEXP (x
, 0), code
);
3031 if (INTVAL (XEXP (x
, 1)) >= 0)
3032 fprintf (file
, "+");
3033 output_pic_addr_const (file
, XEXP (x
, 1), code
);
3037 output_pic_addr_const (file
, XEXP (x
, 1), code
);
3038 if (INTVAL (XEXP (x
, 0)) >= 0)
3039 fprintf (file
, "+");
3040 output_pic_addr_const (file
, XEXP (x
, 0), code
);
3045 output_pic_addr_const (file
, XEXP (x
, 0), code
);
3046 fprintf (file
, "-");
3047 output_pic_addr_const (file
, XEXP (x
, 1), code
);
3051 output_operand_lossage ("invalid expression as operand");
3055 /* Append the correct conditional move suffix which corresponds to CODE. */
3058 put_condition_code (code
, reverse_cc
, mode
, file
)
3061 enum mode_class mode
;
3064 int ieee
= (TARGET_IEEE_FP
&& (cc_prev_status
.flags
& CC_IN_80387
)
3065 && ! (cc_prev_status
.flags
& CC_FCOMI
));
3066 if (reverse_cc
&& ! ieee
)
3067 code
= reverse_condition (code
);
3069 if (mode
== MODE_INT
)
3073 if (cc_prev_status
.flags
& CC_Z_IN_NOT_C
)
3080 if (cc_prev_status
.flags
& CC_Z_IN_NOT_C
)
3087 if (cc_prev_status
.flags
& CC_NO_OVERFLOW
)
3102 if (cc_prev_status
.flags
& CC_NO_OVERFLOW
)
3125 output_operand_lossage ("Invalid %%C operand");
3128 else if (mode
== MODE_FLOAT
)
3132 fputs (ieee
? (reverse_cc
? "ne" : "e") : "ne", file
);
3135 fputs (ieee
? (reverse_cc
? "ne" : "e") : "e", file
);
3138 fputs (ieee
? (reverse_cc
? "ne" : "e") : "nb", file
);
3141 fputs (ieee
? (reverse_cc
? "ne" : "e") : "nbe", file
);
3144 fputs (ieee
? (reverse_cc
? "nb" : "b") : "be", file
);
3147 fputs (ieee
? (reverse_cc
? "ne" : "e") : "b", file
);
3150 fputs (ieee
? (reverse_cc
? "ne" : "e") : "nb", file
);
3153 fputs (ieee
? (reverse_cc
? "ne" : "e") : "nbe", file
);
3156 fputs (ieee
? (reverse_cc
? "nb" : "b") : "be", file
);
3159 fputs (ieee
? (reverse_cc
? "ne" : "e") : "b", file
);
3162 output_operand_lossage ("Invalid %%C operand");
3167 L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
3168 C -- print opcode suffix for set/cmov insn.
3169 c -- like C, but print reversed condition
3170 F -- print opcode suffix for fcmov insn.
3171 f -- like C, but print reversed condition
3172 R -- print the prefix for register names.
3173 z -- print the opcode suffix for the size of the current operand.
3174 * -- print a star (in certain assembler syntax)
3175 w -- print the operand as if it's a "word" (HImode) even if it isn't.
3176 c -- don't print special prefixes before constant operands.
3177 J -- print the appropriate jump operand.
3178 s -- print a shift double count, followed by the assemblers argument
3180 b -- print the QImode name of the register for the indicated operand.
3181 %b0 would print %al if operands[0] is reg 0.
3182 w -- likewise, print the HImode name of the register.
3183 k -- likewise, print the SImode name of the register.
3184 h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
3185 y -- print "st(0)" instead of "st" as a register.
3186 P -- print as a PIC constant */
3189 print_operand (file
, x
, code
)
3204 PUT_OP_SIZE (code
, 'l', file
);
3208 PUT_OP_SIZE (code
, 'w', file
);
3212 PUT_OP_SIZE (code
, 'b', file
);
3216 PUT_OP_SIZE (code
, 'l', file
);
3220 PUT_OP_SIZE (code
, 's', file
);
3224 PUT_OP_SIZE (code
, 't', file
);
3228 /* 387 opcodes don't get size suffixes if the operands are
3231 if (STACK_REG_P (x
))
3234 /* this is the size of op from size of operand */
3235 switch (GET_MODE_SIZE (GET_MODE (x
)))
3238 PUT_OP_SIZE ('B', 'b', file
);
3242 PUT_OP_SIZE ('W', 'w', file
);
3246 if (GET_MODE (x
) == SFmode
)
3248 PUT_OP_SIZE ('S', 's', file
);
3252 PUT_OP_SIZE ('L', 'l', file
);
3256 PUT_OP_SIZE ('T', 't', file
);
3260 if (GET_MODE_CLASS (GET_MODE (x
)) == MODE_INT
)
3262 #ifdef GAS_MNEMONICS
3263 PUT_OP_SIZE ('Q', 'q', file
);
3266 PUT_OP_SIZE ('Q', 'l', file
); /* Fall through */
3270 PUT_OP_SIZE ('Q', 'l', file
);
3284 switch (GET_CODE (x
))
3286 /* These conditions are appropriate for testing the result
3287 of an arithmetic operation, not for a compare operation.
3288 Cases GE, LT assume CC_NO_OVERFLOW true. All cases assume
3289 CC_Z_IN_NOT_C false and not floating point. */
3290 case NE
: fputs ("jne", file
); return;
3291 case EQ
: fputs ("je", file
); return;
3292 case GE
: fputs ("jns", file
); return;
3293 case LT
: fputs ("js", file
); return;
3294 case GEU
: fputs ("jmp", file
); return;
3295 case GTU
: fputs ("jne", file
); return;
3296 case LEU
: fputs ("je", file
); return;
3297 case LTU
: fputs ("#branch never", file
); return;
3299 /* no matching branches for GT nor LE */
3306 if (GET_CODE (x
) == CONST_INT
|| ! SHIFT_DOUBLE_OMITS_COUNT
)
3308 PRINT_OPERAND (file
, x
, 0);
3309 fputs (AS2C (,) + 1, file
);
3314 /* This is used by the conditional move instructions. */
3316 put_condition_code (GET_CODE (x
), 0, MODE_INT
, file
);
3319 /* Like above, but reverse condition */
3321 put_condition_code (GET_CODE (x
), 1, MODE_INT
, file
); return;
3324 put_condition_code (GET_CODE (x
), 0, MODE_FLOAT
, file
);
3327 /* Like above, but reverse condition */
3329 put_condition_code (GET_CODE (x
), 1, MODE_FLOAT
, file
);
3336 sprintf (str
, "invalid operand code `%c'", code
);
3337 output_operand_lossage (str
);
3342 if (GET_CODE (x
) == REG
)
3344 PRINT_REG (x
, code
, file
);
3347 else if (GET_CODE (x
) == MEM
)
3349 PRINT_PTR (x
, file
);
3350 if (CONSTANT_ADDRESS_P (XEXP (x
, 0)))
3353 output_pic_addr_const (file
, XEXP (x
, 0), code
);
3355 output_addr_const (file
, XEXP (x
, 0));
3358 output_address (XEXP (x
, 0));
3361 else if (GET_CODE (x
) == CONST_DOUBLE
&& GET_MODE (x
) == SFmode
)
3366 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
3367 REAL_VALUE_TO_TARGET_SINGLE (r
, l
);
3368 PRINT_IMMED_PREFIX (file
);
3369 fprintf (file
, "0x%lx", l
);
3372 /* These float cases don't actually occur as immediate operands. */
3373 else if (GET_CODE (x
) == CONST_DOUBLE
&& GET_MODE (x
) == DFmode
)
3378 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
3379 REAL_VALUE_TO_DECIMAL (r
, "%.22e", dstr
);
3380 fprintf (file
, "%s", dstr
);
3383 else if (GET_CODE (x
) == CONST_DOUBLE
&& GET_MODE (x
) == XFmode
)
3388 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
3389 REAL_VALUE_TO_DECIMAL (r
, "%.22e", dstr
);
3390 fprintf (file
, "%s", dstr
);
3396 if (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
)
3397 PRINT_IMMED_PREFIX (file
);
3398 else if (GET_CODE (x
) == CONST
|| GET_CODE (x
) == SYMBOL_REF
3399 || GET_CODE (x
) == LABEL_REF
)
3400 PRINT_OFFSET_PREFIX (file
);
3403 output_pic_addr_const (file
, x
, code
);
3405 output_addr_const (file
, x
);
3409 /* Print a memory operand whose address is ADDR. */
3412 print_operand_address (file
, addr
)
3416 register rtx reg1
, reg2
, breg
, ireg
;
3419 switch (GET_CODE (addr
))
3423 fprintf (file
, "%se", RP
);
3424 fputs (hi_reg_name
[REGNO (addr
)], file
);
3434 if (CONSTANT_ADDRESS_P (XEXP (addr
, 0)))
3436 offset
= XEXP (addr
, 0);
3437 addr
= XEXP (addr
, 1);
3439 else if (CONSTANT_ADDRESS_P (XEXP (addr
, 1)))
3441 offset
= XEXP (addr
, 1);
3442 addr
= XEXP (addr
, 0);
3445 if (GET_CODE (addr
) != PLUS
)
3447 else if (GET_CODE (XEXP (addr
, 0)) == MULT
)
3448 reg1
= XEXP (addr
, 0), addr
= XEXP (addr
, 1);
3449 else if (GET_CODE (XEXP (addr
, 1)) == MULT
)
3450 reg1
= XEXP (addr
, 1), addr
= XEXP (addr
, 0);
3451 else if (GET_CODE (XEXP (addr
, 0)) == REG
)
3452 reg1
= XEXP (addr
, 0), addr
= XEXP (addr
, 1);
3453 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
3454 reg1
= XEXP (addr
, 1), addr
= XEXP (addr
, 0);
3456 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == MULT
)
3473 if ((reg1
&& GET_CODE (reg1
) == MULT
)
3474 || (reg2
!= 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2
))))
3479 else if (reg1
!= 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1
)))
3485 if (ireg
!= 0 || breg
!= 0)
3492 output_pic_addr_const (file
, addr
, 0);
3493 else if (GET_CODE (addr
) == LABEL_REF
)
3494 output_asm_label (addr
);
3496 output_addr_const (file
, addr
);
3499 if (ireg
!= 0 && GET_CODE (ireg
) == MULT
)
3501 scale
= INTVAL (XEXP (ireg
, 1));
3502 ireg
= XEXP (ireg
, 0);
3505 /* The stack pointer can only appear as a base register,
3506 never an index register, so exchange the regs if it is wrong. */
3508 if (scale
== 1 && ireg
&& REGNO (ireg
) == STACK_POINTER_REGNUM
)
3517 /* output breg+ireg*scale */
3518 PRINT_B_I_S (breg
, ireg
, scale
, file
);
3526 if (GET_CODE (XEXP (addr
, 0)) == CONST_INT
)
3528 scale
= INTVAL (XEXP (addr
, 0));
3529 ireg
= XEXP (addr
, 1);
3533 scale
= INTVAL (XEXP (addr
, 1));
3534 ireg
= XEXP (addr
, 0);
3537 output_addr_const (file
, const0_rtx
);
3538 PRINT_B_I_S (NULL_RTX
, ireg
, scale
, file
);
3543 if (GET_CODE (addr
) == CONST_INT
3544 && INTVAL (addr
) < 0x8000
3545 && INTVAL (addr
) >= -0x8000)
3546 fprintf (file
, "%d", (int) INTVAL (addr
));
3550 output_pic_addr_const (file
, addr
, 0);
3552 output_addr_const (file
, addr
);
3557 /* Set the cc_status for the results of an insn whose pattern is EXP.
3558 On the 80386, we assume that only test and compare insns, as well
3559 as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, BSF, ASHIFT,
3560 ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
3561 Also, we assume that jumps, moves and sCOND don't affect the condition
3562 codes. All else clobbers the condition codes, by assumption.
3564 We assume that ALL integer add, minus, etc. instructions effect the
3565 condition codes. This MUST be consistent with i386.md.
3567 We don't record any float test or compare - the redundant test &
3568 compare check in final.c does not handle stack-like regs correctly. */
3571 notice_update_cc (exp
)
3574 if (GET_CODE (exp
) == SET
)
3576 /* Jumps do not alter the cc's. */
3577 if (SET_DEST (exp
) == pc_rtx
)
3580 /* Moving register or memory into a register:
3581 it doesn't alter the cc's, but it might invalidate
3582 the RTX's which we remember the cc's came from.
3583 (Note that moving a constant 0 or 1 MAY set the cc's). */
3584 if (REG_P (SET_DEST (exp
))
3585 && (REG_P (SET_SRC (exp
)) || GET_CODE (SET_SRC (exp
)) == MEM
3586 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp
))) == '<'
3587 || (GET_CODE (SET_SRC (exp
)) == IF_THEN_ELSE
3588 && GET_MODE_CLASS (GET_MODE (SET_DEST (exp
))) == MODE_INT
)))
3590 if (cc_status
.value1
3591 && reg_overlap_mentioned_p (SET_DEST (exp
), cc_status
.value1
))
3592 cc_status
.value1
= 0;
3594 if (cc_status
.value2
3595 && reg_overlap_mentioned_p (SET_DEST (exp
), cc_status
.value2
))
3596 cc_status
.value2
= 0;
3601 /* Moving register into memory doesn't alter the cc's.
3602 It may invalidate the RTX's which we remember the cc's came from. */
3603 if (GET_CODE (SET_DEST (exp
)) == MEM
3604 && (REG_P (SET_SRC (exp
))
3605 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp
))) == '<'))
3607 if (cc_status
.value1
3608 && reg_overlap_mentioned_p (SET_DEST (exp
), cc_status
.value1
))
3609 cc_status
.value1
= 0;
3610 if (cc_status
.value2
3611 && reg_overlap_mentioned_p (SET_DEST (exp
), cc_status
.value2
))
3612 cc_status
.value2
= 0;
3617 /* Function calls clobber the cc's. */
3618 else if (GET_CODE (SET_SRC (exp
)) == CALL
)
3624 /* Tests and compares set the cc's in predictable ways. */
3625 else if (SET_DEST (exp
) == cc0_rtx
)
3628 cc_status
.value1
= SET_SRC (exp
);
3632 /* Certain instructions effect the condition codes. */
3633 else if (GET_MODE (SET_SRC (exp
)) == SImode
3634 || GET_MODE (SET_SRC (exp
)) == HImode
3635 || GET_MODE (SET_SRC (exp
)) == QImode
)
3636 switch (GET_CODE (SET_SRC (exp
)))
3638 case ASHIFTRT
: case LSHIFTRT
: case ASHIFT
:
3639 /* Shifts on the 386 don't set the condition codes if the
3640 shift count is zero. */
3641 if (GET_CODE (XEXP (SET_SRC (exp
), 1)) != CONST_INT
)
3647 /* We assume that the CONST_INT is non-zero (this rtx would
3648 have been deleted if it were zero. */
3650 case PLUS
: case MINUS
: case NEG
:
3651 case AND
: case IOR
: case XOR
:
3652 cc_status
.flags
= CC_NO_OVERFLOW
;
3653 cc_status
.value1
= SET_SRC (exp
);
3654 cc_status
.value2
= SET_DEST (exp
);
3657 /* This is the bsf pattern used by ffs. */
3659 if (XINT (SET_SRC (exp
), 1) == 5)
3661 /* Only the Z flag is defined after bsf. */
3663 = CC_NOT_POSITIVE
| CC_NOT_NEGATIVE
| CC_NO_OVERFLOW
;
3664 cc_status
.value1
= XVECEXP (SET_SRC (exp
), 0, 0);
3665 cc_status
.value2
= 0;
3678 else if (GET_CODE (exp
) == PARALLEL
3679 && GET_CODE (XVECEXP (exp
, 0, 0)) == SET
)
3681 if (SET_DEST (XVECEXP (exp
, 0, 0)) == pc_rtx
)
3683 if (SET_DEST (XVECEXP (exp
, 0, 0)) == cc0_rtx
)
3687 if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp
, 0, 0))))
3689 cc_status
.flags
|= CC_IN_80387
;
3690 if (0 && TARGET_CMOVE
&& stack_regs_mentioned_p
3691 (XEXP (SET_SRC (XVECEXP (exp
, 0, 0)), 1)))
3692 cc_status
.flags
|= CC_FCOMI
;
3695 cc_status
.value1
= SET_SRC (XVECEXP (exp
, 0, 0));
3707 /* Split one or more DImode RTL references into pairs of SImode
3708 references. The RTL can be REG, offsettable MEM, integer constant, or
3709 CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to
3710 split and "num" is its length. lo_half and hi_half are output arrays
3711 that parallel "operands". */
3714 split_di (operands
, num
, lo_half
, hi_half
)
3717 rtx lo_half
[], hi_half
[];
3721 rtx op
= operands
[num
];
3722 if (GET_CODE (op
) == REG
)
3724 lo_half
[num
] = gen_rtx_REG (SImode
, REGNO (op
));
3725 hi_half
[num
] = gen_rtx_REG (SImode
, REGNO (op
) + 1);
3727 else if (CONSTANT_P (op
))
3728 split_double (op
, &lo_half
[num
], &hi_half
[num
]);
3729 else if (offsettable_memref_p (op
))
3731 rtx lo_addr
= XEXP (op
, 0);
3732 rtx hi_addr
= XEXP (adj_offsettable_operand (op
, 4), 0);
3733 lo_half
[num
] = change_address (op
, SImode
, lo_addr
);
3734 hi_half
[num
] = change_address (op
, SImode
, hi_addr
);
3741 /* Return 1 if this is a valid binary operation on a 387.
3742 OP is the expression matched, and MODE is its mode. */
3745 binary_387_op (op
, mode
)
3747 enum machine_mode mode
;
3749 if (mode
!= VOIDmode
&& mode
!= GET_MODE (op
))
3752 switch (GET_CODE (op
))
3758 return GET_MODE_CLASS (GET_MODE (op
)) == MODE_FLOAT
;
3765 /* Return 1 if this is a valid shift or rotate operation on a 386.
3766 OP is the expression matched, and MODE is its mode. */
3771 enum machine_mode mode
;
3773 rtx operand
= XEXP (op
, 0);
3775 if (mode
!= VOIDmode
&& mode
!= GET_MODE (op
))
3778 if (GET_MODE (operand
) != GET_MODE (op
)
3779 || GET_MODE_CLASS (GET_MODE (op
)) != MODE_INT
)
3782 return (GET_CODE (op
) == ASHIFT
3783 || GET_CODE (op
) == ASHIFTRT
3784 || GET_CODE (op
) == LSHIFTRT
3785 || GET_CODE (op
) == ROTATE
3786 || GET_CODE (op
) == ROTATERT
);
3789 /* Return 1 if OP is COMPARE rtx with mode VOIDmode.
3790 MODE is not used. */
3793 VOIDmode_compare_op (op
, mode
)
3795 enum machine_mode mode ATTRIBUTE_UNUSED
;
3797 return GET_CODE (op
) == COMPARE
&& GET_MODE (op
) == VOIDmode
;
3800 /* Output code to perform a 387 binary operation in INSN, one of PLUS,
3801 MINUS, MULT or DIV. OPERANDS are the insn operands, where operands[3]
3802 is the expression of the binary operation. The output may either be
3803 emitted here, or returned to the caller, like all output_* functions.
3805 There is no guarantee that the operands are the same mode, as they
3806 might be within FLOAT or FLOAT_EXTEND expressions. */
3809 output_387_binary_op (insn
, operands
)
3815 static char buf
[100];
3817 switch (GET_CODE (operands
[3]))
3820 if (GET_MODE_CLASS (GET_MODE (operands
[1])) == MODE_INT
3821 || GET_MODE_CLASS (GET_MODE (operands
[2])) == MODE_INT
)
3828 if (GET_MODE_CLASS (GET_MODE (operands
[1])) == MODE_INT
3829 || GET_MODE_CLASS (GET_MODE (operands
[2])) == MODE_INT
)
3836 if (GET_MODE_CLASS (GET_MODE (operands
[1])) == MODE_INT
3837 || GET_MODE_CLASS (GET_MODE (operands
[2])) == MODE_INT
)
3844 if (GET_MODE_CLASS (GET_MODE (operands
[1])) == MODE_INT
3845 || GET_MODE_CLASS (GET_MODE (operands
[2])) == MODE_INT
)
3855 strcpy (buf
, base_op
);
3857 switch (GET_CODE (operands
[3]))
3861 if (REG_P (operands
[2]) && REGNO (operands
[0]) == REGNO (operands
[2]))
3864 operands
[2] = operands
[1];
3868 if (GET_CODE (operands
[2]) == MEM
)
3869 return strcat (buf
, AS1 (%z2
,%2));
3871 if (NON_STACK_REG_P (operands
[1]))
3873 output_op_from_reg (operands
[1], strcat (buf
, AS1 (%z0
,%1)));
3877 else if (NON_STACK_REG_P (operands
[2]))
3879 output_op_from_reg (operands
[2], strcat (buf
, AS1 (%z0
,%1)));
3883 if (find_regno_note (insn
, REG_DEAD
, REGNO (operands
[2])))
3885 if (STACK_TOP_P (operands
[0]))
3886 return strcat (buf
, AS2 (p
,%0,%2));
3888 return strcat (buf
, AS2 (p
,%2,%0));
3891 if (STACK_TOP_P (operands
[0]))
3892 return strcat (buf
, AS2C (%y2
,%0));
3894 return strcat (buf
, AS2C (%2,%0));
3898 if (GET_CODE (operands
[1]) == MEM
)
3899 return strcat (buf
, AS1 (r
%z1
,%1));
3901 if (GET_CODE (operands
[2]) == MEM
)
3902 return strcat (buf
, AS1 (%z2
,%2));
3904 if (NON_STACK_REG_P (operands
[1]))
3906 output_op_from_reg (operands
[1], strcat (buf
, AS1 (r
%z0
,%1)));
3910 else if (NON_STACK_REG_P (operands
[2]))
3912 output_op_from_reg (operands
[2], strcat (buf
, AS1 (%z0
,%1)));
3916 if (! STACK_REG_P (operands
[1]) || ! STACK_REG_P (operands
[2]))
3919 if (find_regno_note (insn
, REG_DEAD
, REGNO (operands
[2])))
3921 if (STACK_TOP_P (operands
[0]))
3922 return strcat (buf
, AS2 (p
,%0,%2));
3924 return strcat (buf
, AS2 (rp
,%2,%0));
3927 if (find_regno_note (insn
, REG_DEAD
, REGNO (operands
[1])))
3929 if (STACK_TOP_P (operands
[0]))
3930 return strcat (buf
, AS2 (rp
,%0,%1));
3932 return strcat (buf
, AS2 (p
,%1,%0));
3935 if (STACK_TOP_P (operands
[0]))
3937 if (STACK_TOP_P (operands
[1]))
3938 return strcat (buf
, AS2C (%y2
,%0));
3940 return strcat (buf
, AS2 (r
,%y1
,%0));
3942 else if (STACK_TOP_P (operands
[1]))
3943 return strcat (buf
, AS2C (%1,%0));
3945 return strcat (buf
, AS2 (r
,%2,%0));
3952 /* Output code for INSN to convert a float to a signed int. OPERANDS
3953 are the insn operands. The output may be SFmode or DFmode and the
3954 input operand may be SImode or DImode. As a special case, make sure
3955 that the 387 stack top dies if the output mode is DImode, because the
3956 hardware requires this. */
3959 output_fix_trunc (insn
, operands
)
3963 int stack_top_dies
= find_regno_note (insn
, REG_DEAD
, FIRST_STACK_REG
) != 0;
3966 if (! STACK_TOP_P (operands
[1]))
3969 xops
[0] = GEN_INT (12);
3970 xops
[1] = operands
[4];
3972 output_asm_insn (AS1 (fnstc
%W2
,%2), operands
);
3973 output_asm_insn (AS2 (mov
%L2
,%2,%4), operands
);
3974 output_asm_insn (AS2 (mov
%B1
,%0,%h1
), xops
);
3975 output_asm_insn (AS2 (mov
%L4
,%4,%3), operands
);
3976 output_asm_insn (AS1 (fldc
%W3
,%3), operands
);
3978 if (NON_STACK_REG_P (operands
[0]))
3979 output_to_reg (operands
[0], stack_top_dies
, operands
[3]);
3981 else if (GET_CODE (operands
[0]) == MEM
)
3984 output_asm_insn (AS1 (fistp
%z0
,%0), operands
);
3985 else if (GET_MODE (operands
[0]) == DImode
&& ! stack_top_dies
)
3987 /* There is no DImode version of this without a stack pop, so
3988 we must emulate it. It doesn't matter much what the second
3989 instruction is, because the value being pushed on the FP stack
3990 is not used except for the following stack popping store.
3991 This case can only happen without optimization, so it doesn't
3992 matter that it is inefficient. */
3993 output_asm_insn (AS1 (fistp
%z0
,%0), operands
);
3994 output_asm_insn (AS1 (fild
%z0
,%0), operands
);
3997 output_asm_insn (AS1 (fist
%z0
,%0), operands
);
4002 return AS1 (fldc
%W2
,%2);
4005 /* Output code for INSN to compare OPERANDS. The two operands might
4006 not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
4007 expression. If the compare is in mode CCFPEQmode, use an opcode that
4008 will not fault if a qNaN is present. */
4011 output_float_compare (insn
, operands
)
4016 rtx body
= XVECEXP (PATTERN (insn
), 0, 0);
4017 int unordered_compare
= GET_MODE (SET_SRC (body
)) == CCFPEQmode
;
4020 if (0 && TARGET_CMOVE
&& STACK_REG_P (operands
[1]))
4022 cc_status
.flags
|= CC_FCOMI
;
4023 cc_prev_status
.flags
&= ~CC_TEST_AX
;
4026 if (! STACK_TOP_P (operands
[0]))
4029 operands
[0] = operands
[1];
4031 cc_status
.flags
|= CC_REVERSED
;
4034 if (! STACK_TOP_P (operands
[0]))
4037 stack_top_dies
= find_regno_note (insn
, REG_DEAD
, FIRST_STACK_REG
) != 0;
4039 if (STACK_REG_P (operands
[1])
4041 && find_regno_note (insn
, REG_DEAD
, REGNO (operands
[1]))
4042 && REGNO (operands
[1]) != FIRST_STACK_REG
)
4044 /* If both the top of the 387 stack dies, and the other operand
4045 is also a stack register that dies, then this must be a
4046 `fcompp' float compare */
4048 if (unordered_compare
)
4050 if (cc_status
.flags
& CC_FCOMI
)
4052 output_asm_insn (AS2 (fucomip
,%y1
,%0), operands
);
4053 output_asm_insn (AS1 (fstp
, %y0
), operands
);
4057 output_asm_insn ("fucompp", operands
);
4061 if (cc_status
.flags
& CC_FCOMI
)
4063 output_asm_insn (AS2 (fcomip
, %y1
,%0), operands
);
4064 output_asm_insn (AS1 (fstp
, %y0
), operands
);
4068 output_asm_insn ("fcompp", operands
);
4073 static char buf
[100];
4075 /* Decide if this is the integer or float compare opcode, or the
4076 unordered float compare. */
4078 if (unordered_compare
)
4079 strcpy (buf
, (cc_status
.flags
& CC_FCOMI
) ? "fucomi" : "fucom");
4080 else if (GET_MODE_CLASS (GET_MODE (operands
[1])) == MODE_FLOAT
)
4081 strcpy (buf
, (cc_status
.flags
& CC_FCOMI
) ? "fcomi" : "fcom");
4083 strcpy (buf
, "ficom");
4085 /* Modify the opcode if the 387 stack is to be popped. */
4090 if (NON_STACK_REG_P (operands
[1]))
4091 output_op_from_reg (operands
[1], strcat (buf
, AS1 (%z0
,%1)));
4092 else if (cc_status
.flags
& CC_FCOMI
)
4094 output_asm_insn (strcat (buf
, AS2 (%z1
,%y1
,%0)), operands
);
4098 output_asm_insn (strcat (buf
, AS1 (%z1
,%y1
)), operands
);
4101 /* Now retrieve the condition code. */
4103 return output_fp_cc0_set (insn
);
4106 /* Output opcodes to transfer the results of FP compare or test INSN
4107 from the FPU to the CPU flags. If TARGET_IEEE_FP, ensure that if the
4108 result of the compare or test is unordered, no comparison operator
4109 succeeds except NE. Return an output template, if any. */
4112 output_fp_cc0_set (insn
)
4119 xops
[0] = gen_rtx_REG (HImode
, 0);
4120 output_asm_insn (AS1 (fnsts
%W0
,%0), xops
);
4122 if (! TARGET_IEEE_FP
)
4124 if (!(cc_status
.flags
& CC_REVERSED
))
4126 next
= next_cc0_user (insn
);
4128 if (GET_CODE (next
) == JUMP_INSN
4129 && GET_CODE (PATTERN (next
)) == SET
4130 && SET_DEST (PATTERN (next
)) == pc_rtx
4131 && GET_CODE (SET_SRC (PATTERN (next
))) == IF_THEN_ELSE
)
4132 code
= GET_CODE (XEXP (SET_SRC (PATTERN (next
)), 0));
4133 else if (GET_CODE (PATTERN (next
)) == SET
)
4134 code
= GET_CODE (SET_SRC (PATTERN (next
)));
4138 if (code
== GT
|| code
== LT
|| code
== EQ
|| code
== NE
4139 || code
== LE
|| code
== GE
)
4141 /* We will test eax directly. */
4142 cc_status
.flags
|= CC_TEST_AX
;
4150 next
= next_cc0_user (insn
);
4151 if (next
== NULL_RTX
)
4154 if (GET_CODE (next
) == JUMP_INSN
4155 && GET_CODE (PATTERN (next
)) == SET
4156 && SET_DEST (PATTERN (next
)) == pc_rtx
4157 && GET_CODE (SET_SRC (PATTERN (next
))) == IF_THEN_ELSE
)
4158 code
= GET_CODE (XEXP (SET_SRC (PATTERN (next
)), 0));
4159 else if (GET_CODE (PATTERN (next
)) == SET
)
4161 if (GET_CODE (SET_SRC (PATTERN (next
))) == IF_THEN_ELSE
)
4162 code
= GET_CODE (XEXP (SET_SRC (PATTERN (next
)), 0));
4164 code
= GET_CODE (SET_SRC (PATTERN (next
)));
4167 else if (GET_CODE (PATTERN (next
)) == PARALLEL
4168 && GET_CODE (XVECEXP (PATTERN (next
), 0, 0)) == SET
)
4170 if (GET_CODE (SET_SRC (XVECEXP (PATTERN (next
), 0, 0))) == IF_THEN_ELSE
)
4171 code
= GET_CODE (XEXP (SET_SRC (XVECEXP (PATTERN (next
), 0, 0)), 0));
4173 code
= GET_CODE (SET_SRC (XVECEXP (PATTERN (next
), 0, 0)));
4178 xops
[0] = gen_rtx_REG (QImode
, 0);
4183 xops
[1] = GEN_INT (0x45);
4184 output_asm_insn (AS2 (and%B0
,%1,%h0
), xops
);
4189 xops
[1] = GEN_INT (0x45);
4190 xops
[2] = GEN_INT (0x01);
4191 output_asm_insn (AS2 (and%B0
,%1,%h0
), xops
);
4192 output_asm_insn (AS2 (cmp
%B0
,%2,%h0
), xops
);
4197 xops
[1] = GEN_INT (0x05);
4198 output_asm_insn (AS2 (and%B0
,%1,%h0
), xops
);
4203 xops
[1] = GEN_INT (0x45);
4204 xops
[2] = GEN_INT (0x40);
4205 output_asm_insn (AS2 (and%B0
,%1,%h0
), xops
);
4206 output_asm_insn (AS1 (dec
%B0
,%h0
), xops
);
4207 output_asm_insn (AS2 (cmp
%B0
,%2,%h0
), xops
);
4212 xops
[1] = GEN_INT (0x45);
4213 xops
[2] = GEN_INT (0x40);
4214 output_asm_insn (AS2 (and%B0
,%1,%h0
), xops
);
4215 output_asm_insn (AS2 (cmp
%B0
,%2,%h0
), xops
);
4220 xops
[1] = GEN_INT (0x44);
4221 xops
[2] = GEN_INT (0x40);
4222 output_asm_insn (AS2 (and%B0
,%1,%h0
), xops
);
4223 output_asm_insn (AS2 (xor%B0
,%2,%h0
), xops
);
4238 #define MAX_386_STACK_LOCALS 2
4240 static rtx i386_stack_locals
[(int) MAX_MACHINE_MODE
][MAX_386_STACK_LOCALS
];
4242 /* Define the structure for the machine field in struct function. */
4243 struct machine_function
4245 rtx i386_stack_locals
[(int) MAX_MACHINE_MODE
][MAX_386_STACK_LOCALS
];
4247 char pic_label_name
[256];
4250 /* Functions to save and restore i386_stack_locals.
4251 These will be called, via pointer variables,
4252 from push_function_context and pop_function_context. */
4255 save_386_machine_status (p
)
4259 = (struct machine_function
*) xmalloc (sizeof (struct machine_function
));
4260 bcopy ((char *) i386_stack_locals
, (char *) p
->machine
->i386_stack_locals
,
4261 sizeof i386_stack_locals
);
4262 p
->machine
->pic_label_rtx
= pic_label_rtx
;
4263 bcopy (pic_label_name
, p
->machine
->pic_label_name
, 256);
4267 restore_386_machine_status (p
)
4270 bcopy ((char *) p
->machine
->i386_stack_locals
, (char *) i386_stack_locals
,
4271 sizeof i386_stack_locals
);
4272 pic_label_rtx
= p
->machine
->pic_label_rtx
;
4273 bcopy (p
->machine
->pic_label_name
, pic_label_name
, 256);
4278 /* Clear stack slot assignments remembered from previous functions.
4279 This is called from INIT_EXPANDERS once before RTL is emitted for each
4283 clear_386_stack_locals ()
4285 enum machine_mode mode
;
4288 for (mode
= VOIDmode
; (int) mode
< (int) MAX_MACHINE_MODE
;
4289 mode
= (enum machine_mode
) ((int) mode
+ 1))
4290 for (n
= 0; n
< MAX_386_STACK_LOCALS
; n
++)
4291 i386_stack_locals
[(int) mode
][n
] = NULL_RTX
;
4293 pic_label_rtx
= NULL_RTX
;
4294 bzero (pic_label_name
, 256);
4295 /* Arrange to save and restore i386_stack_locals around nested functions. */
4296 save_machine_status
= save_386_machine_status
;
4297 restore_machine_status
= restore_386_machine_status
;
4300 /* Return a MEM corresponding to a stack slot with mode MODE.
4301 Allocate a new slot if necessary.
4303 The RTL for a function can have several slots available: N is
4304 which slot to use. */
4307 assign_386_stack_local (mode
, n
)
4308 enum machine_mode mode
;
4311 if (n
< 0 || n
>= MAX_386_STACK_LOCALS
)
4314 if (i386_stack_locals
[(int) mode
][n
] == NULL_RTX
)
4315 i386_stack_locals
[(int) mode
][n
]
4316 = assign_stack_local (mode
, GET_MODE_SIZE (mode
), 0);
4318 return i386_stack_locals
[(int) mode
][n
];
4323 enum machine_mode mode ATTRIBUTE_UNUSED
;
4325 return (GET_CODE (op
) == MULT
);
4330 enum machine_mode mode ATTRIBUTE_UNUSED
;
4332 return (GET_CODE (op
) == DIV
);
4336 /* Create a new copy of an rtx.
4337 Recursively copies the operands of the rtx,
4338 except for those few rtx codes that are sharable.
4339 Doesn't share CONST */
4347 register RTX_CODE code
;
4348 register char *format_ptr
;
4350 code
= GET_CODE (orig
);
4363 /* SCRATCH must be shared because they represent distinct values. */
4368 /* CONST can be shared if it contains a SYMBOL_REF. If it contains
4369 a LABEL_REF, it isn't sharable. */
4370 if (GET_CODE (XEXP (orig
, 0)) == PLUS
4371 && GET_CODE (XEXP (XEXP (orig
, 0), 0)) == SYMBOL_REF
4372 && GET_CODE (XEXP (XEXP (orig
, 0), 1)) == CONST_INT
)
4376 /* A MEM with a constant address is not sharable. The problem is that
4377 the constant address may need to be reloaded. If the mem is shared,
4378 then reloading one copy of this mem will cause all copies to appear
4379 to have been reloaded. */
4382 copy
= rtx_alloc (code
);
4383 PUT_MODE (copy
, GET_MODE (orig
));
4384 copy
->in_struct
= orig
->in_struct
;
4385 copy
->volatil
= orig
->volatil
;
4386 copy
->unchanging
= orig
->unchanging
;
4387 copy
->integrated
= orig
->integrated
;
4389 copy
->is_spill_rtx
= orig
->is_spill_rtx
;
4391 format_ptr
= GET_RTX_FORMAT (GET_CODE (copy
));
4393 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (copy
)); i
++)
4395 switch (*format_ptr
++)
4398 XEXP (copy
, i
) = XEXP (orig
, i
);
4399 if (XEXP (orig
, i
) != NULL
)
4400 XEXP (copy
, i
) = copy_rtx (XEXP (orig
, i
));
4405 XEXP (copy
, i
) = XEXP (orig
, i
);
4410 XVEC (copy
, i
) = XVEC (orig
, i
);
4411 if (XVEC (orig
, i
) != NULL
)
4413 XVEC (copy
, i
) = rtvec_alloc (XVECLEN (orig
, i
));
4414 for (j
= 0; j
< XVECLEN (copy
, i
); j
++)
4415 XVECEXP (copy
, i
, j
) = copy_rtx (XVECEXP (orig
, i
, j
));
4420 XWINT (copy
, i
) = XWINT (orig
, i
);
4424 XINT (copy
, i
) = XINT (orig
, i
);
4429 XSTR (copy
, i
) = XSTR (orig
, i
);
4440 /* Try to rewrite a memory address to make it valid */
4443 rewrite_address (mem_rtx
)
4446 rtx index_rtx
, base_rtx
, offset_rtx
, scale_rtx
, ret_rtx
;
4448 int offset_adjust
= 0;
4449 int was_only_offset
= 0;
4450 rtx mem_addr
= XEXP (mem_rtx
, 0);
4451 char *storage
= oballoc (0);
4453 int is_spill_rtx
= 0;
4455 in_struct
= MEM_IN_STRUCT_P (mem_rtx
);
4456 is_spill_rtx
= RTX_IS_SPILL_P (mem_rtx
);
4458 if (GET_CODE (mem_addr
) == PLUS
4459 && GET_CODE (XEXP (mem_addr
, 1)) == PLUS
4460 && GET_CODE (XEXP (XEXP (mem_addr
, 1), 0)) == REG
)
4462 /* This part is utilized by the combiner. */
4464 = gen_rtx (PLUS
, GET_MODE (mem_addr
),
4465 gen_rtx (PLUS
, GET_MODE (XEXP (mem_addr
, 1)),
4466 XEXP (mem_addr
, 0), XEXP (XEXP (mem_addr
, 1), 0)),
4467 XEXP (XEXP (mem_addr
, 1), 1));
4469 if (memory_address_p (GET_MODE (mem_rtx
), ret_rtx
))
4471 XEXP (mem_rtx
, 0) = ret_rtx
;
4472 RTX_IS_SPILL_P (ret_rtx
) = is_spill_rtx
;
4479 /* This part is utilized by loop.c.
4480 If the address contains PLUS (reg,const) and this pattern is invalid
4481 in this case - try to rewrite the address to make it valid. */
4482 storage
= oballoc (0);
4483 index_rtx
= base_rtx
= offset_rtx
= NULL
;
4485 /* Find the base index and offset elements of the memory address. */
4486 if (GET_CODE (mem_addr
) == PLUS
)
4488 if (GET_CODE (XEXP (mem_addr
, 0)) == REG
)
4490 if (GET_CODE (XEXP (mem_addr
, 1)) == REG
)
4491 base_rtx
= XEXP (mem_addr
, 1), index_rtx
= XEXP (mem_addr
, 0);
4493 base_rtx
= XEXP (mem_addr
, 0), offset_rtx
= XEXP (mem_addr
, 1);
4496 else if (GET_CODE (XEXP (mem_addr
, 0)) == MULT
)
4498 index_rtx
= XEXP (mem_addr
, 0);
4499 if (GET_CODE (XEXP (mem_addr
, 1)) == REG
)
4500 base_rtx
= XEXP (mem_addr
, 1);
4502 offset_rtx
= XEXP (mem_addr
, 1);
4505 else if (GET_CODE (XEXP (mem_addr
, 0)) == PLUS
)
4507 if (GET_CODE (XEXP (XEXP (mem_addr
, 0), 0)) == PLUS
4508 && GET_CODE (XEXP (XEXP (XEXP (mem_addr
, 0), 0), 0)) == MULT
4509 && (GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr
, 0), 0), 0), 0))
4511 && (GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr
, 0), 0), 0), 1))
4513 && (GET_CODE (XEXP (XEXP (XEXP (mem_addr
, 0), 0), 1))
4515 && GET_CODE (XEXP (XEXP (mem_addr
, 0), 1)) == REG
4516 && GET_CODE (XEXP (mem_addr
, 1)) == SYMBOL_REF
)
4518 index_rtx
= XEXP (XEXP (XEXP (mem_addr
, 0), 0), 0);
4519 offset_rtx
= XEXP (mem_addr
, 1);
4520 base_rtx
= XEXP (XEXP (mem_addr
, 0), 1);
4521 offset_adjust
= INTVAL (XEXP (XEXP (XEXP (mem_addr
, 0), 0), 1));
4525 offset_rtx
= XEXP (mem_addr
, 1);
4526 index_rtx
= XEXP (XEXP (mem_addr
, 0), 0);
4527 base_rtx
= XEXP (XEXP (mem_addr
, 0), 1);
4531 else if (GET_CODE (XEXP (mem_addr
, 0)) == CONST_INT
)
4533 was_only_offset
= 1;
4536 offset_rtx
= XEXP (mem_addr
, 1);
4537 offset_adjust
= INTVAL (XEXP (mem_addr
, 0));
4538 if (offset_adjust
== 0)
4540 XEXP (mem_rtx
, 0) = offset_rtx
;
4541 RTX_IS_SPILL_P (XEXP (mem_rtx
, 0)) = is_spill_rtx
;
4551 else if (GET_CODE (mem_addr
) == MULT
)
4552 index_rtx
= mem_addr
;
4559 if (index_rtx
!= 0 && GET_CODE (index_rtx
) == MULT
)
4561 if (GET_CODE (XEXP (index_rtx
, 1)) != CONST_INT
)
4567 scale_rtx
= XEXP (index_rtx
, 1);
4568 scale
= INTVAL (scale_rtx
);
4569 index_rtx
= copy_all_rtx (XEXP (index_rtx
, 0));
4572 /* Now find which of the elements are invalid and try to fix them. */
4573 if (index_rtx
&& GET_CODE (index_rtx
) == CONST_INT
&& base_rtx
== NULL
)
4575 offset_adjust
= INTVAL (index_rtx
) * scale
;
4577 if (offset_rtx
!= 0 && CONSTANT_P (offset_rtx
))
4578 offset_rtx
= plus_constant (offset_rtx
, offset_adjust
);
4579 else if (offset_rtx
== 0)
4580 offset_rtx
= const0_rtx
;
4582 RTX_IS_SPILL_P (XEXP (mem_rtx
, 0)) = is_spill_rtx
;
4583 XEXP (mem_rtx
, 0) = offset_rtx
;
4587 if (base_rtx
&& GET_CODE (base_rtx
) == PLUS
4588 && GET_CODE (XEXP (base_rtx
, 0)) == REG
4589 && GET_CODE (XEXP (base_rtx
, 1)) == CONST_INT
)
4591 offset_adjust
+= INTVAL (XEXP (base_rtx
, 1));
4592 base_rtx
= copy_all_rtx (XEXP (base_rtx
, 0));
4595 else if (base_rtx
&& GET_CODE (base_rtx
) == CONST_INT
)
4597 offset_adjust
+= INTVAL (base_rtx
);
4601 if (index_rtx
&& GET_CODE (index_rtx
) == PLUS
4602 && GET_CODE (XEXP (index_rtx
, 0)) == REG
4603 && GET_CODE (XEXP (index_rtx
, 1)) == CONST_INT
)
4605 offset_adjust
+= INTVAL (XEXP (index_rtx
, 1)) * scale
;
4606 index_rtx
= copy_all_rtx (XEXP (index_rtx
, 0));
4611 if (! LEGITIMATE_INDEX_P (index_rtx
)
4612 && ! (index_rtx
== stack_pointer_rtx
&& scale
== 1
4613 && base_rtx
== NULL
))
4622 if (! LEGITIMATE_INDEX_P (base_rtx
) && GET_CODE (base_rtx
) != REG
)
4629 if (offset_adjust
!= 0)
4631 if (offset_rtx
!= 0 && CONSTANT_P (offset_rtx
))
4632 offset_rtx
= plus_constant (offset_rtx
, offset_adjust
);
4634 offset_rtx
= const0_rtx
;
4642 ret_rtx
= gen_rtx (PLUS
, GET_MODE (base_rtx
),
4643 gen_rtx (MULT
, GET_MODE (index_rtx
),
4644 index_rtx
, scale_rtx
),
4647 if (GET_CODE (offset_rtx
) != CONST_INT
4648 || INTVAL (offset_rtx
) != 0)
4649 ret_rtx
= gen_rtx (PLUS
, GET_MODE (ret_rtx
),
4650 ret_rtx
, offset_rtx
);
4654 ret_rtx
= gen_rtx (PLUS
, GET_MODE (index_rtx
),
4655 index_rtx
, base_rtx
);
4657 if (GET_CODE (offset_rtx
) != CONST_INT
4658 || INTVAL (offset_rtx
) != 0)
4659 ret_rtx
= gen_rtx (PLUS
, GET_MODE (ret_rtx
),
4660 ret_rtx
, offset_rtx
);
4667 ret_rtx
= gen_rtx (MULT
, GET_MODE (index_rtx
),
4668 index_rtx
, scale_rtx
);
4670 if (GET_CODE (offset_rtx
) != CONST_INT
4671 || INTVAL (offset_rtx
) != 0)
4672 ret_rtx
= gen_rtx (PLUS
, GET_MODE (ret_rtx
),
4673 ret_rtx
, offset_rtx
);
4677 if (GET_CODE (offset_rtx
) == CONST_INT
4678 && INTVAL (offset_rtx
) == 0)
4679 ret_rtx
= index_rtx
;
4681 ret_rtx
= gen_rtx (PLUS
, GET_MODE (index_rtx
),
4682 index_rtx
, offset_rtx
);
4690 if (GET_CODE (offset_rtx
) == CONST_INT
4691 && INTVAL (offset_rtx
) == 0)
4694 ret_rtx
= gen_rtx (PLUS
, GET_MODE (base_rtx
), base_rtx
,
4697 else if (was_only_offset
)
4698 ret_rtx
= offset_rtx
;
4706 XEXP (mem_rtx
, 0) = ret_rtx
;
4707 RTX_IS_SPILL_P (XEXP (mem_rtx
, 0)) = is_spill_rtx
;
4718 /* Return 1 if the first insn to set cc before INSN also sets the register
4719 REG_RTX; otherwise return 0. */
4721 last_to_set_cc (reg_rtx
, insn
)
4724 rtx prev_insn
= PREV_INSN (insn
);
4728 if (GET_CODE (prev_insn
) == NOTE
)
4731 else if (GET_CODE (prev_insn
) == INSN
)
4733 if (GET_CODE (PATTERN (prev_insn
)) != SET
)
4736 if (rtx_equal_p (SET_DEST (PATTERN (prev_insn
)), reg_rtx
))
4738 if (sets_condition_code (SET_SRC (PATTERN (prev_insn
))))
4744 else if (! doesnt_set_condition_code (SET_SRC (PATTERN (prev_insn
))))
4751 prev_insn
= PREV_INSN (prev_insn
);
4758 doesnt_set_condition_code (pat
)
4761 switch (GET_CODE (pat
))
4774 sets_condition_code (pat
)
4777 switch (GET_CODE (pat
))
4799 str_immediate_operand (op
, mode
)
4801 enum machine_mode mode ATTRIBUTE_UNUSED
;
4803 if (GET_CODE (op
) == CONST_INT
&& INTVAL (op
) <= 32 && INTVAL (op
) >= 0)
4813 if (GET_CODE (insn
) == INSN
&& GET_CODE (PATTERN (insn
)) == SET
4814 && (GET_MODE (SET_DEST (PATTERN (insn
))) == DFmode
4815 || GET_MODE (SET_DEST (PATTERN (insn
))) == SFmode
4816 || GET_MODE (SET_DEST (PATTERN (insn
))) == XFmode
))
4822 /* Return 1 if the mode of the SET_DEST of insn is floating point
4823 and it is not an fld or a move from memory to memory.
4824 Otherwise return 0 */
4830 if (GET_CODE (insn
) == INSN
&& GET_CODE (PATTERN (insn
)) == SET
4831 && (GET_MODE (SET_DEST (PATTERN (insn
))) == DFmode
4832 || GET_MODE (SET_DEST (PATTERN (insn
))) == SFmode
4833 || GET_MODE (SET_DEST (PATTERN (insn
))) == XFmode
)
4834 && GET_CODE (SET_DEST (PATTERN (insn
))) == REG
4835 && REGNO (SET_DEST (PATTERN (insn
))) >= FIRST_FLOAT_REG
4836 && GET_CODE (SET_SRC (insn
)) != MEM
)
4842 /* Return 1 if the mode of the SET_DEST of INSN is floating point and is
4843 memory and the source is a register. */
4849 if (GET_CODE (insn
) == INSN
&& GET_CODE (PATTERN (insn
)) == SET
4850 && (GET_MODE (SET_DEST (PATTERN (insn
))) == DFmode
4851 || GET_MODE (SET_DEST (PATTERN (insn
))) == SFmode
4852 || GET_MODE (SET_DEST (PATTERN (insn
))) == XFmode
)
4853 && GET_CODE (SET_DEST (PATTERN (insn
))) == MEM
4854 && GET_CODE (SET_SRC (PATTERN (insn
))) == REG
)
4860 /* Return 1 if DEP_INSN sets a register which INSN uses as a base
4861 or index to reference memory.
4862 otherwise return 0 */
4865 agi_dependent (insn
, dep_insn
)
4868 if (GET_CODE (dep_insn
) == INSN
4869 && GET_CODE (PATTERN (dep_insn
)) == SET
4870 && GET_CODE (SET_DEST (PATTERN (dep_insn
))) == REG
)
4871 return reg_mentioned_in_mem (SET_DEST (PATTERN (dep_insn
)), insn
);
4873 if (GET_CODE (dep_insn
) == INSN
&& GET_CODE (PATTERN (dep_insn
)) == SET
4874 && GET_CODE (SET_DEST (PATTERN (dep_insn
))) == MEM
4875 && push_operand (SET_DEST (PATTERN (dep_insn
)),
4876 GET_MODE (SET_DEST (PATTERN (dep_insn
)))))
4877 return reg_mentioned_in_mem (stack_pointer_rtx
, insn
);
4882 /* Return 1 if reg is used in rtl as a base or index for a memory ref
4883 otherwise return 0. */
4886 reg_mentioned_in_mem (reg
, rtl
)
4891 register enum rtx_code code
;
4896 code
= GET_CODE (rtl
);
4914 if (code
== MEM
&& reg_mentioned_p (reg
, rtl
))
4917 fmt
= GET_RTX_FORMAT (code
);
4918 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
4922 for (j
= XVECLEN (rtl
, i
) - 1; j
>= 0; j
--)
4923 if (reg_mentioned_in_mem (reg
, XVECEXP (rtl
, i
, j
)))
4927 else if (fmt
[i
] == 'e' && reg_mentioned_in_mem (reg
, XEXP (rtl
, i
)))
4934 /* Output the appropriate insns for doing strlen if not just doing repnz; scasb
4936 operands[0] = result, initialized with the startaddress
4937 operands[1] = alignment of the address.
4938 operands[2] = scratch register, initialized with the startaddress when
4939 not aligned, otherwise undefined
4941 This is just the body. It needs the initialisations mentioned above and
4942 some address computing at the end. These things are done in i386.md. */
4945 output_strlen_unroll (operands
)
4950 xops
[0] = operands
[0]; /* Result */
4951 /* operands[1]; * Alignment */
4952 xops
[1] = operands
[2]; /* Scratch */
4953 xops
[2] = GEN_INT (0);
4954 xops
[3] = GEN_INT (2);
4955 xops
[4] = GEN_INT (3);
4956 xops
[5] = GEN_INT (4);
4957 /* xops[6] = gen_label_rtx (); * label when aligned to 3-byte */
4958 /* xops[7] = gen_label_rtx (); * label when aligned to 2-byte */
4959 xops
[8] = gen_label_rtx (); /* label of main loop */
4961 if (TARGET_USE_Q_REG
&& QI_REG_P (xops
[1]))
4962 xops
[9] = gen_label_rtx (); /* pentium optimisation */
4964 xops
[10] = gen_label_rtx (); /* end label 2 */
4965 xops
[11] = gen_label_rtx (); /* end label 1 */
4966 xops
[12] = gen_label_rtx (); /* end label */
4967 /* xops[13] * Temporary used */
4968 xops
[14] = GEN_INT (0xff);
4969 xops
[15] = GEN_INT (0xff00);
4970 xops
[16] = GEN_INT (0xff0000);
4971 xops
[17] = GEN_INT (0xff000000);
4973 /* Loop to check 1..3 bytes for null to get an aligned pointer. */
4975 /* Is there a known alignment and is it less than 4? */
4976 if (GET_CODE (operands
[1]) != CONST_INT
|| INTVAL (operands
[1]) < 4)
4978 /* Is there a known alignment and is it not 2? */
4979 if (GET_CODE (operands
[1]) != CONST_INT
|| INTVAL (operands
[1]) != 2)
4981 xops
[6] = gen_label_rtx (); /* Label when aligned to 3-byte */
4982 xops
[7] = gen_label_rtx (); /* Label when aligned to 2-byte */
4984 /* Leave just the 3 lower bits.
4985 If this is a q-register, then the high part is used later
4986 therefore use andl rather than andb. */
4987 output_asm_insn (AS2 (and%L1
,%4,%1), xops
);
4989 /* Is aligned to 4-byte address when zero */
4990 output_asm_insn (AS1 (je
,%l8
), xops
);
4992 /* Side-effect even Parity when %eax == 3 */
4993 output_asm_insn (AS1 (jp
,%6), xops
);
4995 /* Is it aligned to 2 bytes ? */
4996 if (QI_REG_P (xops
[1]))
4997 output_asm_insn (AS2 (cmp
%L1
,%3,%1), xops
);
4999 output_asm_insn (AS2 (cmp
%L1
,%3,%1), xops
);
5001 output_asm_insn (AS1 (je
,%7), xops
);
5005 /* Since the alignment is 2, we have to check 2 or 0 bytes;
5006 check if is aligned to 4 - byte. */
5007 output_asm_insn (AS2 (and%L1
,%3,%1), xops
);
5009 /* Is aligned to 4-byte address when zero */
5010 output_asm_insn (AS1 (je
,%l8
), xops
);
5013 xops
[13] = gen_rtx_MEM (QImode
, xops
[0]);
5015 /* Now compare the bytes; compare with the high part of a q-reg
5016 gives shorter code. */
5017 if (QI_REG_P (xops
[1]))
5019 /* Compare the first n unaligned byte on a byte per byte basis. */
5020 output_asm_insn (AS2 (cmp
%B1
,%h1
,%13), xops
);
5022 /* When zero we reached the end. */
5023 output_asm_insn (AS1 (je
,%l12
), xops
);
5025 /* Increment the address. */
5026 output_asm_insn (AS1 (inc
%L0
,%0), xops
);
5028 /* Not needed with an alignment of 2 */
5029 if (GET_CODE (operands
[1]) != CONST_INT
|| INTVAL (operands
[1]) != 2)
5031 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
5032 CODE_LABEL_NUMBER (xops
[7]));
5033 output_asm_insn (AS2 (cmp
%B1
,%h1
,%13), xops
);
5034 output_asm_insn (AS1 (je
,%l12
), xops
);
5035 output_asm_insn (AS1 (inc
%L0
,%0), xops
);
5037 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
5038 CODE_LABEL_NUMBER (xops
[6]));
5041 output_asm_insn (AS2 (cmp
%B1
,%h1
,%13), xops
);
5045 output_asm_insn (AS2 (cmp
%B13
,%2,%13), xops
);
5046 output_asm_insn (AS1 (je
,%l12
), xops
);
5047 output_asm_insn (AS1 (inc
%L0
,%0), xops
);
5049 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
5050 CODE_LABEL_NUMBER (xops
[7]));
5051 output_asm_insn (AS2 (cmp
%B13
,%2,%13), xops
);
5052 output_asm_insn (AS1 (je
,%l12
), xops
);
5053 output_asm_insn (AS1 (inc
%L0
,%0), xops
);
5055 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
5056 CODE_LABEL_NUMBER (xops
[6]));
5057 output_asm_insn (AS2 (cmp
%B13
,%2,%13), xops
);
5060 output_asm_insn (AS1 (je
,%l12
), xops
);
5061 output_asm_insn (AS1 (inc
%L0
,%0), xops
);
5064 /* Generate loop to check 4 bytes at a time. It is not a good idea to
5065 align this loop. It gives only huge programs, but does not help to
5067 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L", CODE_LABEL_NUMBER (xops
[8]));
5069 xops
[13] = gen_rtx_MEM (SImode
, xops
[0]);
5070 output_asm_insn (AS2 (mov
%L1
,%13,%1), xops
);
5072 if (QI_REG_P (xops
[1]))
5074 /* On i586 it is faster to combine the hi- and lo- part as
5075 a kind of lookahead. If anding both yields zero, then one
5076 of both *could* be zero, otherwise none of both is zero;
5077 this saves one instruction, on i486 this is slower
5078 tested with P-90, i486DX2-66, AMD486DX2-66 */
5081 output_asm_insn (AS2 (test
%B1
,%h1
,%b1
), xops
);
5082 output_asm_insn (AS1 (jne
,%l9
), xops
);
5085 /* Check first byte. */
5086 output_asm_insn (AS2 (test
%B1
,%b1
,%b1
), xops
);
5087 output_asm_insn (AS1 (je
,%l12
), xops
);
5089 /* Check second byte. */
5090 output_asm_insn (AS2 (test
%B1
,%h1
,%h1
), xops
);
5091 output_asm_insn (AS1 (je
,%l11
), xops
);
5094 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L",
5095 CODE_LABEL_NUMBER (xops
[9]));
5100 /* Check first byte. */
5101 output_asm_insn (AS2 (test
%L1
,%14,%1), xops
);
5102 output_asm_insn (AS1 (je
,%l12
), xops
);
5104 /* Check second byte. */
5105 output_asm_insn (AS2 (test
%L1
,%15,%1), xops
);
5106 output_asm_insn (AS1 (je
,%l11
), xops
);
5109 /* Check third byte. */
5110 output_asm_insn (AS2 (test
%L1
,%16,%1), xops
);
5111 output_asm_insn (AS1 (je
,%l10
), xops
);
5113 /* Check fourth byte and increment address. */
5114 output_asm_insn (AS2 (add
%L0
,%5,%0), xops
);
5115 output_asm_insn (AS2 (test
%L1
,%17,%1), xops
);
5116 output_asm_insn (AS1 (jne
,%l8
), xops
);
5118 /* Now generate fixups when the compare stops within a 4-byte word. */
5119 output_asm_insn (AS2 (sub
%L0
,%4,%0), xops
);
5121 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L", CODE_LABEL_NUMBER (xops
[10]));
5122 output_asm_insn (AS1 (inc
%L0
,%0), xops
);
5124 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L", CODE_LABEL_NUMBER (xops
[11]));
5125 output_asm_insn (AS1 (inc
%L0
,%0), xops
);
5127 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "L", CODE_LABEL_NUMBER (xops
[12]));
5133 output_fp_conditional_move (which_alternative
, operands
)
5134 int which_alternative
;
5137 switch (which_alternative
)
5140 /* r <- cond ? arg : r */
5141 output_asm_insn (AS2 (fcmov
%F1
,%2,%0), operands
);
5145 /* r <- cond ? r : arg */
5146 output_asm_insn (AS2 (fcmov
%f1
,%3,%0), operands
);
5150 /* r <- cond ? r : arg */
5151 output_asm_insn (AS2 (fcmov
%F1
,%2,%0), operands
);
5152 output_asm_insn (AS2 (fcmov
%f1
,%3,%0), operands
);
5163 output_int_conditional_move (which_alternative
, operands
)
5164 int which_alternative
;
5167 int code
= GET_CODE (operands
[1]);
5168 enum machine_mode mode
;
5171 /* This is very tricky. We have to do it right. For a code segement
5180 final_scan_insn () may delete the insn which sets CC. We have to
5181 tell final_scan_insn () if it should be reinserted. When CODE is
5182 GT or LE, we have to check the CC_NO_OVERFLOW bit and return
5183 NULL_PTR to tell final to reinsert the test insn because the
5184 conditional move cannot be handled properly without it. */
5185 if ((code
== GT
|| code
== LE
)
5186 && (cc_prev_status
.flags
& CC_NO_OVERFLOW
))
5189 mode
= GET_MODE (operands
[0]);
5192 xops
[0] = gen_rtx_SUBREG (SImode
, operands
[0], 1);
5193 xops
[1] = operands
[1];
5194 xops
[2] = gen_rtx_SUBREG (SImode
, operands
[2], 1);
5195 xops
[3] = gen_rtx_SUBREG (SImode
, operands
[3], 1);
5198 switch (which_alternative
)
5201 /* r <- cond ? arg : r */
5202 output_asm_insn (AS2 (cmov
%C1
,%2,%0), operands
);
5204 output_asm_insn (AS2 (cmov
%C1
,%2,%0), xops
);
5208 /* r <- cond ? r : arg */
5209 output_asm_insn (AS2 (cmov
%c1
,%3,%0), operands
);
5211 output_asm_insn (AS2 (cmov
%c1
,%3,%0), xops
);
5215 /* rm <- cond ? arg1 : arg2 */
5216 output_asm_insn (AS2 (cmov
%C1
,%2,%0), operands
);
5217 output_asm_insn (AS2 (cmov
%c1
,%3,%0), operands
);
5220 output_asm_insn (AS2 (cmov
%C1
,%2,%0), xops
);
5221 output_asm_insn (AS2 (cmov
%c1
,%3,%0), xops
);