aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Lyon <christophe.lyon@linaro.org>2020-05-04 13:42:03 +0000
committerChristophe Lyon <christophe.lyon@linaro.org>2020-05-15 09:57:57 +0000
commit62af27e77b5b985bd496d9bc9ed35233bd612b04 (patch)
tree4537cc23cd106c1f31c2b57082edb2550c2f730c
parent9f0f7da9aa98eec28b4e5e34ade0aa0028df161d (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/config/arm/arm.c28
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. */