Implement sqshll, srshrl, uqshll and urshrl using the new MVE builtins
framework.

gcc/ChangeLog:
        * config/arm/arm-mve-builtins-base.cc (enum which_scalar_shift):
        Add ss_SQSHLL, ss_SRSHRL, ss_UQSHLL, ss_URSHRL.
        (mve_function_scalar_shift): Add support for ss_SQSHLL, ss_SRSHRL,
        ss_UQSHLL, ss_URSHRL.
        * config/arm/arm-mve-builtins-base.def (sqshll, srshrl, uqshll)
        (urshrl): New.
        * config/arm/arm-mve-builtins-base.h (sqshll, srshrl, uqshll)
        (urshrl): New.
        * config/arm/arm-mve-builtins-shapes.cc (scalar_s64_shift_imm)
        (scalar_u64_shift_imm): New.
        * config/arm/arm-mve-builtins-shapes.h (scalar_s64_shift_imm)
        (scalar_u64_shift_imm): New.
        * config/arm/arm_mve.h (sqshll): Delete.
        (srshrl): Delete.
        (uqshll): Delete.
        (urshrl): Delete.
        (__arm_uqshll): Delete.
        (__arm_urshrl): Delete.
        (__arm_srshrl): Delete.
        (__arm_sqshll): Delete.

gcc/testsuite/ChangeLog:
        * gcc.target/arm/mve/intrinsics/sqshll_check_shift.c: New test.
        * gcc.target/arm/mve/intrinsics/srshrl_check_shift.c: New test.
        * gcc.target/arm/mve/intrinsics/uqshll_check_shift.c: New test.
        * gcc.target/arm/mve/intrinsics/urshrl_check_shift.c: New test.
---
 gcc/config/arm/arm-mve-builtins-base.cc       | 24 ++++++++++
 gcc/config/arm/arm-mve-builtins-base.def      |  4 ++
 gcc/config/arm/arm-mve-builtins-base.h        |  4 ++
 gcc/config/arm/arm-mve-builtins-shapes.cc     | 46 +++++++++++++++++++
 gcc/config/arm/arm-mve-builtins-shapes.h      |  2 +
 gcc/config/arm/arm_mve.h                      | 32 -------------
 .../arm/mve/intrinsics/sqshll_check_shift.c   | 24 ++++++++++
 .../arm/mve/intrinsics/srshrl_check_shift.c   | 24 ++++++++++
 .../arm/mve/intrinsics/uqshll_check_shift.c   | 24 ++++++++++
 .../arm/mve/intrinsics/urshrl_check_shift.c   | 24 ++++++++++
 10 files changed, 176 insertions(+), 32 deletions(-)
 create mode 100644 
gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshll_check_shift.c
 create mode 100644 
gcc/testsuite/gcc.target/arm/mve/intrinsics/srshrl_check_shift.c
 create mode 100644 
gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshll_check_shift.c
 create mode 100644 
gcc/testsuite/gcc.target/arm/mve/intrinsics/urshrl_check_shift.c

diff --git a/gcc/config/arm/arm-mve-builtins-base.cc 
b/gcc/config/arm/arm-mve-builtins-base.cc
index d2989044dd3..a1c667faa73 100644
--- a/gcc/config/arm/arm-mve-builtins-base.cc
+++ b/gcc/config/arm/arm-mve-builtins-base.cc
@@ -1174,8 +1174,12 @@ enum which_scalar_shift {
   ss_LSLL,
   ss_SQRSHRL,
   ss_SQRSHRL_SAT48,
+  ss_SQSHLL,
+  ss_SRSHRL,
   ss_UQRSHLL,
   ss_UQRSHLL_SAT48,
+  ss_UQSHLL,
+  ss_URSHRL
 };
 
 class mve_function_scalar_shift : public function_base
@@ -1213,6 +1217,14 @@ public:
        code = code_for_mve_sqrshrl_sat_di (SQRSHRL_48);
        break;
 
+      case ss_SQSHLL:
+       code = CODE_FOR_mve_sqshll_di;
+       break;
+
+      case ss_SRSHRL:
+       code = CODE_FOR_mve_srshrl_di;
+       break;
+
       case ss_UQRSHLL:
        code = code_for_mve_uqrshll_sat_di (UQRSHLL_64);
        break;
@@ -1221,6 +1233,14 @@ public:
        code = code_for_mve_uqrshll_sat_di (UQRSHLL_48);
        break;
 
+      case ss_UQSHLL:
+       code = CODE_FOR_mve_uqshll_di;
+       break;
+
+      case ss_URSHRL:
+       code = CODE_FOR_mve_urshrl_di;
+       break;
+
       default:
        gcc_unreachable ();
       }
@@ -1419,8 +1439,12 @@ FUNCTION (asrl, mve_function_scalar_shift, (ss_ASRL))
 FUNCTION (lsll, mve_function_scalar_shift, (ss_LSLL))
 FUNCTION (sqrshrl, mve_function_scalar_shift, (ss_SQRSHRL))
 FUNCTION (sqrshrl_sat48, mve_function_scalar_shift, (ss_SQRSHRL_SAT48))
+FUNCTION (sqshll, mve_function_scalar_shift, (ss_SQSHLL))
+FUNCTION (srshrl, mve_function_scalar_shift, (ss_SRSHRL))
 FUNCTION (uqrshll, mve_function_scalar_shift, (ss_UQRSHLL))
 FUNCTION (uqrshll_sat48, mve_function_scalar_shift, (ss_UQRSHLL_SAT48))
+FUNCTION (uqshll, mve_function_scalar_shift, (ss_UQSHLL))
+FUNCTION (urshrl, mve_function_scalar_shift, (ss_URSHRL))
 FUNCTION_PRED_P_S_U (vabavq, VABAVQ)
 FUNCTION_WITHOUT_N (vabdq, VABDQ)
 FUNCTION (vabsq, unspec_based_mve_function_exact_insn, (ABS, ABS, ABS, -1, -1, 
-1, VABSQ_M_S, -1, VABSQ_M_F, -1, -1, -1))
diff --git a/gcc/config/arm/arm-mve-builtins-base.def 
b/gcc/config/arm/arm-mve-builtins-base.def
index fdeb7411e75..9602ff9fa93 100644
--- a/gcc/config/arm/arm-mve-builtins-base.def
+++ b/gcc/config/arm/arm-mve-builtins-base.def
@@ -22,8 +22,12 @@ DEF_MVE_FUNCTION (asrl, scalar_s64_shift, none, none)
 DEF_MVE_FUNCTION (lsll, scalar_u64_shift, none, none)
 DEF_MVE_FUNCTION (sqrshrl, scalar_s64_shift, none, none)
 DEF_MVE_FUNCTION (sqrshrl_sat48, scalar_s64_shift, none, none)
+DEF_MVE_FUNCTION (sqshll, scalar_s64_shift_imm, none, none)
+DEF_MVE_FUNCTION (srshrl, scalar_s64_shift_imm, none, none)
 DEF_MVE_FUNCTION (uqrshll, scalar_u64_shift, none, none)
 DEF_MVE_FUNCTION (uqrshll_sat48, scalar_u64_shift, none, none)
+DEF_MVE_FUNCTION (uqshll, scalar_u64_shift_imm, none, none)
+DEF_MVE_FUNCTION (urshrl, scalar_u64_shift_imm, none, none)
 DEF_MVE_FUNCTION (vabavq, binary_acca_int32, all_integer, p_or_none)
 DEF_MVE_FUNCTION (vabdq, binary, all_integer, mx_or_none)
 DEF_MVE_FUNCTION (vabsq, unary, all_signed, mx_or_none)
diff --git a/gcc/config/arm/arm-mve-builtins-base.h 
b/gcc/config/arm/arm-mve-builtins-base.h
index dfec2193672..c7c0c7f9779 100644
--- a/gcc/config/arm/arm-mve-builtins-base.h
+++ b/gcc/config/arm/arm-mve-builtins-base.h
@@ -27,8 +27,12 @@ extern const function_base *const asrl;
 extern const function_base *const lsll;
 extern const function_base *const sqrshrl;
 extern const function_base *const sqrshrl_sat48;
+extern const function_base *const sqshll;
+extern const function_base *const srshrl;
 extern const function_base *const uqrshll;
 extern const function_base *const uqrshll_sat48;
+extern const function_base *const uqshll;
+extern const function_base *const urshrl;
 extern const function_base *const vabavq;
 extern const function_base *const vabdq;
 extern const function_base *const vabsq;
diff --git a/gcc/config/arm/arm-mve-builtins-shapes.cc 
b/gcc/config/arm/arm-mve-builtins-shapes.cc
index 02458c75755..35ae2724e0a 100644
--- a/gcc/config/arm/arm-mve-builtins-shapes.cc
+++ b/gcc/config/arm/arm-mve-builtins-shapes.cc
@@ -1697,6 +1697,29 @@ struct scalar_s64_shift_def : public nonoverloaded_base
 };
 SHAPE (scalar_s64_shift)
 
+/* int64_t foo(int64_t, const int)
+
+   Check that 'shift' is in the [1,32] range.
+
+   Example: sqshll.
+   int64_t [__arm_]sqshll(int64_t value, const int shift)  */
+struct scalar_s64_shift_imm_def : public nonoverloaded_base
+{
+  void
+  build (function_builder &b, const function_group_info &group,
+        bool preserve_user_namespace) const override
+  {
+    build_all (b, "ss64,ss64,su64", group, MODE_none, preserve_user_namespace);
+  }
+
+  bool
+  check (function_checker &c) const override
+  {
+    return c.require_immediate_range (1, 1, 32);
+  }
+};
+SHAPE (scalar_s64_shift_imm)
+
 /* uint64_t foo(uint64_t, int32_t)
 
    Example: lsll.
@@ -1712,6 +1735,29 @@ struct scalar_u64_shift_def : public nonoverloaded_base
 };
 SHAPE (scalar_u64_shift)
 
+/* uint64_t foo(uint64_t, const int)
+
+   Check that 'shift' is in the [1,32] range.
+
+   Example: uqshll.
+   uint64_t [__arm_]uqshll(uint64_t value, const int shift)  */
+struct scalar_u64_shift_imm_def : public nonoverloaded_base
+{
+  void
+  build (function_builder &b, const function_group_info &group,
+        bool preserve_user_namespace) const override
+  {
+    build_all (b, "su64,su64,su64", group, MODE_none, preserve_user_namespace);
+  }
+
+  bool
+  check (function_checker &c) const override
+  {
+    return c.require_immediate_range (1, 1, 32);
+  }
+};
+SHAPE (scalar_u64_shift_imm)
+
 /* void vfoo[_t0](<X>_t *, <T0>[xN]_t)
 
    where <X> might be tied to <t0> (for non-truncating stores) or might
diff --git a/gcc/config/arm/arm-mve-builtins-shapes.h 
b/gcc/config/arm/arm-mve-builtins-shapes.h
index 89ef75c5443..4e6a23fcca6 100644
--- a/gcc/config/arm/arm-mve-builtins-shapes.h
+++ b/gcc/config/arm/arm-mve-builtins-shapes.h
@@ -67,7 +67,9 @@ namespace arm_mve
     extern const function_shape *const load_gather_base;
     extern const function_shape *const mvn;
     extern const function_shape *const scalar_s64_shift;
+    extern const function_shape *const scalar_s64_shift_imm;
     extern const function_shape *const scalar_u64_shift;
+    extern const function_shape *const scalar_u64_shift_imm;
     extern const function_shape *const store;
     extern const function_shape *const store_scatter_base;
     extern const function_shape *const store_scatter_offset;
diff --git a/gcc/config/arm/arm_mve.h b/gcc/config/arm/arm_mve.h
index 5a12d982c50..877bbf35014 100644
--- a/gcc/config/arm/arm_mve.h
+++ b/gcc/config/arm/arm_mve.h
@@ -82,14 +82,10 @@
 #define vgetq_lane_u64(__a,  __idx) __arm_vgetq_lane_u64(__a,  __idx)
 #define sqrshr(__p0, __p1) __arm_sqrshr(__p0, __p1)
 #define sqshl(__p0, __p1) __arm_sqshl(__p0, __p1)
-#define sqshll(__p0, __p1) __arm_sqshll(__p0, __p1)
 #define srshr(__p0, __p1) __arm_srshr(__p0, __p1)
-#define srshrl(__p0, __p1) __arm_srshrl(__p0, __p1)
 #define uqrshl(__p0, __p1) __arm_uqrshl(__p0, __p1)
 #define uqshl(__p0, __p1) __arm_uqshl(__p0, __p1)
-#define uqshll(__p0, __p1) __arm_uqshll(__p0, __p1)
 #define urshr(__p0, __p1) __arm_urshr(__p0, __p1)
-#define urshrl(__p0, __p1) __arm_urshrl(__p0, __p1)
 #endif
 
 /* For big-endian, GCC's vector indices are reversed within each 64 bits
@@ -240,34 +236,6 @@ __arm_vgetq_lane_u64 (uint64x2_t __a, const int __idx)
   return __a[__ARM_LANEQ(__a,__idx)];
 }
 
-__extension__ extern __inline uint64_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_uqshll (uint64_t value, const int shift)
-{
-  return __builtin_mve_uqshll_di (value, shift);
-}
-
-__extension__ extern __inline uint64_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_urshrl (uint64_t value, const int shift)
-{
-  return __builtin_mve_urshrl_di (value, shift);
-}
-
-__extension__ extern __inline int64_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_srshrl (int64_t value, const int shift)
-{
-  return __builtin_mve_srshrl_di (value, shift);
-}
-
-__extension__ extern __inline int64_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_sqshll (int64_t value, const int shift)
-{
-  return __builtin_mve_sqshll_di (value, shift);
-}
-
 __extension__ extern __inline uint32_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 __arm_uqrshl (uint32_t value, int32_t shift)
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshll_check_shift.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshll_check_shift.c
new file mode 100644
index 00000000000..6b5fc41b003
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/sqshll_check_shift.c
@@ -0,0 +1,24 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int64_t
+foo (int64_t value)
+{
+  return sqshll (value, 33); /* { dg-error {passing 33 to argument 2 of 
'sqshll', which expects a value in the range \[1, 32\]} } */
+}
+
+int64_t
+foo1 (int64_t value)
+{
+  return sqshll (value, -1); /* { dg-error {passing -1 to argument 2 of 
'sqshll', which expects a value in the range \[1, 32\]} } */
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshrl_check_shift.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshrl_check_shift.c
new file mode 100644
index 00000000000..d29a2390a19
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/srshrl_check_shift.c
@@ -0,0 +1,24 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int64_t
+foo (int64_t value)
+{
+  return srshrl (value, 33); /* { dg-error {passing 33 to argument 2 of 
'srshrl', which expects a value in the range \[1, 32\]} } */
+}
+
+int64_t
+foo1 (int64_t value)
+{
+  return srshrl (value, -1); /* { dg-error {passing -1 to argument 2 of 
'srshrl', which expects a value in the range \[1, 32\]} } */
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshll_check_shift.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshll_check_shift.c
new file mode 100644
index 00000000000..485fd01d4e7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/uqshll_check_shift.c
@@ -0,0 +1,24 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+uint64_t
+foo (uint64_t value)
+{
+  return uqshll (value, 33); /* { dg-error {passing 33 to argument 2 of 
'uqshll', which expects a value in the range \[1, 32\]} } */
+}
+
+uint64_t
+foo1 (uint64_t value)
+{
+  return uqshll (value, -1); /* { dg-error {passing -1 to argument 2 of 
'uqshll', which expects a value in the range \[1, 32\]} } */
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshrl_check_shift.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshrl_check_shift.c
new file mode 100644
index 00000000000..9d0d3b1d5ee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/urshrl_check_shift.c
@@ -0,0 +1,24 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+uint64_t
+foo (uint64_t value)
+{
+  return urshrl (value, 33); /* { dg-error {passing 33 to argument 2 of 
'urshrl', which expects a value in the range \[1, 32\]} } */
+}
+
+uint64_t
+foo1 (uint64_t value)
+{
+  return urshrl (value, -1); /* { dg-error {passing -1 to argument 2 of 
'urshrl', which expects a value in the range \[1, 32\]} } */
+}
+
+#ifdef __cplusplus
+}
+#endif
-- 
2.34.1

Reply via email to