On Thu, 14 Nov 2019 at 15:19, Mihail Ionescu
<mihail.ione...@foss.arm.com> 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  <mihail.ione...@arm.com>
> 2019-11-14  Sudakshina Das  <sudi....@arm.com>
>
>         * 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  <mihail.ione...@arm.com>
> 2019-11-14  Sudakshina Das  <sudi....@arm.com>
>
>         * 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\]" } } */
>

Reply via email to