From patchwork Thu Feb 9 21:45:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "juzhe.zhong@rivai.ai" X-Patchwork-Id: 55097 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp591441wrn; Thu, 9 Feb 2023 13:46:55 -0800 (PST) X-Google-Smtp-Source: AK7set84HMHKNIMucoFs1XO/48D3LDeuVERkPPu/I0jLy77RNBA75F9krr048viG0Ste5FJ8Mr6j X-Received: by 2002:a50:c34f:0:b0:4ab:421d:e434 with SMTP id q15-20020a50c34f000000b004ab421de434mr720793edb.25.1675979215678; Thu, 09 Feb 2023 13:46:55 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675979215; cv=none; d=google.com; s=arc-20160816; b=MVoQxDoBzMOzb21dPdN7v8+cDOYl5IGFtVucGBY+bgzxTS+0vwrK5iaR+taM2gKxLI eHx/js3C0uGUZkVs6HEJ4NJnqqhdOOOG7jAVUrQqWFMFmFhLlG2WYmXI9ySwkGjE4QId jeC/QprGQUTjPVrM0DHsbZMjn5OFtGHG0v1U9rbiECBtjZeRtjOFUZ1MQQyd+9brf5Py 960xfrd1OvnecKLBiDPvtE1rxYXiikHCFPLh7y2SGhqVfcZDB3Tr3yhVaZq8JE1YHA4A uvFYqJVRenbtufNmkL/LhK9gaFir5km1D5+gGJfxJUrAn13I84JaN4xY21fLWh7wJ88k J7Uw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:feedback-id :content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:dmarc-filter:delivered-to; bh=vxF3Blj5qX/7qyTre0K/KGHniDdIGHHYkU5UVFCbMLQ=; b=wEmVwXQGbQSrVcQ1VuTfgeBGuNff3Syj7DeA8WGExsbw/JgZ9Pf57mZbZgNF7tDeuU 8aDZtECu9kam9tSu75gdXECn96kemdEaXPIzoey9KDgyzTWuRBoaSGN9gy2NbZvil1Q3 tDQeOkA4f0P7a0ZaNv66ZyW1I1/ZQvsCiSEH+OOL3LVN+zuH4otfLT7M8KuJz4OZS37Q NLG8AYll6Ze8TbZwJkzT4YDpScI6VxuDj1lB8B+MI1LPJj4gYmjSkScjuCVkYh8btvOM 7C4mTyjhp3GkDFyrg0j+LJbr9yq8JCs/V3Z8qTFOQkf/8YBftmfgnEh+AXgqRdIEcDZn 53xg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id l21-20020aa7c315000000b004ab250bceedsi1851766edq.655.2023.02.09.13.46.55 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Feb 2023 13:46:55 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3F1DE3843854 for ; Thu, 9 Feb 2023 21:46:25 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from smtpbg153.qq.com (smtpbg153.qq.com [13.245.218.24]) by sourceware.org (Postfix) with ESMTPS id 649733858C50 for ; Thu, 9 Feb 2023 21:45:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 649733858C50 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: bizesmtp81t1675979146t8aow4x6 Received: from rios-cad5.localdomain ( [58.60.1.11]) by bizesmtp.qq.com (ESMTP) with id ; Fri, 10 Feb 2023 05:45:45 +0800 (CST) X-QQ-SSF: 01400000009000E0L000B00A0000000 X-QQ-FEAT: +oIWmpEafD/xMgc3KlB1b+7Z2r2fc3egfTgqHeJzuOA4tGNePaSJc9XJbIOT2 ZEypdaAHwxC6U2t2l+heDUfl32NifP24VF3xFZm+lQI2xpFDuifoBsBcfhuKfbP1O2EV3yp Uf5X7KZLkXw3bm0TmfXBLPpI06pc+L5rT/yv1q4IT5KeXvdidvPctdohHS2mZ/PGVZMn1SC 0mfaS/peddMvqIfFluneRcjs6KYc49cF2Ib63spsBRWUWVULO/jFgJYHmABX9d67T1ZavqV aEfVwHBcEeXPtz3bGFiE5Wo73bgijohhu3+TPZErPytB0XyOuVb+oo6hvFOxiXovqQ0ETEu JCssWLmQoRJzIaCe5QpREYK0Dg/SSnE7yU7hIBL+mNTec3v5O4YbUBC9n03bQ== 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 vnsrl/vnsra/vncvt/vmerge/vmv C/C++ support Date: Fri, 10 Feb 2023 05:45:44 +0800 Message-Id: <20230209214544.20460-1-juzhe.zhong@rivai.ai> X-Mailer: git-send-email 2.36.3 MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:rivai.ai:qybglogicsvr:qybglogicsvr7 X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_ASCII_DIVIDERS, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, 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+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1757391581905250270?= X-GMAIL-MSGID: =?utf-8?q?1757391581905250270?= From: Ju-Zhe Zhong gcc/ChangeLog: * config/riscv/constraints.md (Wbr): Remove unused constraint. * config/riscv/predicates.md: Fix move operand predicate. * config/riscv/riscv-vector-builtins-bases.cc (class vnshift): New class. (class vncvt_x): Ditto. (class vmerge): Ditto. (class vmv_v): Ditto. (BASE): Ditto. * config/riscv/riscv-vector-builtins-bases.h: Ditto. * config/riscv/riscv-vector-builtins-functions.def (vsra): Ditto. (vsrl): Ditto. (vnsrl): Ditto. (vnsra): Ditto. (vncvt_x): Ditto. (vmerge): Ditto. (vmv_v): Ditto. * config/riscv/riscv-vector-builtins-shapes.cc (struct narrow_alu_def): Ditto. (struct move_def): Ditto. (SHAPE): Ditto. * config/riscv/riscv-vector-builtins-shapes.h: Ditto. * config/riscv/riscv-vector-builtins.cc (DEF_RVV_WEXTI_OPS): New variable. (DEF_RVV_WEXTU_OPS): Ditto * config/riscv/riscv-vector-builtins.def (x_x_w): Fix type for suffix. (v_v): Ditto. (v_x): Ditto. (x_w): Ditto. (x): Ditto. * config/riscv/riscv.cc (riscv_print_operand): Refine ASM printting rule. * config/riscv/vector-iterators.md (nmsac):New iterator. (nmsub): New iterator. * config/riscv/vector.md (@pred_merge): New pattern. (@pred_merge_scalar): New pattern. (*pred_merge_scalar): New pattern. (*pred_merge_extended_scalar): New pattern. (@pred_narrow_): New pattern. (@pred_narrow__scalar): New pattern. (@pred_trunc): New pattern. --- gcc/config/riscv/constraints.md | 13 - gcc/config/riscv/predicates.md | 7 +- .../riscv/riscv-vector-builtins-bases.cc | 78 ++++++ .../riscv/riscv-vector-builtins-bases.h | 5 + .../riscv/riscv-vector-builtins-functions.def | 17 +- .../riscv/riscv-vector-builtins-shapes.cc | 54 ++++ .../riscv/riscv-vector-builtins-shapes.h | 2 + gcc/config/riscv/riscv-vector-builtins.cc | 115 ++++++++ gcc/config/riscv/riscv-vector-builtins.def | 5 +- gcc/config/riscv/riscv.cc | 42 ++- gcc/config/riscv/vector-iterators.md | 3 + gcc/config/riscv/vector.md | 253 ++++++++++++++++-- 12 files changed, 537 insertions(+), 57 deletions(-) diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md index b646ad4853c..a051d466ae2 100644 --- a/gcc/config/riscv/constraints.md +++ b/gcc/config/riscv/constraints.md @@ -166,16 +166,3 @@ "Vector duplicate memory operand" (and (match_code "mem") (match_code "reg" "0"))) - -;; (vec_duplicate:V (const_int 2863311530 [0xaaaaaaaa])) of pred_broadcast -;; is CSEed into (const_vector:V (const_int 2863311530 [0xaaaaaaaa])) here -;; which is not the pattern matching we want since we can't generate -;; instruction directly for it when SEW = 64 and !TARGET_64BIT. We should -;; not allow RA (register allocation) allocate a DImode register in -;; pred_broadcast pattern. -(define_constraint "Wbr" - "@internal - Broadcast register operand" - (and (match_code "reg") - (match_test "REGNO (op) <= GP_REG_LAST - && direct_broadcast_operand (op, GET_MODE (op))"))) diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md index 8d2ccb0f7a2..fe2c5ba3c5c 100644 --- a/gcc/config/riscv/predicates.md +++ b/gcc/config/riscv/predicates.md @@ -288,10 +288,9 @@ (match_test "op == CONSTM1_RTX (GET_MODE (op))"))) (define_predicate "vector_merge_operand" - (ior (match_operand 0 "memory_operand") - (ior (match_operand 0 "register_operand") - (match_test "GET_CODE (op) == UNSPEC - && (XINT (op, 1) == UNSPEC_VUNDEF)")))) + (ior (match_operand 0 "register_operand") + (match_test "GET_CODE (op) == UNSPEC + && (XINT (op, 1) == UNSPEC_VUNDEF)"))) (define_predicate "vector_arith_operand" (ior (match_operand 0 "register_operand") diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc index bcf2dfe805a..30f9734c36b 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc @@ -396,6 +396,74 @@ public: } }; +/* Implements vnsrl/vnsra. */ +template +class vnshift : public function_base +{ +public: + rtx expand (function_expander &e) const override + { + switch (e.op_info->op) + { + case OP_TYPE_wx: + return e.use_exact_insn ( + code_for_pred_narrow_scalar (CODE, e.vector_mode ())); + case OP_TYPE_wv: + return e.use_exact_insn (code_for_pred_narrow (CODE, e.vector_mode ())); + default: + gcc_unreachable (); + } + } +}; + +/* Implements vncvt. */ +class vncvt_x : public function_base +{ +public: + rtx expand (function_expander &e) const override + { + return e.use_exact_insn (code_for_pred_trunc (e.vector_mode ())); + } +}; + +/* Implements vmerge. */ +class vmerge : public function_base +{ +public: + bool apply_mask_policy_p () const override { return false; } + bool use_mask_predication_p () const override { return false; } + rtx expand (function_expander &e) const override + { + switch (e.op_info->op) + { + case OP_TYPE_vvm: + return e.use_exact_insn (code_for_pred_merge (e.vector_mode ())); + case OP_TYPE_vxm: + return e.use_exact_insn (code_for_pred_merge_scalar (e.vector_mode ())); + default: + gcc_unreachable (); + } + } +}; + +/* Implements vmv.v.x/vmv.v.v. */ +class vmv_v : public function_base +{ +public: + rtx expand (function_expander &e) const override + { + switch (e.op_info->op) + { + case OP_TYPE_v: + return e.use_exact_insn (code_for_pred_mov (e.vector_mode ())); + case OP_TYPE_x: + return e.use_exact_insn (code_for_pred_broadcast (e.vector_mode ())); + default: + gcc_unreachable (); + } + } +}; + static CONSTEXPR const vsetvl vsetvl_obj; static CONSTEXPR const vsetvl vsetvlmax_obj; static CONSTEXPR const loadstore vle_obj; @@ -458,6 +526,11 @@ static CONSTEXPR const vadc vadc_obj; static CONSTEXPR const vsbc vsbc_obj; static CONSTEXPR const vmadc vmadc_obj; static CONSTEXPR const vmsbc vmsbc_obj; +static CONSTEXPR const vnshift vnsrl_obj; +static CONSTEXPR const vnshift vnsra_obj; +static CONSTEXPR const vncvt_x vncvt_x_obj; +static CONSTEXPR const vmerge vmerge_obj; +static CONSTEXPR const vmv_v vmv_v_obj; static CONSTEXPR const binop vsadd_obj; static CONSTEXPR const binop vssub_obj; static CONSTEXPR const binop vsaddu_obj; @@ -530,6 +603,11 @@ BASE (vadc) BASE (vsbc) BASE (vmadc) BASE (vmsbc) +BASE (vnsrl) +BASE (vnsra) +BASE (vncvt_x) +BASE (vmerge) +BASE (vmv_v) 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 6a8747b184e..411db5627ee 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.h +++ b/gcc/config/riscv/riscv-vector-builtins-bases.h @@ -86,6 +86,11 @@ extern const function_base *const vadc; extern const function_base *const vsbc; extern const function_base *const vmadc; extern const function_base *const vmsbc; +extern const function_base *const vnsrl; +extern const function_base *const vnsra; +extern const function_base *const vncvt_x; +extern const function_base *const vmerge; +extern const function_base *const vmv_v; 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 6d328537ab8..28483463d64 100644 --- a/gcc/config/riscv/riscv-vector-builtins-functions.def +++ b/gcc/config/riscv/riscv-vector-builtins-functions.def @@ -69,8 +69,8 @@ DEF_RVV_FUNCTION (vand, alu, full_preds, iu_vvv_ops) DEF_RVV_FUNCTION (vor, alu, full_preds, iu_vvv_ops) DEF_RVV_FUNCTION (vxor, alu, full_preds, iu_vvv_ops) DEF_RVV_FUNCTION (vsll, alu, full_preds, iu_shift_vvv_ops) -DEF_RVV_FUNCTION (vsra, alu, full_preds, iu_shift_vvv_ops) -DEF_RVV_FUNCTION (vsrl, alu, full_preds, iu_shift_vvv_ops) +DEF_RVV_FUNCTION (vsra, alu, full_preds, i_shift_vvv_ops) +DEF_RVV_FUNCTION (vsrl, alu, full_preds, u_shift_vvv_ops) DEF_RVV_FUNCTION (vmin, alu, full_preds, i_vvv_ops) DEF_RVV_FUNCTION (vmax, alu, full_preds, i_vvv_ops) DEF_RVV_FUNCTION (vminu, alu, full_preds, u_vvv_ops) @@ -90,8 +90,8 @@ DEF_RVV_FUNCTION (vand, alu, full_preds, iu_vvx_ops) DEF_RVV_FUNCTION (vor, alu, full_preds, iu_vvx_ops) DEF_RVV_FUNCTION (vxor, alu, full_preds, iu_vvx_ops) DEF_RVV_FUNCTION (vsll, alu, full_preds, iu_shift_vvx_ops) -DEF_RVV_FUNCTION (vsra, alu, full_preds, iu_shift_vvx_ops) -DEF_RVV_FUNCTION (vsrl, alu, full_preds, iu_shift_vvx_ops) +DEF_RVV_FUNCTION (vsra, alu, full_preds, i_shift_vvx_ops) +DEF_RVV_FUNCTION (vsrl, alu, full_preds, u_shift_vvx_ops) DEF_RVV_FUNCTION (vmin, alu, full_preds, i_vvx_ops) DEF_RVV_FUNCTION (vmax, alu, full_preds, i_vvx_ops) DEF_RVV_FUNCTION (vminu, alu, full_preds, u_vvx_ops) @@ -148,6 +148,15 @@ DEF_RVV_FUNCTION (vmadc, return_mask, none_preds, iu_mvv_ops) DEF_RVV_FUNCTION (vmsbc, return_mask, none_preds, iu_mvv_ops) DEF_RVV_FUNCTION (vmadc, return_mask, none_preds, iu_mvx_ops) DEF_RVV_FUNCTION (vmsbc, return_mask, none_preds, iu_mvx_ops) +DEF_RVV_FUNCTION (vnsrl, narrow_alu, full_preds, u_narrow_shift_vwv_ops) +DEF_RVV_FUNCTION (vnsra, narrow_alu, full_preds, i_narrow_shift_vwv_ops) +DEF_RVV_FUNCTION (vnsrl, narrow_alu, full_preds, u_narrow_shift_vwx_ops) +DEF_RVV_FUNCTION (vnsra, narrow_alu, full_preds, i_narrow_shift_vwx_ops) +DEF_RVV_FUNCTION (vncvt_x, narrow_alu, full_preds, iu_trunc_ops) +DEF_RVV_FUNCTION (vmerge, no_mask_policy, tu_preds, all_vvvm_ops) +DEF_RVV_FUNCTION (vmerge, no_mask_policy, tu_preds, iu_vvxm_ops) +DEF_RVV_FUNCTION (vmv_v, move, tu_preds, all_v_ops) +DEF_RVV_FUNCTION (vmv_v, move, tu_preds, iu_x_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 dae515cb5c3..e1d8f4f13f0 100644 --- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc @@ -293,6 +293,58 @@ struct return_mask_def : public build_base } }; +/* narrow_alu_def class. Handle narrowing instructions like vnsrl.wv. */ +struct narrow_alu_def : public build_base +{ + char *get_name (function_builder &b, const function_instance &instance, + bool overloaded_p) const override + { + b.append_base_name (instance.base_name); + + if (!overloaded_p) + { + /* vop --> vop_. */ + b.append_name (operand_suffixes[instance.op_info->op]); + /* vop_ --> vop__. */ + vector_type_index ret_type_idx + = instance.op_info->ret.get_base_vector_type ( + builtin_types[instance.type.index].vector); + b.append_name (type_suffixes[ret_type_idx].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) + return b.finish_name (); + b.append_name (predication_suffixes[instance.pred]); + return b.finish_name (); + } +}; + +/* move_def class. Handle vmv.v.v/vmv.v.x. */ +struct move_def : public build_base +{ + char *get_name (function_builder &b, const function_instance &instance, + bool overloaded_p) const override + { + /* vmv.v.x (PRED_none) can not be overloaded. */ + if (instance.op_info->op == OP_TYPE_x && overloaded_p + && instance.pred == PRED_TYPE_none) + return nullptr; + + b.append_base_name (instance.base_name); + + if (!overloaded_p) + { + b.append_name (operand_suffixes[instance.op_info->op]); + b.append_name (type_suffixes[instance.type.index].vector); + } + + b.append_name (predication_suffixes[instance.pred]); + return b.finish_name (); + } +}; + SHAPE(vsetvl, vsetvl) SHAPE(vsetvl, vsetvlmax) SHAPE(loadstore, loadstore) @@ -301,5 +353,7 @@ SHAPE(alu, alu) SHAPE(widen_alu, widen_alu) SHAPE(no_mask_policy, no_mask_policy) SHAPE(return_mask, return_mask) +SHAPE(narrow_alu, narrow_alu) +SHAPE(move, move) } // end namespace riscv_vector diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.h b/gcc/config/riscv/riscv-vector-builtins-shapes.h index 783b4712a45..91c174f56cd 100644 --- a/gcc/config/riscv/riscv-vector-builtins-shapes.h +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.h @@ -32,6 +32,8 @@ extern const function_shape *const alu; extern const function_shape *const widen_alu; extern const function_shape *const no_mask_policy; extern const function_shape *const return_mask; +extern const function_shape *const narrow_alu; +extern const function_shape *const move; } } // end namespace riscv_vector diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc index 00cb721d408..486b8b722b5 100644 --- a/gcc/config/riscv/riscv-vector-builtins.cc +++ b/gcc/config/riscv/riscv-vector-builtins.cc @@ -202,6 +202,14 @@ static const rvv_type_info wextu_ops[] = { #include "riscv-vector-builtins-types.def" {NUM_VECTOR_TYPES, 0}}; +/* A list of Double-Widening all integer will be registered for intrinsic + * functions. */ +static const rvv_type_info wextiu_ops[] = { +#define DEF_RVV_WEXTI_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE}, +#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[] = { @@ -340,10 +348,21 @@ static CONSTEXPR const rvv_arg_type_info shift_vv_args[] = {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info (RVV_BASE_shift_vector), rvv_arg_type_info_end}; +/* A list of args for double demote type func (vector_type, shift_type) + * function. */ +static CONSTEXPR const rvv_arg_type_info shift_wv_args[] + = {rvv_arg_type_info (RVV_BASE_vector), + rvv_arg_type_info (RVV_BASE_double_trunc_unsigned_vector), + rvv_arg_type_info_end}; + /* A list of args for vector_type func (vector_type) function. */ static CONSTEXPR const rvv_arg_type_info v_args[] = {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info_end}; +/* A list of args for vector_type func (scalar_type) function. */ +static CONSTEXPR const rvv_arg_type_info x_args[] + = {rvv_arg_type_info (RVV_BASE_scalar), rvv_arg_type_info_end}; + /* A list of args for vector_type func (vector_type, size) function. */ static CONSTEXPR const rvv_arg_type_info vector_size_args[] = {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info (RVV_BASE_size), @@ -562,6 +581,14 @@ static CONSTEXPR const rvv_op_info iu_vvvm_ops rvv_arg_type_info (RVV_BASE_vector), /* Return type */ vvm_args /* Args */}; +/* A static operand information for vector_type func (vector_type, vector_type, + * mask_type) function registration. */ +static CONSTEXPR const rvv_op_info all_vvvm_ops + = {all_ops, /* Types */ + OP_TYPE_vvm, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + vvm_args /* Args */}; + /* A static operand information for vector_type func (vector_type, scalar_type, * mask_type) function registration. */ static CONSTEXPR const rvv_op_info iu_vvxm_ops @@ -707,6 +734,38 @@ static CONSTEXPR const rvv_op_info iu_shift_vvx_ops rvv_arg_type_info (RVV_BASE_vector), /* Return type */ vector_size_args /* Args */}; +/* A static operand information for vector_type func (vector_type, shift_type) + * function registration. */ +static CONSTEXPR const rvv_op_info i_shift_vvv_ops + = {i_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + shift_vv_args /* Args */}; + +/* A static operand information for vector_type func (vector_type, size_t) + * function registration. */ +static CONSTEXPR const rvv_op_info i_shift_vvx_ops + = {i_ops, /* Types */ + OP_TYPE_vx, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + vector_size_args /* Args */}; + +/* A static operand information for vector_type func (vector_type, shift_type) + * function registration. */ +static CONSTEXPR const rvv_op_info u_shift_vvv_ops + = {u_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + shift_vv_args /* Args */}; + +/* A static operand information for vector_type func (vector_type, size_t) + * function registration. */ +static CONSTEXPR const rvv_op_info u_shift_vvx_ops + = {u_ops, /* Types */ + OP_TYPE_vx, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + vector_size_args /* Args */}; + /* A static operand information for vector_type func (vector_type) * function registration. */ static CONSTEXPR const rvv_op_info iu_v_ops @@ -715,6 +774,22 @@ 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 (vector_type) + * function registration. */ +static CONSTEXPR const rvv_op_info all_v_ops + = {all_ops, /* Types */ + OP_TYPE_v, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + v_args /* Args */}; + +/* A static operand information for vector_type func (scalar_type) + * function registration. */ +static CONSTEXPR const rvv_op_info iu_x_ops + = {iu_ops, /* Types */ + OP_TYPE_x, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + x_args /* Args */}; + /* A static operand information for vector_type func (double demote type) * function registration. */ static CONSTEXPR const rvv_op_info i_vf2_ops @@ -859,6 +934,46 @@ static CONSTEXPR const rvv_op_info u_x_x_v_ops rvv_arg_type_info (RVV_BASE_vector), /* Return type */ x_x_v_args /* Args */}; +/* A static operand information for double demote type func (vector_type, + * shift_type) function registration. */ +static CONSTEXPR const rvv_op_info i_narrow_shift_vwv_ops + = {wexti_ops, /* Types */ + OP_TYPE_wv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_double_trunc_vector), /* Return type */ + shift_wv_args /* Args */}; + +/* A static operand information for double demote type func (vector_type, + * shift_type) function registration. */ +static CONSTEXPR const rvv_op_info u_narrow_shift_vwv_ops + = {wextu_ops, /* Types */ + OP_TYPE_wv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_double_trunc_vector), /* Return type */ + shift_wv_args /* Args */}; + +/* A static operand information for double demote type func (vector_type, + * size_t) function registration. */ +static CONSTEXPR const rvv_op_info i_narrow_shift_vwx_ops + = {wexti_ops, /* Types */ + OP_TYPE_wx, /* Suffix */ + rvv_arg_type_info (RVV_BASE_double_trunc_vector), /* Return type */ + vector_size_args /* Args */}; + +/* A static operand information for double demote type func (vector_type, + * size_t) function registration. */ +static CONSTEXPR const rvv_op_info u_narrow_shift_vwx_ops + = {wextu_ops, /* Types */ + OP_TYPE_wx, /* Suffix */ + rvv_arg_type_info (RVV_BASE_double_trunc_vector), /* Return type */ + vector_size_args /* Args */}; + +/* A static operand information for double demote type func (vector_type) + * function registration. */ +static CONSTEXPR const rvv_op_info iu_trunc_ops + = {wextiu_ops, /* Types */ + OP_TYPE_x_w, /* Suffix */ + rvv_arg_type_info (RVV_BASE_double_trunc_vector), /* Return type */ + v_args /* Args */}; + /* A list of all RVV intrinsic functions. */ static function_group_info function_groups[] = { #define DEF_RVV_FUNCTION(NAME, SHAPE, PREDS, OPS_INFO) \ diff --git a/gcc/config/riscv/riscv-vector-builtins.def b/gcc/config/riscv/riscv-vector-builtins.def index 9f4cd011404..baafed8a4e9 100644 --- a/gcc/config/riscv/riscv-vector-builtins.def +++ b/gcc/config/riscv/riscv-vector-builtins.def @@ -279,9 +279,8 @@ DEF_RVV_OP_TYPE (vf4) DEF_RVV_OP_TYPE (vf8) DEF_RVV_OP_TYPE (vvm) DEF_RVV_OP_TYPE (vxm) -DEF_RVV_OP_TYPE (x_x_w) -DEF_RVV_OP_TYPE (v_v) -DEF_RVV_OP_TYPE (v_x) +DEF_RVV_OP_TYPE (x_w) +DEF_RVV_OP_TYPE (x) DEF_RVV_OP_TYPE (vs) DEF_RVV_OP_TYPE (mm) DEF_RVV_OP_TYPE (m) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 209d9a53e7b..88a73297ffa 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -4229,17 +4229,45 @@ riscv_print_operand (FILE *file, rtx op, int letter) switch (letter) { + case 'o': { + /* Print 'OP' variant for RVV instructions. + 1. If the operand is VECTOR REG, we print 'v'(vnsrl.wv). + 2. If the operand is CONST_INT/CONST_VECTOR, we print 'i'(vnsrl.wi). + 3. If the operand is SCALAR REG, we print 'x'(vnsrl.wx). */ + if (riscv_v_ext_vector_mode_p (mode)) + { + if (REG_P (op)) + asm_fprintf (file, "v"); + else if (CONST_VECTOR_P (op)) + asm_fprintf (file, "i"); + else + output_operand_lossage ("invalid vector operand"); + } + else + { + if (CONST_INT_P (op)) + asm_fprintf (file, "i"); + else + asm_fprintf (file, "x"); + } + break; + } case 'v': { rtx elt; - if (!const_vec_duplicate_p (op, &elt)) - output_operand_lossage ("invalid vector constant"); - else if (satisfies_constraint_Wc0 (op)) - asm_fprintf (file, "0"); - else if (satisfies_constraint_vi (op)) - asm_fprintf (file, "%wd", INTVAL (elt)); + if (REG_P (op)) + asm_fprintf (file, "%s", reg_names[REGNO (op)]); else - output_operand_lossage ("invalid vector constant"); + { + if (!const_vec_duplicate_p (op, &elt)) + output_operand_lossage ("invalid vector constant"); + else if (satisfies_constraint_Wc0 (op)) + asm_fprintf (file, "0"); + else if (satisfies_constraint_vi (op)) + asm_fprintf (file, "%wd", INTVAL (elt)); + else + output_operand_lossage ("invalid vector constant"); + } break; } case 'V': { diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index 6b255c4ddb3..e76ad21140b 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -289,6 +289,9 @@ (define_code_iterator any_widen_binop [plus minus mult]) (define_code_iterator plus_minus [plus minus]) +(define_code_attr macc_nmsac [(plus "macc") (minus "nmsac")]) +(define_code_attr madd_nmsub [(plus "madd") (minus "nmsub")]) + (define_code_attr binop_rhs1_predicate [ (plus "register_operand") (minus "vector_arith_operand") diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index b3d4eb79193..cad678369e0 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -144,7 +144,8 @@ (define_attr "ratio" "" (cond [(eq_attr "type" "vimov,vfmov,vldux,vldox,vstux,vstox,\ vialu,vshift,vicmp,vimul,vidiv,vsalu,\ - vext,viwalu,viwmul,vicalu") + vext,viwalu,viwmul,vicalu,vnshift,\ + vimuladd,vimerge") (const_int INVALID_ATTRIBUTE) (eq_attr "mode" "VNx1QI,VNx1BI") (symbol_ref "riscv_vector::get_ratio(E_VNx1QImode)") @@ -195,8 +196,12 @@ ;; 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,vext,viwalu,viwmul") - (const_int 2)] + vialu,vshift,vicmp,vimul,vidiv,vsalu,vext,viwalu,\ + viwmul,vnshift,vimuladd") + (const_int 2) + + (eq_attr "type" "vimerge") + (const_int 1)] (const_int INVALID_ATTRIBUTE))) ;; The index of operand[] to get the avl op. @@ -213,7 +218,7 @@ (const_int 4)) (eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu,\ - viwalu,viwmul") + viwalu,viwmul,vnshift,vimuladd,vimerge") (const_int 5)] (const_int INVALID_ATTRIBUTE))) @@ -230,7 +235,7 @@ (symbol_ref "riscv_vector::get_ta(operands[5])")) (eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu,\ - viwalu,viwmul") + viwalu,viwmul,vnshift,vimuladd,vimerge") (symbol_ref "riscv_vector::get_ta(operands[6])")] (const_int INVALID_ATTRIBUTE))) @@ -247,13 +252,13 @@ (symbol_ref "riscv_vector::get_ma(operands[6])")) (eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu,\ - viwalu,viwmul") + viwalu,viwmul,vnshift,vimuladd") (symbol_ref "riscv_vector::get_ma(operands[7])")] (const_int INVALID_ATTRIBUTE))) ;; The avl type value. (define_attr "avl_type" "" - (cond [(eq_attr "type" "vlde,vlde,vste,vimov,vimov,vimov,vfmov,vext") + (cond [(eq_attr "type" "vlde,vlde,vste,vimov,vimov,vimov,vfmov,vext,vimerge") (symbol_ref "INTVAL (operands[7])") (eq_attr "type" "vldm,vstm,vimov,vmalu,vmalu") (symbol_ref "INTVAL (operands[5])") @@ -266,7 +271,7 @@ (symbol_ref "INTVAL (operands[7])")) (eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu,\ - viwalu,viwmul") + viwalu,viwmul,vnshift,vimuladd") (symbol_ref "INTVAL (operands[8])") (eq_attr "type" "vstux,vstox") (symbol_ref "INTVAL (operands[5])")] @@ -659,6 +664,7 @@ ;; ------------------------------------------------------------------------------- ;; Includes: ;; - 7.4. Vector Unit-Stride Instructions +;; - 11.15 Vector Integer Merge Instructions ;; - 11.16 Vector Integer Move Instructions ;; - 13.16 Vector Floating-Point Move Instruction ;; - 15.1 Vector Mask-Register Logical Instructions @@ -709,7 +715,7 @@ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operand:V 3 "vector_move_operand" " m, m, m, vr, vr, viWc0") (match_operand:V 2 "vector_merge_operand" " 0, vu, vu, vu, vu0, vu0")))] - "TARGET_VECTOR && (MEM_P (operands[0]) || MEM_P (operands[3]) + "TARGET_VECTOR && (MEM_P (operands[0]) || MEM_P (operands[3]) || CONST_VECTOR_P (operands[1]))" "@ vle.v\t%0,%3%p1 @@ -720,7 +726,8 @@ vmv.v.i\t%0,%v3" "&& register_operand (operands[0], mode) && register_operand (operands[3], mode) - && satisfies_constraint_vu (operands[2])" + && satisfies_constraint_vu (operands[2]) + && INTVAL (operands[7]) == riscv_vector::VLMAX" [(set (match_dup 0) (match_dup 3))] "" [(set_attr "type" "vlde,vlde,vlde,vste,vimov,vimov") @@ -794,6 +801,134 @@ (set (attr "avl_type") (symbol_ref "riscv_vector::NONVLMAX")) (set_attr "vl_op_idx" "3")]) +(define_insn "@pred_merge" + [(set (match_operand:V 0 "register_operand" "=vd, vd") + (if_then_else:V + (match_operand: 4 "register_operand" " vm, vm") + (if_then_else:V + (unspec: + [(match_dup 4) + (match_operand 5 "vector_length_operand" " rK, rK") + (match_operand 6 "const_int_operand" " i, i") + (match_operand 7 "const_int_operand" " i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (match_operand:V 3 "vector_arith_operand" " vr, vi") + (match_operand:V 2 "register_operand" " vr, vr")) + (match_operand:V 1 "vector_merge_operand" " 0vu, 0vu")))] + "TARGET_VECTOR" + "vmerge.v%o3m\t%0,%2,%v3,%4" + [(set_attr "type" "vimerge") + (set_attr "mode" "")]) + +(define_insn "@pred_merge_scalar" + [(set (match_operand:VI_QHS 0 "register_operand" "=vd") + (if_then_else:VI_QHS + (match_operand: 4 "register_operand" " vm") + (if_then_else:VI_QHS + (unspec: + [(match_dup 4) + (match_operand 5 "vector_length_operand" " rK") + (match_operand 6 "const_int_operand" " i") + (match_operand 7 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (vec_duplicate:VI_QHS + (match_operand: 3 "register_operand" " r")) + (match_operand:VI_QHS 2 "register_operand" " vr")) + (match_operand:VI_QHS 1 "vector_merge_operand" "0vu")))] + "TARGET_VECTOR" + "vmerge.vxm\t%0,%2,%3,%4" + [(set_attr "type" "vimerge") + (set_attr "mode" "")]) + +(define_expand "@pred_merge_scalar" + [(set (match_operand:VI_D 0 "register_operand") + (if_then_else:VI_D + (match_operand: 4 "register_operand") + (if_then_else:VI_D + (unspec: + [(match_dup 4) + (match_operand 5 "vector_length_operand") + (match_operand 6 "const_int_operand") + (match_operand 7 "const_int_operand") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (vec_duplicate:VI_D + (match_operand: 3 "reg_or_int_operand")) + (match_operand:VI_D 2 "register_operand")) + (match_operand:VI_D 1 "vector_merge_operand")))] + "TARGET_VECTOR" + { + if (riscv_vector::neg_simm5_p (operands[3])) + operands[3] = force_reg (mode, operands[3]); + else if (!TARGET_64BIT) + { + rtx v = gen_reg_rtx (mode); + + if (riscv_vector::simm32_p (operands[3])) + operands[3] = gen_rtx_SIGN_EXTEND (mode, + force_reg (Pmode, operands[3])); + else + { + if (CONST_INT_P (operands[3])) + operands[3] = force_reg (mode, operands[3]); + + riscv_vector::emit_nonvlmax_op (code_for_pred_broadcast (mode), + v, operands[3], operands[5], mode); + emit_insn (gen_pred_merge (operands[0], operands[1], + operands[2], v, operands[4],operands[5], + operands[6], operands[7])); + DONE; + } + } + else + operands[3] = force_reg (mode, operands[3]); + }) + +(define_insn "*pred_merge_scalar" + [(set (match_operand:VI_D 0 "register_operand" "=vd") + (if_then_else:VI_D + (match_operand: 4 "register_operand" " vm") + (if_then_else:VI_D + (unspec: + [(match_dup 4) + (match_operand 5 "vector_length_operand" " rK") + (match_operand 6 "const_int_operand" " i") + (match_operand 7 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (vec_duplicate:VI_D + (match_operand: 3 "register_operand" " r")) + (match_operand:VI_D 2 "register_operand" " vr")) + (match_operand:VI_D 1 "vector_merge_operand" "0vu")))] + "TARGET_VECTOR" + "vmerge.vxm\t%0,%2,%3,%4" + [(set_attr "type" "vimerge") + (set_attr "mode" "")]) + +(define_insn "*pred_merge_extended_scalar" + [(set (match_operand:VI_D 0 "register_operand" "=vd") + (if_then_else:VI_D + (match_operand: 4 "register_operand" " vm") + (if_then_else:VI_D + (unspec: + [(match_dup 4) + (match_operand 5 "vector_length_operand" " rK") + (match_operand 6 "const_int_operand" " i") + (match_operand 7 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (vec_duplicate:VI_D + (sign_extend: + (match_operand: 3 "register_operand" " r"))) + (match_operand:VI_D 2 "register_operand" " vr")) + (match_operand:VI_D 1 "vector_merge_operand" "0vu")))] + "TARGET_VECTOR" + "vmerge.vxm\t%0,%2,%3,%4" + [(set_attr "type" "vimerge") + (set_attr "mode" "")]) + ;; ------------------------------------------------------------------------------- ;; ---- Predicated Broadcast ;; ------------------------------------------------------------------------------- @@ -823,7 +958,7 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (vec_duplicate:V - (match_operand: 3 "direct_broadcast_operand" "Wbr, f, Wdm, Wdm")) + (match_operand: 3 "direct_broadcast_operand" " r, f, Wdm, Wdm")) (match_operand:V 2 "vector_merge_operand" "0vu, 0vu, 0vu, 0vu")))] "TARGET_VECTOR" "@ @@ -1227,11 +1362,7 @@ (match_operand 4 "pmode_reg_or_uimm5_operand" " r, r, K, K")) (match_operand:VI 2 "vector_merge_operand" "0vu,0vu,0vu,0vu")))] "TARGET_VECTOR" - "@ - v.vx\t%0,%3,%4%p1 - v.vx\t%0,%3,%4%p1 - v.vi\t%0,%3,%4%p1 - v.vi\t%0,%3,%4%p1" + "v.v%o4\t%0,%3,%4%p1" [(set_attr "type" "vshift") (set_attr "mode" "")]) @@ -1957,9 +2088,7 @@ (match_operand: 4 "register_operand" " vm, vm")] UNSPEC_VADC) (match_operand:VI 1 "vector_merge_operand" " 0vu, 0vu")))] "TARGET_VECTOR" - "@ - vadc.vvm\t%0,%2,%3,%4 - vadc.vim\t%0,%2,%v3,%4" + "vadc.v%o3m\t%0,%2,%v3,%4" [(set_attr "type" "vicalu") (set_attr "mode" "") (set_attr "merge_op_idx" "1") @@ -2250,9 +2379,7 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_VMADC))] "TARGET_VECTOR" - "@ - vmadc.vvm\t%0,%1,%2,%3 - vmadc.vim\t%0,%1,%v2,%3" + "vmadc.v%o2m\t%0,%1,%v2,%3" [(set_attr "type" "vicalu") (set_attr "mode" "") (set_attr "vl_op_idx" "4") @@ -2497,9 +2624,7 @@ (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_OVERFLOW))] "TARGET_VECTOR" - "@ - vmadc.vv\t%0,%1,%2 - vmadc.vi\t%0,%1,%v2" + "vmadc.v%o2\t%0,%1,%v2" [(set_attr "type" "vicalu") (set_attr "mode" "") (set_attr "vl_op_idx" "3") @@ -2754,7 +2879,7 @@ (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))]) ;; ------------------------------------------------------------------------------- -;; ---- Predicated integer widening operations +;; ---- Predicated integer widening binary operations ;; ------------------------------------------------------------------------------- ;; Includes: ;; - 11.2 Vector Widening Integer Add/Subtract @@ -2982,3 +3107,79 @@ (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[5])")) (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])")) (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))]) + +;; ------------------------------------------------------------------------------- +;; ---- Predicated integer Narrowing operations +;; ------------------------------------------------------------------------------- +;; Includes: +;; - 11.7 Vector Narrowing Integer Right Shift Instructions +;; ------------------------------------------------------------------------------- + +;; The destination EEW is smaller than the source EEW and the overlap is in the +;; lowest-numbered part of the source register group +;; e.g, when LMUL = 1, vnsrl.wi v0,v0,3 is legal but a destination of v1 is not. +(define_insn "@pred_narrow_" + [(set (match_operand: 0 "register_operand" "=vd, vr, &vr, vd, vr, &vr") + (if_then_else: + (unspec: + [(match_operand: 1 "vector_mask_operand" " vm,Wc1,vmWc1, vm,Wc1,vmWc1") + (match_operand 5 "vector_length_operand" " rK, rK, rK, rK, rK, rK") + (match_operand 6 "const_int_operand" " i, i, i, i, i, i") + (match_operand 7 "const_int_operand" " i, i, i, i, i, i") + (match_operand 8 "const_int_operand" " i, i, i, i, i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (truncate: + (any_shiftrt:VWEXTI + (match_operand:VWEXTI 3 "register_operand" " 0, 0, vr, 0, 0, vr") + (match_operand: 4 "vector_shift_operand" " vr, vr, vr, vk, vk, vk"))) + (match_operand: 2 "vector_merge_operand" "0vu,0vu, 0vu,0vu,0vu, 0vu")))] + "TARGET_VECTOR" + "vn.w%o4\t%0,%3,%v4%p1" + [(set_attr "type" "vnshift") + (set_attr "mode" "")]) + +(define_insn "@pred_narrow__scalar" + [(set (match_operand: 0 "register_operand" "=vd, vr, &vr, vd, vr, &vr") + (if_then_else: + (unspec: + [(match_operand: 1 "vector_mask_operand" " vm,Wc1,vmWc1, vm,Wc1,vmWc1") + (match_operand 5 "vector_length_operand" " rK, rK, rK, rK, rK, rK") + (match_operand 6 "const_int_operand" " i, i, i, i, i, i") + (match_operand 7 "const_int_operand" " i, i, i, i, i, i") + (match_operand 8 "const_int_operand" " i, i, i, i, i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (truncate: + (any_shiftrt:VWEXTI + (match_operand:VWEXTI 3 "register_operand" " 0, 0, vr, 0, 0, vr") + (match_operand 4 "pmode_reg_or_uimm5_operand" " r, r, r, K, K, K"))) + (match_operand: 2 "vector_merge_operand" "0vu,0vu, 0vu,0vu,0vu, 0vu")))] + "TARGET_VECTOR" + "vn.w%o4\t%0,%3,%4%p1" + [(set_attr "type" "vnshift") + (set_attr "mode" "")]) + +;; vncvt.x.x.w +(define_insn "@pred_trunc" + [(set (match_operand: 0 "register_operand" "=vd, vr, &vr") + (if_then_else: + (unspec: + [(match_operand: 1 "vector_mask_operand" " vm,Wc1,vmWc1") + (match_operand 4 "vector_length_operand" " rK, rK, rK") + (match_operand 5 "const_int_operand" " i, i, i") + (match_operand 6 "const_int_operand" " i, i, i") + (match_operand 7 "const_int_operand" " i, i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (truncate: + (match_operand:VWEXTI 3 "register_operand" " 0, 0, vr")) + (match_operand: 2 "vector_merge_operand" "0vu,0vu, 0vu")))] + "TARGET_VECTOR" + "vncvt.x.x.w\t%0,%3%p1" + [(set_attr "type" "vnshift") + (set_attr "mode" "") + (set_attr "vl_op_idx" "4") + (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[5])")) + (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])")) + (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])