diff options
author | Richard Earnshaw <rearnsha@arm.com> | 2010-03-21 20:27:00 +0000 |
---|---|---|
committer | Richard Earnshaw <rearnsha@gcc.gnu.org> | 2010-03-21 20:27:00 +0000 |
commit | f8b68ed3c3dcd9bc49821677d8c23d4ad0f1d4f7 (patch) | |
tree | 2312aaf6703c79a8b840222145b8a7825f2990ef | |
parent | 474b97ce0ff47918ce4fb78b4ee970d4009ecf02 (diff) | |
download | gcc-f8b68ed3c3dcd9bc49821677d8c23d4ad0f1d4f7.zip gcc-f8b68ed3c3dcd9bc49821677d8c23d4ad0f1d4f7.tar.gz gcc-f8b68ed3c3dcd9bc49821677d8c23d4ad0f1d4f7.tar.bz2 |
re PR target/42321 (NEON/VFP registers from inline assembly clobber list are saved/restored incorrectly)
PR target/42321
* arm.c (arm_output_epilogue): Correctly match VFP pop instructions
with their corresponding prologue pushes.
From-SVN: r157609
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 27 |
2 files changed, 22 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d098df7..06e2ffd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2010-03-21 Richard Earnshaw <rearnsha@arm.com> + + PR target/42321 + * arm.c (arm_output_epilogue): Correctly match VFP pop instructions + with their corresponding prologue pushes. + 2010-03-20 Andrew Pinski <pinskia@gmail.com> PR target/43156 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index cc023c1..6f42dd0 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -13731,24 +13731,29 @@ arm_output_epilogue (rtx sibling) if (TARGET_HARD_FLOAT && TARGET_VFP) { - start_reg = FIRST_VFP_REGNUM; - for (reg = FIRST_VFP_REGNUM; reg < LAST_VFP_REGNUM; reg += 2) + int end_reg = LAST_VFP_REGNUM + 1; + + /* Scan the registers in reverse order. We need to match + any groupings made in the prologue and generate matching + pop operations. */ + for (reg = LAST_VFP_REGNUM - 1; reg >= FIRST_VFP_REGNUM; reg -= 2) { if ((!df_regs_ever_live_p (reg) || call_used_regs[reg]) - && (!df_regs_ever_live_p (reg + 1) || call_used_regs[reg + 1])) + && (!df_regs_ever_live_p (reg + 1) + || call_used_regs[reg + 1])) { - if (start_reg != reg) + if (end_reg > reg + 2) vfp_output_fldmd (f, SP_REGNUM, - (start_reg - FIRST_VFP_REGNUM) / 2, - (reg - start_reg) / 2); - start_reg = reg + 2; + (reg + 2 - FIRST_VFP_REGNUM) / 2, + (end_reg - (reg + 2)) / 2); + end_reg = reg; } } - if (start_reg != reg) - vfp_output_fldmd (f, SP_REGNUM, - (start_reg - FIRST_VFP_REGNUM) / 2, - (reg - start_reg) / 2); + if (end_reg > reg + 2) + vfp_output_fldmd (f, SP_REGNUM, 0, + (end_reg - (reg + 2)) / 2); } + if (TARGET_IWMMXT) for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++) if (df_regs_ever_live_p (reg) && !call_used_regs[reg]) |