This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[arm] Fix -fPIC
- From: Paul Brook <paul at codesourcery dot com>
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Cc: Richard Earnshaw <Richard dot Earnshaw at arm dot com>
- Date: Wed, 11 Aug 2004 14:55:58 +0100
- Subject: [arm] Fix -fPIC
- Organization: CodeSourcery
The following patch fixes PIC code generation on arm. It currently fails with
"insn outside basic block".
I've moved the PIC register initialization code from FINALIZE_PIC to the
function prologue. This seems to be how other targets do it. I'm guessing
that FINALIZE_PIC is from when we did inlining on RTL.
This patch requires my previous "rework thumb function prologue" patch.
Tested with cross to arm-none-elf.
Ok?
Paul
2004-08-07 Paul Brook <paul@codesourcery.com>
* config/arm/arm-protos.h (arm_finalize_pic) Rename ...
(arm_load_pic_register): ... to this.
* config/arm/arm.c (arm_finalize_pic): Rename ...
(arm_load_pic_register): ... to this. Always output insns at the
current location.
(arm_expand_prologue): Call arm_load_pic_register.
(thumb_expand_prologue): Ditto.
* config/arm/arm.h (FINALIZE_PIC): Remove.
* config/arm/arm.md (builtin_setjmp_receiver) Call
arm_load_pic_register.
Index: arm-protos.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/arm/arm-protos.h,v
retrieving revision 1.71
diff -u -p -r1.71 arm-protos.h
--- arm-protos.h 14 Jul 2004 17:51:17 -0000 1.71
+++ arm-protos.h 7 Aug 2004 22:31:15 -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_finalize_pic (int);
+extern void arm_load_pic_register (void);
extern int arm_volatile_func (void);
extern const char *arm_output_epilogue (rtx);
extern void arm_expand_prologue (void);
Index: arm.c
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.383
diff -u -p -r1.383 arm.c
--- arm.c 6 Aug 2004 02:03:22 -0000 1.383
+++ arm.c 7 Aug 2004 23:33:30 -0000
@@ -2883,16 +2885,14 @@ legitimize_pic_address (rtx orig, enum m
abort ();
}
-/* Generate code to load the PIC register. PROLOGUE is true if
- called from arm_expand_prologue (in which case we want the
- generated insns at the start of the function); false if called
- by an exception receiver that needs the PIC register reloaded
- (in which case the insns are just dumped at the current location). */
+
+/* Generate code to load the PIC register. */
+
void
-arm_finalize_pic (int prologue ATTRIBUTE_UNUSED)
+arm_load_pic_register (void)
{
#ifndef AOF_ASSEMBLER
- rtx l1, pic_tmp, pic_tmp2, seq, pic_rtx;
+ rtx l1, pic_tmp, pic_tmp2, pic_rtx;
rtx global_offset_table;
if (current_function_uses_pic_offset_table == 0 || TARGET_SINGLE_PIC_BASE)
@@ -2901,7 +2922,6 @@ arm_finalize_pic (int prologue ATTRIBUTE
if (!flag_pic)
abort ();
- start_sequence ();
l1 = gen_label_rtx ();
global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
@@ -2923,23 +2943,29 @@ arm_finalize_pic (int prologue ATTRIBUTE
}
else
{
- emit_insn (gen_pic_load_addr_thumb (pic_offset_table_rtx, pic_rtx));
+ 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);
+ emit_insn (gen_pic_load_addr_thumb (pic_tmp, pic_rtx));
+ emit_insn (gen_movsi (pic_offset_table_rtx, pic_tmp));
+ }
+ else
+ 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, l1));
}
- seq = get_insns ();
- end_sequence ();
- if (prologue)
- emit_insn_after (seq, get_insns ());
- else
- emit_insn (seq);
-
/* Need to emit this whether or not we obey regdecls,
since setjmp/longjmp can cause life info to screw up. */
emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
#endif /* AOF_ASSEMBLER */
}
+
/* Return nonzero if X is valid as an ARM state addressing register. */
static int
arm_address_register_rtx_p (rtx x, int strict_p)
@@ -10537,6 +10576,10 @@ arm_expand_prologue (void)
hard_frame_pointer_rtx));
}
+
+ if (flag_pic)
+ arm_load_pic_register ();
+
/* If we are profiling, make sure no instructions are scheduled before
the call to mcount. Similarly if the user has requested no
scheduling in the prolog. */
@@ -13215,6 +13248,11 @@ thumb_expand_prologue (void)
return;
}
+ /* Load the pic recister before setting the frame pointer, so we can use r7
+ as a temporary work register. */
+ if (flag_pic)
+ arm_load_pic_register ();
+
offsets = arm_get_frame_offsets ();
if (frame_pointer_needed)
Index: arm.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/arm/arm.h,v
retrieving revision 1.245
diff -u -p -r1.245 arm.h
--- arm.h 14 Jul 2004 17:51:18 -0000 1.245
+++ arm.h 7 Aug 2004 23:20:09 -0000
@@ -2261,8 +2255,6 @@ extern const char * arm_pic_register_str
data addresses in memory. */
#define PIC_OFFSET_TABLE_REGNUM arm_pic_register
-#define FINALIZE_PIC arm_finalize_pic (1)
-
/* We can't directly access anything that contains a symbol,
nor can we indirect via the constant pool. */
#define LEGITIMATE_PIC_OPERAND_P(X) \
Index: arm.md
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/arm/arm.md,v
retrieving revision 1.174
diff -u -p -r1.174 arm.md
--- arm.md 3 Aug 2004 13:27:02 -0000 1.174
+++ arm.md 7 Aug 2004 22:31:15 -0000
@@ -4460,7 +4460,7 @@
"flag_pic"
"
{
- arm_finalize_pic (0);
+ arm_load_pic_register ();
DONE;
}")