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: [PATCH, arm] Stack the PIC register for Thumb if PIC is enabled


Hi Adam,

> 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.
> 
> 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.

I think that this patch would be better if you moved the entire test
for a thumb register being pushed into a macro and then just used the
macro throughtout arm.[ch].  See the attached reworked patch for an
example.

Using a macro has several advantages:

  * It will be easier to update the test in the future.

  * It eliminates discrepancies in different functions which need to
    decide if a register will be stacked.  For example the current
    implementation of THUMB_INITIAL_ELIMINATION_OFFSET does not take
    into account "!(TARGET_SINGLE_PIC_BASE && ((reg) == arm_pic_register))"

  * It reduces source code size and makes the code easier to read.

What do you think ?

Cheers
        Nick

Index: gcc/config/arm/arm.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.h,v
retrieving revision 1.154
diff -c -3 -p -w -r1.154 arm.h
*** gcc/config/arm/arm.h	17 Jul 2002 09:54:11 -0000	1.154
--- gcc/config/arm/arm.h	1 Aug 2002 14:38:59 -0000
*************** typedef struct
*** 1622,1627 ****
--- 1622,1633 ----
     ((TO) == THUMB_HARD_FRAME_POINTER_REGNUM && TARGET_ARM) ? 0 :	\
     1)
  
+ #define THUMB_REG_PUSHED_P(reg)					\
+   (regs_ever_live [reg]						\
+    && (! call_used_regs [reg]					\
+        || (flag_pic && (reg) == PIC_OFFSET_TABLE_REGNUM))	\
+    && !(TARGET_SINGLE_PIC_BASE && ((reg) == arm_pic_register)))
+      
  /* Define the offset between two registers, one to be eliminated, and the
     other its replacement, at the start of a routine.  */
  #define ARM_INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)		\
*************** typedef struct
*** 1640,1652 ****
        int count_regs = 0;						\
        int regno;							\
        for (regno = 8; regno < 13; regno ++)				\
! 	if (regs_ever_live[regno] && ! call_used_regs[regno])		\
  	  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])		\
  	  count_regs ++;						\
        if (count_regs || ! leaf_function_p () || thumb_far_jump_used_p (0))\
  	(OFFSET) += 4 * (count_regs + 1);				\
--- 1646,1658 ----
        int count_regs = 0;						\
        int regno;							\
        for (regno = 8; regno < 13; regno ++)				\
!         if (THUMB_REG_PUSHED_P (regno))					\
            count_regs ++;						\
        if (count_regs)							\
  	(OFFSET) += 4 * count_regs;					\
        count_regs = 0;							\
        for (regno = 0; regno <= LAST_LO_REGNUM; regno ++)		\
!         if (THUMB_REG_PUSHED_P (regno))					\
  	  count_regs ++;						\
        if (count_regs || ! leaf_function_p () || thumb_far_jump_used_p (0))\
  	(OFFSET) += 4 * (count_regs + 1);				\

Index: gcc/config/arm/arm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.218
diff -c -3 -p -w -r1.218 arm.c
*** gcc/config/arm/arm.c	23 Jul 2002 06:22:02 -0000	1.218
--- gcc/config/arm/arm.c	1 Aug 2002 14:39:01 -0000
*************** thumb_unexpanded_epilogue ()
*** 9912,9927 ****
      return "";
  
    for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
!     if (regs_ever_live[regno] && !call_used_regs[regno]
! 	&& !(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]
! 	  && !(TARGET_SINGLE_PIC_BASE && (regno == arm_pic_register)))
  	high_regs_pushed++;
-     }
  
    /* The prolog may have pushed some high registers to use as
       work registers.  eg the testuite file:
--- 9912,9923 ----
      return "";
  
    for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
!     if (THUMB_REG_PUSHED_P (regno))
        live_regs_mask |= 1 << regno;
  
    for (regno = 8; regno < 13; regno++)
!     if (THUMB_REG_PUSHED_P (regno))
        high_regs_pushed++;
  
    /* The prolog may have pushed some high registers to use as
       work registers.  eg the testuite file:
*************** thumb_unexpanded_epilogue ()
*** 9966,9973 ****
  	  ("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]
! 	    && !(TARGET_SINGLE_PIC_BASE && (next_hi_reg == arm_pic_register)))
  	  break;
  
        while (high_regs_pushed)
--- 9962,9968 ----
  	  ("no low registers available for popping high registers");
        
        for (next_hi_reg = 8; next_hi_reg < 13; next_hi_reg++)
! 	if (THUMB_REG_PUSHED_P (next_hi_reg))
  	  break;
  
        while (high_regs_pushed)
*************** thumb_unexpanded_epilogue ()
*** 9996,10005 ****
  			       regno);
  		  
  		  for (next_hi_reg++; next_hi_reg < 13; next_hi_reg++)
! 		    if (regs_ever_live[next_hi_reg]
! 			&& !call_used_regs[next_hi_reg]
! 			&& !(TARGET_SINGLE_PIC_BASE 
! 			     && (next_hi_reg == arm_pic_register)))
  		      break;
  		}
  	    }
--- 9991,9997 ----
  			       regno);
  		  
  		  for (next_hi_reg++; next_hi_reg < 13; next_hi_reg++)
! 		    if (THUMB_REG_PUSHED_P (next_hi_reg))
  		      break;
  		}
  	    }
*************** thumb_expand_prologue ()
*** 10166,10179 ****
  	     been pushed at the start of the prologue and so we can corrupt
  	     it now.  */
  	  for (regno = LAST_ARG_REGNUM + 1; regno <= LAST_LO_REGNUM; regno++)
! 	    if (regs_ever_live[regno]
! 		&& !call_used_regs[regno] /* Paranoia */
! 		&& !(TARGET_SINGLE_PIC_BASE && (regno == arm_pic_register))
  		&& !(frame_pointer_needed
  		     && (regno == THUMB_HARD_FRAME_POINTER_REGNUM)))
  	      break;
  
! 	  if (regno > LAST_LO_REGNUM) /* Very unlikely */
  	    {
  	      rtx spare = gen_rtx (REG, SImode, IP_REGNUM);
  
--- 10158,10169 ----
  	     been pushed at the start of the prologue and so we can corrupt
  	     it now.  */
  	  for (regno = LAST_ARG_REGNUM + 1; regno <= LAST_LO_REGNUM; regno++)
! 	    if (THUMB_REG_PUSHED_P (regno)
  		&& !(frame_pointer_needed
  		     && (regno == THUMB_HARD_FRAME_POINTER_REGNUM)))
  	      break;
  
! 	  if (regno > LAST_LO_REGNUM) /* Very unlikely.  */
  	    {
  	      rtx spare = gen_rtx (REG, SImode, IP_REGNUM);
  
*************** thumb_output_function_prologue (f, size)
*** 10323,10330 ****
      }
  
    for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
!     if (regs_ever_live[regno] && !call_used_regs[regno]
! 	&& !(TARGET_SINGLE_PIC_BASE && (regno == arm_pic_register)))
        live_regs_mask |= 1 << regno;
  
    if (live_regs_mask || !leaf_function_p () || thumb_far_jump_used_p (1))
--- 10313,10319 ----
      }
  
    for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
!     if (THUMB_REG_PUSHED_P (regno))
        live_regs_mask |= 1 << regno;
  
    if (live_regs_mask || !leaf_function_p () || thumb_far_jump_used_p (1))
*************** thumb_output_function_prologue (f, size)
*** 10426,10433 ****
  
    for (regno = 8; regno < 13; regno++)
      {
!       if (regs_ever_live[regno] && !call_used_regs[regno]
! 	  && !(TARGET_SINGLE_PIC_BASE && (regno == arm_pic_register)))
  	high_regs_pushed++;
      }
  
--- 10415,10421 ----
  
    for (regno = 8; regno < 13; regno++)
      {
!       if (THUMB_REG_PUSHED_P (regno))
  	high_regs_pushed++;
      }
  
*************** thumb_output_function_prologue (f, size)
*** 10439,10447 ****
  
        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]
! 	      && !(TARGET_SINGLE_PIC_BASE
! 		   && (next_hi_reg == arm_pic_register)))
  	    break;
  	}
  
--- 10427,10433 ----
  
        for (next_hi_reg = 12; next_hi_reg > LAST_LO_REGNUM; next_hi_reg--)
  	{
! 	  if (THUMB_REG_PUSHED_P (next_hi_reg))
  	    break;
  	}
  
*************** thumb_output_function_prologue (f, size)
*** 10450,10457 ****
        if (pushable_regs == 0)
  	{
  	  /* Desperation time -- this probably will never happen.  */
! 	  if (regs_ever_live[LAST_ARG_REGNUM]
! 	      || !call_used_regs[LAST_ARG_REGNUM])
  	    asm_fprintf (f, "\tmov\t%r, %r\n", IP_REGNUM, LAST_ARG_REGNUM);
  	  mask = 1 << LAST_ARG_REGNUM;
  	}
--- 10436,10442 ----
        if (pushable_regs == 0)
  	{
  	  /* Desperation time -- this probably will never happen.  */
! 	  if (THUMB_REG_PUSHED_P (LAST_ARG_REGNUM))
  	    asm_fprintf (f, "\tmov\t%r, %r\n", IP_REGNUM, LAST_ARG_REGNUM);
  	  mask = 1 << LAST_ARG_REGNUM;
  	}
*************** thumb_output_function_prologue (f, size)
*** 10467,10479 ****
  		  high_regs_pushed--;
  		  
  		  if (high_regs_pushed)
  		    for (next_hi_reg--; next_hi_reg > LAST_LO_REGNUM;
  			 next_hi_reg--)
! 		      {
! 			if (regs_ever_live[next_hi_reg]
! 			    && !call_used_regs[next_hi_reg]
! 			    && !(TARGET_SINGLE_PIC_BASE 
! 				 && (next_hi_reg == arm_pic_register)))
  			  break;
  		      }
  		  else
--- 10452,10461 ----
  		  high_regs_pushed--;
  		  
  		  if (high_regs_pushed)
+ 		    {
  		      for (next_hi_reg--; next_hi_reg > LAST_LO_REGNUM;
  			   next_hi_reg--)
! 			if (THUMB_REG_PUSHED_P (next_hi_reg))
  			  break;
  		    }
  		  else
*************** thumb_output_function_prologue (f, size)
*** 10488,10495 ****
  	}
  
        if (pushable_regs == 0
! 	  && (regs_ever_live[LAST_ARG_REGNUM]
! 	      || !call_used_regs[LAST_ARG_REGNUM]))
  	asm_fprintf (f, "\tmov\t%r, %r\n", LAST_ARG_REGNUM, IP_REGNUM);
      }
  }
--- 10470,10476 ----
  	}
  
        if (pushable_regs == 0
! 	  && (THUMB_REG_PUSHED_P (LAST_ARG_REGNUM)))
  	asm_fprintf (f, "\tmov\t%r, %r\n", LAST_ARG_REGNUM, IP_REGNUM);
      }
  }


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