arm: PR target/95646: Do not clobber callee saved registers with CMSE
As reported in bugzilla when the -mcmse option is used while compiling for size (-Os) with a thumb-1 target the generated code will clear the registers r7-r10. These however are callee saved and should be preserved accross ABI boundaries. The reason this happens is because these registers are made "fixed" when optimising for size with Thumb-1 in a way to make sure they are not used, as pushing and popping hi-registers requires extra moves to and from LO_REGS. To fix this, this patch uses 'callee_saved_reg_p', which accounts for this optimisation, instead of 'call_used_or_fixed_reg_p'. Be aware of 'callee_saved_reg_p''s definition, as it does still take call used registers into account, which aren't callee_saved in my opinion, so it is a rather misnoemer, works in our advantage here though as it does exactly what we need. Regression tested on arm-none-eabi. Is this OK for trunk? (Will eventually backport to previous versions if stable.) gcc/ChangeLog: 2020-06-19 Andre Vieira <andre.simoesdiasvieira@arm.com> PR target/95646 * config/arm/arm.c: (cmse_nonsecure_entry_clear_before_return): Use 'callee_saved_reg_p' instead of 'calL_used_or_fixed_reg_p'. gcc/testsuite/ChangeLog: 2020-06-19 Andre Vieira <andre.simoesdiasvieira@arm.com> PR target/95646 * gcc.target/arm/pr95646.c: New test.
This commit is contained in:
parent
b81d4f1e3d
commit
5f426554fd
@ -26960,7 +26960,7 @@ cmse_nonsecure_entry_clear_before_return (void)
|
||||
continue;
|
||||
if (IN_RANGE (regno, IP_REGNUM, PC_REGNUM))
|
||||
continue;
|
||||
if (call_used_or_fixed_reg_p (regno)
|
||||
if (!callee_saved_reg_p (regno)
|
||||
&& (!IN_RANGE (regno, FIRST_VFP_REGNUM, LAST_VFP_REGNUM)
|
||||
|| TARGET_HARD_FLOAT))
|
||||
bitmap_set_bit (to_clear_bitmap, regno);
|
||||
|
32
gcc/testsuite/gcc.target/arm/pr95646.c
Normal file
32
gcc/testsuite/gcc.target/arm/pr95646.c
Normal file
@ -0,0 +1,32 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv8-m.base" } } */
|
||||
/* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-mcpu=*" } { "-mcpu=cortex-m23" } } */
|
||||
/* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-mfpu=*" } { } } */
|
||||
/* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=soft" } } */
|
||||
/* { dg-options "-mcpu=cortex-m23 -mcmse" } */
|
||||
/* { dg-additional-options "-Os" } */
|
||||
/* { dg-final { check-function-bodies "**" "" } } */
|
||||
|
||||
int __attribute__ ((cmse_nonsecure_entry))
|
||||
foo (void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
/* { { dg-final { scan-assembler-not "mov\tr9, r0" } } */
|
||||
|
||||
/*
|
||||
** __acle_se_bar:
|
||||
** mov (r[0-3]), r9
|
||||
** push {\1}
|
||||
** ...
|
||||
** pop {(r[0-3])}
|
||||
** mov r9, \2
|
||||
** ...
|
||||
** bxns lr
|
||||
*/
|
||||
int __attribute__ ((cmse_nonsecure_entry))
|
||||
bar (void)
|
||||
{
|
||||
asm ("": : : "r9");
|
||||
return 1;
|
||||
}
|
Loading…
Reference in New Issue
Block a user