On Thu, 14 Nov 2019 at 15:19, Mihail Ionescu
<[email protected]> wrote:
>
> Hi,
>
> This patch adds the new scalar shift instructions for Armv8.1-M
> Mainline to the arm backend.
> This patch is adding the following instructions:
>
> ASRL (reg)
> LSLL (reg)
>
>
> ChangeLog entry are as follow:
>
> *** gcc/ChangeLog ***
>
>
> 2019-11-14 Mihail-Calin Ionescu <[email protected]>
> 2019-11-14 Sudakshina Das <[email protected]>
>
> * config/arm/arm.h (TARGET_MVE): New macro for MVE support.
> * config/arm/arm.md (ashldi3): Generate thumb2_lsll for TARGET_MVE.
> (ashrdi3): Generate thumb2_asrl for TARGET_MVE.
> * config/arm/arm.c (arm_hard_regno_mode_ok): Allocate even odd
> register pairs for doubleword quantities for ARMv8.1M-Mainline.
> * config/arm/thumb2.md (thumb2_asrl): New.
> (thumb2_lsll): Likewise.
>
> *** gcc/testsuite/ChangeLog ***
>
> 2019-11-14 Mihail-Calin Ionescu <[email protected]>
> 2019-11-14 Sudakshina Das <[email protected]>
>
> * gcc.target/arm/armv8_1m-shift-reg_1.c: New test.
>
> Testsuite shows no regression when run for arm-none-eabi targets.
>
> Is this ok for trunk?
>
> Thanks
> Mihail
>
>
> ############### Attachment also inlined for ease of reply
> ###############
>
>
> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
> index
> be51df7d14738bc1addeab8ac5a3806778106bce..bf788087a30343269b30cf7054ec29212ad9c572
> 100644
> --- a/gcc/config/arm/arm.c
> +++ b/gcc/config/arm/arm.c
> @@ -24454,14 +24454,15 @@ arm_hard_regno_mode_ok (unsigned int regno,
> machine_mode mode)
>
> /* We allow almost any value to be stored in the general registers.
> Restrict doubleword quantities to even register pairs in ARM state
> - so that we can use ldrd. Do not allow very large Neon structure
> - opaque modes in general registers; they would use too many. */
> + so that we can use ldrd and Armv8.1-M Mainline instructions.
> + Do not allow very large Neon structure opaque modes in general
> + registers; they would use too many. */
> if (regno <= LAST_ARM_REGNUM)
> {
> if (ARM_NUM_REGS (mode) > 4)
> return false;
>
> - if (TARGET_THUMB2)
> + if (TARGET_THUMB2 && !TARGET_HAVE_MVE)
> return true;
>
> return !(TARGET_LDRD && GET_MODE_SIZE (mode) > 4 && (regno & 1) != 0);
> diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
> index
> a91a4b941c3f9d2c3d443f9f4639069ae953fb3b..b735f858a6a5c94d02a6765c1b349cdcb5e77ee3
> 100644
> --- a/gcc/config/arm/arm.md
> +++ b/gcc/config/arm/arm.md
> @@ -3503,6 +3503,22 @@
> (match_operand:SI 2 "reg_or_int_operand")))]
> "TARGET_32BIT"
> "
> + if (TARGET_HAVE_MVE)
> + {
> + if (!reg_or_int_operand (operands[2], SImode))
> + operands[2] = force_reg (SImode, operands[2]);
> +
> + /* Armv8.1-M Mainline double shifts are not expanded. */
> + if (REG_P (operands[2]))
> + {
> + if (!reg_overlap_mentioned_p(operands[0], operands[1]))
> + emit_insn (gen_movdi (operands[0], operands[1]));
> +
> + emit_insn (gen_thumb2_lsll (operands[0], operands[2]));
> + DONE;
> + }
> + }
> +
> arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
> operands[2], gen_reg_rtx (SImode),
> gen_reg_rtx (SImode));
> @@ -3530,6 +3546,16 @@
> (match_operand:SI 2 "reg_or_int_operand")))]
> "TARGET_32BIT"
> "
> + /* Armv8.1-M Mainline double shifts are not expanded. */
> + if (TARGET_HAVE_MVE && REG_P (operands[2]))
> + {
> + if (!reg_overlap_mentioned_p(operands[0], operands[1]))
> + emit_insn (gen_movdi (operands[0], operands[1]));
> +
> + emit_insn (gen_thumb2_asrl (operands[0], operands[2]));
> + DONE;
> + }
> +
> arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
> operands[2], gen_reg_rtx (SImode),
> gen_reg_rtx (SImode));
> diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
> index
> c08dab233784bd1cbaae147ece795058d2ef234f..3a716ea954ac55b2081121248b930b7f11520ffa
> 100644
> --- a/gcc/config/arm/thumb2.md
> +++ b/gcc/config/arm/thumb2.md
> @@ -1645,3 +1645,19 @@
> }
> [(set_attr "predicable" "yes")]
> )
> +
> +(define_insn "thumb2_asrl"
> + [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
> + (ashiftrt:DI (match_dup 0)
> + (match_operand:SI 1 "arm_general_register_operand"
> "r")))]
> + "TARGET_HAVE_MVE"
> + "asrl%?\\t%Q0, %R0, %1"
> + [(set_attr "predicable" "yes")])
> +
> +(define_insn "thumb2_lsll"
> + [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
> + (ashift:DI (match_dup 0)
> + (match_operand:SI 1 "arm_general_register_operand" "r")))]
> + "TARGET_HAVE_MVE"
> + "lsll%?\\t%Q0, %R0, %1"
> + [(set_attr "predicable" "yes")])
Hi,
> diff --git a/gcc/testsuite/gcc.target/arm/armv8_1m-shift-reg-1.c
> b/gcc/testsuite/gcc.target/arm/armv8_1m-shift-reg-1.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..a97e9d687ef66e9642dd1d735125c8ee941fb151
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/armv8_1m-shift-reg-1.c
> @@ -0,0 +1,20 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -march=armv8.1-m.main+mve -mfloat-abi=softfp" } */
This new test fails to compile when GCC is configured to default to
arm mode (or rather, not configured to default to thumb mode):
cc1: error: target CPU does not support ARM mode
compiler exited with status 1
FAIL: gcc.target/arm/armv8_1m-shift-reg-1.c (test for excess errors)
Excess errors:
cc1: error: target CPU does not support ARM mode
gcc.target/arm/armv8_1m-shift-reg-1.c: output file does not exist
M-profile targets need -mthumb.
Did you test with gcc configured --with-thumb only?
Thanks,
Christophe
> +
> +long long longval2;
> +int intval2;
> +
> +long long int
> +asrl_reg ()
> +{
> + return (longval2 >> intval2);
> +}
> +
> +long long unsigned int
> +lsll_reg (long long unsigned longval1, int intval1)
> +{
> + return (longval1 << intval1);
> +}
> +
> +/* { dg-final { scan-assembler "asrl\\tr\[0-9\], r\[0-9\], r\[0-9\]" } } */
> +/* { dg-final { scan-assembler "lsll\\tr\[0-9\], r\[0-9\], r\[0-9\]" } } */
>