[PATCH 2/2] arm: Add support for interrupt routines to reg_needs_saving_p
Christophe Lyon
christophe.lyon@linaro.org
Thu May 14 14:58:23 GMT 2020
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.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.
---
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
More information about the Gcc-patches
mailing list