#include "toplev.h"
#include "basic-block.h"
#include "ggc.h"
+#include "target.h"
+#include "target-def.h"
#ifndef CHECK_STACK_LIMIT
#define CHECK_STACK_LIMIT -1
const int x86_unroll_strlen = m_486 | m_PENT | m_PPRO | m_ATHLON | m_K6;
const int x86_cmove = m_PPRO | m_ATHLON | m_PENT4;
const int x86_deep_branch = m_PPRO | m_K6 | m_ATHLON | m_PENT4;
+const int x86_branch_hints = m_PENT4;
const int x86_use_sahf = m_PPRO | m_K6 | m_PENT4;
const int x86_partial_reg_stall = m_PPRO;
const int x86_use_loop = m_K6;
const int x86_integer_DFmode_moves = ~(m_ATHLON | m_PENT4);
const int x86_partial_reg_dependency = m_ATHLON | m_PENT4;
const int x86_memory_mismatch_stall = m_ATHLON | m_PENT4;
+const int x86_accumulate_outgoing_args = m_ATHLON | m_PENT4 | m_PPRO;
+const int x86_prologue_using_move = m_ATHLON | m_PENT4 | m_PPRO;
+const int x86_epilogue_using_move = m_ATHLON | m_PENT4 | m_PPRO;
#define AT_BP(mode) (gen_rtx_MEM ((mode), hard_frame_pointer_rtx))
struct rtx_def *ix86_compare_op0 = NULL_RTX;
struct rtx_def *ix86_compare_op1 = NULL_RTX;
-#define MAX_386_STACK_LOCALS 2
+#define MAX_386_STACK_LOCALS 3
/* Size of the register save area. */
#define X86_64_VARARGS_SIZE (REGPARM_MAX * UNITS_PER_WORD + SSE_REGPARM_MAX * 16)
const char *ix86_branch_cost_string;
/* Power of two alignment for functions. */
-int ix86_align_funcs;
const char *ix86_align_funcs_string;
-
-/* Power of two alignment for loops. */
-int ix86_align_loops;
-
-/* Power of two alignment for non-loop jumps. */
-int ix86_align_jumps;
\f
static void output_pic_addr_const PARAMS ((FILE *, rtx, int));
static void put_condition_code PARAMS ((enum rtx_code, enum machine_mode,
static int ix86_safe_length_prefix PARAMS ((rtx));
static int ix86_nsaved_regs PARAMS((void));
static void ix86_emit_save_regs PARAMS((void));
-static void ix86_emit_restore_regs_using_mov PARAMS ((rtx, int, bool));
-static void ix86_emit_epilogue_esp_adjustment PARAMS((int));
+static void ix86_emit_save_regs_using_mov PARAMS ((rtx, HOST_WIDE_INT));
+static void ix86_emit_restore_regs_using_mov PARAMS ((rtx, int, int));
static void ix86_set_move_mem_attrs_1 PARAMS ((rtx, rtx, rtx, rtx, rtx));
static void ix86_sched_reorder_pentium PARAMS((rtx *, rtx *));
static void ix86_sched_reorder_ppro PARAMS((rtx *, rtx *));
static int ix86_fp_comparison_fcomi_cost PARAMS ((enum rtx_code code));
static int ix86_fp_comparison_sahf_cost PARAMS ((enum rtx_code code));
static int ix86_fp_comparison_cost PARAMS ((enum rtx_code code));
-static int ix86_save_reg PARAMS ((int, bool));
+static int ix86_save_reg PARAMS ((int, int));
static void ix86_compute_frame_layout PARAMS ((struct ix86_frame *));
+static int ix86_comp_type_attributes PARAMS ((tree, tree));
+\f
+/* Initialize the GCC target structure. */
+#undef TARGET_VALID_TYPE_ATTRIBUTE
+#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
+# define TARGET_VALID_TYPE_ATTRIBUTE i386_pe_valid_type_attribute_p
+# undef TARGET_VALID_DECL_ATTRIBUTE
+# define TARGET_VALID_DECL_ATTRIBUTE i386_pe_valid_decl_attribute_p
+# undef TARGET_MERGE_DECL_ATTRIBUTES
+# define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
+#else
+# define TARGET_VALID_TYPE_ATTRIBUTE ix86_valid_type_attribute_p
+#endif
+
+#undef TARGET_COMP_TYPE_ATTRIBUTES
+#define TARGET_COMP_TYPE_ATTRIBUTES ix86_comp_type_attributes
+
+struct gcc_target target = TARGET_INITIALIZER;
\f
/* Sometimes certain combinations of command options do not make
sense on a particular target machine. You can define a macro
ix86_cmodel_string, TARGET_64BIT ? "64" : "32");
if (ix86_cmodel == CM_LARGE)
sorry ("Code model `large' not supported yet.");
+ if ((TARGET_64BIT != 0) != ((target_flags & MASK_64BIT) != 0))
+ sorry ("%i-bit mode not compiled in.",
+ (target_flags & MASK_64BIT) ? 64 : 32);
if (ix86_arch_string != 0)
{
if (TARGET_64BIT)
ix86_regparm = REGPARM_MAX;
- /* Validate -malign-loops= value, or provide default. */
- ix86_align_loops = processor_target_table[ix86_cpu].align_loop;
+ /* If the user has provided any of the -malign-* options,
+ warn and use that value only if -falign-* is not set.
+ Remove this code in GCC 3.2 or later. */
if (ix86_align_loops_string)
{
- i = atoi (ix86_align_loops_string);
- if (i < 0 || i > MAX_CODE_ALIGN)
- error ("-malign-loops=%d is not between 0 and %d", i, MAX_CODE_ALIGN);
- else
- ix86_align_loops = i;
+ warning ("-malign-loops is obsolete, use -falign-loops");
+ if (align_loops == 0)
+ {
+ i = atoi (ix86_align_loops_string);
+ if (i < 0 || i > MAX_CODE_ALIGN)
+ error ("-malign-loops=%d is not between 0 and %d", i, MAX_CODE_ALIGN);
+ else
+ align_loops = 1 << i;
+ }
}
- /* Validate -malign-jumps= value, or provide default. */
- ix86_align_jumps = processor_target_table[ix86_cpu].align_jump;
if (ix86_align_jumps_string)
{
- i = atoi (ix86_align_jumps_string);
- if (i < 0 || i > MAX_CODE_ALIGN)
- error ("-malign-jumps=%d is not between 0 and %d", i, MAX_CODE_ALIGN);
- else
- ix86_align_jumps = i;
+ warning ("-malign-jumps is obsolete, use -falign-jumps");
+ if (align_jumps == 0)
+ {
+ i = atoi (ix86_align_jumps_string);
+ if (i < 0 || i > MAX_CODE_ALIGN)
+ error ("-malign-loops=%d is not between 0 and %d", i, MAX_CODE_ALIGN);
+ else
+ align_jumps = 1 << i;
+ }
}
- /* Validate -malign-functions= value, or provide default. */
- ix86_align_funcs = processor_target_table[ix86_cpu].align_func;
if (ix86_align_funcs_string)
{
- i = atoi (ix86_align_funcs_string);
- if (i < 0 || i > MAX_CODE_ALIGN)
- error ("-malign-functions=%d is not between 0 and %d",
- i, MAX_CODE_ALIGN);
- else
- ix86_align_funcs = i;
+ warning ("-malign-functions is obsolete, use -falign-functions");
+ if (align_functions == 0)
+ {
+ i = atoi (ix86_align_funcs_string);
+ if (i < 0 || i > MAX_CODE_ALIGN)
+ error ("-malign-loops=%d is not between 0 and %d", i, MAX_CODE_ALIGN);
+ else
+ align_functions = 1 << i;
+ }
}
+ /* Default align_* from the processor table. */
+#define abs(n) (n < 0 ? -n : n)
+ if (align_loops == 0)
+ align_loops = 1 << abs (processor_target_table[ix86_cpu].align_loop);
+ if (align_jumps == 0)
+ align_jumps = 1 << abs (processor_target_table[ix86_cpu].align_jump);
+ if (align_functions == 0)
+ align_functions = 1 << abs (processor_target_table[ix86_cpu].align_func);
+
/* Validate -mpreferred-stack-boundary= value, or provide default.
The default of 128 bits is for Pentium III's SSE __m128. */
ix86_preferred_stack_boundary = 128;
on by -msse. */
if (TARGET_SSE)
target_flags |= MASK_MMX;
+
+ if ((x86_accumulate_outgoing_args & CPUMASK)
+ && !(target_flags & MASK_NO_ACCUMULATE_OUTGOING_ARGS)
+ && !optimize_size)
+ target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
}
\f
void
}
\f
/* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
- attribute for DECL. The attributes in ATTRIBUTES have previously been
- assigned to DECL. */
-
-int
-ix86_valid_decl_attribute_p (decl, attributes, identifier, args)
- tree decl ATTRIBUTE_UNUSED;
- tree attributes ATTRIBUTE_UNUSED;
- tree identifier ATTRIBUTE_UNUSED;
- tree args ATTRIBUTE_UNUSED;
-{
- return 0;
-}
-
-/* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
attribute for TYPE. The attributes in ATTRIBUTES have previously been
assigned to TYPE. */
are compatible, and 2 if they are nearly compatible (which causes a
warning to be generated). */
-int
+static int
ix86_comp_type_attributes (type1, type2)
tree type1;
tree type2;
int
incdec_operand (op, mode)
register rtx op;
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
/* On Pentium4, the inc and dec operations causes extra dependancy on flag
registers, since carry flag is not set. */
if (TARGET_PENTIUM4 && !optimize_size)
return 0;
- if (op == const1_rtx || op == constm1_rtx)
- return 1;
- if (GET_CODE (op) != CONST_INT)
- return 0;
- if (mode == SImode && INTVAL (op) == (HOST_WIDE_INT) 0xffffffff)
- return 1;
- if (mode == HImode && INTVAL (op) == (HOST_WIDE_INT) 0xffff)
- return 1;
- if (mode == QImode && INTVAL (op) == (HOST_WIDE_INT) 0xff)
- return 1;
- return 0;
+ return op == const1_rtx || op == constm1_rtx;
}
/* Return nonzero if OP is acceptable as operand of DImode shift
register rtx op;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
+ int regno;
if ((!TARGET_64BIT || GET_MODE (op) != DImode)
&& GET_MODE (op) != SImode && GET_MODE (op) != HImode)
return 0;
- return register_operand (op, VOIDmode);
+
+ if (!register_operand (op, VOIDmode))
+ return 0;
+
+ /* Be curefull to accept only registers having upper parts. */
+ regno = REG_P (op) ? REGNO (op) : REGNO (SUBREG_REG (op));
+ return (regno > LAST_VIRTUAL_REGISTER || regno < 4);
}
/* Return 1 if this is a valid binary floating-point operation.
rtx op;
enum machine_mode mode;
{
- if (general_operand (op, mode))
+ if (nonimmediate_operand (op, mode))
return 1;
if (GET_CODE (op) == AND
static int
ix86_save_reg (regno, maybe_eh_return)
int regno;
- bool maybe_eh_return;
+ int maybe_eh_return;
{
if (flag_pic
&& ! TARGET_64BIT
}
}
+/* Emit code to save registers using MOV insns. First register
+ is restored from POINTER + OFFSET. */
+static void
+ix86_emit_save_regs_using_mov (pointer, offset)
+ rtx pointer;
+ HOST_WIDE_INT offset;
+{
+ int regno;
+ rtx insn;
+
+ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ if (ix86_save_reg (regno, true))
+ {
+ insn = emit_move_insn (adj_offsettable_operand (gen_rtx_MEM (Pmode,
+ pointer),
+ offset),
+ gen_rtx_REG (Pmode, regno));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ offset += UNITS_PER_WORD;
+ }
+}
+
/* Expand the prologue into a bunch of separate insns. */
void
|| current_function_uses_const_pool)
&& !TARGET_64BIT);
struct ix86_frame frame;
+ int use_mov = (TARGET_PROLOGUE_USING_MOVE && !optimize_size);
+ HOST_WIDE_INT allocate;
ix86_compute_frame_layout (&frame);
RTX_FRAME_RELATED_P (insn) = 1;
}
- ix86_emit_save_regs ();
+ allocate = frame.to_allocate;
+ /* In case we are dealing only with single register and empty frame,
+ push is equivalent of the mov+add sequence. */
+ if (allocate == 0 && frame.nregs <= 1)
+ use_mov = 0;
+
+ if (!use_mov)
+ ix86_emit_save_regs ();
+ else
+ allocate += frame.nregs * UNITS_PER_WORD;
- if (frame.to_allocate == 0)
+ if (allocate == 0)
;
- else if (! TARGET_STACK_PROBE || frame.to_allocate < CHECK_STACK_LIMIT)
+ else if (! TARGET_STACK_PROBE || allocate < CHECK_STACK_LIMIT)
{
- if (frame_pointer_needed)
- insn = emit_insn (gen_pro_epilogue_adjust_stack
- (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (-frame.to_allocate), hard_frame_pointer_rtx));
- else
- if (TARGET_64BIT)
- insn = emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (-frame.to_allocate)));
- else
- insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (-frame.to_allocate)));
+ insn = emit_insn (gen_pro_epilogue_adjust_stack
+ (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (-allocate)));
RTX_FRAME_RELATED_P (insn) = 1;
}
else
abort();
arg0 = gen_rtx_REG (SImode, 0);
- emit_move_insn (arg0, GEN_INT (frame.to_allocate));
+ emit_move_insn (arg0, GEN_INT (allocate));
sym = gen_rtx_MEM (FUNCTION_MODE,
gen_rtx_SYMBOL_REF (Pmode, "_alloca"));
= gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_USE (VOIDmode, arg0),
CALL_INSN_FUNCTION_USAGE (insn));
}
+ if (use_mov)
+ {
+ if (!frame_pointer_needed || !frame.to_allocate)
+ ix86_emit_save_regs_using_mov (stack_pointer_rtx, frame.to_allocate);
+ else
+ ix86_emit_save_regs_using_mov (hard_frame_pointer_rtx,
+ -frame.nregs * UNITS_PER_WORD);
+ }
#ifdef SUBTARGET_PROLOGUE
SUBTARGET_PROLOGUE;
emit_insn (gen_blockage ());
}
-/* Emit code to add TSIZE to esp value. Use POP instruction when
- profitable. */
-
-static void
-ix86_emit_epilogue_esp_adjustment (tsize)
- int tsize;
-{
- /* If a frame pointer is present, we must be sure to tie the sp
- to the fp so that we don't mis-schedule. */
- if (frame_pointer_needed)
- emit_insn (gen_pro_epilogue_adjust_stack (stack_pointer_rtx,
- stack_pointer_rtx,
- GEN_INT (tsize),
- hard_frame_pointer_rtx));
- else
- if (TARGET_64BIT)
- emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (tsize)));
- else
- emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (tsize)));
-}
-
/* Emit code to restore saved registers using MOV insns. First register
is restored from POINTER + OFFSET. */
static void
ix86_emit_restore_regs_using_mov (pointer, offset, maybe_eh_return)
rtx pointer;
int offset;
- bool maybe_eh_return;
+ int maybe_eh_return;
{
int regno;
and there is exactly one register to pop. This heruistic may need some
tuning in future. */
if ((!sp_valid && frame.nregs <= 1)
+ || (TARGET_EPILOGUE_USING_MOVE && !optimize_size
+ && (frame.nregs > 1 || frame.to_allocate))
|| (frame_pointer_needed && !frame.nregs && frame.to_allocate)
|| (frame_pointer_needed && TARGET_USE_LEAVE && !optimize_size
&& frame.nregs == 1)
emit_move_insn (hard_frame_pointer_rtx, tmp);
emit_insn (gen_pro_epilogue_adjust_stack
- (stack_pointer_rtx, sa, const0_rtx,
- hard_frame_pointer_rtx));
+ (stack_pointer_rtx, sa, const0_rtx));
}
else
{
}
}
else if (!frame_pointer_needed)
- ix86_emit_epilogue_esp_adjustment (frame.to_allocate
- + frame.nregs * UNITS_PER_WORD);
+ emit_insn (gen_pro_epilogue_adjust_stack
+ (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (frame.to_allocate
+ + frame.nregs * UNITS_PER_WORD)));
/* If not an i386, mov & pop is faster than "leave". */
else if (TARGET_USE_LEAVE || optimize_size)
emit_insn (TARGET_64BIT ? gen_leave_rex64 () : gen_leave ());
{
emit_insn (gen_pro_epilogue_adjust_stack (stack_pointer_rtx,
hard_frame_pointer_rtx,
- const0_rtx,
- hard_frame_pointer_rtx));
+ const0_rtx));
if (TARGET_64BIT)
emit_insn (gen_popdi1 (hard_frame_pointer_rtx));
else
abort ();
emit_insn (gen_pro_epilogue_adjust_stack (stack_pointer_rtx,
hard_frame_pointer_rtx,
- GEN_INT (offset),
- hard_frame_pointer_rtx));
+ GEN_INT (offset)));
}
else if (frame.to_allocate)
- ix86_emit_epilogue_esp_adjustment (frame.to_allocate);
+ emit_insn (gen_pro_epilogue_adjust_stack
+ (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (frame.to_allocate)));
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (ix86_save_reg (regno, false))
if (ASSEMBLER_DIALECT == 0 || USER_LABEL_PREFIX[0] == 0)
putc ('%', file);
- if (code == 'w')
+ if (code == 'w' || MMX_REG_P (x))
code = 2;
else if (code == 'b')
code = 1;
code = 3;
else if (code == 'h')
code = 0;
- else if (code == 'm' || MMX_REG_P (x))
- code = 5;
else
code = GET_MODE_SIZE (GET_MODE (x));
abort ();
switch (code)
{
- case 5:
+ case 0:
error ("Extended registers have no high halves\n");
break;
case 1:
}
switch (code)
{
- case 5:
- fputs (hi_reg_name[REGNO (x)], file);
- break;
case 3:
if (STACK_TOP_P (x))
{
L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
C -- print opcode suffix for set/cmov insn.
c -- like C, but print reversed condition
+ F,f -- likewise, but for floating-point.
R -- print the prefix for register names.
z -- print the opcode suffix for the size of the current operand.
* -- print a star (in certain assembler syntax)
w -- likewise, print the HImode name of the register.
k -- likewise, print the SImode name of the register.
q -- likewise, print the DImode name of the register.
- h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
- y -- print "st(0)" instead of "st" as a register.
- m -- print "st(n)" as an mmx register.
+ h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
+ y -- print "st(0)" instead of "st" as a register.
D -- print condition for SSE cmp instruction.
+ P -- if PIC, print an @PLT suffix.
+ X -- don't print any sort of PIC '@' suffix for a symbol.
*/
void
case 'q':
case 'h':
case 'y':
- case 'm':
case 'X':
case 'P':
break;
case 'f':
put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 1, 1, file);
return;
+ case '+':
+ {
+ rtx x;
+ if (!optimize || optimize_size || !TARGET_BRANCH_PREDICTION_HINTS)
+ return;
+
+ x = find_reg_note (current_output_insn, REG_BR_PROB, 0);
+ if (x)
+ {
+ int pred_val = INTVAL (XEXP (x, 0));
+
+ if (pred_val < REG_BR_PROB_BASE * 45 / 100
+ || pred_val > REG_BR_PROB_BASE * 55 / 100)
+ {
+ int taken = pred_val > REG_BR_PROB_BASE / 2;
+ int cputaken = final_forward_branch_p (current_output_insn) == 0;
+
+ /* Emit hints only in the case default branch prediction
+ heruistics would fail. */
+ if (taken != cputaken)
+ {
+ /* We use 3e (DS) prefix for taken branches and
+ 2e (CS) prefix for not taken branches. */
+ if (taken)
+ fputs ("ds ; ", file);
+ else
+ fputs ("cs ; ", file);
+ }
+ }
+ }
+ return;
+ }
default:
{
char str[50];
}
else if (offsettable_memref_p (op))
{
- rtx lo_addr = XEXP (op, 0);
rtx hi_addr = XEXP (adj_offsettable_operand (op, 4), 0);
- lo_half[num] = change_address (op, SImode, lo_addr);
+
+ lo_half[num] = adjust_address (op, SImode, 0);
hi_half[num] = change_address (op, SImode, hi_addr);
}
else
return buf;
}
+/* Output code to initialize control word copies used by
+ trunc?f?i patterns. NORMAL is set to current control word, while ROUND_DOWN
+ is set to control word rounding downwards. */
+void
+emit_i387_cw_initialization (normal, round_down)
+ rtx normal, round_down;
+{
+ rtx reg = gen_reg_rtx (HImode);
+
+ emit_insn (gen_x86_fnstcw_1 (normal));
+ emit_move_insn (reg, normal);
+ if (!TARGET_PARTIAL_REG_STALL && !optimize_size
+ && !TARGET_64BIT)
+ emit_insn (gen_movsi_insv_1 (reg, GEN_INT (0xc)));
+ else
+ emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0xc00)));
+ emit_move_insn (round_down, reg);
+}
+
/* Output code for INSN to convert a float to a signed int. OPERANDS
are the insn operands. The output may be [HSD]Imode and the input
operand may be [SDX]Fmode. */
if (dimode_p && !stack_top_dies)
output_asm_insn ("fld\t%y1", operands);
- if (! STACK_TOP_P (operands[1]))
+ if (!STACK_TOP_P (operands[1]))
abort ();
- xops[0] = GEN_INT (12);
- xops[1] = adj_offsettable_operand (operands[2], 1);
- xops[1] = change_address (xops[1], QImode, NULL_RTX);
-
- xops[2] = operands[0];
if (GET_CODE (operands[0]) != MEM)
- xops[2] = operands[3];
-
- output_asm_insn ("fnstcw\t%2", operands);
- output_asm_insn ("mov{l}\t{%2, %4|%4, %2}", operands);
- output_asm_insn ("mov{b}\t{%0, %1|%1, %0}", xops);
- output_asm_insn ("fldcw\t%2", operands);
- output_asm_insn ("mov{l}\t{%4, %2|%2, %4}", operands);
+ abort ();
+ output_asm_insn ("fldcw\t%3", operands);
if (stack_top_dies || dimode_p)
- output_asm_insn ("fistp%z2\t%2", xops);
+ output_asm_insn ("fistp%z0\t%0", operands);
else
- output_asm_insn ("fist%z2\t%2", xops);
-
+ output_asm_insn ("fist%z0\t%0", operands);
output_asm_insn ("fldcw\t%2", operands);
- if (GET_CODE (operands[0]) != MEM)
- {
- if (dimode_p)
- {
- split_di (operands+0, 1, xops+0, xops+1);
- split_di (operands+3, 1, xops+2, xops+3);
- output_asm_insn ("mov{l}\t{%2, %0|%0, %2}", xops);
- output_asm_insn ("mov{l}\t{%3, %1|%1, %3}", xops);
- }
- else if (GET_MODE (operands[0]) == SImode)
- output_asm_insn ("mov{l}\t{%3, %0|%0, %3}", operands);
- else
- output_asm_insn ("mov{w}\t{%3, %0|%0, %3}", operands);
- }
-
return "";
}
emit_move_insn (tmp, operands[2]);
operands[2] = tmp;
}
+ if (! register_operand (operands[2], VOIDmode)
+ && ! register_operand (operands[3], VOIDmode))
+ operands[2] = force_reg (GET_MODE (operands[0]), operands[2]);
emit_insn (compare_seq);
emit_insn (gen_rtx_SET (VOIDmode, operands[0],
/* We may be called from the post-reload splitter. */
&& (!REG_P (operands[0])
|| SSE_REG_P (operands[0])
- || REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
- && 0)
+ || REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
{
rtx op0 = ix86_compare_op0, op1 = ix86_compare_op1;
code = GET_CODE (operands[1]);
}
else if (offsettable_memref_p (operand))
{
- operand = change_address (operand, SImode, XEXP (operand, 0));
+ operand = adjust_address (operand, SImode, 0);
parts[0] = operand;
parts[1] = adj_offsettable_operand (operand, 4);
if (size == 3)
if (GET_MODE (part[1][1]) == SImode)
{
if (GET_CODE (part[1][1]) == MEM)
- part[1][1] = change_address (part[1][1], DImode, XEXP (part[1][1], 0));
+ part[1][1] = adjust_address (part[1][1], DImode, 0);
else if (REG_P (part[1][1]))
part[1][1] = gen_rtx_REG (DImode, REGNO (part[1][1]));
else
insn_type = get_attr_type (insn);
dep_insn_type = get_attr_type (dep_insn);
- /* Prologue and epilogue allocators can have a false dependency on ebp.
- This results in one cycle extra stall on Pentium prologue scheduling,
- so handle this important case manually. */
- if (dep_insn_code_number == CODE_FOR_pro_epilogue_adjust_stack
- && dep_insn_type == TYPE_ALU
- && !reg_mentioned_p (stack_pointer_rtx, insn))
- return 0;
-
switch (ix86_cpu)
{
case PROCESSOR_PENTIUM:
}
#define def_builtin(NAME, TYPE, CODE) \
- builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL_PTR)
+ builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL)
struct builtin_description
{
enum insn_code icode;
case IX86_BUILTIN_SETPS1:
target = assign_386_stack_local (SFmode, 0);
arg0 = TREE_VALUE (arglist);
- emit_move_insn (change_address (target, SFmode, XEXP (target, 0)),
+ emit_move_insn (adjust_address (target, SFmode, 0),
expand_expr (arg0, NULL_RTX, VOIDmode, 0));
op0 = gen_reg_rtx (V4SFmode);
- emit_insn (gen_sse_loadss (op0, change_address (target, V4SFmode,
- XEXP (target, 0))));
+ emit_insn (gen_sse_loadss (op0, adjust_address (target, V4SFmode, 0)));
emit_insn (gen_sse_shufps (op0, op0, op0, GEN_INT (0)));
return op0;
case IX86_BUILTIN_SETPS:
target = assign_386_stack_local (V4SFmode, 0);
- op0 = change_address (target, SFmode, XEXP (target, 0));
+ op0 = adjust_address (target, SFmode, 0);
arg0 = TREE_VALUE (arglist);
arg1 = TREE_VALUE (TREE_CHAIN (arglist));
arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));