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:
("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)
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;
}
}
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);
}
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))
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++;
}
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;
}
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;
}
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);
}
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);
}
}
((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) \
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); \