[PATCH, GCC/ARM, 4/10] Clear GPR with CLRM
Kyrill Tkachov
kyrylo.tkachov@foss.arm.com
Mon Jan 13 17:30:00 GMT 2020
On 12/18/19 1:26 PM, Mihail Ionescu wrote:
> Hi Kyrill,
>
> On 12/17/2019 10:26 AM, Kyrill Tkachov wrote:
>> Hi Mihail,
>>
>> On 12/16/19 6:29 PM, Mihail Ionescu wrote:
>>> Hi Kyrill,
>>>
>>> On 11/12/2019 09:55 AM, Kyrill Tkachov wrote:
>>>> Hi Mihail,
>>>>
>>>> On 10/23/19 10:26 AM, Mihail Ionescu wrote:
>>>>> [PATCH, GCC/ARM, 4/10] Clear GPR with CLRM
>>>>>
>>>>> Hi,
>>>>>
>>>>> === Context ===
>>>>>
>>>>> This patch is part of a patch series to add support for Armv8.1-M
>>>>> Mainline Security Extensions architecture. Its purpose is to improve
>>>>> code density of functions with the cmse_nonsecure_entry attribute and
>>>>> when calling function with the cmse_nonsecure_call attribute by using
>>>>> CLRM to do all the general purpose registers clearing as well as
>>>>> clearing the APSR register.
>>>>>
>>>>> === Patch description ===
>>>>>
>>>>> This patch adds a new pattern for the CLRM instruction and guards the
>>>>> current clearing code in output_return_instruction() and thumb_exit()
>>>>> on Armv8.1-M Mainline instructions not being present.
>>>>> cmse_clear_registers () is then modified to use the new CLRM
>>>>> instruction
>>>>> when targeting Armv8.1-M Mainline while keeping Armv8-M register
>>>>> clearing code for VFP registers.
>>>>>
>>>>> For the CLRM instruction, which does not mandated APSR in the
>>>>> register
>>>>> list, checking whether it is the right volatile unspec or a clearing
>>>>> register is done in clear_operation_p.
>>>>>
>>>>> Note that load/store multiple were deemed sufficiently different in
>>>>> terms of RTX structure compared to the CLRM pattern for a different
>>>>> function to be used to validate the match_parallel.
>>>>>
>>>>> ChangeLog entries are as follows:
>>>>>
>>>>> *** gcc/ChangeLog ***
>>>>>
>>>>> 2019-10-23Â Mihail-Calin Ionescu <mihail.ionescu@arm.com>
>>>>> 2019-10-23Â Thomas Preud'homme <thomas.preudhomme@arm.com>
>>>>>
>>>>> Â Â Â Â Â Â Â * config/arm/arm-protos.h (clear_operation_p): Declare.
>>>>> Â Â Â Â Â Â Â * config/arm/arm.c (clear_operation_p): New function.
>>>>> Â Â Â Â Â Â Â (cmse_clear_registers): Generate clear_multiple
>>>>> instruction pattern if
>>>>> Â Â Â Â Â Â Â targeting Armv8.1-M Mainline or successor.
>>>>> Â Â Â Â Â Â Â (output_return_instruction): Only output APSR register
>>>>> clearing if
>>>>> Â Â Â Â Â Â Â Armv8.1-M Mainline instructions not available.
>>>>> Â Â Â Â Â Â Â (thumb_exit): Likewise.
>>>>> Â Â Â Â Â Â Â * config/arm/predicates.md (clear_multiple_operation): New
>>>>> predicate.
>>>>> Â Â Â Â Â Â Â * config/arm/thumb2.md (clear_apsr): New define_insn.
>>>>> Â Â Â Â Â Â Â (clear_multiple): Likewise.
>>>>> Â Â Â Â Â Â Â * config/arm/unspecs.md (VUNSPEC_CLRM_APSR): New volatile
>>>>> unspec.
>>>>>
>>>>> *** gcc/testsuite/ChangeLog ***
>>>>>
>>>>> 2019-10-23Â Mihail-Calin Ionescu <mihail.ionescu@arm.com>
>>>>> 2019-10-23Â Thomas Preud'homme <thomas.preudhomme@arm.com>
>>>>>
>>>>> Â Â Â Â Â Â Â * gcc.target/arm/cmse/bitfield-1.c: Add check for CLRM.
>>>>> Â Â Â Â Â Â Â * gcc.target/arm/cmse/bitfield-2.c: Likewise.
>>>>> Â Â Â Â Â Â Â * gcc.target/arm/cmse/bitfield-3.c: Likewise.
>>>>> Â Â Â Â Â Â Â * gcc.target/arm/cmse/struct-1.c: Likewise.
>>>>> Â Â Â Â Â Â Â * gcc.target/arm/cmse/cmse-14.c: Likewise.
>>>>> Â Â Â Â Â Â Â * gcc.target/arm/cmse/cmse-1.c: Likewise. Restrict checks
>>>>> for Armv8-M
>>>>> Â Â Â Â Â Â Â GPR clearing when CLRM is not available.
>>>>> Â Â Â Â Â Â Â * 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/hard-sp/cmse-13.c:
>>>>> Likewise.
>>>>> Â Â Â Â Â Â Â * gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-5.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-5.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-5.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-5.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-5.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.
>>>>>
>>>>> Testing: bootstrapped on arm-linux-gnueabihf and testsuite shows no
>>>>> regression.
>>>>>
>>>>> Is this ok for trunk?
>>>>>
>>>>> Best regards,
>>>>>
>>>>> Mihail
>>>>>
>>>>>
>>>>> ###############Â Â Â Â Attachment also inlined for ease of reply
>>>>> ###############
>>>>>
>>>>>
>>>>> diff --git a/gcc/config/arm/arm-protos.h
>>>>> b/gcc/config/arm/arm-protos.h
>>>>> index
>>>>> f995974f9bb89ab3c7ff0888c394b0dfaf7da60c..1a948d2c97526ad7e67e8d4a610ac74cfdb13882
>>>>> 100644
>>>>> --- a/gcc/config/arm/arm-protos.h
>>>>> +++ b/gcc/config/arm/arm-protos.h
>>>>> @@ -77,6 +77,7 @@ extern int thumb_legitimate_offset_p
>>>>> (machine_mode, HOST_WIDE_INT);
>>>>> Â extern int thumb1_legitimate_address_p (machine_mode, rtx, int);
>>>>> Â extern bool ldm_stm_operation_p (rtx, bool, machine_mode mode,
>>>>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â bool, bool);
>>>>> +extern bool clear_operation_p (rtx);
>>>>> Â extern int arm_const_double_rtx (rtx);
>>>>> Â extern int vfp3_const_double_rtx (rtx);
>>>>> Â extern int neon_immediate_valid_for_move (rtx, machine_mode, rtx
>>>>> *, int *);
>>>>> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
>>>>> index
>>>>> d485e80096c9d2eef2172d211a0a5ab63cdbb3c7..3a373cea33c3d0b966cbe700d26f66fe069e1efb
>>>>> 100644
>>>>> --- a/gcc/config/arm/arm.c
>>>>> +++ b/gcc/config/arm/arm.c
>>>>> @@ -13499,6 +13499,66 @@ ldm_stm_operation_p (rtx op, bool load,
>>>>> machine_mode mode,
>>>>> Â Â return true;
>>>>> Â }
>>>>>
>>>>> +/* Checks whether OP is a valid parallel pattern for a CLRM insn.
>>>>> To be a
>>>>> +Â Â valid CLRM pattern, OP must have the following form:
>>>>> +
>>>>> +Â Â [(set (reg:SI <N>) (const_int 0))
>>>>> +Â Â Â (set (reg:SI <M>) (const_int 0))
>>>>> +Â Â Â ...
>>>>> +Â Â Â (unspec_volatile [(const_int 0)]
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â VUNSPEC_CLRM_APSR)
>>>>> +Â Â ]
>>>>
>>>>
>>>> If this clears the whole APSR than it also clobbers the condition
>>>> flags, right?
>>>>
>>>> Then it should also have a (clobber (reg:CC CC_REGNUM)) in there.
>>>> Yes -- it should also clobber the condition flags, thanks for catching
>>> this. I've updated the patch to include the CC clobbering.
>>>
>>> Regards,
>>> Mihail
>>>>
>>>>> +
>>>>> +Â Â Any number (including 0) of set expressions is valid, the
>>>>> volatile unspec is
>>>>> +  optional. All registers but SP and PC are allowed and
>>>>> registers must be in
>>>>> +  strict increasing order. */
>>>>> +
>>>>> +bool
>>>>> +clear_operation_p (rtx op)
>>>>> +{
>>>>> +Â HOST_WIDE_INT i;
>>>>> +Â unsigned regno, last_regno;
>>>>> +Â rtx elt, reg, zero;
>>>>> +Â machine_mode mode;
>>>>> +Â HOST_WIDE_INT count = XVECLEN (op, 0);
>>>>> +
>>>>> +Â for (i = 0; i < count; i++)
>>>>> +Â Â Â {
>>>>> +Â Â Â Â Â elt = XVECEXP (op, 0, i);
>>>>> +
>>>>> +Â Â Â Â Â if (GET_CODE (elt) == UNSPEC_VOLATILE)
>>>>> +Â Â Â Â Â Â {
>>>>> +Â Â Â Â Â Â Â Â if (XINT (elt, 1) != VUNSPEC_CLRM_APSR
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â || XVECLEN (elt, 0) != 1
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â || XVECEXP (elt, 0, 0) != CONST0_RTX (SImode)
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â || i != count - 1)
>>>>> +Â Â Â Â Â Â Â Â Â Â return false;
>>>>> +
>>>>> +Â Â Â Â Â Â Â Â continue;
>>>>> +Â Â Â Â Â Â }
>>>>> +
>>>>> +Â Â Â Â Â if (GET_CODE (elt) != SET)
>>>>> +Â Â Â Â Â Â return false;
>>>>> +
>>>>> +Â Â Â Â Â reg = SET_DEST (elt);
>>>>> +Â Â Â Â Â regno = REGNO (reg);
>>>>> +Â Â Â Â Â mode = GET_MODE (reg);
>>>>> +Â Â Â Â Â zero = SET_SRC (elt);
>>>>> +
>>>>> +Â Â Â Â Â if (!REG_P (reg)
>>>>> +Â Â Â Â Â Â Â Â || GET_MODE (reg) != SImode
>>>>> +Â Â Â Â Â Â Â Â || regno == SP_REGNUM
>>>>> +Â Â Â Â Â Â Â Â || regno == PC_REGNUM
>>>>> +Â Â Â Â Â Â Â Â || (i != 0 && regno <= last_regno)
>>>>> +Â Â Â Â Â Â Â Â || zero != CONST0_RTX (SImode))
>>>>> +Â Â Â Â Â Â return false;
>>>>> +
>>>>> +Â Â Â Â Â last_regno = REGNO (reg);
>>>>> +Â Â Â }
>>>>> +
>>>>> +Â return true;
>>>>> +}
>>>>> +
>>>>> Â /* Return true iff it would be profitable to turn a sequence of
>>>>> NOPS loads
>>>>> Â Â Â or stores (depending on IS_STORE) into a load-multiple or
>>>>> store-multiple
>>>>>    instruction. ADD_OFFSET is nonzero if the base address
>>>>> register needs
>>>>> @@ -17596,6 +17656,56 @@ cmse_clear_registers (sbitmap
>>>>> to_clear_bitmap, uint32_t *padding_bits_to_clear,
>>>>>
>>>>>   /* Clear full registers. */
>>>>>
>>>>> +Â if (TARGET_HAVE_FPCXT_CMSE)
>>>>> +Â Â Â {
>>>>> +Â Â Â Â Â rtvec vunspec_vec;
>>>>> +Â Â Â Â Â int i, j, k, nb_regs;
>>>>> +Â Â Â Â Â rtx use_seq, par, reg, set, vunspec;
>>>>> +Â Â Â Â Â int to_clear_bitmap_size = SBITMAP_SIZE (to_clear_bitmap);
>>>>> +Â Â Â Â Â auto_sbitmap core_regs_bitmap (to_clear_bitmap_size);
>>>>> +Â Â Â Â Â auto_sbitmap to_clear_core_bitmap (to_clear_bitmap_size);
>>>>> +
>>>>> +     /* Get set of core registers to clear. */
>>>>> +Â Â Â Â Â bitmap_clear (core_regs_bitmap);
>>>>> +Â Â Â Â Â bitmap_set_range (core_regs_bitmap, R0_REGNUM,
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â IP_REGNUM - R0_REGNUM + 1);
>>>>> +Â Â Â Â Â bitmap_and (to_clear_core_bitmap, to_clear_bitmap,
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â core_regs_bitmap);
>>>>> +Â Â Â Â Â gcc_assert (!bitmap_empty_p (to_clear_core_bitmap));
>>>>> +
>>>>> +Â Â Â Â Â if (bitmap_empty_p (to_clear_core_bitmap))
>>>>> +Â Â Â Â Â Â return;
>>>>> +
>>>>> +     /* Create clrm RTX pattern. */
>>>>> +Â Â Â Â Â nb_regs = bitmap_count_bits (to_clear_core_bitmap);
>>>>> +Â Â Â Â Â par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nb_regs + 1));
>>>>> +
>>>>> +Â Â Â Â Â /* Insert core register clearing RTX in the pattern. */
>>>>> +Â Â Â Â Â start_sequence ();
>>>>> +Â Â Â Â Â for (j = 0, i = minregno; j < nb_regs; i++)
>>>>> +Â Â Â Â Â Â {
>>>>> +Â Â Â Â Â Â Â Â if (!bitmap_bit_p (to_clear_core_bitmap, i))
>>>>> +Â Â Â Â Â Â Â Â Â Â continue;
>>>>> +
>>>>> +Â Â Â Â Â Â Â Â reg = gen_rtx_REG (SImode, i);
>>>>> +Â Â Â Â Â Â Â Â set = gen_rtx_SET (reg, const0_rtx);
>>>>> +Â Â Â Â Â Â Â Â XVECEXP (par, 0, j++) = set;
>>>>> +Â Â Â Â Â Â Â Â emit_use (reg);
>>>>> +Â Â Â Â Â Â }
>>>>> +
>>>>> +Â Â Â Â Â /* Insert APSR register clearing RTX in the pattern. */
>>>>> +Â Â Â Â Â vunspec_vec = gen_rtvec (1, gen_int_mode (0, SImode));
>>>>> +Â Â Â Â Â vunspec = gen_rtx_UNSPEC_VOLATILE (SImode, vunspec_vec,
>>>>> + VUNSPEC_CLRM_APSR);
>>>>> +Â Â Â Â Â XVECEXP (par, 0, j) = vunspec;
>>>>> +
>>>>> +Â Â Â Â Â use_seq = get_insns ();
>>>>> +Â Â Â Â Â end_sequence ();
>>>>> +
>>>>> +Â Â Â Â Â emit_insn_after (use_seq, emit_insn (par));
>>>>> +Â Â Â Â Â minregno = FIRST_VFP_REGNUM;
>>>>> +Â Â Â }
>>>>> +
>>>>> Â Â /* If not marked for clearing, clearing_reg already does not
>>>>> contain
>>>>>      any secret. */
>>>>> Â Â if (clearing_regno <= maxregno
>>>>> @@ -20259,40 +20369,50 @@ output_return_instruction (rtx operand,
>>>>> bool really_return, bool reverse,
>>>>> Â Â Â Â Â Â Â Â default:
>>>>> Â Â Â Â Â Â Â Â Â Â if (IS_CMSE_ENTRY (func_type))
>>>>> Â Â Â Â Â Â Â Â Â Â Â Â {
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â /* Check if we have to clear the 'GE bits' which is
>>>>> only used if
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â parallel add and subtraction instructions are
>>>>> available. */
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â if (TARGET_INT_SIMD)
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â snprintf (instr, sizeof (instr),
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "msr%s\tAPSR_nzcvqg, %%|lr", conditional);
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â else
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â snprintf (instr, sizeof (instr),
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "msr%s\tAPSR_nzcvq, %%|lr", conditional);
>>>>> -
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â output_asm_insn (instr, & operand);
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â /* Do not clear FPSCR if targeting Armv8.1-M
>>>>> Mainline, VLDR takes
>>>>> -               care of it. */
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â if (TARGET_HARD_FLOAT && ! TARGET_HAVE_FPCXT_CMSE)
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â /* For Armv8.1-M, this is cleared as part of the
>>>>> CLRM instruction
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â emitted by
>>>>> cmse_nonsecure_entry_clear_before_return () and the
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â VSTR/VLDR instructions in the prologue and
>>>>> epilogue. */
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â if (!TARGET_HAVE_FPCXT_CMSE)
>>>>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â {
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â /* Clear the cumulative exception-status bits
>>>>> (0-4,7) and the
>>>>> -                   condition code bits (28-31) of the FPSCR. We
>>>>> need to
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â remember to clear the first scratch register
>>>>> used (IP) and
>>>>> -                   save and restore the second (r4). */
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â snprintf (instr, sizeof (instr), "push\t{%%|r4}");
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â output_asm_insn (instr, & operand);
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â snprintf (instr, sizeof (instr), "vmrs\t%%|ip,
>>>>> fpscr");
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â output_asm_insn (instr, & operand);
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â snprintf (instr, sizeof (instr), "movw\t%%|r4,
>>>>> #65376");
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â output_asm_insn (instr, & operand);
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â snprintf (instr, sizeof (instr), "movt\t%%|r4,
>>>>> #4095");
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â output_asm_insn (instr, & operand);
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â snprintf (instr, sizeof (instr), "and\t%%|ip,
>>>>> %%|r4");
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â output_asm_insn (instr, & operand);
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â snprintf (instr, sizeof (instr), "vmsr\tfpscr,
>>>>> %%|ip");
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â output_asm_insn (instr, & operand);
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â snprintf (instr, sizeof (instr), "pop\t{%%|r4}");
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â output_asm_insn (instr, & operand);
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â snprintf (instr, sizeof (instr), "mov\t%%|ip,
>>>>> %%|lr");
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â /* Check if we have to clear the 'GE bits' which
>>>>> is only used if
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â parallel add and subtraction instructions are
>>>>> available. */
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â if (TARGET_INT_SIMD)
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â snprintf (instr, sizeof (instr),
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "msr%s\tAPSR_nzcvqg, %%|lr",
>>>>> conditional);
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â else
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â snprintf (instr, sizeof (instr),
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "msr%s\tAPSR_nzcvq, %%|lr",
>>>>> conditional);
>>>>> +
>>>>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â output_asm_insn (instr, & operand);
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â /* Do not clear FPSCR if targeting Armv8.1-M
>>>>> Mainline, VLDR takes
>>>>> +                   care of it. */
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â if (TARGET_HARD_FLOAT)
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â {
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â /* Clear the cumulative exception-status
>>>>> bits (0-4,7) and
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â the condition code bits (28-31) of the
>>>>> FPSCR. We need
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â to remember to clear the first scratch
>>>>> register used
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â (IP) and save and restore the second (r4).
>>>>> +
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Important note: the length of the
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â thumb2_cmse_entry_return insn pattern
>>>>> must account for
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â the size of the below instructions. */
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â snprintf (instr, sizeof (instr),
>>>>> "push\t{%%|r4}");
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â output_asm_insn (instr, & operand);
>>>>
>>>>
>>>> I know this is pre-existing in this function, but I think we should
>>>> just use output_asm_insn directly here:
>>>> output_asm_insn ("push\t{%%|r4}", & operand);
>>>>
>>>> and avoid all the snprintfs.
>>>>
>>>>
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â snprintf (instr, sizeof (instr),
>>>>> "vmrs\t%%|ip, fpscr");
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â output_asm_insn (instr, & operand);
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â snprintf (instr, sizeof (instr),
>>>>> "movw\t%%|r4, #65376");
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â output_asm_insn (instr, & operand);
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â snprintf (instr, sizeof (instr),
>>>>> "movt\t%%|r4, #4095");
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â output_asm_insn (instr, & operand);
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â snprintf (instr, sizeof (instr),
>>>>> "and\t%%|ip, %%|r4");
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â output_asm_insn (instr, & operand);
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â snprintf (instr, sizeof (instr),
>>>>> "vmsr\tfpscr, %%|ip");
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â output_asm_insn (instr, & operand);
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â snprintf (instr, sizeof (instr),
>>>>> "pop\t{%%|r4}");
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â output_asm_insn (instr, & operand);
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â snprintf (instr, sizeof (instr),
>>>>> "mov\t%%|ip, %%|lr");
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â output_asm_insn (instr, & operand);
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â }
>>>>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â }
>>>>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â snprintf (instr, sizeof (instr), "bxns\t%%|lr");
>>>>> Â Â Â Â Â Â Â Â Â Â Â Â }
>>>>> @@ -24690,8 +24810,11 @@ thumb_exit (FILE *f, int
>>>>> reg_containing_return_addr)
>>>>>
>>>>> Â Â Â Â Â Â if (IS_CMSE_ENTRY (arm_current_func_type ()))
>>>>> Â Â Â Â Â Â Â Â {
>>>>> -Â Â Â Â Â Â Â Â asm_fprintf (f, "\tmsr\tAPSR_nzcvq, %r\n",
>>>>> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â reg_containing_return_addr);
>>>>> +Â Â Â Â Â Â Â Â /* For Armv8.1-M, this is cleared as part of the CLRM
>>>>> instruction
>>>>> +Â Â Â Â Â Â Â Â Â Â Â emitted by cmse_nonsecure_entry_clear_before_return
>>>>> (). */
>>>>> +Â Â Â Â Â Â Â Â if (!TARGET_HAVE_FPCXT_CMSE)
>>>>> +Â Â Â Â Â Â Â Â Â Â asm_fprintf (f, "\tmsr\tAPSR_nzcvq, %r\n",
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â reg_containing_return_addr);
>>>>> Â Â Â Â Â Â Â Â Â Â asm_fprintf (f, "\tbxns\t%r\n",
>>>>> reg_containing_return_addr);
>>>>> Â Â Â Â Â Â Â Â }
>>>>> Â Â Â Â Â Â else
>>>>> @@ -24931,11 +25054,14 @@ thumb_exit (FILE *f, int
>>>>> reg_containing_return_addr)
>>>>>          address. It may therefore contain information that we
>>>>> might not want
>>>>>          to leak, hence it must be cleared. The value in R0 will
>>>>> never be a
>>>>> Â Â Â Â Â Â Â Â Â secret at this point, so it is safe to use it, see the
>>>>> clearing code
>>>>> -Â Â Â Â Â Â Â in 'cmse_nonsecure_entry_clear_before_return'. */
>>>>> +Â Â Â Â Â Â Â in cmse_nonsecure_entry_clear_before_return (). */
>>>>> Â Â Â Â Â Â if (reg_containing_return_addr != LR_REGNUM)
>>>>> Â Â Â Â Â Â Â Â asm_fprintf (f, "\tmov\tlr, r0\n");
>>>>>
>>>>> -Â Â Â Â Â asm_fprintf (f, "\tmsr\tAPSR_nzcvq, %r\n",
>>>>> reg_containing_return_addr);
>>>>> +Â Â Â Â Â /* For Armv8.1-M, this is cleared as part of the CLRM
>>>>> instruction emitted
>>>>> +Â Â Â Â Â Â Â by cmse_nonsecure_entry_clear_before_return (). */
>>>>> +Â Â Â Â Â if (!TARGET_HAVE_FPCXT_CMSE)
>>>>> +Â Â Â Â Â Â asm_fprintf (f, "\tmsr\tAPSR_nzcvq, %r\n",
>>>>> reg_containing_return_addr);
>>>>> Â Â Â Â Â Â asm_fprintf (f, "\tbxns\t%r\n", reg_containing_return_addr);
>>>>> Â Â Â Â }
>>>>> Â Â else
>>>>> diff --git a/gcc/config/arm/predicates.md
>>>>> b/gcc/config/arm/predicates.md
>>>>> index
>>>>> 8b36e7ee462235ad26e132f1ccf98d28c2487d67..e5c583ef3d167194e7a061d7c3e98d3b4bb5269c
>>>>> 100644
>>>>> --- a/gcc/config/arm/predicates.md
>>>>> +++ b/gcc/config/arm/predicates.md
>>>>> @@ -510,6 +510,12 @@
>>>>> Â Â Â Â Â Â Â Â Â Â Â Â (match_test "satisfies_constraint_Dy (op)")
>>>>> Â Â Â Â Â Â Â Â Â Â Â Â (match_test "satisfies_constraint_G (op)"))))
>>>>>
>>>>> +(define_special_predicate "clear_multiple_operation"
>>>>> +Â (match_code "parallel")
>>>>> +{
>>>>> + return clear_operation_p (op);
>>>>> +})
>>>>> +
>>>>> Â (define_special_predicate "load_multiple_operation"
>>>>> Â Â (match_code "parallel")
>>>>> Â {
>>>>> diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
>>>>> index
>>>>> 6ccc875e2b4e7b8ce256e52da966dfe220c6f5d6..9994c0d59f741ef47d0ec43dd53a2324b031d048
>>>>> 100644
>>>>> --- a/gcc/config/arm/thumb2.md
>>>>> +++ b/gcc/config/arm/thumb2.md
>>>>> @@ -1599,3 +1599,39 @@
>>>>> Â Â Â Â Â Â FAIL;
>>>>> Â }")
>>>>>
>>>>> +(define_insn "*clear_apsr"
>>>>> +Â [(unspec_volatile:SI [(const_int 0)] VUNSPEC_CLRM_APSR)]
>>>>> +Â "TARGET_THUMB2 && TARGET_HAVE_FPCXT_CMSE && use_cmse"
>>>>> +Â "clrm%?\\t{APSR}"
>>>>> +Â [(set_attr "predicable" "yes")]
>>>>> +)
>>>>
>>>>
>>>> Similar to earlier, if this clears the whole APSR then it should
>>>> also represent a clobber of the CC reg.
>>>>
>>>>
>>>>> +
>>>>> +;; The operands are validated through the clear_multiple_operation
>>>>> +;; match_parallel predicate rather than through constraints so
>>>>> enable it only
>>>>> +;; after reload.
>>>>> +(define_insn "*clear_multiple"
>>>>> +Â [(match_parallel 0 "clear_multiple_operation"
>>>>> +Â Â Â Â [(set (match_operand:SI 1 "register_operand" "")
>>>>> +Â Â Â Â Â Â Â Â Â (const_int 0))])]
>>>>> +Â "TARGET_THUMB2 && TARGET_HAVE_FPCXT_CMSE && use_cmse &&
>>>>> reload_completed"
>>>>> +Â {
>>>>> +Â Â Â char pattern[100];
>>>>> +Â Â Â int i, num_saves = XVECLEN (operands[0], 0);
>>>>> +
>>>>> +Â Â Â strcpy (pattern, \"clrm%?\\t{\");
>>>>> +Â Â Â for (i = 0; i < num_saves; i++)
>>>>> +Â Â Â Â Â {
>>>>> +Â Â Â Â Â Â if (GET_CODE (XVECEXP (operands[0], 0, i)) ==
>>>>> UNSPEC_VOLATILE)
>>>>> +Â Â Â Â Â Â Â Â strcat (pattern, \"APSR\");
>>>>> +Â Â Â Â Â Â else
>>>>> +Â Â Â Â Â Â Â Â strcat (pattern,
>>>>> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â reg_names[REGNO (XEXP (XVECEXP (operands[0], 0,
>>>>> i), 0))]);
>>>>> +Â Â Â Â Â Â if (i < num_saves - 1)
>>>>> +Â Â Â Â Â Â Â Â strcat (pattern, \", %|\");
>>>>> +Â Â Â Â Â }
>>>>> +Â Â Â strcat (pattern, \"}\");
>>>>> +Â Â Â output_asm_insn (pattern, operands);
>>>>> +Â Â Â return \"\";
>>>>> +Â }
>>>>> +Â [(set_attr "predicable" "yes")]
>>>>> +)
>>>>> diff --git a/gcc/config/arm/unspecs.md b/gcc/config/arm/unspecs.md
>>>>> index
>>>>> 324359be7127f04a80ebc0079ad0a9964dfd82a7..498bc0798dbaaa3ee73815ba27864ae92a2fd08e
>>>>> 100644
>>>>> --- a/gcc/config/arm/unspecs.md
>>>>> +++ b/gcc/config/arm/unspecs.md
>>>>> @@ -174,6 +174,7 @@
>>>>> Â Â VUNSPEC_MRRC2Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ; Represent the coprocessor mrrc2
>>>>> instruction.
>>>>> Â Â VUNSPEC_SPECULATION_BARRIER ; Represents an unconditional
>>>>> speculation barrier.
>>>>> Â Â VUNSPEC_VSTR_VLDRÂ Â Â ; Represent the vstr/vldr instruction.
>>>>> +Â VUNSPEC_CLRM_APSRÂ Â Â ; Represent the clearing of APSR with clrm
>>>>> instruction.
>>>>> Â ])
>>>>>
>>>>> Â ;; Enumerators for NEON unspecs.
>>>>> diff --git a/gcc/testsuite/gcc.target/arm/cmse/bitfield-1.c
>>>>> b/gcc/testsuite/gcc.target/arm/cmse/bitfield-1.c
>>>>> index
>>>>> 6d611e130b6f3b544807b767927d99b89071343b..7036cb9508c27d56c4b2c01a81c44bf6f1f9c781
>>>>> 100644
>>>>> --- a/gcc/testsuite/gcc.target/arm/cmse/bitfield-1.c
>>>>> +++ b/gcc/testsuite/gcc.target/arm/cmse/bitfield-1.c
>>>>> @@ -36,6 +36,7 @@ main (void)
>>>>> Â /* { dg-final { scan-assembler "movw\tr1, #1855" } } */
>>>>> Â /* { dg-final { scan-assembler "movt\tr1, 65535" } } */
>>>>> Â /* { dg-final { scan-assembler "ands\tr0(, r0)?, r1" } } */
>>>>> +/* { 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 "bxns" } } */
>>>>>
>>>>> diff --git a/gcc/testsuite/gcc.target/arm/cmse/bitfield-2.c
>>>>> b/gcc/testsuite/gcc.target/arm/cmse/bitfield-2.c
>>>>> index
>>>>> b7ec0a040319545b50590261278f1517bcb22796..50d4979470dd21738453e0d70c7a69ee0752ac41
>>>>> 100644
>>>>> --- a/gcc/testsuite/gcc.target/arm/cmse/bitfield-2.c
>>>>> +++ b/gcc/testsuite/gcc.target/arm/cmse/bitfield-2.c
>>>>> @@ -33,6 +33,7 @@ main (void)
>>>>> Â /* { dg-final { scan-assembler "movw\tr1, #1919" } } */
>>>>> Â /* { dg-final { scan-assembler "movt\tr1, 2047" } } */
>>>>> Â /* { dg-final { scan-assembler "ands\tr0(, r0)?, r1" } } */
>>>>> +/* { 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 "bxns" } } */
>>>>>
>>>>> diff --git a/gcc/testsuite/gcc.target/arm/cmse/bitfield-3.c
>>>>> b/gcc/testsuite/gcc.target/arm/cmse/bitfield-3.c
>>>>> index
>>>>> 7b9c3f0fe061317f71d3122dea7a55ab5311f234..2b7507c900ab18705083ba1d86359e1ae36a50a2
>>>>> 100644
>>>>> --- a/gcc/testsuite/gcc.target/arm/cmse/bitfield-3.c
>>>>> +++ b/gcc/testsuite/gcc.target/arm/cmse/bitfield-3.c
>>>>> @@ -34,5 +34,6 @@ main (void)
>>>>> Â /* { dg-final { scan-assembler "movw\tr1, #65535" } } */
>>>>> Â /* { dg-final { scan-assembler "movt\tr1, 63" } } */
>>>>> Â /* { dg-final { scan-assembler "ands\tr0(, r0)?, r1" } } */
>>>>> +/* { 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 "bxns" } } */
>>>>> diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c
>>>>> b/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c
>>>>> index
>>>>> aa0ec8e0b0f0953a5a5cbc2db58413176c2505f3..35cab1f3233daac9fba50d25dac23364c798fb9c
>>>>> 100644
>>>>> --- a/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c
>>>>> +++ b/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c
>>>>> @@ -105,8 +105,10 @@ qux (int_nsfunc_t * callback)
>>>>> Â /* { dg-final { scan-assembler "bic" } } */
>>>>> Â /* { dg-final { scan-assembler "push\t\{r4, r5, r6" } } */
>>>>> Â /* { dg-final { scan-assembler "vstr\tFPCXTNS, \\\[sp, #-4\\\]!"
>>>>> { target arm_cmse_clear_ok } } } */
>>>>> +/* { 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" } } */
>>>>> +/* { 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 } } } */
>>>>>
>>>>> Â int call_callback (void)
>>>>> Â {
>>>>> diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse-14.c
>>>>> b/gcc/testsuite/gcc.target/arm/cmse/cmse-14.c
>>>>> index
>>>>> df1ea52bec533c36a738d7d3b2b2ff749b0f3713..1f5af7c2dba7747f6058d12af8ef80b4dd1b1431
>>>>> 100644
>>>>> --- a/gcc/testsuite/gcc.target/arm/cmse/cmse-14.c
>>>>> +++ b/gcc/testsuite/gcc.target/arm/cmse/cmse-14.c
>>>>> @@ -9,5 +9,6 @@ int foo (void)
>>>>> Â Â return bar ();
>>>>> Â }
>>>>>
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, APSR\}" {
>>>>> 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"
>>>>> } } */
>>>>> 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
>>>>> 62c63b888ab49e99fba0a08b69941e73c9a8d33b..c52e1c14d9956743625e3b8a200e823f163924e3
>>>>> 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
>>>>> @@ -12,5 +12,5 @@
>>>>> Â /* { 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 "mov\tr3, r4" } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r3, APSR\}" } } */
>>>>> Â /* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" }
>>>>> } */
>>>>> 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
>>>>> b718a70522b86e2bc58900681a781129543f8869..fdba955a32fc5ad492b74974185f98470bc49a7e
>>>>> 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
>>>>> @@ -10,6 +10,5 @@
>>>>> Â /* { 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 "mov\tr2, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr3, r4" } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r2, r3, APSR\}" } } */
>>>>> Â /* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" }
>>>>> } */
>>>>> 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
>>>>> 16536ab4f9ec5782463ab90f404a2e9f6f938850..85068ceaac6a5c0c60af4a54c0af0d20326fc18d
>>>>> 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
>>>>> @@ -13,5 +13,5 @@
>>>>> Â /* { 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 "mov\tr3, r4" } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r3, APSR\}" } } */
>>>>> Â /* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" }
>>>>> } */
>>>>> 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
>>>>> 0b3cc1e2b2b26e185a9d5d4855d3bea8c70289b5..af69d38acf47d9d1d55480edba2b66f07e2d06ad
>>>>> 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
>>>>> @@ -10,6 +10,5 @@
>>>>> Â /* { 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 "mov\tr2, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr3, r4" } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r2, r3, APSR\}" } } */
>>>>> Â /* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" }
>>>>> } */
>>>>> 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
>>>>> 914ea39626f2f72eac8c9c1cb495b0855e58f5e1..62201595549f07b046c7c5972d612ab155c4c38c
>>>>> 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
>>>>> @@ -13,5 +13,5 @@
>>>>> Â /* { 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 "mov\tr3, r4" } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r3, APSR\}" } } */
>>>>> Â /* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" }
>>>>> } */
>>>>> 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
>>>>> 32435d255805331c7c56a096675b7a2af3286e5e..287f0d6faad113fbc8c30051280668baa58ab130
>>>>> 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
>>>>> @@ -7,7 +7,5 @@
>>>>> Â /* { 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 "mov\tr1, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr2, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr3, r4" } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r1, r2, r3, APSR\}" } } */
>>>>> Â /* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" }
>>>>> } */
>>>>> 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
>>>>> eb655b5504e58dc842853c8cb874c5cef3b82aa6..7b2df1faff5ea6ce6e7a58a37cd23eaf9616ee97
>>>>> 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
>>>>> @@ -8,10 +8,7 @@
>>>>> Â /* 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 "mov\tr0, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr1, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr2, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr3, r4" } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, APSR\}" }
>>>>> } */
>>>>> Â /* { dg-final { scan-assembler-not "vmov\.f32\ts0, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f32\ts1, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler-not "vmov\.f32\ts2, #1\.0" } } */
>>>>> diff --git
>>>>> a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-5.c
>>>>> b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-5.c
>>>>> index
>>>>> ab266af7092afbce868792446124c291188e8a90..638643d0a6772d43f440df3942c6c723f1eff3ef
>>>>> 100644
>>>>> ---
>>>>> a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-5.c
>>>>> +++
>>>>> b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard-sp/cmse-5.c
>>>>> @@ -6,10 +6,6 @@
>>>>> Â #include "../../../cmse-5.x"
>>>>>
>>>>> Â /* { dg-final { scan-assembler "vstr\tFPCXTNS, \\\[sp, #-4\\\]!"
>>>>> } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr0, lr" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr1, lr" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr2, lr" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr3, lr" } } */
>>>>> Â /* { dg-final { scan-assembler-not "vmov\.f32\ts0, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f32\ts1, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f32\ts2, #1\.0" } } */
>>>>> @@ -26,7 +22,6 @@
>>>>> Â /* { dg-final { scan-assembler "vmov\.f32\ts13, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f32\ts14, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f32\ts15, #1\.0" } } */
>>>>> -/* { dg-final { scan-assembler "msr\tAPSR_nzcvq, lr" { target { !
>>>>> arm_dsp } } } } */
>>>>> -/* { dg-final { scan-assembler "msr\tAPSR_nzcvqg, lr" { target
>>>>> arm_dsp } } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, ip,
>>>>> APSR\}" } } */
>>>>> Â /* { dg-final { scan-assembler "vldr\tFPCXTNS, \\\[sp\\\], #4" }
>>>>> } */
>>>>> Â /* { dg-final { scan-assembler "bxns" } } */
>>>>> 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
>>>>> fd1a24b3258e8403394dac98ff7c4712b0eb7a1b..9ec14d1a707839e4858bac72bc292fd0984bf86c
>>>>> 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
>>>>> @@ -8,10 +8,7 @@
>>>>> Â /* 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 "mov\tr0, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr1, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr2, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr3, r4" } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, APSR\}" }
>>>>> } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f32\ts0, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f32\ts1, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f32\ts2, #1\.0" } } */
>>>>> 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
>>>>> d8f9b7758d50f74f777fcda22f3f6714ff28bb96..d375879ed02483c05d7853c95f9b9e15383ff321
>>>>> 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
>>>>> @@ -8,10 +8,7 @@
>>>>> Â /* 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 "mov\tr0, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr1, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr2, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr3, r4" } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, 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 "vmov\.f32\ts2, #1\.0" } } */
>>>>> 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
>>>>> 4878c6ef9157abff003780fbf6401db8eb3ef2f3..e5cb0fabd4ce20ef8e57f25778b81a3ed3908af0
>>>>> 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
>>>>> @@ -8,10 +8,7 @@
>>>>> Â /* 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 "mov\tr0, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr1, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr2, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr3, r4" } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, APSR\}" }
>>>>> } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f32\ts1, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler-not "vmov\.f32\ts0, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler-not "vmov\.f64\td0, #1\.0" } } */
>>>>> diff --git
>>>>> a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-5.c
>>>>> b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-5.c
>>>>> index
>>>>> 82aad2d13d6b170c92fd2c2345ab76f41e383013..7e3b7609dfa5c8c1df77e413fa1bb85aa80ea9f6
>>>>> 100644
>>>>> --- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-5.c
>>>>> +++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/hard/cmse-5.c
>>>>> @@ -6,10 +6,6 @@
>>>>> Â #include "../../../cmse-5.x"
>>>>>
>>>>> Â /* { dg-final { scan-assembler "vstr\tFPCXTNS, \\\[sp, #-4\\\]!"
>>>>> } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr0, lr" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr1, lr" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr2, lr" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr3, lr" } } */
>>>>> Â /* { dg-final { scan-assembler-not "vmov\.f32\ts0, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f32\ts1, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f64\td1, #1\.0" } } */
>>>>> @@ -19,7 +15,6 @@
>>>>> Â /* { dg-final { scan-assembler "vmov\.f64\td5, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f64\td6, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f64\td7, #1\.0" } } */
>>>>> -/* { dg-final { scan-assembler "msr\tAPSR_nzcvq, lr" { target { !
>>>>> arm_dsp } } } } */
>>>>> -/* { dg-final { scan-assembler "msr\tAPSR_nzcvqg, lr" { target
>>>>> arm_dsp } } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, ip,
>>>>> APSR\}" } } */
>>>>> Â /* { dg-final { scan-assembler "vldr\tFPCXTNS, \\\[sp\\\], #4" }
>>>>> } */
>>>>> Â /* { dg-final { scan-assembler "bxns" } } */
>>>>> 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
>>>>> 8e054c2aeebac4bd3f164b00ad867bc2d72cb674..d998b43a148250a15eb4aae9fb0ef6e4bf51203b
>>>>> 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
>>>>> @@ -8,10 +8,7 @@
>>>>> Â /* 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 "mov\tr0, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr1, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr2, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr3, r4" } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, APSR\}" }
>>>>> } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f64\td0, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f64\td1, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f64\td2, #1\.0" } } */
>>>>> 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
>>>>> e74cea7697ba1c12ebeef21636d1b8fd60b42677..e416bef2cb9fabd9cb33e3c1c87057ebdd3d6daf
>>>>> 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
>>>>> @@ -8,10 +8,7 @@
>>>>> Â /* 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 "mov\tr0, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr1, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr2, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr3, r4" } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, APSR\}" }
>>>>> } */
>>>>> Â /* { dg-final { scan-assembler-not "vmov\.f64\td0, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f64\td1, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f64\td2, #1\.0" } } */
>>>>> 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
>>>>> 4c4a0c956fa574f8fa25e4222ce9274bfbc5e32d..d43a9f85a199ecdf7e018852b3af9b4cf36af81f
>>>>> 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
>>>>> @@ -8,9 +8,9 @@
>>>>> Â /* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
>>>>> Â /* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
>>>>> Â /* { dg-final { scan-assembler-not "mov\tr0, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr1, 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-not "vmov" } } */
>>>>> Â /* { dg-final { scan-assembler-not "vmsr" } } */
>>>>>
>>>>> diff --git
>>>>> a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/soft/cmse-5.c
>>>>> b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/soft/cmse-5.c
>>>>> index
>>>>> c684d79fae00feb8e15e9f142735f005473b6011..157bccb9ff3256056d496a0d0770374315b04d87
>>>>> 100644
>>>>> --- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/soft/cmse-5.c
>>>>> +++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/soft/cmse-5.c
>>>>> @@ -5,13 +5,8 @@
>>>>> Â #include "../../../cmse-5.x"
>>>>>
>>>>> Â /* { dg-final { scan-assembler "vstr\tFPCXTNS, \\\[sp, #-4\\\]!"
>>>>> } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr1, lr" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr2, lr" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr3, lr" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tip, lr" } } */
>>>>> Â /* { dg-final { scan-assembler-not "vmov" } } */
>>>>> Â /* { dg-final { scan-assembler-not "vmsr" } } */
>>>>> -/* { dg-final { scan-assembler "msr\tAPSR_nzcvq, lr" { target { !
>>>>> arm_dsp } } } } */
>>>>> -/* { dg-final { scan-assembler "msr\tAPSR_nzcvqg, lr" { target
>>>>> arm_dsp } } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r1, r2, r3, ip, APSR\}" }
>>>>> } */
>>>>> Â /* { dg-final { scan-assembler "vldr\tFPCXTNS, \\\[sp\\\], #4" }
>>>>> } */
>>>>> Â /* { dg-final { scan-assembler "bxns" } } */
>>>>> 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
>>>>> 4cb6a54a0a5b02954519e64503d7c2c4c0e4750d..02e48157a2c61b0a8bee77e949944acc2a4bee37
>>>>> 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
>>>>> @@ -7,10 +7,7 @@
>>>>> Â /* 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 "mov\tr0, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr1, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr2, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr3, r4" } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, APSR\}" }
>>>>> } */
>>>>> Â /* { dg-final { scan-assembler-not "vmov" } } */
>>>>> Â /* { dg-final { scan-assembler-not "vmsr" } } */
>>>>>
>>>>> 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
>>>>> 4764b2fadfb38661764b909cdb2c9cd109e24df0..c7a22a2ba464dce26b289635dd8dcc8213ae33d8
>>>>> 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
>>>>> @@ -9,8 +9,7 @@
>>>>> Â /* { 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 "mov\tr2, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr3, r4" } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r2, r3, APSR\}" } } */
>>>>> Â /* { dg-final { scan-assembler-not "vmov" } } */
>>>>> Â /* { dg-final { scan-assembler-not "vmsr" } } */
>>>>>
>>>>> diff --git
>>>>> a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp-sp/cmse-5.c
>>>>> b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp-sp/cmse-5.c
>>>>> index
>>>>> 9b2e7565d24ff52138b0fb90a1e6268aa4c515a0..2522a17a6316d76a21d8d241d4c44cdddf1981e0
>>>>> 100644
>>>>> ---
>>>>> a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp-sp/cmse-5.c
>>>>> +++
>>>>> b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp-sp/cmse-5.c
>>>>> @@ -8,9 +8,6 @@
>>>>> Â /* { dg-final { scan-assembler "__acle_se_foo:" } } */
>>>>> Â /* { dg-final { scan-assembler "vstr\tFPCXTNS, \\\[sp, #-4\\\]!"
>>>>> } } */
>>>>> Â /* { dg-final { scan-assembler-not "mov\tr0, lr" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr1, lr" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr2, lr" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr3, lr" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f32\ts0, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f32\ts1, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f32\ts2, #1\.0" } } */
>>>>> @@ -27,7 +24,6 @@
>>>>> Â /* { dg-final { scan-assembler "vmov\.f32\ts13, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f32\ts14, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f32\ts15, #1\.0" } } */
>>>>> -/* { dg-final { scan-assembler "msr\tAPSR_nzcvq, lr" { target { !
>>>>> arm_dsp } } } } */
>>>>> -/* { dg-final { scan-assembler "msr\tAPSR_nzcvqg, lr" { target
>>>>> arm_dsp } } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r1, r2, r3, ip, APSR\}" }
>>>>> } */
>>>>> Â /* { dg-final { scan-assembler "vldr\tFPCXTNS, \\\[sp\\\], #4" }
>>>>> } */
>>>>> Â /* { dg-final { scan-assembler "bxns" } } */
>>>>> 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
>>>>> 9e93d75c35de5e3dde1074fb99da94edc2648319..d34ca383236fdd31723966e6218ea918cf8c9122
>>>>> 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
>>>>> @@ -8,10 +8,7 @@
>>>>> Â /* 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 "mov\tr0, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr1, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr2, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr3, r4" } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, APSR\}" }
>>>>> } */
>>>>>
>>>>> Â /* Now we check that we use the correct intrinsic to call. */
>>>>> Â /* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" }
>>>>> } */
>>>>> 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
>>>>> 566889e66c8cea6ca32348f48742d2c325336995..ff8e9816cff1569bbfc1c5213c1f8ed2e49ba250
>>>>> 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
>>>>> @@ -10,8 +10,7 @@
>>>>> Â /* { 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 "mov\tr2, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr3, r4" } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r2, r3, APSR\}" } } */
>>>>>
>>>>> Â /* Now we check that we use the correct intrinsic to call. */
>>>>> Â /* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" }
>>>>> } */
>>>>> 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
>>>>> 0ee28de4123c5e09df7c5d1046e0bd555af6f0fa..ff9a7dfa5e696e3a6c4132343d0ee94c3068c208
>>>>> 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
>>>>> @@ -9,8 +9,9 @@
>>>>> Â /* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
>>>>> Â /* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
>>>>> Â /* { dg-final { scan-assembler-not "mov\tr0, r4" } } */
>>>>> -/* { dg-final { scan-assembler "\n\tmov\tr1, r4" } } */
>>>>> -/* { dg-final { scan-assembler-not "\n\tmov\tr2, r4\n\tmov\tr3,
>>>>> 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\}" } } */
>>>>>
>>>>> Â /* Now we check that we use the correct intrinsic to call. */
>>>>> Â /* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" }
>>>>> } */
>>>>> diff --git
>>>>> a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-5.c
>>>>> b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-5.c
>>>>> index
>>>>> 5af1fdb934ce5aa5afd8d096122b6e9b55591bd9..eb7561f2a2629f3c153afe3a1a5c58d8abb9d07b
>>>>> 100644
>>>>> --- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-5.c
>>>>> +++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-5.c
>>>>> @@ -7,10 +7,6 @@
>>>>>
>>>>> Â /* { dg-final { scan-assembler "__acle_se_foo:" } } */
>>>>> Â /* { dg-final { scan-assembler "vstr\tFPCXTNS, \\\[sp, #-4\\\]!"
>>>>> } } */
>>>>> -/* { dg-final { scan-assembler-not "mov\tr0, lr" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr1, lr" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr2, lr" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr3, lr" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f64\td0, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f64\td1, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f64\td2, #1\.0" } } */
>>>>> @@ -19,7 +15,6 @@
>>>>> Â /* { dg-final { scan-assembler "vmov\.f64\td5, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f64\td6, #1\.0" } } */
>>>>> Â /* { dg-final { scan-assembler "vmov\.f64\td7, #1\.0" } } */
>>>>> -/* { dg-final { scan-assembler "msr\tAPSR_nzcvq, lr" { target { !
>>>>> arm_dsp } } } } */
>>>>> -/* { dg-final { scan-assembler "msr\tAPSR_nzcvqg, lr" { target
>>>>> arm_dsp } } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r1, r2, r3, ip, APSR\}" }
>>>>> } */
>>>>> Â /* { dg-final { scan-assembler "vldr\tFPCXTNS, \\\[sp\\\], #4" }
>>>>> } */
>>>>> Â /* { dg-final { scan-assembler "bxns" } } */
>>>>> 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
>>>>> 1c38290e79d18a8f94e44b974c54220e553a9a49..03d36aa650986b6069e2fe1c1f3f98fa9664d88a
>>>>> 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
>>>>> @@ -8,10 +8,7 @@
>>>>> Â /* 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 "mov\tr0, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr1, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr2, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr3, r4" } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r0, r1, r2, r3, APSR\}" }
>>>>> } */
>>>>>
>>>>> Â /* Now we check that we use the correct intrinsic to call. */
>>>>> Â /* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" }
>>>>> } */
>>>>> 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
>>>>> 39c2e72f968ce9f30d36bd347544ca26b3dfad8a..ce45e10688f855ca7b2a63777d2b3d3418815589
>>>>> 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
>>>>> @@ -10,8 +10,7 @@
>>>>> Â /* { 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 "mov\tr2, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr3, r4" } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r2, r3, APSR\}" } } */
>>>>>
>>>>> Â /* Now we check that we use the correct intrinsic to call. */
>>>>> Â /* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" }
>>>>> } */
>>>>> 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
>>>>> d51db020c7707fa714364b10dd3ec5896a9dad17..dbd1d34413ef36f2b03716c0d9cf46b024af0835
>>>>> 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
>>>>> @@ -10,6 +10,5 @@
>>>>> Â /* { 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 "mov\tr2, r4" } } */
>>>>> -/* { dg-final { scan-assembler "mov\tr3, r4" } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r2, r3, APSR\}" } } */
>>>>> Â /* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" }
>>>>> } */
>>>>> 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
>>>>> 131afbbf4289b238438c53ab9ea55d13b8567513..3edc7f1e259779a24e722d67ed544c0a673090c7
>>>>> 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
>>>>> @@ -14,5 +14,5 @@
>>>>> Â /* { 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 "mov\tr3, r4" } } */
>>>>> +/* { dg-final { scan-assembler "clrm\t\{r3, APSR\}" } } */
>>>>> Â /* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" }
>>>>> } */
>>>>> diff --git
>>>>> a/gcc/testsuite/gcc.target/arm/cmse/mainline/8m/softfp/cmse-13.c
>>>>> b/gcc/testsuite/gcc.target/arm/cmse/mainline/8m/softfp/cmse-13.c
>>>>> index
>>>>> 0ee28de4123c5e09df7c5d1046e0bd555af6f0fa..3a72406df2492206c2cb8ac7b63e4242ec0ba598
>>>>> 100644
>>>>> --- a/gcc/testsuite/gcc.target/arm/cmse/mainline/8m/softfp/cmse-13.c
>>>>> +++ b/gcc/testsuite/gcc.target/arm/cmse/mainline/8m/softfp/cmse-13.c
>>>>> @@ -9,8 +9,9 @@
>>>>> Â /* { dg-final { scan-assembler "lsrs\tr4, r4, #1" } } */
>>>>> Â /* { dg-final { scan-assembler "lsls\tr4, r4, #1" } } */
>>>>> Â /* { dg-final { scan-assembler-not "mov\tr0, r4" } } */
>>>>> -/* { dg-final { scan-assembler "\n\tmov\tr1, r4" } } */
>>>>> -/* { dg-final { scan-assembler-not "\n\tmov\tr2, r4\n\tmov\tr3,
>>>>> r4" } } */
>>>>> +/* { dg-final { scan-assembler "mov\tr1, r4" } } */
>>>>> +/* { dg-final { scan-assembler-not "mov\tr2, r4" } } */
>>>>> +/* { dg-final { scan-assembler-not "mov\tr3, r4" } } */
>>>>>
>>>>> Â /* Now we check that we use the correct intrinsic to call. */
>>>>> Â /* { dg-final { scan-assembler "bl\t__gnu_cmse_nonsecure_call" }
>>>>> } */
>>>>> diff --git a/gcc/testsuite/gcc.target/arm/cmse/struct-1.c
>>>>> b/gcc/testsuite/gcc.target/arm/cmse/struct-1.c
>>>>> index
>>>>> 5f6891a26d9be6edbb81c6c9e71897d1b49c8c60..90fdac18e30424edca60b6f884227adbf716899d
>>>>> 100644
>>>>> --- a/gcc/testsuite/gcc.target/arm/cmse/struct-1.c
>>>>> +++ b/gcc/testsuite/gcc.target/arm/cmse/struct-1.c
>>>>> @@ -29,5 +29,6 @@ main (void)
>>>>> Â /* { dg-final { scan-assembler "movs\tr1, #255" } } */
>>>>> Â /* { dg-final { scan-assembler "movt\tr1, 65535" } } */
>>>>> Â /* { dg-final { scan-assembler "ands\tr0(, r0)?, r1" } } */
>>>>> +/* { 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 "bxns" } } */
>>>>>
>>
>> +;; The operands are validated through the clear_multiple_operation
>> +;; match_parallel predicate rather than through constraints so
>> enable it only
>> +;; after reload.
>> +(define_insn "*clear_multiple"
>> +Â [(match_parallel 0 "clear_multiple_operation"
>> +Â Â Â Â [(set (match_operand:SI 1 "register_operand" "")
>> +Â Â Â Â Â Â (const_int 0))])]
>> +Â "TARGET_THUMB2 && TARGET_HAVE_FPCXT_CMSE && use_cmse &&
>> reload_completed"
>> +Â {
>> +Â Â Â char pattern[100];
>> +Â Â Â int i, num_saves = XVECLEN (operands[0], 0);
>> +
>> +Â Â Â strcpy (pattern, \"clrm%?\\t{\");
>> +Â Â Â for (i = 0; i < num_saves; i++)
>> +Â Â Â Â Â {
>> +Â Â Â if (GET_CODE (XVECEXP (operands[0], 0, i)) == UNSPEC_VOLATILE)
>> +Â Â Â Â Â {
>> +Â Â Â Â Â Â Â strcat (pattern, \"APSR\");
>> +Â Â Â Â Â Â Â // Skip clobber
>>
>>
>> I don't think this comment is useful. If you want to keep it, convert
>> it to C-style /**/.
>>
>>
>> Otherwise ok.
>> Thanks!
>> Kyrill
>>
>>
>
> Ok, I've gotten rid of the comment.
>
This is ok.
Thanks,
Kyrill
>
> Thanks,
> Mihail
>>
>> +Â Â Â Â Â Â Â ++i;
>> +Â Â Â Â Â }
>> +Â Â Â else
>> +Â Â Â Â Â strcat (pattern,
>> +Â Â Â Â Â Â Â Â Â reg_names[REGNO (XEXP (XVECEXP (operands[0], 0, i), 0))]);
>> +Â Â Â if (i < num_saves - 1)
>> +Â Â Â Â Â strcat (pattern, \", %|\");
>> +Â Â Â Â Â }
>> +Â Â Â strcat (pattern, \"}\");
>> +Â Â Â output_asm_insn (pattern, operands);
>> +Â Â Â return \"\";
>> +Â }
>> +Â [(set_attr "predicable" "yes")]
>> +)
>>
More information about the Gcc-patches
mailing list