aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMihail Ionescu <mihail.ionescu@arm.com>2020-01-15 11:45:53 +0000
committerMihail Ionescu <mihail.ionescu@arm.com>2020-01-16 15:12:08 +0000
commita464ffc2156a746d472fc2923d38324bdd06965e (patch)
treec3bbeae3575659bf0b00af642b2832346a5b953f /gcc
parent0ab81d9cc73303c376a0014774ab6058d40a25a0 (diff)
downloadgcc-a464ffc2156a746d472fc2923d38324bdd06965e.zip
gcc-a464ffc2156a746d472fc2923d38324bdd06965e.tar.gz
gcc-a464ffc2156a746d472fc2923d38324bdd06965e.tar.bz2
[PATCH, GCC/ARM, 9/10] Call nscall function with blxns
This change to use BLXNS to call a nonsecure function from secure directly (not using a libcall) is made in 2 steps: - change nonsecure_call patterns to use blxns instead of calling __gnu_cmse_nonsecure_call - loosen requirement for function address to allow any register when doing BLXNS. The former is a straightforward check over whether instructions added in Armv8.1-M Mainline are available while the latter consist in making the nonsecure call pattern accept any register by using match_operand and changing the nonsecure_call_internal expander to no force r4 when targeting Armv8.1-M Mainline. The tricky bit is actually in the test update, specifically how to check that register lists for CLRM have all registers except for the one holding parameters (already done) and the one holding the address used by BLXNS. This is achieved with 3 scan-assembler directives. 1) The first one lists all registers that can appear in CLRM but make each of them optional. Property guaranteed: no wrong register is cleared and none appears twice in the register list. 2) The second directive check that the CLRM is made of a fixed number of the right registers to be cleared. The number used is the number of registers that could contain a secret minus one (used to hold the address of the function to call. Property guaranteed: register list has the right number of registers Cumulated property guaranteed: only registers with a potential secret are cleared and they are all listed but ont 3) The last directive checks that we cannot find a CLRM with a register in it that also appears in BLXNS. This is check via the use of a back-reference on any of the allowed register in CLRM, the back-reference enforcing that whatever register match in CLRM must be the same in the BLXNS. Property guaranteed: register used for BLXNS is different from registers cleared in CLRM. Some more care needs to happen for the gcc.target/arm/cmse/cmse-1.c testcase due to there being two CLRM generated. To ensure the third directive match the right CLRM to the BLXNS, a negative lookahead is used between the CLRM register list and the BLXNS. The way negative lookahead work is by matching the *position* where a given regular expression does not match. In this case, since it comes after the CLRM register list it is requesting that what comes after the register list does not have a CLRM again followed by BLXNS. This guarantees that the .*blxns after only matches a blxns without another CLRM before. *** gcc/ChangeLog *** 2020-01-16 Mihail-Calin Ionescu <mihail.ionescu@arm.com> 2020-01-16 Thomas Preud'homme <thomas.preudhomme@arm.com> * config/arm/arm.md (nonsecure_call_internal): Do not force memory address in r4 when targeting Armv8.1-M Mainline. (nonsecure_call_value_internal): Likewise. * config/arm/thumb2.md (nonsecure_call_reg_thumb2): Make memory address a register match_operand again. Emit BLXNS when targeting Armv8.1-M Mainline. (nonsecure_call_value_reg_thumb2): Likewise. *** gcc/testsuite/ChangeLog *** 2020-01-16 Mihail-Calin Ionescu <mihail.ionescu@arm.com> 2020-01-16 Thomas Preud'homme <thomas.preudhomme@arm.com> * gcc.target/arm/cmse/cmse-1.c: Add check for BLXNS when instructions introduced in Armv8.1-M Mainline Security Extensions are available and restrict checks for libcall to __gnu_cmse_nonsecure_call to Armv8-M targets only. Adapt CLRM check to verify register used for BLXNS is not in the CLRM register list. * gcc.target/arm/cmse/cmse-14.c: Likewise. * gcc.target/arm/cmse/mainline/8_1m/bitfield-4.c: Likewise and adapt check for LSB clearing bit to be using the same register as BLXNS when targeting Armv8.1-M Mainline. * gcc.target/arm/cmse/mainline/8_1m/bitfield-5.c: Likewise. * gcc.target/arm/cmse/mainline/8_1m/bitfield-6.c: Likewise. * gcc.target/arm/cmse/mainline/8_1m/bitfield-7.c: Likewise. * gcc.target/arm/cmse/mainline/8_1m/bitfield-8.c: Likewise. * gcc.target/arm/cmse/mainline/8_1m/bitfield-9.c: Likewise. * gcc.target/arm/cmse/mainline/8_1m/bitfield-and-union.c: Likewise. * gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-13.c: Likewise. * gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-7.c: Likewise. * gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-8.c: Likewise. * gcc.target/arm/cmse/mainline/8_1m/hard/cmse-13.c: Likewise. * gcc.target/arm/cmse/mainline/8_1m/hard/cmse-7.c: Likewise. * gcc.target/arm/cmse/mainline/8_1m/hard/cmse-8.c: Likewise. * gcc.target/arm/cmse/mainline/8_1m/soft/cmse-13.c: Likewise. * gcc.target/arm/cmse/mainline/8_1m/soft/cmse-7.c: Likewise. * gcc.target/arm/cmse/mainline/8_1m/soft/cmse-8.c: Likewise. * gcc.target/arm/cmse/mainline/8_1m/softfp-sp/cmse-7.c: Likewise. * gcc.target/arm/cmse/mainline/8_1m/softfp-sp/cmse-8.c: Likewise. * gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-13.c: Likewise. * gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-7.c: Likewise. * gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-8.c: Likewise. * gcc.target/arm/cmse/mainline/8_1m/union-1.c: Likewise. * gcc.target/arm/cmse/mainline/8_1m/union-2.c: Likewise. * gcc.target/arm/cmse/cmse-15.c: Count BLXNS when targeting Armv8.1-M Mainline and restrict libcall count to Armv8-M.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/arm/arm.md18
-rw-r--r--gcc/config/arm/thumb2.md26
-rw-r--r--gcc/testsuite/ChangeLog37
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/cmse-1.c11
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/cmse-14.c14
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/cmse-15.c7
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-4.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-5.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-6.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-7.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-8.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-9.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-and-union.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-13.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-7.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-8.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-13.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-7.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-8.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/soft/cmse-13.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/soft/cmse-7.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/soft/cmse-8.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp-sp/cmse-7.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp-sp/cmse-8.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-13.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-7.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-8.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/union-1.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/union-2.c15
30 files changed, 357 insertions, 112 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fac36a4..123a9c3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,17 @@
2020-01-16 Mihail-Calin Ionescu <mihail.ionescu@arm.com>
2020-01-16 Thomas Preud'homme <thomas.preudhomme@arm.com>
+ * config/arm/arm.md (nonsecure_call_internal): Do not force memory
+ address in r4 when targeting Armv8.1-M Mainline.
+ (nonsecure_call_value_internal): Likewise.
+ * config/arm/thumb2.md (nonsecure_call_reg_thumb2): Make memory address
+ a register match_operand again. Emit BLXNS when targeting
+ Armv8.1-M Mainline.
+ (nonsecure_call_value_reg_thumb2): Likewise.
+
+2020-01-16 Mihail-Calin Ionescu <mihail.ionescu@arm.com>
+2020-01-16 Thomas Preud'homme <thomas.preudhomme@arm.com>
+
* config/arm/arm.c (arm_add_cfa_adjust_cfa_note): Declare early.
(cmse_nonsecure_call_inline_register_clear): Define new lazy_fpclear
variable as true when floating-point ABI is not hard. Replace
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index f89a2d4..6ec6f71 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -8387,12 +8387,15 @@
"use_cmse"
"
{
- rtx tmp;
- tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
+ if (!TARGET_HAVE_FPCXT_CMSE)
+ {
+ rtx tmp =
+ copy_to_suggested_reg (XEXP (operands[0], 0),
gen_rtx_REG (SImode, R4_REGNUM),
SImode);
- operands[0] = replace_equiv_address (operands[0], tmp);
+ operands[0] = replace_equiv_address (operands[0], tmp);
+ }
}")
(define_insn "*call_reg_armv5"
@@ -8495,12 +8498,15 @@
"use_cmse"
"
{
- rtx tmp;
- tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
+ if (!TARGET_HAVE_FPCXT_CMSE)
+ {
+ rtx tmp =
+ copy_to_suggested_reg (XEXP (operands[1], 0),
gen_rtx_REG (SImode, R4_REGNUM),
SImode);
- operands[1] = replace_equiv_address (operands[1], tmp);
+ operands[1] = replace_equiv_address (operands[1], tmp);
+ }
}")
(define_insn "*call_value_reg_armv5"
diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index 6866b4e..3ca4911 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -537,13 +537,18 @@
)
(define_insn "*nonsecure_call_reg_thumb2"
- [(call (unspec:SI [(mem:SI (reg:SI R4_REGNUM))]
+ [(call (unspec:SI [(mem:SI (match_operand:SI 0 "s_register_operand" "l*r"))]
UNSPEC_NONSECURE_MEM)
- (match_operand 0 "" ""))
- (use (match_operand 1 "" ""))
+ (match_operand 1 "" ""))
+ (use (match_operand 2 "" ""))
(clobber (reg:SI LR_REGNUM))]
"TARGET_THUMB2 && use_cmse"
- "bl\\t__gnu_cmse_nonsecure_call"
+ {
+ if (TARGET_HAVE_FPCXT_CMSE)
+ return "blxns\\t%0";
+ else
+ return "bl\\t__gnu_cmse_nonsecure_call";
+ }
[(set_attr "length" "4")
(set_attr "type" "call")]
)
@@ -562,13 +567,18 @@
(define_insn "*nonsecure_call_value_reg_thumb2"
[(set (match_operand 0 "" "")
(call
- (unspec:SI [(mem:SI (reg:SI R4_REGNUM))]
+ (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "l*r"))]
UNSPEC_NONSECURE_MEM)
- (match_operand 1 "" "")))
- (use (match_operand 2 "" ""))
+ (match_operand 2 "" "")))
+ (use (match_operand 3 "" ""))
(clobber (reg:SI LR_REGNUM))]
"TARGET_THUMB2 && use_cmse"
- "bl\t__gnu_cmse_nonsecure_call"
+ {
+ if (TARGET_HAVE_FPCXT_CMSE)
+ return "blxns\\t%1";
+ else
+ return "bl\\t__gnu_cmse_nonsecure_call";
+ }
[(set_attr "length" "4")
(set_attr "type" "call")]
)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6653b72..1cfe47d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,6 +1,43 @@
2020-01-16 Mihail-Calin Ionescu <mihail.ionescu@arm.com>
2020-01-16 Thomas Preud'homme <thomas.preudhomme@arm.com>
+ * gcc.target/arm/cmse/cmse-1.c: Add check for BLXNS when instructions
+ introduced in Armv8.1-M Mainline Security Extensions are available and
+ restrict checks for libcall to __gnu_cmse_nonsecure_call to Armv8-M
+ targets only. Adapt CLRM check to verify register used for BLXNS is
+ not in the CLRM register list.
+ * gcc.target/arm/cmse/cmse-14.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/bitfield-4.c: Likewise and adapt
+ check for LSB clearing bit to be using the same register as BLXNS when
+ targeting Armv8.1-M Mainline.
+ * gcc.target/arm/cmse/mainline/8_1m/bitfield-5.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/bitfield-6.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/bitfield-7.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/bitfield-8.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/bitfield-9.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/bitfield-and-union.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-13.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-7.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-8.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/hard/cmse-13.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/hard/cmse-7.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/hard/cmse-8.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/soft/cmse-13.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/soft/cmse-7.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/soft/cmse-8.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/softfp-sp/cmse-7.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/softfp-sp/cmse-8.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-13.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-7.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-8.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/union-1.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/union-2.c: Likewise.
+ * gcc.target/arm/cmse/cmse-15.c: Count BLXNS when targeting Armv8.1-M
+ Mainline and restrict libcall count to Armv8-M.
+
+2020-01-16 Mihail-Calin Ionescu <mihail.ionescu@arm.com>
+2020-01-16 Thomas Preud'homme <thomas.preudhomme@arm.com>
+
* gcc.target/arm/cmse/mainline/8_1m/soft/cmse-13.c: Add check for VLSTM and
VLLDM.
* gcc.target/arm/cmse/mainline/8_1m/soft/cmse-7.c: Likewise.
diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c b/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c
index 9f36fa3..ddfcfac 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c
@@ -110,7 +110,13 @@ qux (int_nsfunc_t * callback)
/* { dg-final { scan-assembler "vldr\tFPCXTNS, \\\[sp\\\], #4" { target arm_cmse_clear_ok } } } */
/* { dg-final { scan-assembler "msr\tAPSR_nzcvq" { target { ! arm_cmse_clear_ok } } } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" { target arm_cmse_clear_ok } } } */
-/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" { target arm_cmse_clear_ok } } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r0, )?(r1, )?(r2, )?(r3, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" { target arm_cmse_clear_ok } } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[0-9\]|r10|fp|ip), ){12}APSR\}" { target arm_cmse_clear_ok } } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[0-9\]|r10|fp|ip),\[^\}\]\+\}(?!.*clrm.*blxns).*blxns\t\\1" { target arm_cmse_clear_ok } } } */
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" { target arm_cmse_clear_ok } } } */
int call_callback (void)
@@ -120,4 +126,5 @@ int call_callback (void)
else
return default_callback ();
}
-/* { dg-final { scan-assembler-times "bl\\s+__gnu_cmse_nonsecure_call" 1 } } */
+/* { dg-final { scan-assembler-times "bl\\s+__gnu_cmse_nonsecure_call" 1 { target { ! arm_cmse_clear_ok } } } } */
+/* { dg-final { scan-assembler "blxns" { target arm_cmse_clear_ok } } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse-14.c b/gcc/testsuite/gcc.target/arm/cmse/cmse-14.c
index 6d39afa..5ab9785 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/cmse-14.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/cmse-14.c
@@ -10,7 +10,15 @@ int foo (void)
}
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" { target arm_cmse_clear_ok } } } */
-/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" { target arm_cmse_clear_ok } } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r0, )?(r1, )?(r2, )?(r3, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" { target arm_cmse_clear_ok } } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[0-9\]|r10|fp|ip), ){12}APSR\}" { target arm_cmse_clear_ok } } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[0-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" { target arm_cmse_clear_ok } } } */
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" { target arm_cmse_clear_ok } } } */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
-/* { dg-final { scan-assembler-not "^(.*\\s)?bl?\[^\\s]*\\s+bar" } } */
+/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" { target { ! arm_cmse_clear_ok } } } } */
+/* { dg-final { scan-assembler-not "^(.*\\s)?bl?\[^\\s]*\\s+bar" { target { ! arm_cmse_clear_ok } } } } */
+/* { dg-final { scan-assembler "blxns" { target arm_cmse_clear_ok } } } */
+/* { dg-final { scan-assembler-not "^(.*\\s)?bl?(?!xns)\[^\\s]*\\s+bar" { target arm_cmse_clear_ok } } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse-15.c b/gcc/testsuite/gcc.target/arm/cmse/cmse-15.c
index 4e9ace1..0e37b50 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/cmse-15.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/cmse-15.c
@@ -69,4 +69,9 @@ int secure5 (void)
{
return (*s_bar2) ();
}
-/* { dg-final { scan-assembler-times "bl\\s+__gnu_cmse_nonsecure_call" 6 } } */
+
+/* ARMv8-M expectation. */
+/* { dg-final { scan-assembler-times "bl\\s+__gnu_cmse_nonsecure_call" 6 { target { ! arm_cmse_clear_ok } } } } */
+
+/* ARMv8.1-M expectation. */
+/* { dg-final { scan-assembler-times "blxns" 6 { target arm_cmse_clear_ok } } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-4.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-4.c
index d4caf51..ff34edb 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-4.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-4.c
@@ -10,9 +10,16 @@
/* { dg-final { scan-assembler "and\tr1, r1, ip" } } */
/* { dg-final { scan-assembler "mov\tip, #3" } } */
/* { dg-final { scan-assembler "and\tr2, r2, ip" } } */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[3-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[3-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
-/* { dg-final { scan-assembler "clrm\t\{r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r3, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[3-9\]|r10|fp|ip), ){9}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[3-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-5.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-5.c
index 2b7655a..4d1407a 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-5.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-5.c
@@ -8,9 +8,16 @@
/* { dg-final { scan-assembler "and\tr0, r0, ip" } } */
/* { dg-final { scan-assembler "movw\tip, #2047" } } */
/* { dg-final { scan-assembler "and\tr1, r1, ip" } } */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[2-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[2-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
-/* { dg-final { scan-assembler "clrm\t\{r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r2, )?(r3, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[2-9\]|r10|fp|ip), ){10}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[2-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-6.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-6.c
index 1a62076..9b1227a 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-6.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-6.c
@@ -11,9 +11,16 @@
/* { dg-final { scan-assembler "and\tr1, r1, ip" } } */
/* { dg-final { scan-assembler "mov\tip, #255" } } */
/* { dg-final { scan-assembler "and\tr2, r2, ip" } } */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[3-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[3-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
-/* { dg-final { scan-assembler "clrm\t\{r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r3, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[3-9\]|r10|fp|ip), ){9}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[3-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-7.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-7.c
index 1319ac9..aec958f 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-7.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-7.c
@@ -8,9 +8,16 @@
/* { dg-final { scan-assembler "and\tr0, r0, ip" } } */
/* { dg-final { scan-assembler "movw\tip, #2047" } } */
/* { dg-final { scan-assembler "and\tr1, r1, ip" } } */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[2-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[2-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
-/* { dg-final { scan-assembler "clrm\t\{r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r2, )?(r3, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[2-9\]|r10|fp|ip), ){10}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[2-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-8.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-8.c
index 9bb6017..ae039e2 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-8.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-8.c
@@ -11,9 +11,16 @@
/* { dg-final { scan-assembler "movw\tip, #65535" } } */
/* { dg-final { scan-assembler "movt\tip, 31" } } */
/* { dg-final { scan-assembler "and\tr2, r2, ip" } } */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[3-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[3-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
-/* { dg-final { scan-assembler "clrm\t\{r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r3, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[3-9\]|r10|fp|ip), ){9}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[3-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-9.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-9.c
index 11ca78b..f455f8c 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-9.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-9.c
@@ -5,9 +5,16 @@
/* { dg-final { scan-assembler "movw\tip, #1799" } } */
/* { dg-final { scan-assembler "and\tr0, r0, ip" } } */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[1-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[1-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
-/* { dg-final { scan-assembler "clrm\t\{r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r1, )?(r2, )?(r3, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[1-9\]|r10|fp|ip), ){11}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[1-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-and-union.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-and-union.c
index 2f14c52..3e76364 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-and-union.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/bitfield-and-union.c
@@ -15,9 +15,16 @@
/* { dg-final { scan-assembler "movw\tip, #65535" } } */
/* { dg-final { scan-assembler "movt\tip, 31" } } */
/* { dg-final { scan-assembler "and\tr3, r3, ip" } } */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[4-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[4-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
-/* { dg-final { scan-assembler "clrm\t\{r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[4-9\]|r10|fp|ip), ){8}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[4-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-13.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-13.c
index e759db2..0c49277 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-13.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-13.c
@@ -6,11 +6,18 @@
#include "../../../cmse-13.x"
/* Checks for saving and clearing prior to function call. */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[0-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[0-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* { dg-final { scan-assembler "vpush.64\t\{d8, d9, d10, d11, d12, d13, d14, d15\}" } } */
-/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r0, )?(r1, )?(r2, )?(r3, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[0-9\]|r10|fp|ip), ){12}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[0-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler-not "vmov\.f32\ts0, #1\.0" } } */
/* { dg-final { scan-assembler-not "vmov\.f32\ts2, #1\.0" } } */
/* { dg-final { scan-assembler-not "vmov\.f32\ts3, #1\.0" } } */
@@ -20,4 +27,4 @@
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* Now we check that we use the correct intrinsic to call. */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-7.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-7.c
index 9df7b5d..3c66b0a 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-7.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-7.c
@@ -6,14 +6,21 @@
#include "../../../cmse-7.x"
/* Checks for saving and clearing prior to function call. */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[0-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[0-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* { dg-final { scan-assembler "vpush.64\t\{d8, d9, d10, d11, d12, d13, d14, d15\}" } } */
-/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r0, )?(r1, )?(r2, )?(r3, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[0-9\]|r10|fp|ip), ){12}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[0-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "vscclrm\t\{s0-s31, VPR\}" } } */
/* { dg-final { scan-assembler "vldm\tsp!, \{d8-d15\}" } } */
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* Now we check that we use the correct intrinsic to call. */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-8.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-8.c
index b36ff73..7d456c3 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-8.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-8.c
@@ -6,11 +6,18 @@
#include "../../../cmse-8.x"
/* Checks for saving and clearing prior to function call. */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[0-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[0-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* { dg-final { scan-assembler "vpush.64\t\{d8, d9, d10, d11, d12, d13, d14, d15\}" } } */
-/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r0, )?(r1, )?(r2, )?(r3, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[0-9\]|r10|fp|ip), ){12}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[0-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler-not "vmov\.f32\ts0, #1\.0" } } */
/* { dg-final { scan-assembler-not "vmov\.f32\ts1, #1\.0" } } */
/* { dg-final { scan-assembler "vscclrm\t\{s2-s31, VPR\}" } } */
@@ -18,4 +25,4 @@
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* Now we check that we use the correct intrinsic to call. */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-13.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-13.c
index 72493f0..ab95c83 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-13.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-13.c
@@ -6,11 +6,18 @@
#include "../../../cmse-13.x"
/* Checks for saving and clearing prior to function call. */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[0-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[0-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* { dg-final { scan-assembler "vpush.64\t\{d8, d9, d10, d11, d12, d13, d14, d15\}" } } */
-/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r0, )?(r1, )?(r2, )?(r3, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[0-9\]|r10|fp|ip), ){12}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[0-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler-not "vmov\.f32\ts0, #1\.0" } } */
/* { dg-final { scan-assembler-not "vmov\.f64\td0, #1\.0" } } */
/* { dg-final { scan-assembler-not "vmov\.f64\td1, #1\.0" } } */
@@ -22,4 +29,4 @@
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* Now we check that we use the correct intrinsic to call. */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-7.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-7.c
index 112ed78..cf58d54 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-7.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-7.c
@@ -6,14 +6,21 @@
#include "../../../cmse-7.x"
/* Checks for saving and clearing prior to function call. */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[0-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[0-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* { dg-final { scan-assembler "vpush.64\t\{d8, d9, d10, d11, d12, d13, d14, d15\}" } } */
-/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r0, )?(r1, )?(r2, )?(r3, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[0-9\]|r10|fp|ip), ){12}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[0-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "vscclrm\t\{s0-s31, VPR\}" } } */
/* { dg-final { scan-assembler "vldm\tsp!, \{d8-d15\}" } } */
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* Now we check that we use the correct intrinsic to call. */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-8.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-8.c
index f48e8a0..1854d03 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-8.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-8.c
@@ -6,15 +6,22 @@
#include "../../../cmse-8.x"
/* Checks for saving and clearing prior to function call. */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[0-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[0-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* { dg-final { scan-assembler "vpush.64\t\{d8, d9, d10, d11, d12, d13, d14, d15\}" } } */
-/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r0, )?(r1, )?(r2, )?(r3, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[0-9\]|r10|fp|ip), ){12}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[0-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler-not "vmov\.f64\td0, #1\.0" } } */
/* { dg-final { scan-assembler "vscclrm\t\{s2-s31, VPR\}" } } */
/* { dg-final { scan-assembler "vldm\tsp!, \{d8-d15\}" } } */
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* Now we check that we use the correct intrinsic to call. */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/soft/cmse-13.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/soft/cmse-13.c
index 52d2242..1b207c3 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/soft/cmse-13.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/soft/cmse-13.c
@@ -5,18 +5,25 @@
#include "../../../cmse-13.x"
/* Checks for saving and clearing prior to function call. */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[1,4-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[1,4-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler-not "mov\tr0, r4" } } */
/* { dg-final { scan-assembler-not "mov\tr2, r4" } } */
/* { dg-final { scan-assembler-not "mov\tr3, r4" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* { dg-final { scan-assembler "vlstm\tsp" } } */
-/* { dg-final { scan-assembler "clrm\t\{r1, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r1, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[1,4-9\]|r10|fp|ip), ){9}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[1,4-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "vlldm\tsp" } } */
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* { dg-final { scan-assembler-not "vmov" } } */
/* { dg-final { scan-assembler-not "vmsr" } } */
/* Now we check that we use the correct intrinsic to call. */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/soft/cmse-7.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/soft/cmse-7.c
index 40026d5..3ec6394 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/soft/cmse-7.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/soft/cmse-7.c
@@ -5,15 +5,22 @@
#include "../../../cmse-7.x"
/* Checks for saving and clearing prior to function call. */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[0-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[0-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* { dg-final { scan-assembler "vlstm\tsp" } } */
-/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r0, )?(r1, )?(r2, )?(r3, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[0-9\]|r10|fp|ip), ){12}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[0-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "vlldm\tsp" } } */
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* { dg-final { scan-assembler-not "vmov" } } */
/* { dg-final { scan-assembler-not "vmsr" } } */
/* Now we check that we use the correct intrinsic to call. */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/soft/cmse-8.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/soft/cmse-8.c
index 6edc1f6..5c1d245 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/soft/cmse-8.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/soft/cmse-8.c
@@ -5,17 +5,24 @@
#include "../../../cmse-8.x"
/* Checks for saving and clearing prior to function call. */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[2-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[2-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler-not "mov\tr0, r4" } } */
/* { dg-final { scan-assembler-not "mov\tr1, r4" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* { dg-final { scan-assembler "vlstm\tsp" } } */
-/* { dg-final { scan-assembler "clrm\t\{r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r2, )?(r3, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[2-9\]|r10|fp|ip), ){10}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[2-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "vlldm\tsp" } } */
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* { dg-final { scan-assembler-not "vmov" } } */
/* { dg-final { scan-assembler-not "vmsr" } } */
/* Now we check that we use the correct intrinsic to call. */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp-sp/cmse-7.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp-sp/cmse-7.c
index 8d05576..3228692 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp-sp/cmse-7.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp-sp/cmse-7.c
@@ -6,13 +6,20 @@
#include "../../../cmse-7.x"
/* Checks for saving and clearing prior to function call. */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[0-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[0-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* { dg-final { scan-assembler "vlstm\tsp" } } */
-/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r0, )?(r1, )?(r2, )?(r3, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[0-9\]|r10|fp|ip), ){12}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[0-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "vlldm\tsp" } } */
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* Now we check that we use the correct intrinsic to call. */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp-sp/cmse-8.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp-sp/cmse-8.c
index 1f0a147..1c60d97 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp-sp/cmse-8.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp-sp/cmse-8.c
@@ -6,15 +6,22 @@
#include "../../../cmse-8.x"
/* Checks for saving and clearing prior to function call. */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[2-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[2-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler-not "mov\tr0, r4" } } */
/* { dg-final { scan-assembler-not "mov\tr1, r4" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* { dg-final { scan-assembler "vlstm\tsp" } } */
-/* { dg-final { scan-assembler "clrm\t\{r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r2, )?(r3, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[2-9\]|r10|fp|ip), ){10}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[2-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "vlldm\tsp" } } */
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* Now we check that we use the correct intrinsic to call. */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-13.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-13.c
index 8427941..c366f6a 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-13.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-13.c
@@ -6,16 +6,23 @@
#include "../../../cmse-13.x"
/* Checks for saving and clearing prior to function call. */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[1,4-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[1,4-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler-not "mov\tr0, r4" } } */
/* { dg-final { scan-assembler-not "mov\tr2, r4" } } */
/* { dg-final { scan-assembler-not "mov\tr3, r4" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* { dg-final { scan-assembler "vlstm\tsp" } } */
-/* { dg-final { scan-assembler "clrm\t\{r1, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r1, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[1,4-9\]|r10|fp|ip), ){9}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[1,4-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "vlldm\tsp" } } */
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* Now we check that we use the correct intrinsic to call. */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-7.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-7.c
index 38c9d54..186a448 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-7.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-7.c
@@ -6,13 +6,20 @@
#include "../../../cmse-7.x"
/* Checks for saving and clearing prior to function call. */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[0-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[0-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* { dg-final { scan-assembler "vlstm\tsp" } } */
-/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r0, )?(r1, )?(r2, )?(r3, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[0-9\]|r10|fp|ip), ){12}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[0-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "vlldm\tsp" } } */
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* Now we check that we use the correct intrinsic to call. */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-8.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-8.c
index 6a17bd3..f0f74f0 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-8.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-8.c
@@ -6,15 +6,22 @@
#include "../../../cmse-8.x"
/* Checks for saving and clearing prior to function call. */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[2-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[2-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler-not "mov\tr0, r4" } } */
/* { dg-final { scan-assembler-not "mov\tr1, r4" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* { dg-final { scan-assembler "vlstm\tsp" } } */
-/* { dg-final { scan-assembler "clrm\t\{r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r2, )?(r3, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[2-9\]|r10|fp|ip), ){10}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[2-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "vlldm\tsp" } } */
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* Now we check that we use the correct intrinsic to call. */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/union-1.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/union-1.c
index 43e58eb..4d58eed 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/union-1.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/union-1.c
@@ -8,9 +8,16 @@
/* { dg-final { scan-assembler "and\tr0, r0, ip" } } */
/* { dg-final { scan-assembler "movw\tip, #511" } } */
/* { dg-final { scan-assembler "and\tr1, r1, ip" } } */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[2-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[2-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
-/* { dg-final { scan-assembler "clrm\t\{r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r2, )?(r3, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[2-9\]|r10|fp|ip), ){10}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[2-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/union-2.c b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/union-2.c
index 6adf8fa..95de458 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/union-2.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/union-2.c
@@ -12,9 +12,16 @@
/* { dg-final { scan-assembler "movw\tip, #65535" } } */
/* { dg-final { scan-assembler "movt\tip, 31" } } */
/* { dg-final { scan-assembler "and\tr2, r2, ip" } } */
-/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
+/* Shift on the same register as blxns. */
+/* { dg-final { scan-assembler "lsrs\t(r\[3-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
+/* { dg-final { scan-assembler "lsls\t(r\[3-9\]|r10|fp|ip), \\1, #1.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
-/* { dg-final { scan-assembler "clrm\t\{r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* Check the right registers are cleared and none appears twice. */
+/* { dg-final { scan-assembler "clrm\t\{(r3, )?(r4, )?(r5, )?(r6, )?(r7, )?(r8, )?(r9, )?(r10, )?(fp, )?(ip, )?APSR\}" } } */
+/* Check that the right number of registers is cleared and thus only one
+ register is missing. */
+/* { dg-final { scan-assembler "clrm\t\{((r\[3-9\]|r10|fp|ip), ){9}APSR\}" } } */
+/* Check that no cleared register is used for blxns. */
+/* { dg-final { scan-assembler-not "clrm\t\{\[^\}\]\+(r\[3-9\]|r10|fp|ip),\[^\}\]\+\}.*blxns\t\\1" } } */
/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
-/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
+/* { dg-final { scan-assembler "blxns" } } */