Implement lsll, uqrshll and uqrshll_sat48 using the new MVE builtins
framework.

The new enum uses the 'ss_' prefix to avoid clashes with some unspec
identifiers in later patches in the series.

gcc/ChangeLog:

        * config/arm/arm-mve-builtins-base.cc (enum which_scalar_shift): New.
        (class mve_function_scalar_shift): New.
        (lsll, uqrshll, uqrshll_sat48): New.
        * config/arm/arm-mve-builtins-base.def (lsll, uqrshll)
        (uqrshll_sat48): New.
        * config/arm/arm-mve-builtins-base.h (lsll, uqrshll)
        (uqrshll_sat48): New.
        * config/arm/arm-mve-builtins-shapes.cc (scalar_u64_shift): New.
        * config/arm/arm-mve-builtins-shapes.h (scalar_u64_shift): New.
        * config/arm/arm_mve.h (uqrshll): Delete.
        (uqrshll_sat48): Delete.
        (lsll): Delete.
        (__arm_lsll): Delete.
        (__arm_uqrshll): Delete.
        (__arm_uqrshll_sat48): Delete.
        * config/arm/mve.md (mve_uqrshll_sat<supf>_di): Add '@' prefix.
---
 gcc/config/arm/arm-mve-builtins-base.cc   | 48 +++++++++++++++++++++++
 gcc/config/arm/arm-mve-builtins-base.def  |  3 ++
 gcc/config/arm/arm-mve-builtins-base.h    |  3 ++
 gcc/config/arm/arm-mve-builtins-shapes.cc | 15 +++++++
 gcc/config/arm/arm-mve-builtins-shapes.h  |  1 +
 gcc/config/arm/arm_mve.h                  | 24 ------------
 gcc/config/arm/mve.md                     |  2 +-
 7 files changed, 71 insertions(+), 25 deletions(-)

diff --git a/gcc/config/arm/arm-mve-builtins-base.cc 
b/gcc/config/arm/arm-mve-builtins-base.cc
index c6386a56406..9157f99afb8 100644
--- a/gcc/config/arm/arm-mve-builtins-base.cc
+++ b/gcc/config/arm/arm-mve-builtins-base.cc
@@ -1242,6 +1242,51 @@ public:
   }
 };
 
+/* Map the function directly to the appropriate scalar shift builtin.  */
+enum which_scalar_shift {
+  ss_LSLL,
+  ss_UQRSHLL,
+  ss_UQRSHLL_SAT48
+};
+
+class mve_function_scalar_shift : public function_base
+{
+public:
+  CONSTEXPR mve_function_scalar_shift (enum which_scalar_shift shl)
+    : m_scalar_shift (shl)
+  {}
+
+  /* Which scalar_shift builtin to map.  */
+  enum which_scalar_shift m_scalar_shift;
+
+  rtx
+  expand (function_expander &e) const override
+  {
+    rtx target = e.get_reg_target ();
+    insn_code code;
+
+    switch (m_scalar_shift)
+      {
+      case ss_LSLL:
+       code = CODE_FOR_mve_lsll;
+       break;
+
+      case ss_UQRSHLL:
+       code = code_for_mve_uqrshll_sat_di (UQRSHLL_64);
+       break;
+
+      case ss_UQRSHLL_SAT48:
+       code = code_for_mve_uqrshll_sat_di (UQRSHLL_48);
+       break;
+
+      default:
+       gcc_unreachable ();
+      }
+
+    return e.use_unpred_insn (code);
+  }
+};
+
 } /* end anonymous namespace */
 
 namespace arm_mve {
@@ -1409,6 +1454,9 @@ namespace arm_mve {
    (-1, -1, UNSPEC##_F,                                                        
\
     -1, -1, UNSPEC##_P_F))
 
+FUNCTION (lsll, mve_function_scalar_shift, (ss_LSLL))
+FUNCTION (uqrshll, mve_function_scalar_shift, (ss_UQRSHLL))
+FUNCTION (uqrshll_sat48, mve_function_scalar_shift, (ss_UQRSHLL_SAT48))
 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 e5a295265f6..e6c262dafec 100644
--- a/gcc/config/arm/arm-mve-builtins-base.def
+++ b/gcc/config/arm/arm-mve-builtins-base.def
@@ -18,6 +18,9 @@
    <http://www.gnu.org/licenses/>.  */
 
 #define REQUIRES_FLOAT false
+DEF_MVE_FUNCTION (lsll, scalar_u64_shift, none, none)
+DEF_MVE_FUNCTION (uqrshll, scalar_u64_shift, none, none)
+DEF_MVE_FUNCTION (uqrshll_sat48, scalar_u64_shift, 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 285cb0c6957..8041764997c 100644
--- a/gcc/config/arm/arm-mve-builtins-base.h
+++ b/gcc/config/arm/arm-mve-builtins-base.h
@@ -23,6 +23,9 @@
 namespace arm_mve {
 namespace functions {
 
+extern const function_base *const lsll;
+extern const function_base *const uqrshll;
+extern const function_base *const uqrshll_sat48;
 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 03f70f8ba16..779978acda8 100644
--- a/gcc/config/arm/arm-mve-builtins-shapes.cc
+++ b/gcc/config/arm/arm-mve-builtins-shapes.cc
@@ -1723,6 +1723,21 @@ struct mvn_def : public overloaded_base<0>
 };
 SHAPE (mvn)
 
+/* uint64_t foo(uint64_t, int32_t)
+
+   Example: lsll.
+   uint64_t [__arm_]lsll(uint64_t value, int32_t shift)  */
+struct scalar_u64_shift_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,ss32", group, MODE_none, preserve_user_namespace);
+  }
+};
+SHAPE (scalar_u64_shift)
+
 /* <T0>_t vfoo[_t0](<S0>_t, <T0>_t, const_int)
 
    Check that 'idx' is in the [0..#num_lanes - 1] range.
diff --git a/gcc/config/arm/arm-mve-builtins-shapes.h 
b/gcc/config/arm/arm-mve-builtins-shapes.h
index 4763eeeda32..e630fb27ce0 100644
--- a/gcc/config/arm/arm-mve-builtins-shapes.h
+++ b/gcc/config/arm/arm-mve-builtins-shapes.h
@@ -67,6 +67,7 @@ namespace arm_mve
     extern const function_shape *const load_ext_gather_offset;
     extern const function_shape *const load_gather_base;
     extern const function_shape *const mvn;
+    extern const function_shape *const scalar_u64_shift;
     extern const function_shape *const setq_lane;
     extern const function_shape *const store;
     extern const function_shape *const store_scatter_base;
diff --git a/gcc/config/arm/arm_mve.h b/gcc/config/arm/arm_mve.h
index 9947420dcdb..9381a3e5d06 100644
--- a/gcc/config/arm/arm_mve.h
+++ b/gcc/config/arm/arm_mve.h
@@ -66,23 +66,13 @@
 #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 uqrshll(__p0, __p1) __arm_uqrshll(__p0, __p1)
-#define uqrshll_sat48(__p0, __p1) __arm_uqrshll_sat48(__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)
-#define lsll(__p0, __p1) __arm_lsll(__p0, __p1)
 #define asrl(__p0, __p1) __arm_asrl(__p0, __p1)
 #endif
 
-__extension__ extern __inline  uint64_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_lsll (uint64_t value, int32_t shift)
-{
-  return (value << shift);
-}
-
 __extension__ extern __inline int64_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 __arm_asrl (int64_t value, int32_t shift)
@@ -90,20 +80,6 @@ __arm_asrl (int64_t value, int32_t shift)
   return (value >> shift);
 }
 
-__extension__ extern __inline uint64_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_uqrshll (uint64_t value, int32_t shift)
-{
-  return __builtin_mve_uqrshll_sat64_di (value, shift);
-}
-
-__extension__ extern __inline uint64_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_uqrshll_sat48 (uint64_t value, int32_t shift)
-{
-  return __builtin_mve_uqrshll_sat48_di (value, shift);
-}
-
 __extension__ extern __inline int64_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 __arm_sqrshrl (int64_t value, int32_t shift)
diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md
index 4636ff356f0..fa6fe392936 100644
--- a/gcc/config/arm/mve.md
+++ b/gcc/config/arm/mve.md
@@ -4267,7 +4267,7 @@ (define_insn "mve_vec_setv2di_internal"
 ;;
 ;; [uqrshll_di]
 ;;
-(define_insn "mve_uqrshll_sat<supf>_di"
+(define_insn "@mve_uqrshll_sat<supf>_di"
   [(set (match_operand:DI 0 "arm_low_register_operand" "=l")
        (unspec:DI [(match_operand:DI 1 "arm_low_register_operand" "0")
                    (match_operand:SI 2 "register_operand" "r")]
-- 
2.34.1

Reply via email to