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]

Re: [arm] Fix thumb -fPIC


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


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