From patchwork Mon Feb 6 05:06:56 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: 1738003 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4P9Dlq0QkBz23j7 for ; Mon, 6 Feb 2023 16:07:33 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B4C41385703F for ; Mon, 6 Feb 2023 05:07:24 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from smtpbgbr2.qq.com (smtpbgbr2.qq.com [54.207.22.56]) by sourceware.org (Postfix) with ESMTPS id 04DDF3858D1E for ; Mon, 6 Feb 2023 05:07:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 04DDF3858D1E 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: bizesmtp79t1675660019t61f0h8u Received: from server1.localdomain ( [58.60.1.22]) by bizesmtp.qq.com (ESMTP) with id ; Mon, 06 Feb 2023 13:06:58 +0800 (CST) X-QQ-SSF: 01400000000000E0L000000A0000000 X-QQ-FEAT: BJh8VuJn7fIgpiRx7tfhVIei8DMeP0nvajjGlYBw8UUDcZsEffHPipLGQ3dGu dszF06MNzh1jX1v/ltclc+hEh/oTc6ushpgPK9CeyO4dwQ+8MYWhtsRM/9LWTcDC0O5TIrr 8HD8kKBudW3aUDlJblal2+7iEu1/si0vIOCXrUZmRe6c7ONbIEIH1orEgkcW9jBOCj/zMPs rkHYfpM5QxakcfkqeXAiXZfS07jgH/7nJRslWfUjZ0LWMroTBe1qcCT4Iu3/Lojr01CcIfI Ylbhepj+r+euk7GkOa1fbQT2o30RxKitgNe2uvqy2V+aTGm2SdgE5/9S23bu40fwCeu5QB9 ZaffzXF8lil5j1KJY9QaLrWcTxMSD10hLu6tvBMUi1lduCp7UDje1voKvz4fyjz0+s+Zob7 X-QQ-GoodBg: 2 From: juzhe.zhong@rivai.ai To: gcc-patches@gcc.gnu.org Cc: kito.cheng@gmail.com, Ju-Zhe Zhong Subject: [PATCH] RISC-V: Add vsext/vzext C/C++ intrinsic support Date: Mon, 6 Feb 2023 13:06:56 +0800 Message-Id: <20230206050656.211738-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, SPF_HELO_PASS, SPF_PASS, TXREP 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+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" From: Ju-Zhe Zhong gcc/ChangeLog: * config/riscv/iterators.md: Add sign_extend/zero_extend. * config/riscv/riscv-vector-builtins-bases.cc (class ext): New class. (BASE): Ditto. * config/riscv/riscv-vector-builtins-bases.h: Add vsext/vzext support. * config/riscv/riscv-vector-builtins-functions.def (vsext): New macro define. (vzext): Ditto. * config/riscv/riscv-vector-builtins-shapes.cc (struct alu_def): Adjust for vsext/vzext support. * config/riscv/riscv-vector-builtins-types.def (DEF_RVV_WEXTI_OPS): New macro define. (DEF_RVV_QEXTI_OPS): Ditto. (DEF_RVV_OEXTI_OPS): Ditto. (DEF_RVV_WEXTU_OPS): Ditto. (DEF_RVV_QEXTU_OPS): Ditto. (DEF_RVV_OEXTU_OPS): 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. (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_WEXTI_OPS): Ditto. (DEF_RVV_QEXTI_OPS): Ditto. (DEF_RVV_OEXTI_OPS): Ditto. (DEF_RVV_WEXTU_OPS): Ditto. (DEF_RVV_QEXTU_OPS): Ditto. (DEF_RVV_OEXTU_OPS): Ditto. (rvv_arg_type_info::get_base_vector_type): Add sign_exted/zero_extend support. (rvv_arg_type_info::get_tree_type): Ditto. * config/riscv/riscv-vector-builtins.h (enum rvv_base_type): Ditto. * config/riscv/vector-iterators.md (z): New attribute. * config/riscv/vector.md (@pred__vf2): New pattern. (@pred__vf4): Ditto. (@pred__vf8): Ditto. --- gcc/config/riscv/iterators.md | 4 +- .../riscv/riscv-vector-builtins-bases.cc | 25 ++++ .../riscv/riscv-vector-builtins-bases.h | 2 + .../riscv/riscv-vector-builtins-functions.def | 6 + .../riscv/riscv-vector-builtins-shapes.cc | 21 ++- .../riscv/riscv-vector-builtins-types.def | 104 ++++++++++++++ gcc/config/riscv/riscv-vector-builtins.cc | 131 +++++++++++++++++- gcc/config/riscv/riscv-vector-builtins.h | 3 + gcc/config/riscv/vector-iterators.md | 39 ++++++ gcc/config/riscv/vector.md | 80 ++++++++++- 10 files changed, 401 insertions(+), 14 deletions(-) diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md index 7e5415cc80b..f95dd405e12 100644 --- a/gcc/config/riscv/iterators.md +++ b/gcc/config/riscv/iterators.md @@ -207,7 +207,9 @@ (ss_plus "ssadd") (us_plus "usadd") (ss_minus "sssub") - (us_minus "ussub")]) + (us_minus "ussub") + (sign_extend "extend") + (zero_extend "zero_extend")]) ;; code attributes (define_code_attr or_optab [(ior "ior") diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc index 7e6ee1d7b53..1a9469a370a 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc @@ -197,6 +197,27 @@ public: } }; +/* Implements vsext.vf2/vsext.vf4/vsext.vf8/vzext.vf2/vzext.vf4/vzext.vf8. */ +template +class ext : public function_base +{ +public: + rtx expand (function_expander &e) const override + { + switch (e.op_info->op) + { + case OP_TYPE_vf2: + return e.use_exact_insn (code_for_pred_vf2 (CODE, e.vector_mode ())); + case OP_TYPE_vf4: + return e.use_exact_insn (code_for_pred_vf4 (CODE, e.vector_mode ())); + case OP_TYPE_vf8: + return e.use_exact_insn (code_for_pred_vf8 (CODE, e.vector_mode ())); + default: + gcc_unreachable (); + } + } +}; + static CONSTEXPR const vsetvl vsetvl_obj; static CONSTEXPR const vsetvl vsetvlmax_obj; static CONSTEXPR const loadstore vle_obj; @@ -241,6 +262,8 @@ static CONSTEXPR const binop vdivu_obj; static CONSTEXPR const binop vremu_obj; static CONSTEXPR const unop vneg_obj; static CONSTEXPR const unop vnot_obj; +static CONSTEXPR const ext vsext_obj; +static CONSTEXPR const ext vzext_obj; static CONSTEXPR const binop vsadd_obj; static CONSTEXPR const binop vssub_obj; static CONSTEXPR const binop vsaddu_obj; @@ -295,6 +318,8 @@ BASE (vdivu) BASE (vremu) BASE (vneg) BASE (vnot) +BASE (vsext) +BASE (vzext) BASE (vsadd) BASE (vssub) BASE (vsaddu) diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.h b/gcc/config/riscv/riscv-vector-builtins-bases.h index a59fd918af8..71629f36738 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.h +++ b/gcc/config/riscv/riscv-vector-builtins-bases.h @@ -68,6 +68,8 @@ extern const function_base *const vdivu; extern const function_base *const vremu; extern const function_base *const vneg; extern const function_base *const vnot; +extern const function_base *const vsext; +extern const function_base *const vzext; extern const function_base *const vsadd; extern const function_base *const vssub; extern const function_base *const vsaddu; diff --git a/gcc/config/riscv/riscv-vector-builtins-functions.def b/gcc/config/riscv/riscv-vector-builtins-functions.def index 74a1864b725..42514ed5a37 100644 --- a/gcc/config/riscv/riscv-vector-builtins-functions.def +++ b/gcc/config/riscv/riscv-vector-builtins-functions.def @@ -100,6 +100,12 @@ DEF_RVV_FUNCTION (vdivu, alu, full_preds, u_vvx_ops) DEF_RVV_FUNCTION (vremu, alu, full_preds, u_vvx_ops) DEF_RVV_FUNCTION (vneg, alu, full_preds, iu_v_ops) DEF_RVV_FUNCTION (vnot, alu, full_preds, iu_v_ops) +DEF_RVV_FUNCTION (vsext, alu, full_preds, i_vf2_ops) +DEF_RVV_FUNCTION (vsext, alu, full_preds, i_vf4_ops) +DEF_RVV_FUNCTION (vsext, alu, full_preds, i_vf8_ops) +DEF_RVV_FUNCTION (vzext, alu, full_preds, u_vf2_ops) +DEF_RVV_FUNCTION (vzext, alu, full_preds, u_vf4_ops) +DEF_RVV_FUNCTION (vzext, alu, full_preds, u_vf8_ops) /* 12. Vector Fixed-Point Arithmetic Instructions. */ DEF_RVV_FUNCTION (vsadd, alu, full_preds, i_vvv_ops) DEF_RVV_FUNCTION (vssub, alu, full_preds, i_vvv_ops) diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc b/gcc/config/riscv/riscv-vector-builtins-shapes.cc index d6dc4c7049e..e772a7ca475 100644 --- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc @@ -192,14 +192,23 @@ struct alu_def : public build_base bool overloaded_p) const override { b.append_base_name (instance.base_name); - /* vop_v --> vop_v_. */ - if (!overloaded_p) + + /* vop --> vop_. According to rvv-intrinsic-doc, _vv/_vx/_v + API doesn't have OP suffix in overloaded function name, otherwise, we + always append OP suffix in function name. For example, vsext_vf2. */ + if (instance.op_info->op == OP_TYPE_vv || instance.op_info->op == OP_TYPE_vx + || instance.op_info->op == OP_TYPE_v) { - /* vop --> vop_v. */ - b.append_name (operand_suffixes[instance.op_info->op]); - /* vop_v --> vop_v_. */ - b.append_name (type_suffixes[instance.type.index].vector); + if (!overloaded_p) + b.append_name (operand_suffixes[instance.op_info->op]); } + else + b.append_name (operand_suffixes[instance.op_info->op]); + + /* vop_ --> vop__. */ + if (!overloaded_p) + b.append_name (type_suffixes[instance.type.index].vector); + /* According to rvv-intrinsic-doc, it does not add "_m" suffix for vop_m C++ overloaded API. */ if (overloaded_p && instance.pred == PRED_TYPE_m) diff --git a/gcc/config/riscv/riscv-vector-builtins-types.def b/gcc/config/riscv/riscv-vector-builtins-types.def index a95fad031be..d3129b9f753 100644 --- a/gcc/config/riscv/riscv-vector-builtins-types.def +++ b/gcc/config/riscv/riscv-vector-builtins-types.def @@ -42,6 +42,42 @@ along with GCC; see the file COPYING3. If not see #define DEF_RVV_B_OPS(TYPE, REQUIRE) #endif +/* Use "DEF_RVV_WEXTI_OPS" macro include Double-Widening signed integer which + will be iterated and registered as intrinsic functions. */ +#ifndef DEF_RVV_WEXTI_OPS +#define DEF_RVV_WEXTI_OPS(TYPE, REQUIRE) +#endif + +/* Use "DEF_RVV_QEXTI_OPS" macro include Quad-Widening signed integer which will + be iterated and registered as intrinsic functions. */ +#ifndef DEF_RVV_QEXTI_OPS +#define DEF_RVV_QEXTI_OPS(TYPE, REQUIRE) +#endif + +/* Use "DEF_RVV_OEXTI_OPS" macro include Oct-Widening signed integer which will + be iterated and registered as intrinsic functions. */ +#ifndef DEF_RVV_OEXTI_OPS +#define DEF_RVV_OEXTI_OPS(TYPE, REQUIRE) +#endif + +/* Use "DEF_RVV_WEXTU_OPS" macro include Double-Widening unsigned integer which + will be iterated and registered as intrinsic functions. */ +#ifndef DEF_RVV_WEXTU_OPS +#define DEF_RVV_WEXTU_OPS(TYPE, REQUIRE) +#endif + +/* Use "DEF_RVV_QEXTU_OPS" macro include Quad-Widening unsigned integer which + will be iterated and registered as intrinsic functions. */ +#ifndef DEF_RVV_QEXTU_OPS +#define DEF_RVV_QEXTU_OPS(TYPE, REQUIRE) +#endif + +/* Use "DEF_RVV_OEXTU_OPS" macro include Oct-Widening unsigned integer which + will be iterated and registered as intrinsic functions. */ +#ifndef DEF_RVV_OEXTU_OPS +#define DEF_RVV_OEXTU_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) @@ -106,7 +142,75 @@ DEF_RVV_B_OPS (vbool4_t, 0) DEF_RVV_B_OPS (vbool2_t, 0) DEF_RVV_B_OPS (vbool1_t, 0) +DEF_RVV_WEXTI_OPS (vint16mf4_t, RVV_REQUIRE_ZVE64) +DEF_RVV_WEXTI_OPS (vint16mf2_t, 0) +DEF_RVV_WEXTI_OPS (vint16m1_t, 0) +DEF_RVV_WEXTI_OPS (vint16m2_t, 0) +DEF_RVV_WEXTI_OPS (vint16m4_t, 0) +DEF_RVV_WEXTI_OPS (vint16m8_t, 0) +DEF_RVV_WEXTI_OPS (vint32mf2_t, RVV_REQUIRE_ZVE64) +DEF_RVV_WEXTI_OPS (vint32m1_t, 0) +DEF_RVV_WEXTI_OPS (vint32m2_t, 0) +DEF_RVV_WEXTI_OPS (vint32m4_t, 0) +DEF_RVV_WEXTI_OPS (vint32m8_t, 0) +DEF_RVV_WEXTI_OPS (vint64m1_t, RVV_REQUIRE_ZVE64) +DEF_RVV_WEXTI_OPS (vint64m2_t, RVV_REQUIRE_ZVE64) +DEF_RVV_WEXTI_OPS (vint64m4_t, RVV_REQUIRE_ZVE64) +DEF_RVV_WEXTI_OPS (vint64m8_t, RVV_REQUIRE_ZVE64) + +DEF_RVV_QEXTI_OPS (vint32mf2_t, RVV_REQUIRE_ZVE64) +DEF_RVV_QEXTI_OPS (vint32m1_t, 0) +DEF_RVV_QEXTI_OPS (vint32m2_t, 0) +DEF_RVV_QEXTI_OPS (vint32m4_t, 0) +DEF_RVV_QEXTI_OPS (vint32m8_t, 0) +DEF_RVV_QEXTI_OPS (vint64m1_t, RVV_REQUIRE_ZVE64) +DEF_RVV_QEXTI_OPS (vint64m2_t, RVV_REQUIRE_ZVE64) +DEF_RVV_QEXTI_OPS (vint64m4_t, RVV_REQUIRE_ZVE64) +DEF_RVV_QEXTI_OPS (vint64m8_t, RVV_REQUIRE_ZVE64) + +DEF_RVV_OEXTI_OPS (vint64m1_t, RVV_REQUIRE_ZVE64) +DEF_RVV_OEXTI_OPS (vint64m2_t, RVV_REQUIRE_ZVE64) +DEF_RVV_OEXTI_OPS (vint64m4_t, RVV_REQUIRE_ZVE64) +DEF_RVV_OEXTI_OPS (vint64m8_t, RVV_REQUIRE_ZVE64) + +DEF_RVV_WEXTU_OPS (vuint16mf4_t, RVV_REQUIRE_ZVE64) +DEF_RVV_WEXTU_OPS (vuint16mf2_t, 0) +DEF_RVV_WEXTU_OPS (vuint16m1_t, 0) +DEF_RVV_WEXTU_OPS (vuint16m2_t, 0) +DEF_RVV_WEXTU_OPS (vuint16m4_t, 0) +DEF_RVV_WEXTU_OPS (vuint16m8_t, 0) +DEF_RVV_WEXTU_OPS (vuint32mf2_t, RVV_REQUIRE_ZVE64) +DEF_RVV_WEXTU_OPS (vuint32m1_t, 0) +DEF_RVV_WEXTU_OPS (vuint32m2_t, 0) +DEF_RVV_WEXTU_OPS (vuint32m4_t, 0) +DEF_RVV_WEXTU_OPS (vuint32m8_t, 0) +DEF_RVV_WEXTU_OPS (vuint64m1_t, RVV_REQUIRE_ZVE64) +DEF_RVV_WEXTU_OPS (vuint64m2_t, RVV_REQUIRE_ZVE64) +DEF_RVV_WEXTU_OPS (vuint64m4_t, RVV_REQUIRE_ZVE64) +DEF_RVV_WEXTU_OPS (vuint64m8_t, RVV_REQUIRE_ZVE64) + +DEF_RVV_QEXTU_OPS (vuint32mf2_t, RVV_REQUIRE_ZVE64) +DEF_RVV_QEXTU_OPS (vuint32m1_t, 0) +DEF_RVV_QEXTU_OPS (vuint32m2_t, 0) +DEF_RVV_QEXTU_OPS (vuint32m4_t, 0) +DEF_RVV_QEXTU_OPS (vuint32m8_t, 0) +DEF_RVV_QEXTU_OPS (vuint64m1_t, RVV_REQUIRE_ZVE64) +DEF_RVV_QEXTU_OPS (vuint64m2_t, RVV_REQUIRE_ZVE64) +DEF_RVV_QEXTU_OPS (vuint64m4_t, RVV_REQUIRE_ZVE64) +DEF_RVV_QEXTU_OPS (vuint64m8_t, RVV_REQUIRE_ZVE64) + +DEF_RVV_OEXTU_OPS (vuint64m1_t, RVV_REQUIRE_ZVE64) +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) + #undef DEF_RVV_I_OPS #undef DEF_RVV_U_OPS #undef DEF_RVV_F_OPS #undef DEF_RVV_B_OPS +#undef DEF_RVV_WEXTI_OPS +#undef DEF_RVV_QEXTI_OPS +#undef DEF_RVV_OEXTI_OPS +#undef DEF_RVV_WEXTU_OPS +#undef DEF_RVV_QEXTU_OPS +#undef DEF_RVV_OEXTU_OPS diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc index 95a949aab7c..85adcf328ce 100644 --- a/gcc/config/riscv/riscv-vector-builtins.cc +++ b/gcc/config/riscv/riscv-vector-builtins.cc @@ -160,6 +160,48 @@ static const rvv_type_info b_ops[] = { #include "riscv-vector-builtins-types.def" {NUM_VECTOR_TYPES, 0}}; +/* A list of Double-Widening signed integer will be registered for intrinsic + * functions. */ +static const rvv_type_info wexti_ops[] = { +#define DEF_RVV_WEXTI_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE}, +#include "riscv-vector-builtins-types.def" + {NUM_VECTOR_TYPES, 0}}; + +/* A list of Quad-Widening signed integer will be registered for intrinsic + * functions. */ +static const rvv_type_info qexti_ops[] = { +#define DEF_RVV_QEXTI_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE}, +#include "riscv-vector-builtins-types.def" + {NUM_VECTOR_TYPES, 0}}; + +/* A list of Oct-Widening signed integer will be registered for intrinsic + * functions. */ +static const rvv_type_info oexti_ops[] = { +#define DEF_RVV_OEXTI_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE}, +#include "riscv-vector-builtins-types.def" + {NUM_VECTOR_TYPES, 0}}; + +/* A list of Double-Widening unsigned integer will be registered for intrinsic + * functions. */ +static const rvv_type_info wextu_ops[] = { +#define DEF_RVV_WEXTU_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE}, +#include "riscv-vector-builtins-types.def" + {NUM_VECTOR_TYPES, 0}}; + +/* A list of Quad-Widening unsigned integer will be registered for intrinsic + * functions. */ +static const rvv_type_info qextu_ops[] = { +#define DEF_RVV_QEXTU_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE}, +#include "riscv-vector-builtins-types.def" + {NUM_VECTOR_TYPES, 0}}; + +/* A list of Oct-Widening unsigned integer will be registered for intrinsic + * functions. */ +static const rvv_type_info oextu_ops[] = { +#define DEF_RVV_OEXTU_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE}, +#include "riscv-vector-builtins-types.def" + {NUM_VECTOR_TYPES, 0}}; + static CONSTEXPR const rvv_arg_type_info rvv_arg_type_info_end = rvv_arg_type_info (NUM_BASE_TYPES); @@ -269,6 +311,18 @@ static CONSTEXPR const rvv_arg_type_info vector_size_args[] = {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info_end}; +/* A list of args for vector_type func (double demote type) function. */ +static CONSTEXPR const rvv_arg_type_info vf2_args[] + = {rvv_arg_type_info (RVV_BASE_double_trunc_vector), rvv_arg_type_info_end}; + +/* A list of args for vector_type func (quad demote type) function. */ +static CONSTEXPR const rvv_arg_type_info vf4_args[] + = {rvv_arg_type_info (RVV_BASE_quad_trunc_vector), rvv_arg_type_info_end}; + +/* A list of args for vector_type func (oct demote type) function. */ +static CONSTEXPR const rvv_arg_type_info vf8_args[] + = {rvv_arg_type_info (RVV_BASE_oct_trunc_vector), rvv_arg_type_info_end}; + /* A list of none preds that will be registered for intrinsic functions. */ static CONSTEXPR const predication_type_index none_preds[] = {PRED_TYPE_none, NUM_PRED_TYPES}; @@ -481,6 +535,54 @@ static CONSTEXPR const rvv_op_info iu_v_ops rvv_arg_type_info (RVV_BASE_vector), /* Return type */ v_args /* Args */}; +/* A static operand information for vector_type func (double demote type) + * function registration. */ +static CONSTEXPR const rvv_op_info i_vf2_ops + = {wexti_ops, /* Types */ + OP_TYPE_vf2, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + vf2_args /* Args */}; + +/* A static operand information for vector_type func (quad demote type) + * function registration. */ +static CONSTEXPR const rvv_op_info i_vf4_ops + = {qexti_ops, /* Types */ + OP_TYPE_vf4, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + vf4_args /* Args */}; + +/* A static operand information for vector_type func (oct demote type) + * function registration. */ +static CONSTEXPR const rvv_op_info i_vf8_ops + = {oexti_ops, /* Types */ + OP_TYPE_vf8, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + vf8_args /* Args */}; + +/* A static operand information for vector_type func (double demote type) + * function registration. */ +static CONSTEXPR const rvv_op_info u_vf2_ops + = {wextu_ops, /* Types */ + OP_TYPE_vf2, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + vf2_args /* Args */}; + +/* A static operand information for vector_type func (quad demote type) + * function registration. */ +static CONSTEXPR const rvv_op_info u_vf4_ops + = {qextu_ops, /* Types */ + OP_TYPE_vf4, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + vf4_args /* Args */}; + +/* A static operand information for vector_type func (oct demote type) + * function registration. */ +static CONSTEXPR const rvv_op_info u_vf8_ops + = {oextu_ops, /* Types */ + OP_TYPE_vf8, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + vf8_args /* Args */}; + /* A list of all RVV intrinsic functions. */ static function_group_info function_groups[] = { #define DEF_RVV_FUNCTION(NAME, SHAPE, PREDS, OPS_INFO) \ @@ -763,7 +865,7 @@ rvv_arg_type_info::get_base_vector_type (tree type) const if (!type) return NUM_VECTOR_TYPES; poly_int64 nunits = GET_MODE_NUNITS (TYPE_MODE (type)); - machine_mode inner_mode; + machine_mode inner_mode = GET_MODE_INNER (TYPE_MODE (type)); bool unsigned_p = TYPE_UNSIGNED (type); switch (base_type) { @@ -787,6 +889,30 @@ rvv_arg_type_info::get_base_vector_type (tree type) const inner_mode = GET_MODE_INNER (TYPE_MODE (type)); unsigned_p = true; break; + case RVV_BASE_double_trunc_vector: + if (inner_mode == DImode) + inner_mode = SImode; + else if (inner_mode == SImode) + inner_mode = HImode; + else if (inner_mode == HImode) + inner_mode = QImode; + else + gcc_unreachable (); + break; + case RVV_BASE_quad_trunc_vector: + if (inner_mode == DImode) + inner_mode = HImode; + else if (inner_mode == SImode) + inner_mode = QImode; + else + gcc_unreachable (); + break; + case RVV_BASE_oct_trunc_vector: + if (inner_mode == DImode) + inner_mode = QImode; + else + gcc_unreachable (); + break; default: return NUM_VECTOR_TYPES; } @@ -851,6 +977,9 @@ rvv_arg_type_info::get_tree_type (vector_type_index type_idx) const case RVV_BASE_uint32_index: case RVV_BASE_uint64_index: case RVV_BASE_shift_vector: + case RVV_BASE_double_trunc_vector: + case RVV_BASE_quad_trunc_vector: + case RVV_BASE_oct_trunc_vector: if (get_base_vector_type (builtin_types[type_idx].vector) != NUM_VECTOR_TYPES) return builtin_types[get_base_vector_type ( diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h index c20d8f8835c..f14b6a55ec2 100644 --- a/gcc/config/riscv/riscv-vector-builtins.h +++ b/gcc/config/riscv/riscv-vector-builtins.h @@ -152,6 +152,9 @@ enum rvv_base_type RVV_BASE_uint32_index, RVV_BASE_uint64_index, RVV_BASE_shift_vector, + RVV_BASE_double_trunc_vector, + RVV_BASE_quad_trunc_vector, + RVV_BASE_oct_trunc_vector, NUM_BASE_TYPES }; diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index 2460ed670c0..6528e5711a4 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -164,6 +164,24 @@ (VNx64BI "TARGET_MIN_VLEN > 32") ]) +(define_mode_iterator VWEXTI [ + VNx1HI VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN > 32") + VNx1SI VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32") + (VNx1DI "TARGET_MIN_VLEN > 32") (VNx2DI "TARGET_MIN_VLEN > 32") + (VNx4DI "TARGET_MIN_VLEN > 32") (VNx8DI "TARGET_MIN_VLEN > 32") +]) + +(define_mode_iterator VQEXTI [ + VNx1SI VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32") + (VNx1DI "TARGET_MIN_VLEN > 32") (VNx2DI "TARGET_MIN_VLEN > 32") + (VNx4DI "TARGET_MIN_VLEN > 32") (VNx8DI "TARGET_MIN_VLEN > 32") +]) + +(define_mode_iterator VOEXTI [ + (VNx1DI "TARGET_MIN_VLEN > 32") (VNx2DI "TARGET_MIN_VLEN > 32") + (VNx4DI "TARGET_MIN_VLEN > 32") (VNx8DI "TARGET_MIN_VLEN > 32") +]) + (define_mode_attr VM [ (VNx1QI "VNx1BI") (VNx2QI "VNx2BI") (VNx4QI "VNx4BI") (VNx8QI "VNx8BI") (VNx16QI "VNx16BI") (VNx32QI "VNx32BI") (VNx64QI "VNx64BI") (VNx1HI "VNx1BI") (VNx2HI "VNx2BI") (VNx4HI "VNx4BI") (VNx8HI "VNx8BI") (VNx16HI "VNx16BI") (VNx32HI "VNx32BI") @@ -199,6 +217,25 @@ (VNx1DF "64") (VNx2DF "64") (VNx4DF "64") (VNx8DF "64") ]) +(define_mode_attr V_DOUBLE_TRUNC [ + (VNx1HI "VNx1QI") (VNx2HI "VNx2QI") (VNx4HI "VNx4QI") (VNx8HI "VNx8QI") + (VNx16HI "VNx16QI") (VNx32HI "VNx32QI") + (VNx1SI "VNx1HI") (VNx2SI "VNx2HI") (VNx4SI "VNx4HI") (VNx8SI "VNx8HI") + (VNx16SI "VNx16HI") + (VNx1DI "VNx1SI") (VNx2DI "VNx2SI") (VNx4DI "VNx4SI") (VNx8DI "VNx8SI") +]) + +(define_mode_attr V_QUAD_TRUNC [ + (VNx1SI "VNx1QI") (VNx2SI "VNx2QI") (VNx4SI "VNx4QI") (VNx8SI "VNx8QI") + (VNx16SI "VNx16QI") + (VNx1DI "VNx1HI") (VNx2DI "VNx2HI") + (VNx4DI "VNx4HI") (VNx8DI "VNx8HI") +]) + +(define_mode_attr V_OCT_TRUNC [ + (VNx1DI "VNx1QI") (VNx2DI "VNx2QI") (VNx4DI "VNx4QI") (VNx8DI "VNx8QI") +]) + (define_int_iterator ORDER [UNSPEC_ORDERED UNSPEC_UNORDERED]) (define_int_attr order [ @@ -415,3 +452,5 @@ (umin "%3,%4") (umax "%3,%4") (mult "%3,%4")]) + +(define_code_attr sz [(sign_extend "s") (zero_extend "z")]) diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index 44584e17105..8bafbdc8704 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -142,7 +142,7 @@ ;; It is valid for instruction that require sew/lmul ratio. (define_attr "ratio" "" (cond [(eq_attr "type" "vimov,vfmov,vldux,vldox,vstux,vstox,\ - vialu,vshift,vicmp,vimul,vidiv,vsalu") + vialu,vshift,vicmp,vimul,vidiv,vsalu,vext") (const_int INVALID_ATTRIBUTE) (eq_attr "mode" "VNx1QI,VNx1BI") (symbol_ref "riscv_vector::get_ratio(E_VNx1QImode)") @@ -193,13 +193,14 @@ ;; The index of operand[] to get the merge op. (define_attr "merge_op_idx" "" (cond [(eq_attr "type" "vlde,vimov,vfmov,vldm,vlds,vmalu,vldux,vldox,\ - vialu,vshift,vicmp,vimul,vidiv,vsalu") + vialu,vshift,vicmp,vimul,vidiv,vsalu,vext") (const_int 2)] (const_int INVALID_ATTRIBUTE))) ;; The index of operand[] to get the avl op. (define_attr "vl_op_idx" "" - (cond [(eq_attr "type" "vlde,vste,vimov,vfmov,vldm,vstm,vmalu,vsts,vstux,vstox") + (cond [(eq_attr "type" "vlde,vste,vimov,vfmov,vldm,vstm,vmalu,vsts,vstux,\ + vstox,vext") (const_int 4) ;; If operands[3] of "vlds" is not vector mode, it is pred_broadcast. @@ -215,7 +216,7 @@ ;; The tail policy op value. (define_attr "ta" "" - (cond [(eq_attr "type" "vlde,vimov,vfmov") + (cond [(eq_attr "type" "vlde,vimov,vfmov,vext") (symbol_ref "riscv_vector::get_ta(operands[5])") ;; If operands[3] of "vlds" is not vector mode, it is pred_broadcast. @@ -231,7 +232,7 @@ ;; The mask policy op value. (define_attr "ma" "" - (cond [(eq_attr "type" "vlde") + (cond [(eq_attr "type" "vlde,vext") (symbol_ref "riscv_vector::get_ma(operands[6])") ;; If operands[3] of "vlds" is not vector mode, it is pred_broadcast. @@ -247,7 +248,7 @@ ;; The avl type value. (define_attr "avl_type" "" - (cond [(eq_attr "type" "vlde,vlde,vste,vimov,vimov,vimov,vfmov") + (cond [(eq_attr "type" "vlde,vlde,vste,vimov,vimov,vimov,vfmov,vext") (symbol_ref "INTVAL (operands[7])") (eq_attr "type" "vldm,vstm,vimov,vmalu,vmalu") (symbol_ref "INTVAL (operands[5])") @@ -1803,3 +1804,70 @@ (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[5])")) (set (attr "ma") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))]) + +;; ------------------------------------------------------------------------------- +;; ---- Predicated integer widening operations +;; ------------------------------------------------------------------------------- +;; Includes: +;; - 11.3 Vector Integer Extension +;; ------------------------------------------------------------------------------- + +;; Vector Double-Widening Sign-extend and Zero-extend. +(define_insn "@pred__vf2" + [(set (match_operand:VWEXTI 0 "register_operand" "=&vr") + (if_then_else:VWEXTI + (unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1") + (match_operand 4 "vector_length_operand" " rK") + (match_operand 5 "const_int_operand" " i") + (match_operand 6 "const_int_operand" " i") + (match_operand 7 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (any_extend:VWEXTI + (match_operand: 3 "register_operand" " vr")) + (match_operand:VWEXTI 2 "vector_merge_operand" " 0vu")))] + "TARGET_VECTOR" + "vext.vf2\t%0,%3%p1" + [(set_attr "type" "vext") + (set_attr "mode" "")]) + +;; Vector Quad-Widening Sign-extend and Zero-extend. +(define_insn "@pred__vf4" + [(set (match_operand:VQEXTI 0 "register_operand" "=&vr") + (if_then_else:VQEXTI + (unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1") + (match_operand 4 "vector_length_operand" " rK") + (match_operand 5 "const_int_operand" " i") + (match_operand 6 "const_int_operand" " i") + (match_operand 7 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (any_extend:VQEXTI + (match_operand: 3 "register_operand" " vr")) + (match_operand:VQEXTI 2 "vector_merge_operand" " 0vu")))] + "TARGET_VECTOR" + "vext.vf4\t%0,%3%p1" + [(set_attr "type" "vext") + (set_attr "mode" "")]) + +;; Vector Oct-Widening Sign-extend and Zero-extend. +(define_insn "@pred__vf8" + [(set (match_operand:VOEXTI 0 "register_operand" "=&vr") + (if_then_else:VOEXTI + (unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1") + (match_operand 4 "vector_length_operand" " rK") + (match_operand 5 "const_int_operand" " i") + (match_operand 6 "const_int_operand" " i") + (match_operand 7 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (any_extend:VOEXTI + (match_operand: 3 "register_operand" " vr")) + (match_operand:VOEXTI 2 "vector_merge_operand" " 0vu")))] + "TARGET_VECTOR" + "vext.vf8\t%0,%3%p1" + [(set_attr "type" "vext") + (set_attr "mode" "")])