mirror of git://gcc.gnu.org/git/gcc.git
arm: Fix CMSE nonecure calls [PR 120977]
As discussed in https://gcc.gnu.org/pipermail/gcc-patches/2025-June/685733.html the operand of the call should be a mem rather than an unspec. This patch moves the unspec to an additional argument of the parallel and adjusts cmse_nonsecure_call_inline_register_clear accordingly. The scan-rtl-dump in cmse-18.c needs a fix since we no longer emit the 'unspec' part. In addition, I noticed that since arm_v8_1m_mve_ok is always true in the context of the test (we know we support CMSE as per cmse.exp, and arm_v8_1m_mve_ok finds the adequate options), we actually only use the more permissive regex. To improve that, the patch duplicates the test, such that cmse-18.c forces -march=armv8-m.main+fp (so FPCXP is disabled), and cmse-19.c forces -march=armv8.1-m.main+mve (so FPCXP is enabled). Each test uses the appropriate scan-rtl-dump, and also checks we are using UNSPEC_NONSECURE_MEM (we need to remove -slim for that). The tests enable an FPU via -march so that the test passes whether the testing harness forces -mfloat-abi or not. 2025-07-08 Christophe Lyon <christophe.lyon@linaro.org> PR target/120977 gcc/ * config/arm/arm.md (call): Move unspec parameter to parallel. (nonsecure_call_internal): Likewise. (call_value): Likewise. (nonsecure_call_value_internal): Likewise. * config/arm/thumb1.md (nonsecure_call_reg_thumb1_v5): Likewise. (nonsecure_call_value_reg_thumb1_v5): Likewise. * config/arm/thumb2.md (nonsecure_call_reg_thumb2_fpcxt): Likewise. (nonsecure_call_reg_thumb2): Likewise. (nonsecure_call_value_reg_thumb2_fpcxt): Likewise. (nonsecure_call_value_reg_thumb2): Likewise. * config/arm/arm.cc (cmse_nonsecure_call_inline_register_clear): Likewise. gcc/testsuite * gcc.target/arm/cmse/cmse-18.c: Check only the case when FPCXT is not enabled. * gcc.target/arm/cmse/cmse-19.c: New test.
This commit is contained in:
parent
aa1e7dd6a3
commit
ed520bfcf4
|
|
@ -18983,7 +18983,8 @@ cmse_nonsecure_call_inline_register_clear (void)
|
|||
call = SET_SRC (call);
|
||||
|
||||
/* Check if it is a cmse_nonsecure_call. */
|
||||
unspec = XEXP (call, 0);
|
||||
unspec = XVECEXP (pat, 0, 2);
|
||||
|
||||
if (GET_CODE (unspec) != UNSPEC
|
||||
|| XINT (unspec, 1) != UNSPEC_NONSECURE_MEM)
|
||||
continue;
|
||||
|
|
@ -19010,7 +19011,7 @@ cmse_nonsecure_call_inline_register_clear (void)
|
|||
|
||||
/* Make sure the register used to hold the function address is not
|
||||
cleared. */
|
||||
address = RTVEC_ELT (XVEC (unspec, 0), 0);
|
||||
address = XEXP (call, 0);
|
||||
gcc_assert (MEM_P (address));
|
||||
gcc_assert (REG_P (XEXP (address, 0)));
|
||||
address_regnum = REGNO (XEXP (address, 0));
|
||||
|
|
|
|||
|
|
@ -8623,7 +8623,7 @@
|
|||
if (detect_cmse_nonsecure_call (addr))
|
||||
{
|
||||
pat = gen_nonsecure_call_internal (operands[0], operands[1],
|
||||
operands[2]);
|
||||
operands[2], const0_rtx);
|
||||
emit_call_insn (pat);
|
||||
}
|
||||
else
|
||||
|
|
@ -8665,10 +8665,10 @@
|
|||
(clobber (reg:SI LR_REGNUM))])])
|
||||
|
||||
(define_expand "nonsecure_call_internal"
|
||||
[(parallel [(call (unspec:SI [(match_operand 0 "memory_operand")]
|
||||
UNSPEC_NONSECURE_MEM)
|
||||
[(parallel [(call (match_operand 0 "memory_operand")
|
||||
(match_operand 1 "general_operand"))
|
||||
(use (match_operand 2 "" ""))
|
||||
(unspec:SI [(match_operand 3)] UNSPEC_NONSECURE_MEM)
|
||||
(clobber (reg:SI LR_REGNUM))])]
|
||||
"use_cmse"
|
||||
{
|
||||
|
|
@ -8745,7 +8745,8 @@
|
|||
if (detect_cmse_nonsecure_call (addr))
|
||||
{
|
||||
pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
|
||||
operands[2], operands[3]);
|
||||
operands[2], operands[3],
|
||||
const0_rtx);
|
||||
emit_call_insn (pat);
|
||||
}
|
||||
else
|
||||
|
|
@ -8779,10 +8780,10 @@
|
|||
|
||||
(define_expand "nonsecure_call_value_internal"
|
||||
[(parallel [(set (match_operand 0 "" "")
|
||||
(call (unspec:SI [(match_operand 1 "memory_operand")]
|
||||
UNSPEC_NONSECURE_MEM)
|
||||
(call (match_operand 1 "memory_operand")
|
||||
(match_operand 2 "general_operand")))
|
||||
(use (match_operand 3 "" ""))
|
||||
(unspec:SI [(match_operand 4)] UNSPEC_NONSECURE_MEM)
|
||||
(clobber (reg:SI LR_REGNUM))])]
|
||||
"use_cmse"
|
||||
"
|
||||
|
|
|
|||
|
|
@ -1874,10 +1874,10 @@
|
|||
)
|
||||
|
||||
(define_insn "*nonsecure_call_reg_thumb1_v5"
|
||||
[(call (unspec:SI [(mem:SI (reg:SI R4_REGNUM))]
|
||||
UNSPEC_NONSECURE_MEM)
|
||||
[(call (mem:SI (reg:SI R4_REGNUM))
|
||||
(match_operand 0 "" ""))
|
||||
(use (match_operand 1 "" ""))
|
||||
(unspec:SI [(match_operand 2)]UNSPEC_NONSECURE_MEM)
|
||||
(clobber (reg:SI LR_REGNUM))]
|
||||
"TARGET_THUMB1 && use_cmse && !SIBLING_CALL_P (insn)"
|
||||
"bl\\t__gnu_cmse_nonsecure_call"
|
||||
|
|
@ -1919,11 +1919,10 @@
|
|||
|
||||
(define_insn "*nonsecure_call_value_reg_thumb1_v5"
|
||||
[(set (match_operand 0 "" "")
|
||||
(call (unspec:SI
|
||||
[(mem:SI (reg:SI R4_REGNUM))]
|
||||
UNSPEC_NONSECURE_MEM)
|
||||
(call (mem:SI (reg:SI R4_REGNUM))
|
||||
(match_operand 1 "" "")))
|
||||
(use (match_operand 2 "" ""))
|
||||
(unspec:SI [(match_operand 3)] UNSPEC_NONSECURE_MEM)
|
||||
(clobber (reg:SI LR_REGNUM))]
|
||||
"TARGET_THUMB1 && use_cmse"
|
||||
"bl\\t__gnu_cmse_nonsecure_call"
|
||||
|
|
|
|||
|
|
@ -537,10 +537,10 @@
|
|||
)
|
||||
|
||||
(define_insn "*nonsecure_call_reg_thumb2_fpcxt"
|
||||
[(call (unspec:SI [(mem:SI (match_operand:SI 0 "s_register_operand" "l*r"))]
|
||||
UNSPEC_NONSECURE_MEM)
|
||||
[(call (mem:SI (match_operand:SI 0 "s_register_operand" "l*r"))
|
||||
(match_operand 1 "" ""))
|
||||
(use (match_operand 2 "" ""))
|
||||
(unspec:SI [(match_operand 3)] UNSPEC_NONSECURE_MEM)
|
||||
(clobber (reg:SI LR_REGNUM))]
|
||||
"TARGET_THUMB2 && use_cmse && TARGET_HAVE_FPCXT_CMSE"
|
||||
"blxns\\t%0"
|
||||
|
|
@ -549,10 +549,10 @@
|
|||
)
|
||||
|
||||
(define_insn "*nonsecure_call_reg_thumb2"
|
||||
[(call (unspec:SI [(mem:SI (reg:SI R4_REGNUM))]
|
||||
UNSPEC_NONSECURE_MEM)
|
||||
[(call (mem:SI (reg:SI R4_REGNUM))
|
||||
(match_operand 0 "" ""))
|
||||
(use (match_operand 1 "" ""))
|
||||
(unspec:SI [(match_operand 2)] UNSPEC_NONSECURE_MEM)
|
||||
(clobber (reg:SI LR_REGNUM))]
|
||||
"TARGET_THUMB2 && use_cmse && !TARGET_HAVE_FPCXT_CMSE"
|
||||
"bl\\t__gnu_cmse_nonsecure_call"
|
||||
|
|
@ -573,11 +573,10 @@
|
|||
|
||||
(define_insn "*nonsecure_call_value_reg_thumb2_fpcxt"
|
||||
[(set (match_operand 0 "" "")
|
||||
(call
|
||||
(unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "l*r"))]
|
||||
UNSPEC_NONSECURE_MEM)
|
||||
(match_operand 2 "" "")))
|
||||
(call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
|
||||
(match_operand 2 "" "")))
|
||||
(use (match_operand 3 "" ""))
|
||||
(unspec:SI [(match_operand 4)] UNSPEC_NONSECURE_MEM)
|
||||
(clobber (reg:SI LR_REGNUM))]
|
||||
"TARGET_THUMB2 && use_cmse && TARGET_HAVE_FPCXT_CMSE"
|
||||
"blxns\\t%1"
|
||||
|
|
@ -587,10 +586,10 @@
|
|||
|
||||
(define_insn "*nonsecure_call_value_reg_thumb2"
|
||||
[(set (match_operand 0 "" "")
|
||||
(call
|
||||
(unspec:SI [(mem:SI (reg:SI R4_REGNUM))] UNSPEC_NONSECURE_MEM)
|
||||
(match_operand 1 "" "")))
|
||||
(call (mem:SI (reg:SI R4_REGNUM))
|
||||
(match_operand 1 "" "")))
|
||||
(use (match_operand 2 "" ""))
|
||||
(unspec:SI [(match_operand 3)] UNSPEC_NONSECURE_MEM)
|
||||
(clobber (reg:SI LR_REGNUM))]
|
||||
"TARGET_THUMB2 && use_cmse && !TARGET_HAVE_FPCXT_CMSE"
|
||||
"bl\\t__gnu_cmse_nonsecure_call"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mcmse -fdump-rtl-final-slim" } */
|
||||
/* Make sure FPCXT is not enabled. */
|
||||
/* { dg-options "-mcmse -fdump-rtl-final -march=armv8-m.main+fp" } */
|
||||
|
||||
typedef void (*f)(int) __attribute__((cmse_nonsecure_call));
|
||||
|
||||
|
|
@ -8,5 +9,5 @@ void bar(f func, int a)
|
|||
func(a);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-rtl-dump "call unspec\\\[\\\[r4:SI\\\]\\\]" "final" { target { ! arm_v8_1m_mve_ok } } } } */
|
||||
/* { dg-final { scan-rtl-dump "call unspec\\\[\\\[r\[0-7\]:SI\\\]\\\]" "final" { target { arm_v8_1m_mve_ok } } } } */
|
||||
/* { dg-final { scan-rtl-dump "call \\\(mem:SI \\\(reg:SI 4 r4" "final" } } */
|
||||
/* { dg-final { scan-rtl-dump "UNSPEC_NONSECURE_MEM" "final" } } */
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
/* { dg-do compile } */
|
||||
/* This is a duplicate of cmse-18.c, targetting arm_v8_1m_mve, to make sure
|
||||
FPCXT is enabled. */
|
||||
/* { dg-options "-mcmse -fdump-rtl-final -march=armv8.1-m.main+mve" } */
|
||||
|
||||
typedef void (*f)(int) __attribute__((cmse_nonsecure_call));
|
||||
|
||||
void bar(f func, int a)
|
||||
{
|
||||
func(a);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-rtl-dump "call \\\(mem:SI \\\(reg/f:SI \[0-7] r\[0-7\]" "final" } } */
|
||||
/* { dg-final { scan-rtl-dump "UNSPEC_NONSECURE_MEM" "final" } } */
|
||||
Loading…
Reference in New Issue