From 62af27e77b5b985bd496d9bc9ed35233bd612b04 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Mon, 4 May 2020 13:42:03 +0000 Subject: [PATCH] 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 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/ChangeLog | 6 ++++++ gcc/config/arm/arm.c | 28 +++++++++++++++++++++------- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 592ca9bfd31..fb7ee99fa28 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2020-05-15 Christophe Lyon + + * 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 PR middle-end/94635 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 3dab6145987..349918a9bfa 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. */ -- 2.30.2