aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRamana Radhakrishnan <ramana.radhakrishnan@linaro.org>2012-01-20 09:22:14 +0000
committerRamana Radhakrishnan <ramana@gcc.gnu.org>2012-01-20 09:22:14 +0000
commitf06129ead48be9ed77ae85c7b908c60fc1eeff7a (patch)
tree7fdb1f9be10548b64d5272e6ed52f3b76955c9d4 /gcc
parent583713e3265924f3262ec66872bf7443bb980789 (diff)
downloadgcc-f06129ead48be9ed77ae85c7b908c60fc1eeff7a.zip
gcc-f06129ead48be9ed77ae85c7b908c60fc1eeff7a.tar.gz
gcc-f06129ead48be9ed77ae85c7b908c60fc1eeff7a.tar.bz2
re PR target/50313 (ARM: PIC code references a non-existant label)
Fix PR target/50313 From-SVN: r183328
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/arm/arm.c39
-rw-r--r--gcc/config/arm/arm.md25
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.