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