[PATCH, arm] Stack the PIC register for Thumb if PIC is enabled

Adam Nemet anemet@Lnxw.COM
Tue Jul 9 11:26:00 GMT 2002


Hi,

In the merged ARM-Thumb backend
call_used_regs[PIC_OFFSET_TABLE_REGNUM] == 1.  When producing the
prologue/epilogue the ARM part special-cases the PIC register so that
it gets stacked properly.  Here is the patch for the Thumb part.

The patch is the first of a series of patches (mostly binutils) where
I will attempt to make Thumb shared libs work.

Regtested on arm-elf with all the combinations of the following flags:

1. -marm/-mthumb
2. /-fPIC/-fPIC -mpic-register=6

Please apply if OK.


2002-07-09  Adam Nemet  <anemet@lnxw.com>

	* config/arm/arm.c (thumb_unexpanded_epilogue): Stack the PIC
	register.
	(thumb_expand_prologue): Likewise.
	(thumb_output_function_prologue): Likewise.
	* config/arm/arm.h (THUMB_INITIAL_ELIMINATION_OFFSET): Account for
	the additional push of the PIC register.

Index: arm.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.214
diff -u -p -r1.214 arm.c
--- arm.c	1 Jul 2002 23:07:06 -0000	1.214
+++ arm.c	9 Jul 2002 18:05:19 -0000
@@ -9923,13 +9923,17 @@ thumb_unexpanded_epilogue ()
     return "";
 
   for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
-    if (regs_ever_live[regno] && !call_used_regs[regno]
+    if (regs_ever_live[regno]
+	&& (!call_used_regs[regno]
+	    || flag_pic && regno == PIC_OFFSET_TABLE_REGNUM)
 	&& !(TARGET_SINGLE_PIC_BASE && (regno == arm_pic_register)))
       live_regs_mask |= 1 << regno;
 
   for (regno = 8; regno < 13; regno++)
     {
-      if (regs_ever_live[regno] && !call_used_regs[regno]
+      if (regs_ever_live[regno]
+	  && ((!call_used_regs[regno]
+	       || flag_pic && regno == PIC_OFFSET_TABLE_REGNUM))
 	  && !(TARGET_SINGLE_PIC_BASE && (regno == arm_pic_register)))
 	high_regs_pushed++;
     }
@@ -9977,7 +9981,9 @@ thumb_unexpanded_epilogue ()
 	  ("no low registers available for popping high registers");
       
       for (next_hi_reg = 8; next_hi_reg < 13; next_hi_reg++)
-	if (regs_ever_live[next_hi_reg] && !call_used_regs[next_hi_reg]
+	if (regs_ever_live[next_hi_reg]
+	    && ((!call_used_regs[next_hi_reg]
+		 || flag_pic && next_hi_reg == PIC_OFFSET_TABLE_REGNUM))
 	    && !(TARGET_SINGLE_PIC_BASE && (next_hi_reg == arm_pic_register)))
 	  break;
 
@@ -10008,7 +10014,9 @@ thumb_unexpanded_epilogue ()
 		  
 		  for (next_hi_reg++; next_hi_reg < 13; next_hi_reg++)
 		    if (regs_ever_live[next_hi_reg]
-			&& !call_used_regs[next_hi_reg]
+			&& (!call_used_regs[next_hi_reg]
+			    || (flag_pic
+				&& next_hi_reg == PIC_OFFSET_TABLE_REGNUM))
 			&& !(TARGET_SINGLE_PIC_BASE 
 			     && (next_hi_reg == arm_pic_register)))
 		      break;
@@ -10178,7 +10186,8 @@ thumb_expand_prologue ()
 	     it now.  */
 	  for (regno = LAST_ARG_REGNUM + 1; regno <= LAST_LO_REGNUM; regno++)
 	    if (regs_ever_live[regno]
-		&& !call_used_regs[regno] /* Paranoia */
+		&& (!call_used_regs[regno] /* Paranoia */
+		    || flag_pic && regno == PIC_OFFSET_TABLE_REGNUM)
 		&& !(TARGET_SINGLE_PIC_BASE && (regno == arm_pic_register))
 		&& !(frame_pointer_needed
 		     && (regno == THUMB_HARD_FRAME_POINTER_REGNUM)))
@@ -10334,7 +10343,9 @@ thumb_output_function_prologue (f, size)
     }
 
   for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
-    if (regs_ever_live[regno] && !call_used_regs[regno]
+    if (regs_ever_live[regno]
+	&& (!call_used_regs[regno]
+	    || flag_pic && regno == PIC_OFFSET_TABLE_REGNUM)
 	&& !(TARGET_SINGLE_PIC_BASE && (regno == arm_pic_register)))
       live_regs_mask |= 1 << regno;
 
@@ -10437,7 +10448,9 @@ thumb_output_function_prologue (f, size)
 
   for (regno = 8; regno < 13; regno++)
     {
-      if (regs_ever_live[regno] && !call_used_regs[regno]
+      if (regs_ever_live[regno]
+	  && (!call_used_regs[regno]
+	      || flag_pic && regno == PIC_OFFSET_TABLE_REGNUM)
 	  && !(TARGET_SINGLE_PIC_BASE && (regno == arm_pic_register)))
 	high_regs_pushed++;
     }
@@ -10450,7 +10463,9 @@ thumb_output_function_prologue (f, size)
 
       for (next_hi_reg = 12; next_hi_reg > LAST_LO_REGNUM; next_hi_reg--)
 	{
-	  if (regs_ever_live[next_hi_reg] && !call_used_regs[next_hi_reg]
+	  if (regs_ever_live[next_hi_reg]
+	      && (!call_used_regs[next_hi_reg]
+		  || flag_pic && next_hi_reg == PIC_OFFSET_TABLE_REGNUM)
 	      && !(TARGET_SINGLE_PIC_BASE
 		   && (next_hi_reg == arm_pic_register)))
 	    break;
@@ -10482,7 +10497,9 @@ thumb_output_function_prologue (f, size)
 			 next_hi_reg--)
 		      {
 			if (regs_ever_live[next_hi_reg]
-			    && !call_used_regs[next_hi_reg]
+			    && (!call_used_regs[next_hi_reg]
+				|| (flag_pic
+				    && next_hi_reg == PIC_OFFSET_TABLE_REGNUM))
 			    && !(TARGET_SINGLE_PIC_BASE 
 				 && (next_hi_reg == arm_pic_register)))
 			  break;
Index: arm.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/arm/arm.h,v
retrieving revision 1.152
diff -u -p -r1.152 arm.h
--- arm.h	10 Jun 2002 22:35:45 -0000	1.152
+++ arm.h	9 Jul 2002 18:05:19 -0000
@@ -1640,13 +1640,17 @@ typedef struct
       int count_regs = 0;						\
       int regno;							\
       for (regno = 8; regno < 13; regno ++)				\
-	if (regs_ever_live[regno] && ! call_used_regs[regno])		\
-	  count_regs ++;						\
+	if (regs_ever_live[regno]					\
+	    && (! call_used_regs[regno]					\
+		|| flag_pic && regno == PIC_OFFSET_TABLE_REGNUM))	\
+  	  count_regs ++;						\
       if (count_regs)							\
 	(OFFSET) += 4 * count_regs;					\
       count_regs = 0;							\
       for (regno = 0; regno <= LAST_LO_REGNUM; regno ++)		\
-	if (regs_ever_live[regno] && ! call_used_regs[regno])		\
+	if (regs_ever_live[regno]					\
+	    && (! call_used_regs[regno]					\
+		|| flag_pic && regno == PIC_OFFSET_TABLE_REGNUM))	\
 	  count_regs ++;						\
       if (count_regs || ! leaf_function_p () || thumb_far_jump_used_p (0))\
 	(OFFSET) += 4 * (count_regs + 1);				\



More information about the Gcc-patches mailing list