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-14 Christophe Lyon <christophe.l...@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. --- gcc/config/arm/arm.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 694c1bb..0107f50 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -4188,16 +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 bool reg_needs_saving_p (unsigned reg) { unsigned long func_type = arm_current_func_type (); - if (!df_regs_ever_live_p (reg) - || call_used_or_fixed_reg_p (reg)) - return false; + 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. @@ -20685,8 +20698,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. */ -- 2.7.4