From patchwork Mon Feb 6 11:51:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?6ZKf5bGF5ZOy?= X-Patchwork-Id: 64344 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0EAA0385B51D for ; Mon, 6 Feb 2023 11:51:50 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from smtpbgeu1.qq.com (smtpbgeu1.qq.com [52.59.177.22]) by sourceware.org (Postfix) with ESMTPS id 8B8BD3858D1E for ; Mon, 6 Feb 2023 11:51:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 8B8BD3858D1E Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=rivai.ai Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=rivai.ai X-QQ-mid: bizesmtp88t1675684277tb58q0jy Received: from server1.localdomain ( [58.60.1.22]) by bizesmtp.qq.com (ESMTP) with id ; Mon, 06 Feb 2023 19:51:16 +0800 (CST) X-QQ-SSF: 01400000000000E0L000000A0000000 X-QQ-FEAT: RrZlkntZBfnZZAOEVdqa2lzqAjxb7beqg9UCkylBo6yX99VRyhwzIBflhlSbU Qg26Q+PFEuNZhq4yFCaC/WAIwdJhJp774Dp7NqrmhQOKvlYTx8+fOtK3pB/c326bZQWfiN2 0lqfAL8R4V37ZxpGxng0PlZv9jF++GJAC/2XP6HKLqiPURdh9461WSzeeKVBtAgvIe/fIQE 8IdRfb0B7CGS9wzpb0mgh8rlqbVwRVEh3JVKpc4vSNAVpj2FqntZU2TPm/xiUeuzZ+18bqy T6r95fSeWh1cS3rwtevjgbuvB+Ui1T+9KN/8BfL3I9kEI9xKqLEW4K31JB6HR3SUegtbUAt ZwJqLZpB+BTJ+US8xTzWGWqwh+8Qru57E/lK8ukQmlft/zq/04RViyMDp8MYezlLTWKVhqx fZU4BfNpqzM= X-QQ-GoodBg: 2 From: juzhe.zhong@rivai.ai To: gcc-patches@gcc.gnu.org Cc: kito.cheng@gmail.com, Ju-Zhe Zhong , kito-cheng Subject: [PATCH] RISC-V: Add vmulh C/C++ support Date: Mon, 6 Feb 2023 19:51:13 +0800 Message-Id: <20230206115113.47100-1-juzhe.zhong@rivai.ai> X-Mailer: git-send-email 2.36.1 MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:rivai.ai:qybglogicsvr:qybglogicsvr7 X-Spam-Status: No, score=-10.5 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_ASCII_DIVIDERS, KAM_DMARC_STATUS, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_PASS, TXREP, T_SPF_HELO_TEMPERROR autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" From: Ju-Zhe Zhong Co-authored-by: kito-cheng gcc/ChangeLog: * common/config/riscv/riscv-common.cc: Add flag for 'V' extension. * config/riscv/riscv-vector-builtins-bases.cc (class vmulh): New class. (BASE): Ditto. * config/riscv/riscv-vector-builtins-bases.h: Ditto. * config/riscv/riscv-vector-builtins-functions.def (vmulh): Add vmulh API support. (vmulhu): Ditto. (vmulhsu): Ditto. * config/riscv/riscv-vector-builtins-types.def (DEF_RVV_FULL_V_I_OPS): New macro. (DEF_RVV_FULL_V_U_OPS): Ditto. (vint8mf8_t): Ditto. (vint8mf4_t): Ditto. (vint8mf2_t): Ditto. (vint8m1_t): Ditto. (vint8m2_t): Ditto. (vint8m4_t): Ditto. (vint8m8_t): Ditto. (vint16mf4_t): Ditto. (vint16mf2_t): Ditto. (vint16m1_t): Ditto. (vint16m2_t): Ditto. (vint16m4_t): Ditto. (vint16m8_t): Ditto. (vint32mf2_t): Ditto. (vint32m1_t): Ditto. (vint32m2_t): Ditto. (vint32m4_t): Ditto. (vint32m8_t): Ditto. (vint64m1_t): Ditto. (vint64m2_t): Ditto. (vint64m4_t): Ditto. (vint64m8_t): Ditto. (vuint8mf8_t): Ditto. (vuint8mf4_t): Ditto. (vuint8mf2_t): Ditto. (vuint8m1_t): Ditto. (vuint8m2_t): Ditto. (vuint8m4_t): Ditto. (vuint8m8_t): Ditto. (vuint16mf4_t): Ditto. (vuint16mf2_t): Ditto. (vuint16m1_t): Ditto. (vuint16m2_t): Ditto. (vuint16m4_t): Ditto. (vuint16m8_t): Ditto. (vuint32mf2_t): Ditto. (vuint32m1_t): Ditto. (vuint32m2_t): Ditto. (vuint32m4_t): Ditto. (vuint32m8_t): Ditto. (vuint64m1_t): Ditto. (vuint64m2_t): Ditto. (vuint64m4_t): Ditto. (vuint64m8_t): Ditto. * config/riscv/riscv-vector-builtins.cc (DEF_RVV_FULL_V_I_OPS): Ditto. (DEF_RVV_FULL_V_U_OPS): Ditto. (check_required_extensions): Add vmulh support. (rvv_arg_type_info::get_tree_type): Ditto. * config/riscv/riscv-vector-builtins.h (RVV_REQUIRE_FULL_V): Ditto. (enum rvv_base_type): Ditto. * config/riscv/riscv.opt: Add 'V' extension flag. * config/riscv/vector-iterators.md (su): New iterator. * config/riscv/vector.md (@pred_mulh): New pattern. (@pred_mulh_scalar): Ditto. (*pred_mulh_scalar): Ditto. (*pred_mulh_extended_scalar): Ditto. --- gcc/common/config/riscv/riscv-common.cc | 1 + .../riscv/riscv-vector-builtins-bases.cc | 27 ++++ .../riscv/riscv-vector-builtins-bases.h | 3 + .../riscv/riscv-vector-builtins-functions.def | 6 + .../riscv/riscv-vector-builtins-types.def | 62 +++++++++ gcc/config/riscv/riscv-vector-builtins.cc | 93 +++++++++++++ gcc/config/riscv/riscv-vector-builtins.h | 3 + gcc/config/riscv/riscv.opt | 2 + gcc/config/riscv/vector-iterators.md | 22 +++ gcc/config/riscv/vector.md | 128 ++++++++++++++++++ 10 files changed, 347 insertions(+) diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index 616e2f897b9..1a6c8dbd97d 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -1177,6 +1177,7 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] = {"f", &gcc_options::x_target_flags, MASK_HARD_FLOAT}, {"d", &gcc_options::x_target_flags, MASK_DOUBLE_FLOAT}, {"c", &gcc_options::x_target_flags, MASK_RVC}, + {"v", &gcc_options::x_target_flags, MASK_FULL_V}, {"v", &gcc_options::x_target_flags, MASK_VECTOR}, {"zicsr", &gcc_options::x_riscv_zi_subext, MASK_ZICSR}, diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc index 1a9469a370a..43f815156d8 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc @@ -218,6 +218,27 @@ public: } }; +/* Implements vmulh/vmulhu/vmulhsu. */ +template +class vmulh : public function_base +{ +public: + rtx expand (function_expander &e) const override + { + switch (e.op_info->op) + { + case OP_TYPE_vx: + return e.use_exact_insn ( + code_for_pred_mulh_scalar (UNSPEC, e.vector_mode ())); + case OP_TYPE_vv: + return e.use_exact_insn ( + code_for_pred_mulh (UNSPEC, e.vector_mode ())); + default: + gcc_unreachable (); + } + } +}; + static CONSTEXPR const vsetvl vsetvl_obj; static CONSTEXPR const vsetvl vsetvlmax_obj; static CONSTEXPR const loadstore vle_obj; @@ -256,6 +277,9 @@ static CONSTEXPR const binop vmax_obj; static CONSTEXPR const binop vminu_obj; static CONSTEXPR const binop vmaxu_obj; static CONSTEXPR const binop vmul_obj; +static CONSTEXPR const vmulh vmulh_obj; +static CONSTEXPR const vmulh vmulhu_obj; +static CONSTEXPR const vmulh vmulhsu_obj; static CONSTEXPR const binop
vdiv_obj; static CONSTEXPR const binop vrem_obj; static CONSTEXPR const binop vdivu_obj; @@ -312,6 +336,9 @@ BASE (vmax) BASE (vminu) BASE (vmaxu) BASE (vmul) +BASE (vmulh) +BASE (vmulhu) +BASE (vmulhsu) BASE (vdiv) BASE (vrem) BASE (vdivu) diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.h b/gcc/config/riscv/riscv-vector-builtins-bases.h index 71629f36738..96cfdd85659 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.h +++ b/gcc/config/riscv/riscv-vector-builtins-bases.h @@ -62,6 +62,9 @@ extern const function_base *const vmax; extern const function_base *const vminu; extern const function_base *const vmaxu; extern const function_base *const vmul; +extern const function_base *const vmulh; +extern const function_base *const vmulhu; +extern const function_base *const vmulhsu; extern const function_base *const vdiv; extern const function_base *const vrem; extern const function_base *const vdivu; diff --git a/gcc/config/riscv/riscv-vector-builtins-functions.def b/gcc/config/riscv/riscv-vector-builtins-functions.def index 42514ed5a37..418268f1279 100644 --- a/gcc/config/riscv/riscv-vector-builtins-functions.def +++ b/gcc/config/riscv/riscv-vector-builtins-functions.def @@ -76,6 +76,9 @@ DEF_RVV_FUNCTION (vmax, alu, full_preds, i_vvv_ops) DEF_RVV_FUNCTION (vminu, alu, full_preds, u_vvv_ops) DEF_RVV_FUNCTION (vmaxu, alu, full_preds, u_vvv_ops) DEF_RVV_FUNCTION (vmul, alu, full_preds, iu_vvv_ops) +DEF_RVV_FUNCTION (vmulh, alu, full_preds, full_v_i_vvv_ops) +DEF_RVV_FUNCTION (vmulhu, alu, full_preds, full_v_u_vvv_ops) +DEF_RVV_FUNCTION (vmulhsu, alu, full_preds, full_v_i_su_vvv_ops) DEF_RVV_FUNCTION (vdiv, alu, full_preds, i_vvv_ops) DEF_RVV_FUNCTION (vrem, alu, full_preds, i_vvv_ops) DEF_RVV_FUNCTION (vdivu, alu, full_preds, u_vvv_ops) @@ -94,6 +97,9 @@ DEF_RVV_FUNCTION (vmax, alu, full_preds, i_vvx_ops) DEF_RVV_FUNCTION (vminu, alu, full_preds, u_vvx_ops) DEF_RVV_FUNCTION (vmaxu, alu, full_preds, u_vvx_ops) DEF_RVV_FUNCTION (vmul, alu, full_preds, iu_vvx_ops) +DEF_RVV_FUNCTION (vmulh, alu, full_preds, full_v_i_vvx_ops) +DEF_RVV_FUNCTION (vmulhu, alu, full_preds, full_v_u_vvx_ops) +DEF_RVV_FUNCTION (vmulhsu, alu, full_preds, full_v_i_su_vvx_ops) DEF_RVV_FUNCTION (vdiv, alu, full_preds, i_vvx_ops) DEF_RVV_FUNCTION (vrem, alu, full_preds, i_vvx_ops) DEF_RVV_FUNCTION (vdivu, alu, full_preds, u_vvx_ops) diff --git a/gcc/config/riscv/riscv-vector-builtins-types.def b/gcc/config/riscv/riscv-vector-builtins-types.def index d3129b9f753..0a562bd283f 100644 --- a/gcc/config/riscv/riscv-vector-builtins-types.def +++ b/gcc/config/riscv/riscv-vector-builtins-types.def @@ -78,6 +78,20 @@ along with GCC; see the file COPYING3. If not see #define DEF_RVV_OEXTU_OPS(TYPE, REQUIRE) #endif +/* Use "DEF_RVV_FULL_V_I_OPS" macro include all signed integer that require full + 'V' extension which will be iterated and registered as intrinsic functions. + */ +#ifndef DEF_RVV_FULL_V_I_OPS +#define DEF_RVV_FULL_V_I_OPS(TYPE, REQUIRE) +#endif + +/* Use "DEF_RVV_FULL_V_U_OPS" macro include all unsigned integer that require + full 'V' extension which will be iterated and registered as intrinsic + functions. */ +#ifndef DEF_RVV_FULL_V_U_OPS +#define DEF_RVV_FULL_V_U_OPS(TYPE, REQUIRE) +#endif + DEF_RVV_I_OPS (vint8mf8_t, RVV_REQUIRE_ZVE64) DEF_RVV_I_OPS (vint8mf4_t, 0) DEF_RVV_I_OPS (vint8mf2_t, 0) @@ -204,6 +218,52 @@ DEF_RVV_OEXTU_OPS (vuint64m2_t, RVV_REQUIRE_ZVE64) DEF_RVV_OEXTU_OPS (vuint64m4_t, RVV_REQUIRE_ZVE64) DEF_RVV_OEXTU_OPS (vuint64m8_t, RVV_REQUIRE_ZVE64) +DEF_RVV_FULL_V_I_OPS (vint8mf8_t, RVV_REQUIRE_ZVE64) +DEF_RVV_FULL_V_I_OPS (vint8mf4_t, 0) +DEF_RVV_FULL_V_I_OPS (vint8mf2_t, 0) +DEF_RVV_FULL_V_I_OPS (vint8m1_t, 0) +DEF_RVV_FULL_V_I_OPS (vint8m2_t, 0) +DEF_RVV_FULL_V_I_OPS (vint8m4_t, 0) +DEF_RVV_FULL_V_I_OPS (vint8m8_t, 0) +DEF_RVV_FULL_V_I_OPS (vint16mf4_t, RVV_REQUIRE_ZVE64) +DEF_RVV_FULL_V_I_OPS (vint16mf2_t, 0) +DEF_RVV_FULL_V_I_OPS (vint16m1_t, 0) +DEF_RVV_FULL_V_I_OPS (vint16m2_t, 0) +DEF_RVV_FULL_V_I_OPS (vint16m4_t, 0) +DEF_RVV_FULL_V_I_OPS (vint16m8_t, 0) +DEF_RVV_FULL_V_I_OPS (vint32mf2_t, RVV_REQUIRE_ZVE64) +DEF_RVV_FULL_V_I_OPS (vint32m1_t, 0) +DEF_RVV_FULL_V_I_OPS (vint32m2_t, 0) +DEF_RVV_FULL_V_I_OPS (vint32m4_t, 0) +DEF_RVV_FULL_V_I_OPS (vint32m8_t, 0) +DEF_RVV_FULL_V_I_OPS (vint64m1_t, RVV_REQUIRE_FULL_V) +DEF_RVV_FULL_V_I_OPS (vint64m2_t, RVV_REQUIRE_FULL_V) +DEF_RVV_FULL_V_I_OPS (vint64m4_t, RVV_REQUIRE_FULL_V) +DEF_RVV_FULL_V_I_OPS (vint64m8_t, RVV_REQUIRE_FULL_V) + +DEF_RVV_FULL_V_U_OPS (vuint8mf8_t, RVV_REQUIRE_ZVE64) +DEF_RVV_FULL_V_U_OPS (vuint8mf4_t, 0) +DEF_RVV_FULL_V_U_OPS (vuint8mf2_t, 0) +DEF_RVV_FULL_V_U_OPS (vuint8m1_t, 0) +DEF_RVV_FULL_V_U_OPS (vuint8m2_t, 0) +DEF_RVV_FULL_V_U_OPS (vuint8m4_t, 0) +DEF_RVV_FULL_V_U_OPS (vuint8m8_t, 0) +DEF_RVV_FULL_V_U_OPS (vuint16mf4_t, RVV_REQUIRE_ZVE64) +DEF_RVV_FULL_V_U_OPS (vuint16mf2_t, 0) +DEF_RVV_FULL_V_U_OPS (vuint16m1_t, 0) +DEF_RVV_FULL_V_U_OPS (vuint16m2_t, 0) +DEF_RVV_FULL_V_U_OPS (vuint16m4_t, 0) +DEF_RVV_FULL_V_U_OPS (vuint16m8_t, 0) +DEF_RVV_FULL_V_U_OPS (vuint32mf2_t, RVV_REQUIRE_ZVE64) +DEF_RVV_FULL_V_U_OPS (vuint32m1_t, 0) +DEF_RVV_FULL_V_U_OPS (vuint32m2_t, 0) +DEF_RVV_FULL_V_U_OPS (vuint32m4_t, 0) +DEF_RVV_FULL_V_U_OPS (vuint32m8_t, 0) +DEF_RVV_FULL_V_U_OPS (vuint64m1_t, RVV_REQUIRE_FULL_V) +DEF_RVV_FULL_V_U_OPS (vuint64m2_t, RVV_REQUIRE_FULL_V) +DEF_RVV_FULL_V_U_OPS (vuint64m4_t, RVV_REQUIRE_FULL_V) +DEF_RVV_FULL_V_U_OPS (vuint64m8_t, RVV_REQUIRE_FULL_V) + #undef DEF_RVV_I_OPS #undef DEF_RVV_U_OPS #undef DEF_RVV_F_OPS @@ -214,3 +274,5 @@ DEF_RVV_OEXTU_OPS (vuint64m8_t, RVV_REQUIRE_ZVE64) #undef DEF_RVV_WEXTU_OPS #undef DEF_RVV_QEXTU_OPS #undef DEF_RVV_OEXTU_OPS +#undef DEF_RVV_FULL_V_I_OPS +#undef DEF_RVV_FULL_V_U_OPS diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc index 85adcf328ce..696864ce76d 100644 --- a/gcc/config/riscv/riscv-vector-builtins.cc +++ b/gcc/config/riscv/riscv-vector-builtins.cc @@ -133,6 +133,20 @@ static const rvv_type_info i_ops[] = { #include "riscv-vector-builtins-types.def" {NUM_VECTOR_TYPES, 0}}; +/* A list of all signed integer that SEW = 64 require full 'V' extension will be + registered for intrinsic functions. */ +static const rvv_type_info full_v_i_ops[] = { +#define DEF_RVV_FULL_V_I_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE}, +#include "riscv-vector-builtins-types.def" + {NUM_VECTOR_TYPES, 0}}; + +/* A list of all unsigned integer that SEW = 64 require full 'V' extension will + be registered for intrinsic functions. */ +static const rvv_type_info full_v_u_ops[] = { +#define DEF_RVV_FULL_V_U_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE}, +#include "riscv-vector-builtins-types.def" + {NUM_VECTOR_TYPES, 0}}; + /* A list of all signed integer will be registered for intrinsic functions. */ static const rvv_type_info u_ops[] = { #define DEF_RVV_U_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE}, @@ -292,11 +306,23 @@ static CONSTEXPR const rvv_arg_type_info vv_args[] = {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info_end}; +/* A list of args for vector_type func (signed vector_type, unsigned + * vector_type) function. */ +static CONSTEXPR const rvv_arg_type_info su_vv_args[] + = {rvv_arg_type_info (RVV_BASE_vector), + rvv_arg_type_info (RVV_BASE_unsigned_vector), rvv_arg_type_info_end}; + /* A list of args for vector_type func (vector_type, scalar_type) function. */ static CONSTEXPR const rvv_arg_type_info vx_args[] = {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info (RVV_BASE_scalar), rvv_arg_type_info_end}; +/* A list of args for vector_type func (signed vector_type, unsigned + * scalar_type) function. */ +static CONSTEXPR const rvv_arg_type_info su_vx_args[] + = {rvv_arg_type_info (RVV_BASE_vector), + rvv_arg_type_info (RVV_BASE_unsigned_scalar), rvv_arg_type_info_end}; + /* A list of args for vector_type func (vector_type, shift_type) function. */ static CONSTEXPR const rvv_arg_type_info shift_vv_args[] = {rvv_arg_type_info (RVV_BASE_vector), @@ -487,6 +513,30 @@ static CONSTEXPR const rvv_op_info u_vvv_ops rvv_arg_type_info (RVV_BASE_vector), /* Return type */ vv_args /* Args */}; +/* A static operand information for vector_type func (vector_type, vector_type) + * function registration. */ +static CONSTEXPR const rvv_op_info full_v_i_vvv_ops + = {full_v_i_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + vv_args /* Args */}; + +/* A static operand information for vector_type func (vector_type, vector_type) + * function registration. */ +static CONSTEXPR const rvv_op_info full_v_u_vvv_ops + = {full_v_u_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + vv_args /* Args */}; + +/* A static operand information for vector_type func (signed vector_type, + * unsigned vector_type) function registration. */ +static CONSTEXPR const rvv_op_info full_v_i_su_vvv_ops + = {full_v_i_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + su_vv_args /* Args */}; + /* A static operand information for vector_type func (vector_type, scalar_type) * function registration. */ static CONSTEXPR const rvv_op_info iu_vvx_ops @@ -511,6 +561,31 @@ static CONSTEXPR const rvv_op_info u_vvx_ops rvv_arg_type_info (RVV_BASE_vector), /* Return type */ vx_args /* Args */}; +/* A static operand information for vector_type func (vector_type, scalar_type) + * function registration that require full 'V' extension. */ +static CONSTEXPR const rvv_op_info full_v_i_vvx_ops + = {full_v_i_ops, /* Types */ + OP_TYPE_vx, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + vx_args /* Args */}; + +/* A static operand information for vector_type func (vector_type, scalar_type) + * function registration that require full 'V' extension. */ +static CONSTEXPR const rvv_op_info full_v_u_vvx_ops + = {full_v_u_ops, /* Types */ + OP_TYPE_vx, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + vx_args /* Args */}; + +/* A static operand information for vector_type func (signed vector_type, + * unsigned scalar_type) function registration that require full 'V' extension. + */ +static CONSTEXPR const rvv_op_info full_v_i_su_vvx_ops + = {full_v_i_ops, /* Types */ + OP_TYPE_vx, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + su_vx_args /* Args */}; + /* A static operand information for vector_type func (vector_type, shift_type) * function registration. */ static CONSTEXPR const rvv_op_info iu_shift_vvv_ops @@ -816,6 +891,8 @@ check_required_extensions (const function_instance &instance) riscv_isa_flags |= RVV_REQUIRE_ZVE64; if (TARGET_64BIT) riscv_isa_flags |= RVV_REQUIRE_RV64BIT; + if (TARGET_FULL_V) + riscv_isa_flags |= RVV_REQUIRE_FULL_V; uint64_t missing_extensions = required_extensions & ~riscv_isa_flags; if (missing_extensions != 0) @@ -940,12 +1017,28 @@ rvv_arg_type_info::get_base_vector_type (tree type) const tree rvv_arg_type_info::get_tree_type (vector_type_index type_idx) const { + /* If the builtin type is not registered means '-march' doesn't + satisfy the require extension of the type. For example, + vfloat32m1_t require floating-point extension. In this case, + just return NULL_TREE. */ + if (!builtin_types[type_idx].vector) + return NULL_TREE; switch (base_type) { case RVV_BASE_vector: return builtin_types[type_idx].vector; case RVV_BASE_scalar: return builtin_types[type_idx].scalar; + /* According to riscv-vector-builtins-types.def, the unsigned + type is always the signed type + 1 (They have same SEW and LMUL). + For example 'vuint8mf8_t' enum = 'vint8mf8_t' enum + 1. + Note: We dont't allow type_idx to be unsigned type. */ + case RVV_BASE_unsigned_vector: + gcc_assert (!TYPE_UNSIGNED (builtin_types[type_idx].vector)); + return builtin_types[type_idx + 1].vector; + case RVV_BASE_unsigned_scalar: + gcc_assert (!TYPE_UNSIGNED (builtin_types[type_idx].scalar)); + return builtin_types[type_idx + 1].scalar; case RVV_BASE_vector_ptr: return builtin_types[type_idx].vector_ptr; case RVV_BASE_scalar_ptr: diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h index f14b6a55ec2..fc9d405784c 100644 --- a/gcc/config/riscv/riscv-vector-builtins.h +++ b/gcc/config/riscv/riscv-vector-builtins.h @@ -106,6 +106,7 @@ static const unsigned int CP_WRITE_CSR = 1U << 5; #define RVV_REQUIRE_ZVE64 (1 << 1) /* Require TARGET_MIN_VLEN > 32. */ #define RVV_REQUIRE_ELEN_FP_32 (1 << 2) /* Require FP ELEN >= 32. */ #define RVV_REQUIRE_ELEN_FP_64 (1 << 3) /* Require FP ELEN >= 64. */ +#define RVV_REQUIRE_FULL_V (1 << 4) /* Require Full 'V' extension. */ /* Enumerates the RVV operand types. */ enum operand_type_index @@ -139,6 +140,8 @@ enum rvv_base_type { RVV_BASE_vector, RVV_BASE_scalar, + RVV_BASE_unsigned_vector, + RVV_BASE_unsigned_scalar, RVV_BASE_vector_ptr, RVV_BASE_scalar_ptr, RVV_BASE_scalar_const_ptr, diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt index e78c99382cd..95535235354 100644 --- a/gcc/config/riscv/riscv.opt +++ b/gcc/config/riscv/riscv.opt @@ -154,6 +154,8 @@ Mask(RVE) Mask(VECTOR) +Mask(FULL_V) + mriscv-attribute Target Var(riscv_emit_attribute_p) Init(-1) Emit RISC-V ELF attribute. diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index 6528e5711a4..7f5de072215 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -28,6 +28,11 @@ ;; It's used to specify ordered/unorderd operation. UNSPEC_ORDERED UNSPEC_UNORDERED + + ;; vmulh/vmulhu/vmulhsu + UNSPEC_VMULHS + UNSPEC_VMULHU + UNSPEC_VMULHSU ]) (define_mode_iterator V [ @@ -55,6 +60,14 @@ (VNx4DI "TARGET_MIN_VLEN > 32") (VNx8DI "TARGET_MIN_VLEN > 32") ]) +(define_mode_iterator VFULLI [ + VNx1QI VNx2QI VNx4QI VNx8QI VNx16QI VNx32QI (VNx64QI "TARGET_MIN_VLEN > 32") + VNx1HI VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN > 32") + VNx1SI VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32") + (VNx1DI "TARGET_FULL_V") (VNx2DI "TARGET_FULL_V") + (VNx4DI "TARGET_FULL_V") (VNx8DI "TARGET_FULL_V") +]) + (define_mode_iterator VI_QHS [ VNx1QI VNx2QI VNx4QI VNx8QI VNx16QI VNx32QI (VNx64QI "TARGET_MIN_VLEN > 32") VNx1HI VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN > 32") @@ -66,6 +79,11 @@ (VNx4DI "TARGET_MIN_VLEN > 32") (VNx8DI "TARGET_MIN_VLEN > 32") ]) +(define_mode_iterator VFULLI_D [ + (VNx1DI "TARGET_FULL_V") (VNx2DI "TARGET_FULL_V") + (VNx4DI "TARGET_FULL_V") (VNx8DI "TARGET_FULL_V") +]) + (define_mode_iterator VNX1_QHSD [ VNx1QI VNx1HI VNx1SI (VNx1DI "TARGET_MIN_VLEN > 32") @@ -238,10 +256,14 @@ (define_int_iterator ORDER [UNSPEC_ORDERED UNSPEC_UNORDERED]) +(define_int_iterator VMULH [UNSPEC_VMULHS UNSPEC_VMULHU UNSPEC_VMULHSU]) + (define_int_attr order [ (UNSPEC_ORDERED "o") (UNSPEC_UNORDERED "u") ]) +(define_int_attr v_su [(UNSPEC_VMULHS "") (UNSPEC_VMULHU "u") (UNSPEC_VMULHSU "su")]) + (define_code_iterator any_int_binop [plus minus and ior xor ashift ashiftrt lshiftrt smax umax smin umin mult div udiv mod umod ]) diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index 8bafbdc8704..40a0bbea71a 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -1148,6 +1148,7 @@ ;; - 11.5 Vector Bitwise Logical Instructions ;; - 11.6 Vector Single-Width Bit Shift Instructions ;; - 11.9 Vector Integer Min/Max Instructions +;; - 11.10 Vector Single-Width Integer Multiply Instructions ;; - 11.11 Vector Integer Divide Instructions ;; - 12.1 Vector Single-Width Saturating Add and Subtract ;; ------------------------------------------------------------------------------- @@ -1775,6 +1776,133 @@ [(set_attr "type" "") (set_attr "mode" "")]) +;; Multiply High instructions. +(define_insn "@pred_mulh" + [(set (match_operand:VFULLI 0 "register_operand" "=vd, vr") + (if_then_else:VFULLI + (unspec: + [(match_operand: 1 "vector_mask_operand" " vm,Wc1") + (match_operand 5 "vector_length_operand" " rK, rK") + (match_operand 6 "const_int_operand" " i, i") + (match_operand 7 "const_int_operand" " i, i") + (match_operand 8 "const_int_operand" " i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (unspec:VFULLI + [(match_operand:VFULLI 3 "register_operand" " vr, vr") + (match_operand:VFULLI 4 "register_operand" " vr, vr")] VMULH) + (match_operand:VFULLI 2 "vector_merge_operand" "0vu,0vu")))] + "TARGET_VECTOR" + "vmulh.vv\t%0,%3,%4%p1" + [(set_attr "type" "vimul") + (set_attr "mode" "")]) + +(define_insn "@pred_mulh_scalar" + [(set (match_operand:VI_QHS 0 "register_operand" "=vd, vr") + (if_then_else:VI_QHS + (unspec: + [(match_operand: 1 "vector_mask_operand" " vm,Wc1") + (match_operand 5 "vector_length_operand" " rK, rK") + (match_operand 6 "const_int_operand" " i, i") + (match_operand 7 "const_int_operand" " i, i") + (match_operand 8 "const_int_operand" " i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (unspec:VI_QHS + [(vec_duplicate:VI_QHS + (match_operand: 4 "register_operand" " r, r")) + (match_operand:VI_QHS 3 "register_operand" " vr, vr")] VMULH) + (match_operand:VI_QHS 2 "vector_merge_operand" "0vu,0vu")))] + "TARGET_VECTOR" + "vmulh.vx\t%0,%3,%4%p1" + [(set_attr "type" "vimul") + (set_attr "mode" "")]) + +(define_expand "@pred_mulh_scalar" + [(set (match_operand:VFULLI_D 0 "register_operand") + (if_then_else:VFULLI_D + (unspec: + [(match_operand: 1 "vector_mask_operand") + (match_operand 5 "vector_length_operand") + (match_operand 6 "const_int_operand") + (match_operand 7 "const_int_operand") + (match_operand 8 "const_int_operand") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (unspec:VFULLI_D + [(vec_duplicate:VFULLI_D + (match_operand: 4 "reg_or_int_operand")) + (match_operand:VFULLI_D 3 "register_operand")] VMULH) + (match_operand:VFULLI_D 2 "vector_merge_operand")))] + "TARGET_VECTOR" + { + if (!TARGET_64BIT) + { + rtx v = gen_reg_rtx (mode); + + if (riscv_vector::simm32_p (operands[4])) + operands[4] = gen_rtx_SIGN_EXTEND (mode, + force_reg (Pmode, operands[4])); + else + { + if (CONST_INT_P (operands[4])) + operands[4] = force_reg (mode, operands[4]); + + riscv_vector::emit_nonvlmax_op (code_for_pred_broadcast (mode), + v, operands[4], operands[5], mode); + emit_insn (gen_pred_mulh (operands[0], operands[1], + operands[2], operands[3], v, operands[5], + operands[6], operands[7], operands[8])); + DONE; + } + } + else + operands[4] = force_reg (mode, operands[4]); + }) + +(define_insn "*pred_mulh_scalar" + [(set (match_operand:VFULLI_D 0 "register_operand" "=vd, vr") + (if_then_else:VFULLI_D + (unspec: + [(match_operand: 1 "vector_mask_operand" " vm,Wc1") + (match_operand 5 "vector_length_operand" " rK, rK") + (match_operand 6 "const_int_operand" " i, i") + (match_operand 7 "const_int_operand" " i, i") + (match_operand 8 "const_int_operand" " i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (unspec:VFULLI_D + [(vec_duplicate:VFULLI_D + (match_operand: 4 "register_operand" " r, r")) + (match_operand:VFULLI_D 3 "register_operand" " vr, vr")] VMULH) + (match_operand:VFULLI_D 2 "vector_merge_operand" "0vu,0vu")))] + "TARGET_VECTOR" + "vmulh.vx\t%0,%3,%4%p1" + [(set_attr "type" "vimul") + (set_attr "mode" "")]) + +(define_insn "*pred_mulh_extended_scalar" + [(set (match_operand:VFULLI_D 0 "register_operand" "=vd, vr") + (if_then_else:VFULLI_D + (unspec: + [(match_operand: 1 "vector_mask_operand" " vm,Wc1") + (match_operand 5 "vector_length_operand" " rK, rK") + (match_operand 6 "const_int_operand" " i, i") + (match_operand 7 "const_int_operand" " i, i") + (match_operand 8 "const_int_operand" " i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (unspec:VFULLI_D + [(vec_duplicate:VFULLI_D + (sign_extend: + (match_operand: 4 "register_operand" " r, r"))) + (match_operand:VFULLI_D 3 "register_operand" " vr, vr")] VMULH) + (match_operand:VFULLI_D 2 "vector_merge_operand" "0vu,0vu")))] + "TARGET_VECTOR" + "vmulh.vx\t%0,%3,%4%p1" + [(set_attr "type" "vimul") + (set_attr "mode" "")]) + ;; ------------------------------------------------------------------------------- ;; ---- Predicated integer unary operations ;; -------------------------------------------------------------------------------