Commit 85c9bcd4 by Wei Guozhi Committed by Wei Guozhi

re PR target/42601 (Simplify code to address function static variables with option -fpic)

	PR target/42601
	* config/arm/arm.c (arm_pic_static_addr): New function.
	(legitimize_pic_address): Call arm_pic_static_addr when it detects
	a static symbol.
	(arm_output_addr_const_extra): Output expression for new pattern.
	* config/arm/arm.md (UNSPEC_SYMBOL_OFFSET): New unspec symbol.

From-SVN: r158189
parent 52c1d580
2010-04-10 Wei Guozhi <carrot@google.com>
PR target/42601
* config/arm/arm.c (arm_pic_static_addr): New function.
(legitimize_pic_address): Call arm_pic_static_addr when it detects
a static symbol.
(arm_output_addr_const_extra): Output expression for new pattern.
* config/arm/arm.md (UNSPEC_SYMBOL_OFFSET): New unspec symbol.
2010-04-10 Bernd Schmidt <bernd.schmidt@codesourcery.com> 2010-04-10 Bernd Schmidt <bernd.schmidt@codesourcery.com>
* ira-costs.c (record_reg_classes): Ignore alternatives that are * ira-costs.c (record_reg_classes): Ignore alternatives that are
......
...@@ -224,6 +224,7 @@ static bool arm_can_eliminate (const int, const int); ...@@ -224,6 +224,7 @@ static bool arm_can_eliminate (const int, const int);
static void arm_asm_trampoline_template (FILE *); static void arm_asm_trampoline_template (FILE *);
static void arm_trampoline_init (rtx, tree, rtx); static void arm_trampoline_init (rtx, tree, rtx);
static rtx arm_trampoline_adjust_address (rtx); static rtx arm_trampoline_adjust_address (rtx);
static rtx arm_pic_static_addr (rtx orig, rtx reg);
/* Table of machine attributes. */ /* Table of machine attributes. */
...@@ -4905,29 +4906,16 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg) ...@@ -4905,29 +4906,16 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
{ {
rtx pic_ref, address; rtx pic_ref, address;
rtx insn; rtx insn;
int subregs = 0;
/* If this function doesn't have a pic register, create one now. */
require_pic_register ();
if (reg == 0) if (reg == 0)
{ {
gcc_assert (can_create_pseudo_p ()); gcc_assert (can_create_pseudo_p ());
reg = gen_reg_rtx (Pmode); reg = gen_reg_rtx (Pmode);
address = gen_reg_rtx (Pmode);
subregs = 1;
} }
if (subregs)
address = gen_reg_rtx (Pmode);
else else
address = reg; address = reg;
if (TARGET_32BIT)
emit_insn (gen_pic_load_addr_32bit (address, orig));
else /* TARGET_THUMB1 */
emit_insn (gen_pic_load_addr_thumb1 (address, orig));
/* VxWorks does not impose a fixed gap between segments; the run-time /* VxWorks does not impose a fixed gap between segments; the run-time
gap can be different from the object-file gap. We therefore can't gap can be different from the object-file gap. We therefore can't
use GOTOFF unless we are absolutely sure that the symbol is in the use GOTOFF unless we are absolutely sure that the symbol is in the
...@@ -4939,16 +4927,23 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg) ...@@ -4939,16 +4927,23 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
SYMBOL_REF_LOCAL_P (orig))) SYMBOL_REF_LOCAL_P (orig)))
&& NEED_GOT_RELOC && NEED_GOT_RELOC
&& !TARGET_VXWORKS_RTP) && !TARGET_VXWORKS_RTP)
pic_ref = gen_rtx_PLUS (Pmode, cfun->machine->pic_reg, address); insn = arm_pic_static_addr (orig, reg);
else else
{ {
/* If this function doesn't have a pic register, create one now. */
require_pic_register ();
if (TARGET_32BIT)
emit_insn (gen_pic_load_addr_32bit (address, orig));
else /* TARGET_THUMB1 */
emit_insn (gen_pic_load_addr_thumb1 (address, orig));
pic_ref = gen_const_mem (Pmode, pic_ref = gen_const_mem (Pmode,
gen_rtx_PLUS (Pmode, cfun->machine->pic_reg, gen_rtx_PLUS (Pmode, cfun->machine->pic_reg,
address)); address));
insn = emit_move_insn (reg, pic_ref);
} }
insn = emit_move_insn (reg, pic_ref);
/* Put a REG_EQUAL note on this insn, so that it can be optimized /* Put a REG_EQUAL note on this insn, so that it can be optimized
by loop. */ by loop. */
set_unique_reg_note (insn, REG_EQUAL, orig); set_unique_reg_note (insn, REG_EQUAL, orig);
...@@ -5155,6 +5150,43 @@ arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED) ...@@ -5155,6 +5150,43 @@ arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED)
emit_use (pic_reg); emit_use (pic_reg);
} }
/* Generate code to load the address of a static var when flag_pic is set. */
static rtx
arm_pic_static_addr (rtx orig, rtx reg)
{
rtx l1, labelno, offset_rtx, insn;
gcc_assert (flag_pic);
/* 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);
/* On the ARM the PC register contains 'dot + 8' at the time of the
addition, on the Thumb it is 'dot + 4'. */
offset_rtx = plus_constant (l1, TARGET_ARM ? 8 : 4);
offset_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, orig, offset_rtx),
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));
}
return insn;
}
/* Return nonzero if X is valid as an ARM state addressing register. */ /* Return nonzero if X is valid as an ARM state addressing register. */
static int static int
...@@ -21325,6 +21357,16 @@ arm_output_addr_const_extra (FILE *fp, rtx x) ...@@ -21325,6 +21357,16 @@ arm_output_addr_const_extra (FILE *fp, rtx x)
fputc (')', fp); fputc (')', fp);
return TRUE; return TRUE;
} }
else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_SYMBOL_OFFSET)
{
output_addr_const (fp, XVECEXP (x, 0, 0));
if (GOT_PCREL)
fputs ("+.", fp);
fputs ("-(", fp);
output_addr_const (fp, XVECEXP (x, 0, 1));
fputc (')', fp);
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);
......
...@@ -101,6 +101,8 @@ ...@@ -101,6 +101,8 @@
; a given symbolic address. ; a given symbolic address.
(UNSPEC_THUMB1_CASESI 25) ; A Thumb1 compressed dispatch-table call. (UNSPEC_THUMB1_CASESI 25) ; A Thumb1 compressed dispatch-table call.
(UNSPEC_RBIT 26) ; rbit operation. (UNSPEC_RBIT 26) ; rbit operation.
(UNSPEC_SYMBOL_OFFSET 27) ; The offset of the start of the symbol from
; another symbolic address.
] ]
) )
......
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