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