This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH, arm] Stack the PIC register for Thumb if PIC is enabled
- From: Adam Nemet <anemet at Lnxw dot COM>
- To: gcc-patches at gcc dot gnu dot org
- Date: 09 Jul 2002 11:16:46 -0700
- Subject: [PATCH, arm] Stack the PIC register for Thumb if PIC is enabled
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); \