* Re: [arm] Fix thumb -fPIC
2004-10-12 11:59 ` Richard Earnshaw
@ 2004-10-12 19:14 ` Paul Brook
2004-10-13 9:08 ` Richard Earnshaw
0 siblings, 1 reply; 4+ messages in thread
From: Paul Brook @ 2004-10-12 19:14 UTC (permalink / raw)
To: gcc-patches; +Cc: Richard Earnshaw
> > (thumb_find_work_register): Search full register range.
>
> I'm not 100% sure about the second issue. LAST_LO_REGNUM is sometimes
> used as a frame pointer register when we can't manage without one, have
> you checked that it's safe to use it as a scratch in these conditions
> (it may be, but I'm not sure).
I checked the function prologue usage, but missed the the use from
builtin_setjmp_reciever. Patch below fixes this case, which seemed to be
working by chance.
Tested with cross to arm-none-elf.
Ok?
Paul
2004-10-12 Paul Brook <paul@codesourcery.com>
* config/arm/arm-protos.h (arm_load_pic_register): Update prototype.
* config/arm/arm.c (thumb_find_work_register): Update comments.
(arm_load_pic_register): Add argument for scratch register.
(arm_expand_prologue, thumb_expand_prologue): Pass extra argument.
* config/arm/arm.md (builtin_setjmp_receiver): Ditto.
Index: config/arm/arm-protos.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/arm/arm-protos.h,v
retrieving revision 1.77
diff -u -p -r1.77 arm-protos.h
--- config/arm/arm-protos.h 24 Aug 2004 20:16:40 -0000 1.77
+++ config/arm/arm-protos.h 12 Oct 2004 18:05:54 -0000
@@ -27,7 +27,7 @@
extern void arm_override_options (void);
extern int use_return_insn (int, rtx);
extern int arm_regno_class (int);
-extern void arm_load_pic_register (void);
+extern void arm_load_pic_register (unsigned int);
extern int arm_volatile_func (void);
extern const char *arm_output_epilogue (rtx);
extern void arm_expand_prologue (void);
Index: config/arm/arm.c
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.411
diff -u -p -r1.411 arm.c
--- config/arm/arm.c 12 Oct 2004 16:43:56 -0000 1.411
+++ config/arm/arm.c 12 Oct 2004 18:07:12 -0000
@@ -3023,7 +3023,8 @@ thumb_find_work_register (int live_regs_
if (!regs_ever_live[LAST_ARG_REGNUM])
return LAST_ARG_REGNUM;
- /* Look for a pushed register. */
+ /* Look for a pushed register. This is used before the frame pointer is
+ setup, so r7 is a candidate. */
for (reg = LAST_LO_REGNUM; reg >=0; reg--)
if (live_regs_mask & (1 << reg))
return reg;
@@ -3033,10 +3034,11 @@ thumb_find_work_register (int live_regs_
}
-/* Generate code to load the PIC register. */
+/* Generate code to load the PIC register. In thumb mode SCRATCH is a
+ low register. */
void
-arm_load_pic_register (void)
+arm_load_pic_register (unsigned int scratch)
{
#ifndef AOF_ASSEMBLER
rtx l1, pic_tmp, pic_tmp2, pic_rtx;
@@ -3071,12 +3073,9 @@ arm_load_pic_register (void)
{
if (REGNO (pic_offset_table_rtx) > LAST_LO_REGNUM)
{
- int reg;
-
/* We will have pushed the pic register, so should always be
able to find a work register. */
- reg = thumb_find_work_register (thumb_compute_save_reg_mask ());
- pic_tmp = gen_rtx_REG (SImode, reg);
+ pic_tmp = gen_rtx_REG (SImode, scratch);
emit_insn (gen_pic_load_addr_thumb (pic_tmp, pic_rtx));
emit_insn (gen_movsi (pic_offset_table_rtx, pic_tmp));
}
@@ -10237,7 +10236,7 @@ arm_expand_prologue (void)
if (flag_pic)
- arm_load_pic_register ();
+ arm_load_pic_register (INVALID_REGNUM);
/* If we are profiling, make sure no instructions are scheduled before
the call to mcount. Similarly if the user has requested no
@@ -12964,10 +12963,11 @@ thumb_expand_prologue (void)
return;
}
+ live_regs_mask = thumb_compute_save_reg_mask ();
/* Load the pic register before setting the frame pointer, so we can use r7
as a temporary work register. */
if (flag_pic)
- arm_load_pic_register ();
+ arm_load_pic_register (thumb_find_work_register (live_regs_mask));
offsets = arm_get_frame_offsets ();
@@ -12978,7 +12978,6 @@ thumb_expand_prologue (void)
RTX_FRAME_RELATED_P (insn) = 1;
}
- live_regs_mask = thumb_compute_save_reg_mask ();
amount = offsets->outgoing_args - offsets->saved_regs;
if (amount)
{
Index: config/arm/arm.md
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/arm/arm.md,v
retrieving revision 1.183
diff -u -p -r1.183 arm.md
--- config/arm/arm.md 12 Oct 2004 13:56:03 -0000 1.183
+++ config/arm/arm.md 12 Oct 2004 18:05:54 -0000
@@ -4459,7 +4459,9 @@
"flag_pic"
"
{
- arm_load_pic_register ();
+ /* r3 is clobbered by set/longjmp, so we can use it as a scratch
+ register. */
+ arm_load_pic_register (3);
DONE;
}")
^ permalink raw reply [flat|nested] 4+ messages in thread