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