Commit f16fe45f by Daniel Jacobowitz Committed by Daniel Jacobowitz

arm.c (pic_labelno): New.

	* config/arm/arm.c (pic_labelno): New.
	(arm_load_pic_register): Use an UNSPEC_PIC_LABEL instead of a
	LABEL_REF.  Pass only the labelno to PIC insns.
	(arm_call_tls_get_addr, legitimize_tls_address): Likewise.
	(arm_output_addr_const_extra): Handle UNSPEC_PIC_LABEL.
	* arm.md (UNSPEC_PIC_LABEL): New constant.
	(pic_add_dot_plus_four, pic_add_dot_plus_eight)
	(tls_load_dot_plus_eight): Expect a labelno instead of a LABEL_REF.
	Use the correct label prefix.

From-SVN: r106893
parent e66e1c68
2005-11-14 Daniel Jacobowitz <dan@codesourcery.com> 2005-11-14 Daniel Jacobowitz <dan@codesourcery.com>
* config/arm/arm.c (pic_labelno): New.
(arm_load_pic_register): Use an UNSPEC_PIC_LABEL instead of a
LABEL_REF. Pass only the labelno to PIC insns.
(arm_call_tls_get_addr, legitimize_tls_address): Likewise.
(arm_output_addr_const_extra): Handle UNSPEC_PIC_LABEL.
* arm.md (UNSPEC_PIC_LABEL): New constant.
(pic_add_dot_plus_four, pic_add_dot_plus_eight)
(tls_load_dot_plus_eight): Expect a labelno instead of a LABEL_REF.
Use the correct label prefix.
2005-11-14 Daniel Jacobowitz <dan@codesourcery.com>
* config/arm/arm.c (legitimize_tls_address): Use correct rtx for * config/arm/arm.c (legitimize_tls_address): Use correct rtx for
REQ_EQUIV note. REQ_EQUIV note.
......
...@@ -3340,6 +3340,7 @@ thumb_find_work_register (unsigned long pushed_regs_mask) ...@@ -3340,6 +3340,7 @@ thumb_find_work_register (unsigned long pushed_regs_mask)
gcc_unreachable (); gcc_unreachable ();
} }
static GTY(()) int pic_labelno;
/* Generate code to load the PIC register. In thumb mode SCRATCH is a /* Generate code to load the PIC register. In thumb mode SCRATCH is a
low register. */ low register. */
...@@ -3348,7 +3349,7 @@ void ...@@ -3348,7 +3349,7 @@ void
arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED) arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED)
{ {
#ifndef AOF_ASSEMBLER #ifndef AOF_ASSEMBLER
rtx l1, pic_tmp, pic_tmp2, pic_rtx; rtx l1, labelno, pic_tmp, pic_tmp2, pic_rtx;
rtx global_offset_table; rtx global_offset_table;
if (current_function_uses_pic_offset_table == 0 || TARGET_SINGLE_PIC_BASE) if (current_function_uses_pic_offset_table == 0 || TARGET_SINGLE_PIC_BASE)
...@@ -3356,12 +3357,17 @@ arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED) ...@@ -3356,12 +3357,17 @@ arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED)
gcc_assert (flag_pic); gcc_assert (flag_pic);
l1 = gen_label_rtx (); /* We use an UNSPEC rather than a LABEL_REF because this label never appears
in the code stream. */
labelno = GEN_INT (pic_labelno++);
l1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
l1 = gen_rtx_CONST (VOIDmode, l1);
global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
/* On the ARM the PC register contains 'dot + 8' at the time of the /* On the ARM the PC register contains 'dot + 8' at the time of the
addition, on the Thumb it is 'dot + 4'. */ addition, on the Thumb it is 'dot + 4'. */
pic_tmp = plus_constant (gen_rtx_LABEL_REF (Pmode, l1), TARGET_ARM ? 8 : 4); pic_tmp = plus_constant (l1, TARGET_ARM ? 8 : 4);
if (GOT_PCREL) if (GOT_PCREL)
pic_tmp2 = gen_rtx_CONST (VOIDmode, pic_tmp2 = gen_rtx_CONST (VOIDmode,
gen_rtx_PLUS (Pmode, global_offset_table, pc_rtx)); gen_rtx_PLUS (Pmode, global_offset_table, pc_rtx));
...@@ -3374,7 +3380,7 @@ arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED) ...@@ -3374,7 +3380,7 @@ arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED)
{ {
emit_insn (gen_pic_load_addr_arm (pic_offset_table_rtx, pic_rtx)); emit_insn (gen_pic_load_addr_arm (pic_offset_table_rtx, pic_rtx));
emit_insn (gen_pic_add_dot_plus_eight (pic_offset_table_rtx, emit_insn (gen_pic_add_dot_plus_eight (pic_offset_table_rtx,
pic_offset_table_rtx, l1)); pic_offset_table_rtx, labelno));
} }
else else
{ {
...@@ -3390,7 +3396,7 @@ arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED) ...@@ -3390,7 +3396,7 @@ arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED)
else else
emit_insn (gen_pic_load_addr_thumb (pic_offset_table_rtx, pic_rtx)); emit_insn (gen_pic_load_addr_thumb (pic_offset_table_rtx, pic_rtx));
emit_insn (gen_pic_add_dot_plus_four (pic_offset_table_rtx, emit_insn (gen_pic_add_dot_plus_four (pic_offset_table_rtx,
pic_offset_table_rtx, l1)); pic_offset_table_rtx, labelno));
} }
/* Need to emit this whether or not we obey regdecls, /* Need to emit this whether or not we obey regdecls,
...@@ -3822,22 +3828,24 @@ load_tls_operand (rtx x, rtx reg) ...@@ -3822,22 +3828,24 @@ load_tls_operand (rtx x, rtx reg)
static rtx static rtx
arm_call_tls_get_addr (rtx x, rtx reg, rtx *valuep, int reloc) arm_call_tls_get_addr (rtx x, rtx reg, rtx *valuep, int reloc)
{ {
rtx insns, label, sum; rtx insns, label, labelno, sum;
start_sequence (); start_sequence ();
label = gen_label_rtx (); labelno = GEN_INT (pic_labelno++);
label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
label = gen_rtx_CONST (VOIDmode, label);
sum = gen_rtx_UNSPEC (Pmode, sum = gen_rtx_UNSPEC (Pmode,
gen_rtvec (4, x, GEN_INT (reloc), gen_rtvec (4, x, GEN_INT (reloc), label,
gen_rtx_LABEL_REF (Pmode, label),
GEN_INT (TARGET_ARM ? 8 : 4)), GEN_INT (TARGET_ARM ? 8 : 4)),
UNSPEC_TLS); UNSPEC_TLS);
reg = load_tls_operand (sum, reg); reg = load_tls_operand (sum, reg);
if (TARGET_ARM) if (TARGET_ARM)
emit_insn (gen_pic_add_dot_plus_eight (reg, reg, label)); emit_insn (gen_pic_add_dot_plus_eight (reg, reg, labelno));
else else
emit_insn (gen_pic_add_dot_plus_four (reg, reg, label)); emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));
*valuep = emit_library_call_value (get_tls_get_addr (), NULL_RTX, LCT_PURE, /* LCT_CONST? */ *valuep = emit_library_call_value (get_tls_get_addr (), NULL_RTX, LCT_PURE, /* LCT_CONST? */
Pmode, 1, reg, Pmode); Pmode, 1, reg, Pmode);
...@@ -3851,7 +3859,7 @@ arm_call_tls_get_addr (rtx x, rtx reg, rtx *valuep, int reloc) ...@@ -3851,7 +3859,7 @@ arm_call_tls_get_addr (rtx x, rtx reg, rtx *valuep, int reloc)
rtx rtx
legitimize_tls_address (rtx x, rtx reg) legitimize_tls_address (rtx x, rtx reg)
{ {
rtx dest, tp, label, sum, insns, ret, eqv, addend; rtx dest, tp, label, labelno, sum, insns, ret, eqv, addend;
unsigned int model = SYMBOL_REF_TLS_MODEL (x); unsigned int model = SYMBOL_REF_TLS_MODEL (x);
switch (model) switch (model)
...@@ -3879,19 +3887,20 @@ legitimize_tls_address (rtx x, rtx reg) ...@@ -3879,19 +3887,20 @@ legitimize_tls_address (rtx x, rtx reg)
return gen_rtx_PLUS (Pmode, dest, addend); return gen_rtx_PLUS (Pmode, dest, addend);
case TLS_MODEL_INITIAL_EXEC: case TLS_MODEL_INITIAL_EXEC:
label = gen_label_rtx (); labelno = GEN_INT (pic_labelno++);
label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
label = gen_rtx_CONST (VOIDmode, label);
sum = gen_rtx_UNSPEC (Pmode, sum = gen_rtx_UNSPEC (Pmode,
gen_rtvec (4, x, GEN_INT (TLS_IE32), gen_rtvec (4, x, GEN_INT (TLS_IE32), label,
gen_rtx_LABEL_REF (Pmode, label),
GEN_INT (TARGET_ARM ? 8 : 4)), GEN_INT (TARGET_ARM ? 8 : 4)),
UNSPEC_TLS); UNSPEC_TLS);
reg = load_tls_operand (sum, reg); reg = load_tls_operand (sum, reg);
if (TARGET_ARM) if (TARGET_ARM)
emit_insn (gen_tls_load_dot_plus_eight (reg, reg, label)); emit_insn (gen_tls_load_dot_plus_eight (reg, reg, labelno));
else else
{ {
emit_insn (gen_pic_add_dot_plus_four (reg, reg, label)); emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));
emit_move_insn (reg, gen_const_mem (SImode, reg)); emit_move_insn (reg, gen_const_mem (SImode, reg));
} }
...@@ -15431,6 +15440,16 @@ arm_output_addr_const_extra (FILE *fp, rtx x) ...@@ -15431,6 +15440,16 @@ arm_output_addr_const_extra (FILE *fp, rtx x)
{ {
if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLS) if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLS)
return arm_emit_tls_decoration (fp, x); return arm_emit_tls_decoration (fp, x);
else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_PIC_LABEL)
{
char label[256];
int labelno = INTVAL (XVECEXP (x, 0, 0));
ASM_GENERATE_INTERNAL_LABEL (label, "LPIC", labelno);
assemble_name_raw (fp, label);
return TRUE;
}
else if (GET_CODE (x) == CONST_VECTOR) else if (GET_CODE (x) == CONST_VECTOR)
return arm_emit_vector_const (fp, x); return arm_emit_vector_const (fp, x);
......
...@@ -91,6 +91,8 @@ ...@@ -91,6 +91,8 @@
(UNSPEC_WMADDS 18) ; Used by the intrinsic form of the iWMMXt WMADDS instruction. (UNSPEC_WMADDS 18) ; Used by the intrinsic form of the iWMMXt WMADDS instruction.
(UNSPEC_WMADDU 19) ; Used by the intrinsic form of the iWMMXt WMADDU instruction. (UNSPEC_WMADDU 19) ; Used by the intrinsic form of the iWMMXt WMADDU instruction.
(UNSPEC_TLS 20) ; A symbol that has been treated properly for TLS usage. (UNSPEC_TLS 20) ; A symbol that has been treated properly for TLS usage.
(UNSPEC_PIC_LABEL 21) ; A label used for PIC access that does not appear in the
; instruction stream.
] ]
) )
...@@ -4468,11 +4470,11 @@ ...@@ -4468,11 +4470,11 @@
(unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "0") (unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "0")
(const (plus:SI (pc) (const_int 4))))] (const (plus:SI (pc) (const_int 4))))]
UNSPEC_PIC_BASE)) UNSPEC_PIC_BASE))
(use (label_ref (match_operand 2 "" "")))] (use (match_operand 2 "" ""))]
"TARGET_THUMB" "TARGET_THUMB"
"* "*
(*targetm.asm_out.internal_label) (asm_out_file, \"L\", (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
CODE_LABEL_NUMBER (operands[2])); INTVAL (operands[2]));
return \"add\\t%0, %|pc\"; return \"add\\t%0, %|pc\";
" "
[(set_attr "length" "2")] [(set_attr "length" "2")]
...@@ -4483,11 +4485,11 @@ ...@@ -4483,11 +4485,11 @@
(unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "r") (unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "r")
(const (plus:SI (pc) (const_int 8))))] (const (plus:SI (pc) (const_int 8))))]
UNSPEC_PIC_BASE)) UNSPEC_PIC_BASE))
(use (label_ref (match_operand 2 "" "")))] (use (match_operand 2 "" ""))]
"TARGET_ARM" "TARGET_ARM"
"* "*
(*targetm.asm_out.internal_label) (asm_out_file, \"L\", (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
CODE_LABEL_NUMBER (operands[2])); INTVAL (operands[2]));
return \"add%?\\t%0, %|pc, %1\"; return \"add%?\\t%0, %|pc, %1\";
" "
[(set_attr "predicable" "yes")] [(set_attr "predicable" "yes")]
...@@ -4498,11 +4500,11 @@ ...@@ -4498,11 +4500,11 @@
(mem:SI (unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "r") (mem:SI (unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "r")
(const (plus:SI (pc) (const_int 8))))] (const (plus:SI (pc) (const_int 8))))]
UNSPEC_PIC_BASE))) UNSPEC_PIC_BASE)))
(use (label_ref (match_operand 2 "" "")))] (use (match_operand 2 "" ""))]
"TARGET_ARM" "TARGET_ARM"
"* "*
(*targetm.asm_out.internal_label) (asm_out_file, \"L\", (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
CODE_LABEL_NUMBER (operands[2])); INTVAL (operands[2]));
return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\"; return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
" "
[(set_attr "predicable" "yes")] [(set_attr "predicable" "yes")]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment