aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.7/gcc/config/i386/i386.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.7/gcc/config/i386/i386.c')
-rw-r--r--gcc-4.7/gcc/config/i386/i386.c290
1 files changed, 208 insertions, 82 deletions
diff --git a/gcc-4.7/gcc/config/i386/i386.c b/gcc-4.7/gcc/config/i386/i386.c
index 34e6f1f14..50fe1e24e 100644
--- a/gcc-4.7/gcc/config/i386/i386.c
+++ b/gcc-4.7/gcc/config/i386/i386.c
@@ -2448,6 +2448,8 @@ static rtx (*ix86_gen_andsp) (rtx, rtx, rtx);
static rtx (*ix86_gen_allocate_stack_worker) (rtx, rtx);
static rtx (*ix86_gen_adjust_stack_and_probe) (rtx, rtx, rtx);
static rtx (*ix86_gen_probe_stack_range) (rtx, rtx, rtx);
+static rtx (*ix86_gen_tls_global_dynamic_64) (rtx, rtx, rtx);
+static rtx (*ix86_gen_tls_local_dynamic_base_64) (rtx, rtx);
/* Preferred alignment for stack boundary in bits. */
unsigned int ix86_preferred_stack_boundary;
@@ -2658,7 +2660,6 @@ ix86_target_string (HOST_WIDE_INT isa, int flags, const char *arch,
preceding options while match those first. */
static struct ix86_target_opts isa_opts[] =
{
- { "-m64", OPTION_MASK_ISA_64BIT },
{ "-mfma4", OPTION_MASK_ISA_FMA4 },
{ "-mfma", OPTION_MASK_ISA_FMA },
{ "-mxop", OPTION_MASK_ISA_XOP },
@@ -2731,6 +2732,7 @@ ix86_target_string (HOST_WIDE_INT isa, int flags, const char *arch,
size_t len;
size_t line_len;
size_t sep_len;
+ const char *abi;
memset (opts, '\0', sizeof (opts));
@@ -2748,6 +2750,21 @@ ix86_target_string (HOST_WIDE_INT isa, int flags, const char *arch,
opts[num++][1] = tune;
}
+ /* Add -m32/-m64/-mx32. */
+ if ((isa & OPTION_MASK_ISA_64BIT) != 0)
+ {
+ if ((isa & OPTION_MASK_ABI_64) != 0)
+ abi = "-m64";
+ else
+ abi = "-mx32";
+ isa &= ~ (OPTION_MASK_ISA_64BIT
+ | OPTION_MASK_ABI_64
+ | OPTION_MASK_ABI_X32);
+ }
+ else
+ abi = "-m32";
+ opts[num++][0] = abi;
+
/* Pick out the options in isa options. */
for (i = 0; i < ARRAY_SIZE (isa_opts); i++)
{
@@ -3096,6 +3113,46 @@ ix86_option_override_internal (bool main_args_p)
sw = "attribute";
}
+ /* Turn off both OPTION_MASK_ABI_64 and OPTION_MASK_ABI_X32 if
+ TARGET_64BIT_DEFAULT is true and TARGET_64BIT is false. */
+ if (TARGET_64BIT_DEFAULT && !TARGET_64BIT)
+ ix86_isa_flags &= ~(OPTION_MASK_ABI_64 | OPTION_MASK_ABI_X32);
+#ifdef TARGET_BI_ARCH
+ else
+ {
+#if TARGET_BI_ARCH == 1
+ /* When TARGET_BI_ARCH == 1, by default, OPTION_MASK_ABI_64
+ is on and OPTION_MASK_ABI_X32 is off. We turn off
+ OPTION_MASK_ABI_64 if OPTION_MASK_ABI_X32 is turned on by
+ -mx32. */
+ if (TARGET_X32)
+ ix86_isa_flags &= ~OPTION_MASK_ABI_64;
+#else
+ /* When TARGET_BI_ARCH == 2, by default, OPTION_MASK_ABI_X32 is
+ on and OPTION_MASK_ABI_64 is off. We turn off
+ OPTION_MASK_ABI_X32 if OPTION_MASK_ABI_64 is turned on by
+ -m64. */
+ if (TARGET_LP64)
+ ix86_isa_flags &= ~OPTION_MASK_ABI_X32;
+#endif
+ }
+#endif
+
+ if (TARGET_X32)
+ {
+ /* Always turn on OPTION_MASK_ISA_64BIT and turn off
+ OPTION_MASK_ABI_64 for TARGET_X32. */
+ ix86_isa_flags |= OPTION_MASK_ISA_64BIT;
+ ix86_isa_flags &= ~OPTION_MASK_ABI_64;
+ }
+ else if (TARGET_LP64)
+ {
+ /* Always turn on OPTION_MASK_ISA_64BIT and turn off
+ OPTION_MASK_ABI_X32 for TARGET_LP64. */
+ ix86_isa_flags |= OPTION_MASK_ISA_64BIT;
+ ix86_isa_flags &= ~OPTION_MASK_ABI_X32;
+ }
+
#ifdef SUBTARGET_OVERRIDE_OPTIONS
SUBTARGET_OVERRIDE_OPTIONS;
#endif
@@ -3104,9 +3161,6 @@ ix86_option_override_internal (bool main_args_p)
SUBSUBTARGET_OVERRIDE_OPTIONS;
#endif
- if (TARGET_X32)
- ix86_isa_flags |= OPTION_MASK_ISA_64BIT;
-
/* -fPIC is the default for x86_64. */
if (TARGET_MACHO && TARGET_64BIT)
flag_pic = 2;
@@ -3175,6 +3229,17 @@ ix86_option_override_internal (bool main_args_p)
else
ix86_arch_specified = 1;
+ if (global_options_set.x_ix86_pmode)
+ {
+ if ((TARGET_LP64 && ix86_pmode == PMODE_SI)
+ || (!TARGET_64BIT && ix86_pmode == PMODE_DI))
+ error ("address mode %qs not supported in the %s bit mode",
+ TARGET_64BIT ? "short" : "long",
+ TARGET_64BIT ? "64" : "32");
+ }
+ else
+ ix86_pmode = TARGET_LP64 ? PMODE_DI : PMODE_SI;
+
if (!global_options_set.x_ix86_abi)
ix86_abi = DEFAULT_ABI;
@@ -3588,7 +3653,7 @@ ix86_option_override_internal (bool main_args_p)
ix86_preferred_stack_boundary = PREFERRED_STACK_BOUNDARY_DEFAULT;
if (global_options_set.x_ix86_preferred_stack_boundary_arg)
{
- int min = (TARGET_64BIT ? 4 : 2);
+ int min = (TARGET_64BIT ? (TARGET_SSE ? 4 : 3) : 2);
int max = (TARGET_SEH ? 4 : 12);
if (ix86_preferred_stack_boundary_arg < min
@@ -3751,11 +3816,33 @@ ix86_option_override_internal (bool main_args_p)
if (TARGET_64BIT)
{
ix86_gen_leave = gen_leave_rex64;
+ if (Pmode == DImode)
+ {
+ ix86_gen_monitor = gen_sse3_monitor64_di;
+ ix86_gen_tls_global_dynamic_64 = gen_tls_global_dynamic_64_di;
+ ix86_gen_tls_local_dynamic_base_64
+ = gen_tls_local_dynamic_base_64_di;
+ }
+ else
+ {
+ ix86_gen_monitor = gen_sse3_monitor64_si;
+ ix86_gen_tls_global_dynamic_64 = gen_tls_global_dynamic_64_si;
+ ix86_gen_tls_local_dynamic_base_64
+ = gen_tls_local_dynamic_base_64_si;
+ }
+ }
+ else
+ {
+ ix86_gen_leave = gen_leave;
+ ix86_gen_monitor = gen_sse3_monitor;
+ }
+
+ if (Pmode == DImode)
+ {
ix86_gen_add3 = gen_adddi3;
ix86_gen_sub3 = gen_subdi3;
ix86_gen_sub3_carry = gen_subdi3_carry;
ix86_gen_one_cmpl2 = gen_one_cmpldi2;
- ix86_gen_monitor = gen_sse3_monitor64;
ix86_gen_andsp = gen_anddi3;
ix86_gen_allocate_stack_worker = gen_allocate_stack_worker_probe_di;
ix86_gen_adjust_stack_and_probe = gen_adjust_stack_and_probedi;
@@ -3763,12 +3850,10 @@ ix86_option_override_internal (bool main_args_p)
}
else
{
- ix86_gen_leave = gen_leave;
ix86_gen_add3 = gen_addsi3;
ix86_gen_sub3 = gen_subsi3;
ix86_gen_sub3_carry = gen_subsi3_carry;
ix86_gen_one_cmpl2 = gen_one_cmplsi2;
- ix86_gen_monitor = gen_sse3_monitor;
ix86_gen_andsp = gen_andsi3;
ix86_gen_allocate_stack_worker = gen_allocate_stack_worker_probe_si;
ix86_gen_adjust_stack_and_probe = gen_adjust_stack_and_probesi;
@@ -7239,8 +7324,8 @@ function_value_64 (enum machine_mode orig_mode, enum machine_mode mode,
}
else if (POINTER_TYPE_P (valtype))
{
- /* Pointers are always returned in Pmode. */
- mode = Pmode;
+ /* Pointers are always returned in word_mode. */
+ mode = word_mode;
}
ret = construct_container (mode, orig_mode, valtype, 1,
@@ -7311,7 +7396,8 @@ ix86_function_value (const_tree valtype, const_tree fntype_or_decl,
return ix86_function_value_1 (valtype, fntype_or_decl, orig_mode, mode);
}
-/* Pointer function arguments and return values are promoted to Pmode. */
+/* Pointer function arguments and return values are promoted to
+ word_mode. */
static enum machine_mode
ix86_promote_function_mode (const_tree type, enum machine_mode mode,
@@ -7321,7 +7407,7 @@ ix86_promote_function_mode (const_tree type, enum machine_mode mode,
if (type != NULL_TREE && POINTER_TYPE_P (type))
{
*punsignedp = POINTERS_EXTEND_UNSIGNED;
- return Pmode;
+ return word_mode;
}
return default_promote_function_mode (type, mode, punsignedp, fntype,
for_return);
@@ -7599,12 +7685,13 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
for (i = cum->regno; i < max; i++)
{
- mem = gen_rtx_MEM (Pmode,
+ mem = gen_rtx_MEM (word_mode,
plus_constant (save_area, i * UNITS_PER_WORD));
MEM_NOTRAP_P (mem) = 1;
set_mem_alias_set (mem, set);
- emit_move_insn (mem, gen_rtx_REG (Pmode,
- x86_64_int_parameter_registers[i]));
+ emit_move_insn (mem,
+ gen_rtx_REG (word_mode,
+ x86_64_int_parameter_registers[i]));
}
if (ix86_varargs_fpr_size)
@@ -8664,8 +8751,11 @@ gen_push (rtx arg)
m->fs.cfa_offset += UNITS_PER_WORD;
m->fs.sp_offset += UNITS_PER_WORD;
+ if (REG_P (arg) && GET_MODE (arg) != word_mode)
+ arg = gen_rtx_REG (word_mode, REGNO (arg));
+
return gen_rtx_SET (VOIDmode,
- gen_rtx_MEM (Pmode,
+ gen_rtx_MEM (word_mode,
gen_rtx_PRE_DEC (Pmode,
stack_pointer_rtx)),
arg);
@@ -8676,9 +8766,12 @@ gen_push (rtx arg)
static rtx
gen_pop (rtx arg)
{
+ if (REG_P (arg) && GET_MODE (arg) != word_mode)
+ arg = gen_rtx_REG (word_mode, REGNO (arg));
+
return gen_rtx_SET (VOIDmode,
arg,
- gen_rtx_MEM (Pmode,
+ gen_rtx_MEM (word_mode,
gen_rtx_POST_INC (Pmode,
stack_pointer_rtx)));
}
@@ -9153,7 +9246,7 @@ ix86_emit_save_regs (void)
for (regno = FIRST_PSEUDO_REGISTER - 1; regno-- > 0; )
if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, true))
{
- insn = emit_insn (gen_push (gen_rtx_REG (Pmode, regno)));
+ insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno)));
RTX_FRAME_RELATED_P (insn) = 1;
}
}
@@ -9233,7 +9326,7 @@ ix86_emit_save_regs_using_mov (HOST_WIDE_INT cfa_offset)
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, true))
{
- ix86_emit_save_reg_using_mov (Pmode, regno, cfa_offset);
+ ix86_emit_save_reg_using_mov (word_mode, regno, cfa_offset);
cfa_offset -= UNITS_PER_WORD;
}
}
@@ -9308,7 +9401,7 @@ pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset,
rtx insn;
bool add_frame_related_expr = false;
- if (! TARGET_64BIT)
+ if (Pmode == SImode)
insn = gen_pro_epilogue_adjust_stack_si_add (dest, src, offset);
else if (x86_64_immediate_operand (offset, DImode))
insn = gen_pro_epilogue_adjust_stack_di_add (dest, src, offset);
@@ -10171,7 +10264,7 @@ ix86_expand_prologue (void)
to implement macro RETURN_ADDR_RTX and intrinsic function
expand_builtin_return_addr etc. */
t = plus_constant (crtl->drap_reg, -UNITS_PER_WORD);
- t = gen_frame_mem (Pmode, t);
+ t = gen_frame_mem (word_mode, t);
insn = emit_insn (gen_push (t));
RTX_FRAME_RELATED_P (insn) = 1;
@@ -10376,7 +10469,7 @@ ix86_expand_prologue (void)
emit_insn (ix86_gen_allocate_stack_worker (eax, eax));
/* Use the fact that AX still contains ALLOCATE. */
- adjust_stack_insn = (TARGET_64BIT
+ adjust_stack_insn = (Pmode == DImode
? gen_pro_epilogue_adjust_stack_di_sub
: gen_pro_epilogue_adjust_stack_si_sub);
@@ -10401,14 +10494,18 @@ ix86_expand_prologue (void)
if (r10_live && eax_live)
{
t = choose_baseaddr (m->fs.sp_offset - allocate);
- emit_move_insn (r10, gen_frame_mem (Pmode, t));
+ emit_move_insn (gen_rtx_REG (word_mode, R10_REG),
+ gen_frame_mem (word_mode, t));
t = choose_baseaddr (m->fs.sp_offset - allocate - UNITS_PER_WORD);
- emit_move_insn (eax, gen_frame_mem (Pmode, t));
+ emit_move_insn (gen_rtx_REG (word_mode, AX_REG),
+ gen_frame_mem (word_mode, t));
}
else if (eax_live || r10_live)
{
t = choose_baseaddr (m->fs.sp_offset - allocate);
- emit_move_insn ((eax_live ? eax : r10), gen_frame_mem (Pmode, t));
+ emit_move_insn (gen_rtx_REG (word_mode,
+ (eax_live ? AX_REG : R10_REG)),
+ gen_frame_mem (word_mode, t));
}
}
gcc_assert (m->fs.sp_offset == frame.stack_pointer_offset);
@@ -10578,7 +10675,7 @@ ix86_emit_restore_regs_using_pop (void)
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, false))
- ix86_emit_restore_reg_using_pop (gen_rtx_REG (Pmode, regno));
+ ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno));
}
/* Emit code and notes for the LEAVE instruction. */
@@ -10621,11 +10718,11 @@ ix86_emit_restore_regs_using_mov (HOST_WIDE_INT cfa_offset,
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return))
{
- rtx reg = gen_rtx_REG (Pmode, regno);
+ rtx reg = gen_rtx_REG (word_mode, regno);
rtx insn, mem;
mem = choose_baseaddr (cfa_offset);
- mem = gen_frame_mem (Pmode, mem);
+ mem = gen_frame_mem (word_mode, mem);
insn = emit_move_insn (reg, mem);
if (m->fs.cfa_reg == crtl->drap_reg && regno == REGNO (crtl->drap_reg))
@@ -11235,8 +11332,8 @@ ix86_expand_split_stack_prologue (void)
{
rtx rax;
- rax = gen_rtx_REG (Pmode, AX_REG);
- emit_move_insn (rax, reg10);
+ rax = gen_rtx_REG (word_mode, AX_REG);
+ emit_move_insn (rax, gen_rtx_REG (word_mode, R10_REG));
use_reg (&call_fusage, rax);
}
@@ -11315,8 +11412,8 @@ ix86_expand_split_stack_prologue (void)
/* If we are in 64-bit mode and this function uses a static chain,
we saved %r10 in %rax before calling _morestack. */
if (TARGET_64BIT && DECL_STATIC_CHAIN (cfun->decl))
- emit_move_insn (gen_rtx_REG (Pmode, R10_REG),
- gen_rtx_REG (Pmode, AX_REG));
+ emit_move_insn (gen_rtx_REG (word_mode, R10_REG),
+ gen_rtx_REG (word_mode, AX_REG));
/* If this function calls va_start, we need to store a pointer to
the arguments on the old stack, because they may not have been
@@ -11534,6 +11631,12 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
scale = 1 << scale;
break;
+ case ZERO_EXTEND:
+ op = XEXP (op, 0);
+ if (GET_CODE (op) != UNSPEC)
+ return 0;
+ /* FALLTHRU */
+
case UNSPEC:
if (XINT (op, 1) == UNSPEC_TP
&& TARGET_TLS_DIRECT_SEG_REFS
@@ -11616,6 +11719,12 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
return 0;
}
+/* Address override works only on the (%reg) part of %fs:(%reg). */
+ if (seg != SEG_DEFAULT
+ && ((base && GET_MODE (base) != word_mode)
+ || (index && GET_MODE (index) != word_mode)))
+ return 0;
+
/* Extract the integral value of scale. */
if (scale_rtx)
{
@@ -12561,15 +12670,20 @@ legitimize_pic_address (rtx orig, rtx reg)
/* Load the thread pointer. If TO_REG is true, force it into a register. */
static rtx
-get_thread_pointer (bool to_reg)
+get_thread_pointer (enum machine_mode tp_mode, bool to_reg)
{
rtx tp = gen_rtx_UNSPEC (ptr_mode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
- if (GET_MODE (tp) != Pmode)
- tp = convert_to_mode (Pmode, tp, 1);
+ if (GET_MODE (tp) != tp_mode)
+ {
+ gcc_assert (GET_MODE (tp) == SImode);
+ gcc_assert (tp_mode == DImode);
+
+ tp = gen_rtx_ZERO_EXTEND (tp_mode, tp);
+ }
if (to_reg)
- tp = copy_addr_to_reg (tp);
+ tp = copy_to_mode_reg (tp_mode, tp);
return tp;
}
@@ -12621,6 +12735,7 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
{
rtx dest, base, off;
rtx pic = NULL_RTX, tp = NULL_RTX;
+ enum machine_mode tp_mode = Pmode;
int type;
switch (model)
@@ -12646,7 +12761,7 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
else
emit_insn (gen_tls_dynamic_gnu2_32 (dest, x, pic));
- tp = get_thread_pointer (true);
+ tp = get_thread_pointer (Pmode, true);
dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, tp, dest));
set_unique_reg_note (get_last_insn (), REG_EQUAL, x);
@@ -12660,7 +12775,8 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
rtx rax = gen_rtx_REG (Pmode, AX_REG), insns;
start_sequence ();
- emit_call_insn (gen_tls_global_dynamic_64 (rax, x, caddr));
+ emit_call_insn (ix86_gen_tls_global_dynamic_64 (rax, x,
+ caddr));
insns = get_insns ();
end_sequence ();
@@ -12695,7 +12811,7 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
else
emit_insn (gen_tls_dynamic_gnu2_32 (base, tmp, pic));
- tp = get_thread_pointer (true);
+ tp = get_thread_pointer (Pmode, true);
set_unique_reg_note (get_last_insn (), REG_EQUAL,
gen_rtx_MINUS (Pmode, tmp, tp));
}
@@ -12708,7 +12824,8 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
rtx rax = gen_rtx_REG (Pmode, AX_REG), insns, eqv;
start_sequence ();
- emit_call_insn (gen_tls_local_dynamic_base_64 (rax, caddr));
+ emit_call_insn (ix86_gen_tls_local_dynamic_base_64 (rax,
+ caddr));
insns = get_insns ();
end_sequence ();
@@ -12751,6 +12868,9 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
return dest;
}
+ /* Generate DImode references to avoid %fs:(%reg32)
+ problems and linker IE->LE relaxation bug. */
+ tp_mode = DImode;
pic = NULL;
type = UNSPEC_GOTNTPOFF;
}
@@ -12773,22 +12893,23 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
type = UNSPEC_INDNTPOFF;
}
- off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), type);
- off = gen_rtx_CONST (Pmode, off);
+ off = gen_rtx_UNSPEC (tp_mode, gen_rtvec (1, x), type);
+ off = gen_rtx_CONST (tp_mode, off);
if (pic)
- off = gen_rtx_PLUS (Pmode, pic, off);
- off = gen_const_mem (Pmode, off);
+ off = gen_rtx_PLUS (tp_mode, pic, off);
+ off = gen_const_mem (tp_mode, off);
set_mem_alias_set (off, ix86_GOT_alias_set ());
if (TARGET_64BIT || TARGET_ANY_GNU_TLS)
{
- base = get_thread_pointer (for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
- off = force_reg (Pmode, off);
- return gen_rtx_PLUS (Pmode, base, off);
+ base = get_thread_pointer (tp_mode,
+ for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
+ off = force_reg (tp_mode, off);
+ return gen_rtx_PLUS (tp_mode, base, off);
}
else
{
- base = get_thread_pointer (true);
+ base = get_thread_pointer (Pmode, true);
dest = gen_reg_rtx (Pmode);
emit_insn (gen_subsi3 (dest, base, off));
}
@@ -12802,12 +12923,13 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
if (TARGET_64BIT || TARGET_ANY_GNU_TLS)
{
- base = get_thread_pointer (for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
+ base = get_thread_pointer (Pmode,
+ for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
return gen_rtx_PLUS (Pmode, base, off);
}
else
{
- base = get_thread_pointer (true);
+ base = get_thread_pointer (Pmode, true);
dest = gen_reg_rtx (Pmode);
emit_insn (gen_subsi3 (dest, base, off));
}
@@ -13887,6 +14009,7 @@ get_some_local_dynamic_name (void)
; -- print a semicolon (after prefixes due to bug in older gas).
~ -- print "i" if TARGET_AVX2, "f" otherwise.
@ -- print a segment register of thread base pointer load
+ ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
*/
void
@@ -14397,6 +14520,11 @@ ix86_print_operand (FILE *file, rtx x, int code)
putc (TARGET_AVX2 ? 'i' : 'f', file);
return;
+ case '^':
+ if (TARGET_64BIT && Pmode != word_mode)
+ fputs ("addr32 ", file);
+ return;
+
default:
output_operand_lossage ("invalid operand code '%c'", code);
}
@@ -14536,8 +14664,8 @@ ix86_print_operand (FILE *file, rtx x, int code)
static bool
ix86_print_operand_punct_valid_p (unsigned char code)
{
- return (code == '@' || code == '*' || code == '+'
- || code == '&' || code == ';' || code == '~');
+ return (code == '@' || code == '*' || code == '+' || code == '&'
+ || code == ';' || code == '~' || code == '^');
}
/* Print a memory operand whose address is ADDR. */
@@ -20445,7 +20573,7 @@ ix86_split_to_parts (rtx operand, rtx *parts, enum machine_mode mode)
gcc_assert (ok);
operand = copy_rtx (operand);
- PUT_MODE (operand, Pmode);
+ PUT_MODE (operand, word_mode);
parts[0] = parts[1] = parts[2] = parts[3] = operand;
return size;
}
@@ -20600,7 +20728,7 @@ ix86_split_long_move (rtx operands[])
if (push_operand (operands[0], VOIDmode))
{
operands[0] = copy_rtx (operands[0]);
- PUT_MODE (operands[0], Pmode);
+ PUT_MODE (operands[0], word_mode);
}
else
operands[0] = gen_lowpart (DImode, operands[0]);
@@ -21155,14 +21283,9 @@ ix86_adjust_counter (rtx countreg, HOST_WIDE_INT value)
rtx
ix86_zero_extend_to_Pmode (rtx exp)
{
- rtx r;
- if (GET_MODE (exp) == VOIDmode)
- return force_reg (Pmode, exp);
- if (GET_MODE (exp) == Pmode)
- return copy_to_mode_reg (Pmode, exp);
- r = gen_reg_rtx (Pmode);
- emit_insn (gen_zero_extendsidi2 (r, exp));
- return r;
+ if (GET_MODE (exp) != Pmode)
+ exp = convert_to_mode (Pmode, exp, 1);
+ return force_reg (Pmode, exp);
}
/* Divide COUNTREG by SCALE. */
@@ -22190,11 +22313,11 @@ ix86_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx align_exp,
gcc_unreachable ();
case loop:
need_zero_guard = true;
- size_needed = GET_MODE_SIZE (Pmode);
+ size_needed = GET_MODE_SIZE (word_mode);
break;
case unrolled_loop:
need_zero_guard = true;
- size_needed = GET_MODE_SIZE (Pmode) * (TARGET_64BIT ? 4 : 2);
+ size_needed = GET_MODE_SIZE (word_mode) * (TARGET_64BIT ? 4 : 2);
break;
case rep_prefix_8_byte:
size_needed = 8;
@@ -22360,13 +22483,13 @@ ix86_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx align_exp,
break;
case loop:
expand_set_or_movmem_via_loop (dst, src, destreg, srcreg, NULL,
- count_exp, Pmode, 1, expected_size);
+ count_exp, word_mode, 1, expected_size);
break;
case unrolled_loop:
/* Unroll only by factor of 2 in 32bit mode, since we don't have enough
registers for 4 temporaries anyway. */
expand_set_or_movmem_via_loop (dst, src, destreg, srcreg, NULL,
- count_exp, Pmode, TARGET_64BIT ? 4 : 2,
+ count_exp, word_mode, TARGET_64BIT ? 4 : 2,
expected_size);
break;
case rep_prefix_8_byte:
@@ -22578,11 +22701,11 @@ ix86_expand_setmem (rtx dst, rtx count_exp, rtx val_exp, rtx align_exp,
gcc_unreachable ();
case loop:
need_zero_guard = true;
- size_needed = GET_MODE_SIZE (Pmode);
+ size_needed = GET_MODE_SIZE (word_mode);
break;
case unrolled_loop:
need_zero_guard = true;
- size_needed = GET_MODE_SIZE (Pmode) * 4;
+ size_needed = GET_MODE_SIZE (word_mode) * 4;
break;
case rep_prefix_8_byte:
size_needed = 8;
@@ -22753,11 +22876,11 @@ ix86_expand_setmem (rtx dst, rtx count_exp, rtx val_exp, rtx align_exp,
break;
case loop:
expand_set_or_movmem_via_loop (dst, NULL, destreg, NULL, promoted_val,
- count_exp, Pmode, 1, expected_size);
+ count_exp, word_mode, 1, expected_size);
break;
case unrolled_loop:
expand_set_or_movmem_via_loop (dst, NULL, destreg, NULL, promoted_val,
- count_exp, Pmode, 4, expected_size);
+ count_exp, word_mode, 4, expected_size);
break;
case rep_prefix_8_byte:
expand_setmem_via_rep_stos (dst, destreg, promoted_val, count_exp,
@@ -23120,13 +23243,13 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
&& !local_symbolic_operand (XEXP (fnaddr, 0), VOIDmode))
fnaddr = gen_rtx_MEM (QImode, construct_plt_address (XEXP (fnaddr, 0)));
else if (sibcall
- ? !sibcall_insn_operand (XEXP (fnaddr, 0), Pmode)
- : !call_insn_operand (XEXP (fnaddr, 0), Pmode))
+ ? !sibcall_insn_operand (XEXP (fnaddr, 0), word_mode)
+ : !call_insn_operand (XEXP (fnaddr, 0), word_mode))
{
fnaddr = XEXP (fnaddr, 0);
- if (GET_MODE (fnaddr) != Pmode)
- fnaddr = convert_to_mode (Pmode, fnaddr, 1);
- fnaddr = gen_rtx_MEM (QImode, copy_to_mode_reg (Pmode, fnaddr));
+ if (GET_MODE (fnaddr) != word_mode)
+ fnaddr = convert_to_mode (word_mode, fnaddr, 1);
+ fnaddr = gen_rtx_MEM (QImode, copy_to_mode_reg (word_mode, fnaddr));
}
vec_len = 0;
@@ -24440,10 +24563,13 @@ ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
/* Load the function address to r11. Try to load address using
the shorter movl instead of movabs. We may want to support
movq for kernel mode, but kernel does not use trampolines at
- the moment. */
- if (x86_64_zext_immediate_operand (fnaddr, VOIDmode))
+ the moment. FNADDR is a 32bit address and may not be in
+ DImode when ptr_mode == SImode. Always use movl in this
+ case. */
+ if (ptr_mode == SImode
+ || x86_64_zext_immediate_operand (fnaddr, VOIDmode))
{
- fnaddr = copy_to_mode_reg (DImode, fnaddr);
+ fnaddr = copy_to_mode_reg (Pmode, fnaddr);
mem = adjust_address (m_tramp, HImode, offset);
emit_move_insn (mem, gen_int_mode (0xbb41, HImode));
@@ -24462,9 +24588,9 @@ ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
offset += 10;
}
- /* Load static chain using movabs to r10. Use the
- shorter movl instead of movabs for x32. */
- if (TARGET_X32)
+ /* Load static chain using movabs to r10. Use the shorter movl
+ instead of movabs when ptr_mode == SImode. */
+ if (ptr_mode == SImode)
{
opcode = 0xba41;
size = 6;
@@ -32101,7 +32227,7 @@ x86_this_parameter (tree function)
parm_regs = x86_64_ms_abi_int_parameter_registers;
else
parm_regs = x86_64_int_parameter_registers;
- return gen_rtx_REG (DImode, parm_regs[aggr]);
+ return gen_rtx_REG (Pmode, parm_regs[aggr]);
}
nregs = ix86_function_regparm (type, function);