[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