This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[arm] Fix -fPIC


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;
 }")
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]