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
This commit is contained in:
Adam Nemet 2002-08-08 11:08:34 +00:00 committed by Nick Clifton
parent 5bfc90dea3
commit aeaf4d25a8
3 changed files with 36 additions and 40 deletions

View File

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

View File

@ -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);
}
}

View File

@ -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); \