diff options
author | Christophe Lyon <christophe.lyon@linaro.org> | 2020-05-04 13:42:03 +0000 |
---|---|---|
committer | Christophe Lyon <christophe.lyon@linaro.org> | 2020-05-15 09:57:57 +0000 |
commit | 62af27e77b5b985bd496d9bc9ed35233bd612b04 (patch) | |
tree | 4537cc23cd106c1f31c2b57082edb2550c2f730c | |
parent | 9f0f7da9aa98eec28b4e5e34ade0aa0028df161d (diff) | |
download | gcc-62af27e77b5b985bd496d9bc9ed35233bd612b04.zip gcc-62af27e77b5b985bd496d9bc9ed35233bd612b04.tar.gz gcc-62af27e77b5b985bd496d9bc9ed35233bd612b04.tar.bz2 |
arm: Add support for interrupt routines to reg_needs_saving_p
reg_needs_saving_p is only used when dealing with non-interrupt
routines, but it makes sense to extend it to support that context too,
and make arm_compute_save_reg0_reg12_mask use it.
Save only live registers for non-leaf functions, but assume a callee
could clobber any register.
2020-05-15 Christophe Lyon <christophe.lyon@linaro.org>
gcc/
* config/arm/arm.c (reg_needs_saving_p): Add support for interrupt
routines.
(arm_compute_save_reg0_reg12_mask): Use reg_needs_saving_p.
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 28 |
2 files changed, 27 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 592ca9b..fb7ee99 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2020-05-15 Christophe Lyon <christophe.lyon@linaro.org> + + * config/arm/arm.c (reg_needs_saving_p): Add support for interrupt + routines. + (arm_compute_save_reg0_reg12_mask): Use reg_needs_saving_p. + 2020-05-15 Tobias Burnus <tobias@codesourcery.com> PR middle-end/94635 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 3dab614..349918a 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -4188,14 +4188,29 @@ arm_trampoline_adjust_address (rtx addr) return addr; } -/* Return 1 if REG needs to be saved. */ +/* Return 1 if REG needs to be saved. For interrupt handlers, this + includes call-clobbered registers too. If this is a leaf function + we can just examine the registers used by the RTL, but otherwise we + have to assume that whatever function is called might clobber + anything, and so we have to save all the call-clobbered registers + as well. */ static inline bool reg_needs_saving_p (unsigned reg) { - if (!df_regs_ever_live_p (reg) - || call_used_or_fixed_reg_p (reg)) - return false; + unsigned long func_type = arm_current_func_type (); + + if (IS_INTERRUPT (func_type)) + if (df_regs_ever_live_p (reg) + /* Save call-clobbered core registers. */ + || (! crtl->is_leaf && call_used_or_fixed_reg_p (reg) && reg < FIRST_VFP_REGNUM)) + return true; + else + return false; else - return true; + if (!df_regs_ever_live_p (reg) + || call_used_or_fixed_reg_p (reg)) + return false; + else + return true; } /* Return 1 if it is possible to return using a single instruction. @@ -20677,8 +20692,7 @@ arm_compute_save_reg0_reg12_mask (void) max_reg = 12; for (reg = 0; reg <= max_reg; reg++) - if (df_regs_ever_live_p (reg) - || (! crtl->is_leaf && call_used_or_fixed_reg_p (reg))) + if (reg_needs_saving_p (reg)) save_reg_mask |= (1 << reg); /* Also save the pic base register if necessary. */ |