+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
return addr;
}
\f
-/* 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.
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. */