aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/i386/i386.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/i386/i386.c')
-rw-r--r--gcc/config/i386/i386.c76
1 files changed, 69 insertions, 7 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 47deda7ce50..a0b543a4101 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -13881,6 +13881,12 @@ legitimize_pic_address (rtx orig, rtx reg)
}
else
{
+ /* For %rip addressing, we have to use just disp32, not
+ base nor index. */
+ if (TARGET_64BIT
+ && (GET_CODE (base) == SYMBOL_REF
+ || GET_CODE (base) == LABEL_REF))
+ base = force_reg (mode, base);
if (GET_CODE (new_rtx) == PLUS
&& CONSTANT_P (XEXP (new_rtx, 1)))
{
@@ -23457,12 +23463,19 @@ counter_mode (rtx count_exp)
static rtx
ix86_copy_addr_to_reg (rtx addr)
{
+ rtx reg;
if (GET_MODE (addr) == Pmode || GET_MODE (addr) == VOIDmode)
- return copy_addr_to_reg (addr);
+ {
+ reg = copy_addr_to_reg (addr);
+ REG_POINTER (reg) = 1;
+ return reg;
+ }
else
{
gcc_assert (GET_MODE (addr) == DImode && Pmode == SImode);
- return gen_rtx_SUBREG (SImode, copy_to_mode_reg (DImode, addr), 0);
+ reg = copy_to_mode_reg (DImode, addr);
+ REG_POINTER (reg) = 1;
+ return gen_rtx_SUBREG (SImode, reg, 0);
}
}
@@ -24354,6 +24367,8 @@ expand_set_or_movmem_prologue_epilogue_by_misaligned_moves (rtx destmem, rtx src
*destptr = expand_simple_binop (GET_MODE (*destptr), PLUS, *destptr,
GEN_INT (prolog_size),
NULL_RTX, 1, OPTAB_DIRECT);
+ if (REG_P (*destptr) && REG_P (saveddest) && REG_POINTER (saveddest))
+ REG_POINTER (*destptr) = 1;
*destptr = expand_simple_binop (GET_MODE (*destptr), AND, *destptr,
GEN_INT (-desired_align),
*destptr, 1, OPTAB_DIRECT);
@@ -24363,8 +24378,8 @@ expand_set_or_movmem_prologue_epilogue_by_misaligned_moves (rtx destmem, rtx src
saveddest, 1, OPTAB_DIRECT);
/* Adjust srcptr and count. */
if (!issetmem)
- *srcptr = expand_simple_binop (GET_MODE (*srcptr), MINUS, *srcptr, saveddest,
- *srcptr, 1, OPTAB_DIRECT);
+ *srcptr = expand_simple_binop (GET_MODE (*srcptr), MINUS, *srcptr,
+ saveddest, *srcptr, 1, OPTAB_DIRECT);
*count = expand_simple_binop (GET_MODE (*count), PLUS, *count,
saveddest, *count, 1, OPTAB_DIRECT);
/* We copied at most size + prolog_size. */
@@ -25609,8 +25624,19 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
{
rtx b0 = gen_rtx_REG (BND64mode, FIRST_BND_REG);
rtx b1 = gen_rtx_REG (BND64mode, FIRST_BND_REG + 1);
- retval = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (3, retval, b0, b1));
- chkp_put_regs_to_expr_list (retval);
+ if (GET_CODE (retval) == PARALLEL)
+ {
+ b0 = gen_rtx_EXPR_LIST (VOIDmode, b0, const0_rtx);
+ b1 = gen_rtx_EXPR_LIST (VOIDmode, b1, const0_rtx);
+ rtx par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, b0, b1));
+ retval = chkp_join_splitted_slot (retval, par);
+ }
+ else
+ {
+ retval = gen_rtx_PARALLEL (VOIDmode,
+ gen_rtvec (3, retval, b0, b1));
+ chkp_put_regs_to_expr_list (retval);
+ }
}
call = gen_rtx_SET (VOIDmode, retval, call);
@@ -30588,6 +30614,8 @@ struct builtin_isa {
static struct builtin_isa ix86_builtins_isa[(int) IX86_BUILTIN_MAX];
+/* Bits that can still enable any inclusion of a builtin. */
+static HOST_WIDE_INT deferred_isa_values = 0;
/* Add an ix86 target builtin function with CODE, NAME and TYPE. Save the MASK
of which isa_flags to use in the ix86_builtins_isa array. Stores the
@@ -30631,6 +30659,9 @@ def_builtin (HOST_WIDE_INT mask, const char *name,
}
else
{
+ /* Just a MASK where set_and_not_built_p == true can potentially
+ include a builtin. */
+ deferred_isa_values |= mask;
ix86_builtins[(int) code] = NULL_TREE;
ix86_builtins_isa[(int) code].tcode = tcode;
ix86_builtins_isa[(int) code].name = name;
@@ -30666,6 +30697,12 @@ def_builtin_const (HOST_WIDE_INT mask, const char *name,
static void
ix86_add_new_builtins (HOST_WIDE_INT isa)
{
+ if ((isa & deferred_isa_values) == 0)
+ return;
+
+ /* Bits in ISA value can be removed from potential isa values. */
+ deferred_isa_values &= ~isa;
+
int i;
tree saved_current_target_pragma = current_target_pragma;
current_target_pragma = NULL_TREE;
@@ -35826,6 +35863,15 @@ safe_vector_operand (rtx x, machine_mode mode)
return x;
}
+/* Fixup modeless constants to fit required mode. */
+static rtx
+fixup_modeless_constant (rtx x, machine_mode mode)
+{
+ if (GET_MODE (x) == VOIDmode)
+ x = convert_to_mode (mode, x, 1);
+ return x;
+}
+
/* Subroutine of ix86_expand_builtin to take care of binop insns. */
static rtx
@@ -37472,6 +37518,8 @@ ix86_expand_args_builtin (const struct builtin_description *d,
if (memory_operand (op, mode))
num_memory++;
+ op = fixup_modeless_constant (op, mode);
+
if (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode)
{
if (optimize || !match || num_memory > 1)
@@ -37845,6 +37893,8 @@ ix86_expand_round_builtin (const struct builtin_description *d,
if (VECTOR_MODE_P (mode))
op = safe_vector_operand (op, mode);
+ op = fixup_modeless_constant (op, mode);
+
if (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode)
{
if (optimize || !match)
@@ -38252,6 +38302,8 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
if (VECTOR_MODE_P (mode))
op = safe_vector_operand (op, mode);
+ op = fixup_modeless_constant (op, mode);
+
if (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode)
op = copy_to_mode_reg (mode, op);
else
@@ -39815,6 +39867,9 @@ addcarryx:
op1 = copy_to_mode_reg (Pmode, op1);
if (!insn_data[icode].operand[3].predicate (op2, mode2))
op2 = copy_to_mode_reg (mode2, op2);
+
+ op3 = fixup_modeless_constant (op3, mode3);
+
if (GET_MODE (op3) == mode3 || GET_MODE (op3) == VOIDmode)
{
if (!insn_data[icode].operand[4].predicate (op3, mode3))
@@ -39958,6 +40013,8 @@ addcarryx:
if (!insn_data[icode].operand[0].predicate (op0, Pmode))
op0 = copy_to_mode_reg (Pmode, op0);
+ op1 = fixup_modeless_constant (op1, mode1);
+
if (GET_MODE (op1) == mode1 || GET_MODE (op1) == VOIDmode)
{
if (!insn_data[icode].operand[1].predicate (op1, mode1))
@@ -40004,6 +40061,8 @@ addcarryx:
mode3 = insn_data[icode].operand[3].mode;
mode4 = insn_data[icode].operand[4].mode;
+ op0 = fixup_modeless_constant (op0, mode0);
+
if (GET_MODE (op0) == mode0
|| (GET_MODE (op0) == VOIDmode && op0 != constm1_rtx))
{
@@ -41230,7 +41289,7 @@ ix86_register_priority (int hard_regno)
if (FIRST_REX_SSE_REG <= hard_regno && hard_regno <= LAST_REX_SSE_REG)
return 2;
/* Usage of AX register results in smaller code. Prefer it. */
- if (hard_regno == 0)
+ if (hard_regno == AX_REG)
return 4;
return 3;
}
@@ -51874,6 +51933,9 @@ ix86_initialize_bounds (tree var, tree lb, tree ub, tree *stmts)
#if TARGET_MACHO
#undef TARGET_BINDS_LOCAL_P
#define TARGET_BINDS_LOCAL_P darwin_binds_local_p
+#else
+#undef TARGET_BINDS_LOCAL_P
+#define TARGET_BINDS_LOCAL_P default_binds_local_p_2
#endif
#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
#undef TARGET_BINDS_LOCAL_P