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_emit_multi_reg_pop): Declare early.
+ (cmse_nonsecure_call_clear_caller_saved): Rename into ...
+ (cmse_nonsecure_call_inline_register_clear): This. Save and clear
+ callee-saved GPRs as well as clear ip register before doing a nonsecure
+ call then restore callee-saved GPRs after it when targeting
+ Armv8.1-M Mainline.
+ (arm_reorg): Adapt to function rename.
+
+2020-01-16 Mihail-Calin Ionescu <mihail.ionescu@arm.com>
+2020-01-16 Thomas Preud'homme <thomas.preudhomme@arm.com>
+
* config/arm/arm-protos.h (clear_operation_p): Adapt prototype.
* config/arm/arm.c (clear_operation_p): Extend to be able to check a
clear_vfp_multiple pattern based on a new vfp parameter.
static void emit_constant_insn (rtx cond, rtx pattern);
static rtx_insn *emit_set_insn (rtx, rtx);
static rtx emit_multi_reg_push (unsigned long, unsigned long);
+static void arm_emit_multi_reg_pop (unsigned long);
static int arm_arg_partial_bytes (cumulative_args_t,
const function_arg_info &);
static rtx arm_function_arg (cumulative_args_t, const function_arg_info &);
}
}
-/* Clears caller saved registers not used to pass arguments before a
- cmse_nonsecure_call. Saving, clearing and restoring of callee saved
- registers is done in __gnu_cmse_nonsecure_call libcall.
- See libgcc/config/arm/cmse_nonsecure_call.S. */
+/* Clear core and caller-saved VFP registers not used to pass arguments before
+ a cmse_nonsecure_call. Saving, clearing and restoring of VFP callee-saved
+ registers is done in the __gnu_cmse_nonsecure_call libcall. See
+ libgcc/config/arm/cmse_nonsecure_call.S. */
static void
-cmse_nonsecure_call_clear_caller_saved (void)
+cmse_nonsecure_call_inline_register_clear (void)
{
basic_block bb;
FOR_BB_INSNS (bb, insn)
{
- unsigned address_regnum, regno, maxregno =
- TARGET_HARD_FLOAT_ABI ? D7_VFP_REGNUM : NUM_ARG_REGS - 1;
+ bool clear_callee_saved = TARGET_HAVE_FPCXT_CMSE;
+ unsigned long callee_saved_mask
+ = ((1 << (LAST_HI_REGNUM + 1)) - 1)
+ & ~((1 << (LAST_ARG_REGNUM + 1)) - 1);
+ unsigned address_regnum, regno;
+ unsigned max_int_regno
+ = clear_callee_saved ? IP_REGNUM : LAST_ARG_REGNUM;
+ unsigned maxregno
+ = TARGET_HARD_FLOAT_ABI ? D7_VFP_REGNUM : max_int_regno;
auto_sbitmap to_clear_bitmap (maxregno + 1);
rtx_insn *seq;
rtx pat, call, unspec, clearing_reg, ip_reg, shift;
|| XINT (unspec, 1) != UNSPEC_NONSECURE_MEM)
continue;
- /* Determine the caller-saved registers we need to clear. */
+ /* Mark registers that needs to be cleared. Those that holds a
+ parameter are removed from the set further below. */
bitmap_clear (to_clear_bitmap);
- bitmap_set_range (to_clear_bitmap, R0_REGNUM, NUM_ARG_REGS);
+ bitmap_set_range (to_clear_bitmap, R0_REGNUM,
+ max_int_regno - R0_REGNUM + 1);
/* Only look at the caller-saved floating point registers in case of
-mfloat-abi=hard. For -mfloat-abi=softfp we will be using the
gcc_assert (MEM_P (address));
gcc_assert (REG_P (XEXP (address, 0)));
address_regnum = REGNO (XEXP (address, 0));
- if (address_regnum < R0_REGNUM + NUM_ARG_REGS)
+ if (address_regnum <= max_int_regno)
bitmap_clear_bit (to_clear_bitmap, address_regnum);
/* Set basic block of call insn so that df rescan is performed on
shift = gen_rtx_ASHIFT (SImode, clearing_reg, const1_rtx);
emit_insn (gen_rtx_SET (clearing_reg, shift));
+ if (clear_callee_saved)
+ {
+ rtx push_insn =
+ emit_multi_reg_push (callee_saved_mask, callee_saved_mask);
+ /* Disable frame debug info in push because it needs to be
+ disabled for pop (see below). */
+ RTX_FRAME_RELATED_P (push_insn) = 0;
+ }
+
/* Clear caller-saved registers that leak before doing a non-secure
call. */
ip_reg = gen_rtx_REG (SImode, IP_REGNUM);
seq = get_insns ();
end_sequence ();
emit_insn_before (seq, insn);
+
+ if (TARGET_HAVE_FPCXT_CMSE)
+ {
+ rtx_insn *next, *pop_insn, *after = insn;
+
+ start_sequence ();
+ arm_emit_multi_reg_pop (callee_saved_mask);
+ pop_insn = get_last_insn ();
+
+ /* Disable frame debug info in pop because they reset the state
+ of popped registers to what it was at the beginning of the
+ function, before the prologue. This leads to incorrect state
+ when doing the pop after the nonsecure call for registers that
+ are pushed both in prologue and before the nonsecure call.
+
+ It also occasionally triggers an assert failure in CFI note
+ creation code when there are two codepaths to the epilogue,
+ one of which does not go through the nonsecure call.
+ Obviously this mean that debugging between the push and pop is
+ not reliable. */
+ RTX_FRAME_RELATED_P (pop_insn) = 0;
+
+ end_sequence ();
+
+ emit_insn_after (pop_insn, after);
+
+ /* Skip pop we have just inserted after nonsecure call, we know
+ it does not contain a nonsecure call. */
+ insn = pop_insn;
+ }
}
}
}
Mfix * fix;
if (use_cmse)
- cmse_nonsecure_call_clear_caller_saved ();
+ cmse_nonsecure_call_inline_register_clear ();
/* We cannot run the Thumb passes for thunks because there is no CFG. */
if (cfun->is_thunk)
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 PUSH and POP and update
+ CLRM check.
+ * gcc.target/arm/cmse/cmse-14.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/bitfield-4.c: Likewise.
+ * 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/soft-sp/cmse-7.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/soft-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/softfp/union-1.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/softfp/union-2.c: Likewise.
+
+2020-01-16 Mihail-Calin Ionescu <mihail.ionescu@arm.com>
+2020-01-16 Thomas Preud'homme <thomas.preudhomme@arm.com>
+
* gcc.target/arm/cmse/bitfield-1.c: Add check for VSCCLRM.
* gcc.target/arm/cmse/bitfield-2.c: Likewise.
* gcc.target/arm/cmse/bitfield-3.c: Likewise.
/* { dg-final { scan-assembler "clrm\t\{r1, r2, r3, ip, APSR\}" { target arm_cmse_clear_ok } } } */
/* { 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 "clrm\t\{r0, r1, r2, r3, APSR\}" { 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 } } } */
+/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" { target arm_cmse_clear_ok } } } */
int call_callback (void)
{
return bar ();
}
-/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, APSR\}" { 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 } } } */
+/* { 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 "and\tr2, r2, ip" } } */
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "clrm\t\{r3, APSR\}" } } */
+/* { 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\}" } } */
+/* { 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 "and\tr1, r1, ip" } } */
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "clrm\t\{r2, r3, APSR\}" } } */
+/* { 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\}" } } */
+/* { 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 "and\tr2, r2, ip" } } */
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "clrm\t\{r3, APSR\}" } } */
+/* { 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\}" } } */
+/* { 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 "and\tr1, r1, ip" } } */
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "clrm\t\{r2, r3, APSR\}" } } */
+/* { 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\}" } } */
+/* { 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 "and\tr2, r2, ip" } } */
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "clrm\t\{r3, APSR\}" } } */
+/* { 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\}" } } */
+/* { 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 "and\tr0, r0, ip" } } */
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "clrm\t\{r1, r2, r3, APSR\}" } } */
+/* { 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\}" } } */
+/* { 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 "and\tr3, r3, ip" } } */
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
/* { dg-final { scan-assembler "lsls\tr4, r4, #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\}" } } */
+/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */
/* 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" } } */
-/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, APSR\}" } } */
+/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
+/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
/* { 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" } } */
/* { dg-final { scan-assembler "vscclrm\t\{s1, VPR\}" } } */
/* { dg-final { scan-assembler "vscclrm\t\{s4-s15, VPR\}" } } */
+/* { 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" } } */
/* 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" } } */
-/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, APSR\}" } } */
+/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
+/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
/* { dg-final { scan-assembler "vscclrm\t\{s0-s15, VPR\}" } } */
+/* { 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" } } */
/* 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" } } */
-/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, APSR\}" } } */
+/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
+/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
/* { 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-s15, VPR\}" } } */
+/* { 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" } } */
/* 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" } } */
-/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, APSR\}" } } */
+/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
+/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
/* { 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" } } */
/* { dg-final { scan-assembler-not "vmov\.f32\ts3, #1\.0" } } */
/* { dg-final { scan-assembler "vscclrm\t\{s1, VPR\}" } } */
/* { dg-final { scan-assembler "vscclrm\t\{s4-s15, VPR\}" } } */
+/* { 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" } } */
/* 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" } } */
-/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, APSR\}" } } */
+/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
+/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
/* { dg-final { scan-assembler "vscclrm\t\{s0-s15, VPR\}" } } */
+/* { 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" } } */
/* 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" } } */
-/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, APSR\}" } } */
+/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
+/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
/* { dg-final { scan-assembler-not "vmov\.f64\td0, #1\.0" } } */
/* { dg-final { scan-assembler "vscclrm\t\{s2-s15, VPR\}" } } */
+/* { 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-not "mov\tr0, r4" } } */
/* { dg-final { scan-assembler-not "mov\tr2, r4" } } */
/* { dg-final { scan-assembler-not "mov\tr3, r4" } } */
-/* { dg-final { scan-assembler "clrm\t\{r1, APSR\}" } } */
+/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
+/* { dg-final { scan-assembler "clrm\t\{r1, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* { 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" } } */
/* 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" } } */
-/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, APSR\}" } } */
+/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
+/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* { 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" } } */
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
/* { dg-final { scan-assembler-not "mov\tr0, r4" } } */
/* { dg-final { scan-assembler-not "mov\tr1, r4" } } */
-/* { dg-final { scan-assembler "clrm\t\{r2, r3, APSR\}" } } */
+/* { 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\}" } } */
+/* { 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" } } */
/* 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" } } */
-/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, APSR\}" } } */
+/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
+/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* { 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 "lsls\tr4, r4, #1" } } */
/* { dg-final { scan-assembler-not "mov\tr0, r4" } } */
/* { dg-final { scan-assembler-not "mov\tr1, r4" } } */
-/* { dg-final { scan-assembler "clrm\t\{r2, r3, APSR\}" } } */
+/* { 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\}" } } */
+/* { 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-not "mov\tr0, r4" } } */
/* { dg-final { scan-assembler-not "mov\tr2, r4" } } */
/* { dg-final { scan-assembler-not "mov\tr3, r4" } } */
-/* { dg-final { scan-assembler "clrm\t\{r1, APSR\}" } } */
+/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
+/* { dg-final { scan-assembler "clrm\t\{r1, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* { 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" } } */
/* 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" } } */
-/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, APSR\}" } } */
+/* { dg-final { scan-assembler "push\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
+/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, r5, r6, r7, r8, r9, r10, fp, ip, APSR\}" } } */
+/* { 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 "lsls\tr4, r4, #1" } } */
/* { dg-final { scan-assembler-not "mov\tr0, r4" } } */
/* { dg-final { scan-assembler-not "mov\tr1, r4" } } */
-/* { dg-final { scan-assembler "clrm\t\{r2, r3, APSR\}" } } */
+/* { 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\}" } } */
+/* { 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 "and\tr1, r1, ip" } } */
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "clrm\t\{r2, r3, APSR\}" } } */
+/* { 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\}" } } */
+/* { 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 "and\tr2, r2, ip" } } */
/* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
/* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
-/* { dg-final { scan-assembler "clrm\t\{r3, APSR\}" } } */
+/* { 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\}" } } */
+/* { dg-final { scan-assembler "pop\t\{r4, r5, r6, r7, r8, r9, r10, fp\}" } } */
/* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" } } */