diff options
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 39 | ||||
-rw-r--r-- | gcc/config/arm/arm.md | 25 |
3 files changed, 53 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b05a764..4e35838 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2012-01-20 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org> + + PR target/50313 + * config/arm/arm.c (arm_load_pic_register): Use + gen_pic_load_addr_unified. Delete calls to gen_pic_load_addr_32bit + , gen_pic_add_dot_plus_eight and gen_pic_add_dot_plus_four. + (arm_pic_static_addr): Likewise. + (arm_rtx_costs_1): Adjust cost for UNSPEC_PIC_UNIFIED. + (arm_note_pic_base): Handle UNSPEC_PIC_UNIFIED. + * config/arm/arm.md (UNSPEC_PIC_UNIFIED): Define. + (pic_load_addr_unified): New. + 2012-01-20 Andrey Belevantsev <abel@ispras.ru> PR target/51106 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 4c310d4..64ee6ae 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -5578,11 +5578,7 @@ arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED) if (TARGET_32BIT) { - emit_insn (gen_pic_load_addr_32bit (pic_reg, pic_rtx)); - if (TARGET_ARM) - emit_insn (gen_pic_add_dot_plus_eight (pic_reg, pic_reg, labelno)); - else - emit_insn (gen_pic_add_dot_plus_four (pic_reg, pic_reg, labelno)); + emit_insn (gen_pic_load_addr_unified (pic_reg, pic_rtx, labelno)); } else /* TARGET_THUMB1 */ { @@ -5595,10 +5591,10 @@ arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED) thumb_find_work_register (saved_regs)); emit_insn (gen_pic_load_addr_thumb1 (pic_tmp, pic_rtx)); emit_insn (gen_movsi (pic_offset_table_rtx, pic_tmp)); + emit_insn (gen_pic_add_dot_plus_four (pic_reg, pic_reg, labelno)); } else - emit_insn (gen_pic_load_addr_thumb1 (pic_reg, pic_rtx)); - emit_insn (gen_pic_add_dot_plus_four (pic_reg, pic_reg, labelno)); + emit_insn (gen_pic_load_addr_unified (pic_reg, pic_rtx, labelno)); } } @@ -5628,20 +5624,7 @@ arm_pic_static_addr (rtx orig, rtx reg) UNSPEC_SYMBOL_OFFSET); offset_rtx = gen_rtx_CONST (Pmode, offset_rtx); - if (TARGET_32BIT) - { - emit_insn (gen_pic_load_addr_32bit (reg, offset_rtx)); - if (TARGET_ARM) - insn = emit_insn (gen_pic_add_dot_plus_eight (reg, reg, labelno)); - else - insn = emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno)); - } - else /* TARGET_THUMB1 */ - { - emit_insn (gen_pic_load_addr_thumb1 (reg, offset_rtx)); - insn = emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno)); - } - + insn = emit_insn (gen_pic_load_addr_unified (reg, offset_rtx, labelno)); return insn; } @@ -5684,7 +5667,7 @@ static bool will_be_in_index_register (const_rtx x) { /* arm.md: calculate_pic_address will split this into a register. */ - return GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_PIC_SYM; + return GET_CODE (x) == UNSPEC && (XINT (x, 1) == UNSPEC_PIC_SYM); } /* Return nonzero if X is a valid ARM state address operand. */ @@ -7648,6 +7631,15 @@ arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed) case SET: return false; + + case UNSPEC: + /* We cost this as high as our memory costs to allow this to + be hoisted from loops. */ + if (XINT (x, 1) == UNSPEC_PIC_UNIFIED) + { + *total = COSTS_N_INSNS (2 + ARM_NUM_REGS (mode)); + } + return true; default: *total = COSTS_N_INSNS (4); @@ -10008,7 +10000,8 @@ static int arm_note_pic_base (rtx *x, void *date ATTRIBUTE_UNUSED) { if (GET_CODE (*x) == UNSPEC - && XINT (*x, 1) == UNSPEC_PIC_BASE) + && (XINT (*x, 1) == UNSPEC_PIC_BASE + || XINT (*x, 1) == UNSPEC_PIC_UNIFIED)) return 1; return 0; } diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 5620d7d..97a83a4 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -116,6 +116,7 @@ ; unaligned locations, on architectures which support ; that. UNSPEC_UNALIGNED_STORE ; Same for str/strh. + UNSPEC_PIC_UNIFIED ; Create a common pic addressing form. ]) ;; UNSPEC_VOLATILE Usage: @@ -5613,6 +5614,30 @@ "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];" ) +;; operand1 is the memory address to go into +;; pic_load_addr_32bit. +;; operand2 is the PIC label to be emitted +;; from pic_add_dot_plus_eight. +;; We do this to allow hoisting of the entire insn. +(define_insn_and_split "pic_load_addr_unified" + [(set (match_operand:SI 0 "s_register_operand" "=r,r,l") + (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX") + (match_operand:SI 2 "" "")] + UNSPEC_PIC_UNIFIED))] + "flag_pic" + "#" + "&& reload_completed" + [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM)) + (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3) + (match_dup 2)] UNSPEC_PIC_BASE))] + "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);" + [(set_attr "type" "load1,load1,load1") + (set_attr "pool_range" "4096,4096,1024") + (set_attr "neg_pool_range" "4084,0,0") + (set_attr "arch" "a,t2,t1") + (set_attr "length" "8,6,4")] +) + ;; The rather odd constraints on the following are to force reload to leave ;; the insn alone, and to force the minipool generation pass to then move ;; the GOT symbol to memory. |