diff options
author | Adam Nemet <anemet@lnxw.com> | 2002-08-08 11:08:34 +0000 |
---|---|---|
committer | Nick Clifton <nickc@gcc.gnu.org> | 2002-08-08 11:08:34 +0000 |
commit | aeaf4d25a8a6a06c8dd8735e0a9b3608acc10d3f (patch) | |
tree | 93cd6302918d1181eda42bc96399b563baaea6e1 | |
parent | 5bfc90dea315f4ec135119a3526741e8fa6deb48 (diff) | |
download | gcc-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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 53 | ||||
-rw-r--r-- | gcc/config/arm/arm.h | 14 |
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); \ |