diff options
Diffstat (limited to 'gcc/config/i386/i386.c')
-rw-r--r-- | gcc/config/i386/i386.c | 76 |
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 |