[GCC/ARM, 2/2] Add support for ASRL(imm), LSLL(imm) and LSRL(imm) instructions for...
authorMihail Ionescu <mihail.ionescu@arm.com>
Fri, 17 Jan 2020 18:14:54 +0000 (18:14 +0000)
committerMihail Ionescu <mihail.ionescu@arm.com>
Fri, 17 Jan 2020 18:50:38 +0000 (18:50 +0000)
This patch is adding the following instructions:

ASRL (imm)
LSLL (imm)
LSRL (imm)

*** gcc/ChangeLog ***

2020-01-17  Mihail-Calin Ionescu  <mihail.ionescu@arm.com>
    Sudakshina Das  <sudi.das@arm.com>

* config/arm/arm.md (ashldi3): Generate thumb2_lsll for both reg
and valid immediate.
(ashrdi3): Generate thumb2_asrl for both reg and valid immediate.
(lshrdi3): Generate thumb2_lsrl for valid immediates.
* config/arm/constraints.md (Pg): New.
* config/arm/predicates.md (long_shift_imm): New.
(arm_reg_or_long_shift_imm): Likewise.
* config/arm/thumb2.md (thumb2_asrl): New immediate alternative.
(thumb2_lsll): Likewise.
(thumb2_lsrl): New.

*** gcc/testsuite/ChangeLog ***

2020-01-17  Mihail-Calin Ionescu  <mihail.ionescu@arm.com>
    Sudakshina Das  <sudi.das@arm.com>

* gcc.target/arm/armv8_1m-shift-imm_1.c: New test.

gcc/ChangeLog
gcc/config/arm/arm.md
gcc/config/arm/constraints.md
gcc/config/arm/predicates.md
gcc/config/arm/thumb2.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/armv8_1m-shift-imm-1.c [new file with mode: 0644]

index 2dadf5891e7d8ec1944477a103de7d7158bd4dbe..7986c68e53353a0f4a76a8b7220f8a0ec274d8f0 100644 (file)
@@ -1,3 +1,17 @@
+2020-01-17  Mihail-Calin Ionescu <mihail.ionescu@arm.com>
+           Sudakshina Das  <sudi.das@arm.com>
+
+       * config/arm/arm.md (ashldi3): Generate thumb2_lsll for both reg
+       and valid immediate.
+       (ashrdi3): Generate thumb2_asrl for both reg and valid immediate.
+       (lshrdi3): Generate thumb2_lsrl for valid immediates.
+       * config/arm/constraints.md (Pg): New.
+       * config/arm/predicates.md (long_shift_imm): New.
+       (arm_reg_or_long_shift_imm): Likewise.
+       * config/arm/thumb2.md (thumb2_asrl): New immediate alternative.
+       (thumb2_lsll): Likewise.
+       (thumb2_lsrl): New.
+
 2020-01-17  Mihail-Calin Ionescu  <mihail.ionescu@arm.com>
            Sudakshina Das  <sudi.das@arm.com>
 
index 315b04c4434c0a0d7dd572e432c213bc005782a3..0454908256727247b4d0a4f402ad234bdbf1907c 100644 (file)
         operands[2] = force_reg (SImode, operands[2]);
 
       /* Armv8.1-M Mainline double shifts are not expanded.  */
-      if (REG_P (operands[2]))
-       {
+      if (arm_reg_or_long_shift_imm (operands[2], GET_MODE (operands[2])))
+        {
          if (!reg_overlap_mentioned_p(operands[0], operands[1]))
            emit_insn (gen_movdi (operands[0], operands[1]));
 
   "TARGET_32BIT"
   "
   /* Armv8.1-M Mainline double shifts are not expanded.  */
-  if (TARGET_HAVE_MVE && REG_P (operands[2]))
+  if (TARGET_HAVE_MVE
+      && arm_reg_or_long_shift_imm (operands[2], GET_MODE (operands[2])))
     {
       if (!reg_overlap_mentioned_p(operands[0], operands[1]))
        emit_insn (gen_movdi (operands[0], operands[1]));
                      (match_operand:SI 2 "reg_or_int_operand")))]
   "TARGET_32BIT"
   "
+  /* Armv8.1-M Mainline double shifts are not expanded.  */
+  if (TARGET_HAVE_MVE
+    && long_shift_imm (operands[2], GET_MODE (operands[2])))
+    {
+      if (!reg_overlap_mentioned_p(operands[0], operands[1]))
+        emit_insn (gen_movdi (operands[0], operands[1]));
+
+      emit_insn (gen_thumb2_lsrl (operands[0], operands[2]));
+      DONE;
+    }
+
   arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
                                 operands[2], gen_reg_rtx (SImode),
                                 gen_reg_rtx (SImode));
index c67156ad3079736ce05dc25ca628f16e0c29ca1b..fd120dfaf44694fd40a02c7eb06d7ddc45a4c8a8 100644 (file)
@@ -35,7 +35,7 @@
 ;;                      Dt, Dp, Dz, Tu
 ;; in Thumb-1 state: Pa, Pb, Pc, Pd, Pe
 ;; in Thumb-2 state: Ha, Pj, PJ, Ps, Pt, Pu, Pv, Pw, Px, Py, Pz
-;; in all states: Pf
+;; in all states: Pf, Pg
 
 ;; The following memory constraints have been used:
 ;; in ARM/Thumb-2 state: Uh, Ut, Uv, Uy, Un, Um, Us
                    && !is_mm_consume (memmodel_from_int (ival))
                    && !is_mm_release (memmodel_from_int (ival))")))
 
+(define_constraint "Pg"
+  "@internal In Thumb-2 state a constant in range 1 to 32"
+  (and (match_code "const_int")
+       (match_test "TARGET_THUMB2 && ival >= 1 && ival <= 32")))
+
 (define_constraint "Ps"
   "@internal In Thumb-2 state a constant in the range -255 to +255"
   (and (match_code "const_int")
index 8df99e64bbb8cfcec8c703bb86341e1493fd5cab..3a3941e22462c435d1bcff74b2db08d6f00ea61c 100644 (file)
                              && (UINTVAL (XEXP (op, 1)) < 32)")))
        (match_test "mode == GET_MODE (op)")))
 
+;; True for Armv8.1-M Mainline long shift instructions.
+(define_predicate "long_shift_imm"
+  (match_test "satisfies_constraint_Pg (op)"))
+
+(define_predicate "arm_reg_or_long_shift_imm"
+  (ior (match_test "TARGET_THUMB2
+                   && arm_general_register_operand (op, GET_MODE (op))")
+       (match_test "satisfies_constraint_Pg (op)")))
+
 ;; True for MULT, to identify which variant of shift_operator is in use.
 (define_special_predicate "mult_operator"
   (match_code "mult"))
index a5986de4859a4241dbdcf1606bb16d56d9b0c58e..b0d3bd1cf1c484927e6ac6522bc30f0f089291c7 100644 (file)
 (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")))]
+                    (match_operand:SI 1 "arm_reg_or_long_shift_imm" "rPg")))]
   "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")))]
+                  (match_operand:SI 1 "arm_reg_or_long_shift_imm" "rPg")))]
   "TARGET_HAVE_MVE"
   "lsll%?\\t%Q0, %R0, %1"
   [(set_attr "predicable" "yes")])
+
+(define_insn "thumb2_lsrl"
+  [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
+       (lshiftrt:DI (match_dup 0)
+                    (match_operand:SI 1 "long_shift_imm" "Pg")))]
+  "TARGET_HAVE_MVE"
+  "lsrl%?\\t%Q0, %R0, %1"
+  [(set_attr "predicable" "yes")])
index 9de42e4de428cb0a701c7a780631534da4e6b2f8..24e9475bcfac34c2266b0a42856591bbb4d8fbc1 100644 (file)
@@ -1,3 +1,8 @@
+2020-01-17  Mihail-Calin Ionescu <mihail.ionescu@arm.com>
+           Sudakshina Das  <sudi.das@arm.com>
+
+       * gcc.target/arm/armv8_1m-shift-imm_1.c: New test.
+
 2020-01-17  Mihail-Calin Ionescu <mihail.ionescu@arm.com>
            Sudakshina Das  <sudi.das@arm.com>
 
diff --git a/gcc/testsuite/gcc.target/arm/armv8_1m-shift-imm-1.c b/gcc/testsuite/gcc.target/arm/armv8_1m-shift-imm-1.c
new file mode 100644 (file)
index 0000000..5ffa376
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv8.1-m.main+mve -mfloat-abi=softfp" } */
+
+long long longval1;
+long long unsigned longval2;
+
+long long int
+asrl_imm ()
+{
+ return (longval1 >> 14);
+}
+
+long long unsigned int
+lsrl_imm ()
+{
+ return (longval2 >> 14);
+}
+
+long long int
+lsll_imm (long long int longval3)
+{
+  return (longval3 << 14);
+}
+
+/* { dg-final { scan-assembler "asrl\\tr\[0-9\], r\[0-9\], #14" } } */
+/* { dg-final { scan-assembler "lsrl\\tr\[0-9\], r\[0-9\], #14" } } */
+/* { dg-final { scan-assembler "lsll\\tr\[0-9\], r\[0-9\], #14" } } */