aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Nemet <anemet@lnxw.com>2002-08-08 11:08:34 +0000
committerNick Clifton <nickc@gcc.gnu.org>2002-08-08 11:08:34 +0000
commitaeaf4d25a8a6a06c8dd8735e0a9b3608acc10d3f (patch)
tree93cd6302918d1181eda42bc96399b563baaea6e1
parent5bfc90dea315f4ec135119a3526741e8fa6deb48 (diff)
downloadgcc-aeaf4d25a8a6a06c8dd8735e0a9b3608acc10d3f.zip
gcc-aeaf4d25a8a6a06c8dd8735e0a9b3608acc10d3f.tar.gz
gcc-aeaf4d25a8a6a06c8dd8735e0a9b3608acc10d3f.tar.bz2
arm.c (thumb_unexpanded_epilogue): Stack the PIC register.
* 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. From-SVN: r56128
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/arm/arm.c53
-rw-r--r--gcc/config/arm/arm.h14
3 files changed, 36 insertions, 40 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2ae5cda..2a1311f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2002-08-08 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.
+
2002-08-08 Nathan Sidwell <nathan@codesourcery.com>
* configure.in (enable_coverage): New enable switch.
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index b4b747e..09df214 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -9912,16 +9912,12 @@ thumb_unexpanded_epilogue ()
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)))
+ if (THUMB_REG_PUSHED_P (regno))
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++;
- }
+ 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:
@@ -9966,8 +9962,7 @@ 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]
- && !(TARGET_SINGLE_PIC_BASE && (next_hi_reg == arm_pic_register)))
+ if (THUMB_REG_PUSHED_P (next_hi_reg))
break;
while (high_regs_pushed)
@@ -9996,10 +9991,7 @@ thumb_unexpanded_epilogue ()
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)))
+ if (THUMB_REG_PUSHED_P (next_hi_reg))
break;
}
}
@@ -10166,14 +10158,12 @@ thumb_expand_prologue ()
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))
+ if (THUMB_REG_PUSHED_P (regno)
&& !(frame_pointer_needed
&& (regno == THUMB_HARD_FRAME_POINTER_REGNUM)))
break;
- if (regno > LAST_LO_REGNUM) /* Very unlikely */
+ if (regno > LAST_LO_REGNUM) /* Very unlikely. */
{
rtx spare = gen_rtx (REG, SImode, IP_REGNUM);
@@ -10323,8 +10313,7 @@ thumb_output_function_prologue (f, size)
}
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)))
+ if (THUMB_REG_PUSHED_P (regno))
live_regs_mask |= 1 << regno;
if (live_regs_mask || !leaf_function_p () || thumb_far_jump_used_p (1))
@@ -10426,8 +10415,7 @@ thumb_output_function_prologue (f, size)
for (regno = 8; regno < 13; regno++)
{
- if (regs_ever_live[regno] && !call_used_regs[regno]
- && !(TARGET_SINGLE_PIC_BASE && (regno == arm_pic_register)))
+ if (THUMB_REG_PUSHED_P (regno))
high_regs_pushed++;
}
@@ -10439,9 +10427,7 @@ 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]
- && !(TARGET_SINGLE_PIC_BASE
- && (next_hi_reg == arm_pic_register)))
+ if (THUMB_REG_PUSHED_P (next_hi_reg))
break;
}
@@ -10450,8 +10436,7 @@ thumb_output_function_prologue (f, size)
if (pushable_regs == 0)
{
/* Desperation time -- this probably will never happen. */
- if (regs_ever_live[LAST_ARG_REGNUM]
- || !call_used_regs[LAST_ARG_REGNUM])
+ 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;
}
@@ -10467,15 +10452,12 @@ thumb_output_function_prologue (f, size)
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)))
+ {
+ for (next_hi_reg--; next_hi_reg > LAST_LO_REGNUM;
+ next_hi_reg--)
+ if (THUMB_REG_PUSHED_P (next_hi_reg))
break;
- }
+ }
else
{
mask &= ~((1 << regno) - 1);
@@ -10488,8 +10470,7 @@ thumb_output_function_prologue (f, size)
}
if (pushable_regs == 0
- && (regs_ever_live[LAST_ARG_REGNUM]
- || !call_used_regs[LAST_ARG_REGNUM]))
+ && (THUMB_REG_PUSHED_P (LAST_ARG_REGNUM)))
asm_fprintf (f, "\tmov\t%r, %r\n", LAST_ARG_REGNUM, IP_REGNUM);
}
}
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index aee6484..64e7187 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -1621,7 +1621,13 @@ typedef struct
((TO) == ARM_HARD_FRAME_POINTER_REGNUM && TARGET_THUMB) ? 0 : \
((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) \
@@ -1640,13 +1646,13 @@ 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 (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 (regs_ever_live[regno] && ! call_used_regs[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); \