aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8/gcc/config/arm/arm.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.8/gcc/config/arm/arm.c')
-rw-r--r--gcc-4.8/gcc/config/arm/arm.c74
1 files changed, 50 insertions, 24 deletions
diff --git a/gcc-4.8/gcc/config/arm/arm.c b/gcc-4.8/gcc/config/arm/arm.c
index e8d83e0f3..14c79ec99 100644
--- a/gcc-4.8/gcc/config/arm/arm.c
+++ b/gcc-4.8/gcc/config/arm/arm.c
@@ -230,7 +230,6 @@ static tree arm_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *);
static void arm_option_override (void);
static unsigned HOST_WIDE_INT arm_shift_truncation_mask (enum machine_mode);
static bool arm_cannot_copy_insn_p (rtx);
-static bool arm_tls_symbol_p (rtx x);
static int arm_issue_rate (void);
static void arm_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
static bool arm_output_addr_const_extra (FILE *, rtx);
@@ -5446,7 +5445,8 @@ require_pic_register (void)
if (!crtl->uses_pic_offset_table)
{
gcc_assert (can_create_pseudo_p ());
- if (arm_pic_register != INVALID_REGNUM)
+ if (arm_pic_register != INVALID_REGNUM
+ && !(TARGET_THUMB1 && arm_pic_register > LAST_LO_REGNUM))
{
if (!cfun->machine->pic_reg)
cfun->machine->pic_reg = gen_rtx_REG (Pmode, arm_pic_register);
@@ -5472,6 +5472,11 @@ require_pic_register (void)
crtl->uses_pic_offset_table = 1;
start_sequence ();
+ if (TARGET_THUMB1 && arm_pic_register != INVALID_REGNUM
+ && arm_pic_register > LAST_LO_REGNUM)
+ emit_move_insn (cfun->machine->pic_reg,
+ gen_rtx_REG (Pmode, arm_pic_register));
+ else
arm_load_pic_register (0UL);
seq = get_insns ();
@@ -5730,6 +5735,14 @@ arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED)
emit_insn (gen_movsi (pic_offset_table_rtx, pic_tmp));
emit_insn (gen_pic_add_dot_plus_four (pic_reg, pic_reg, labelno));
}
+ else if (arm_pic_register != INVALID_REGNUM
+ && arm_pic_register > LAST_LO_REGNUM
+ && REGNO (pic_reg) <= LAST_LO_REGNUM)
+ {
+ emit_insn (gen_pic_load_addr_unified (pic_reg, pic_rtx, labelno));
+ emit_move_insn (gen_rtx_REG (Pmode, arm_pic_register), pic_reg);
+ emit_use (gen_rtx_REG (Pmode, arm_pic_register));
+ }
else
emit_insn (gen_pic_load_addr_unified (pic_reg, pic_rtx, labelno));
}
@@ -6595,6 +6608,32 @@ legitimize_tls_address (rtx x, rtx reg)
rtx
arm_legitimize_address (rtx x, rtx orig_x, enum machine_mode mode)
{
+ if (arm_tls_referenced_p (x))
+ {
+ rtx addend = NULL;
+
+ if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS)
+ {
+ addend = XEXP (XEXP (x, 0), 1);
+ x = XEXP (XEXP (x, 0), 0);
+ }
+
+ if (GET_CODE (x) != SYMBOL_REF)
+ return x;
+
+ gcc_assert (SYMBOL_REF_TLS_MODEL (x) != 0);
+
+ x = legitimize_tls_address (x, NULL_RTX);
+
+ if (addend)
+ {
+ x = gen_rtx_PLUS (SImode, x, addend);
+ orig_x = x;
+ }
+ else
+ return x;
+ }
+
if (!TARGET_ARM)
{
/* TODO: legitimize_address for Thumb2. */
@@ -6603,9 +6642,6 @@ arm_legitimize_address (rtx x, rtx orig_x, enum machine_mode mode)
return thumb_legitimize_address (x, orig_x, mode);
}
- if (arm_tls_symbol_p (x))
- return legitimize_tls_address (x, NULL_RTX);
-
if (GET_CODE (x) == PLUS)
{
rtx xop0 = XEXP (x, 0);
@@ -6717,9 +6753,6 @@ arm_legitimize_address (rtx x, rtx orig_x, enum machine_mode mode)
rtx
thumb_legitimize_address (rtx x, rtx orig_x, enum machine_mode mode)
{
- if (arm_tls_symbol_p (x))
- return legitimize_tls_address (x, NULL_RTX);
-
if (GET_CODE (x) == PLUS
&& CONST_INT_P (XEXP (x, 1))
&& (INTVAL (XEXP (x, 1)) >= 32 * GET_MODE_SIZE (mode)
@@ -7010,20 +7043,6 @@ thumb_legitimize_reload_address (rtx *x_p,
/* Test for various thread-local symbols. */
-/* Return TRUE if X is a thread-local symbol. */
-
-static bool
-arm_tls_symbol_p (rtx x)
-{
- if (! TARGET_HAVE_TLS)
- return false;
-
- if (GET_CODE (x) != SYMBOL_REF)
- return false;
-
- return SYMBOL_REF_TLS_MODEL (x) != 0;
-}
-
/* Helper for arm_tls_referenced_p. */
static int
@@ -21305,7 +21324,11 @@ arm_expand_neon_args (rtx target, int icode, int have_retval,
type_mode);
}
- op[argc] = expand_normal (arg[argc]);
+ /* Use EXPAND_MEMORY for NEON_ARG_MEMORY to ensure a MEM_P
+ be returned. */
+ op[argc] = expand_expr (arg[argc], NULL_RTX, VOIDmode,
+ (thisarg == NEON_ARG_MEMORY
+ ? EXPAND_MEMORY : EXPAND_NORMAL));
switch (thisarg)
{
@@ -21324,6 +21347,9 @@ arm_expand_neon_args (rtx target, int icode, int have_retval,
break;
case NEON_ARG_MEMORY:
+ /* Check if expand failed. */
+ if (op[argc] == const0_rtx)
+ return 0;
gcc_assert (MEM_P (op[argc]));
PUT_MODE (op[argc], mode[argc]);
/* ??? arm_neon.h uses the same built-in functions for signed
@@ -23611,7 +23637,7 @@ arm_expand_epilogue_apcs_frame (bool really_return)
if (crtl->calls_eh_return)
emit_insn (gen_addsi3 (stack_pointer_rtx,
stack_pointer_rtx,
- GEN_INT (ARM_EH_STACKADJ_REGNUM)));
+ gen_rtx_REG (SImode, ARM_EH_STACKADJ_REGNUM)));
if (IS_STACKALIGN (func_type))
/* Restore the original stack pointer. Before prologue, the stack was