From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2093) id 890673858D32; Sun, 12 Feb 2023 07:34:14 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 890673858D32 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1676187254; bh=bVcFUqqB29/Tq4FEFsp24FEA91XxxuEHK/p8SSBuS90=; h=From:To:Subject:Date:From; b=vu2TZ6TLmACA1E/b8lbogt7hubQdgN8ltPtDs5qt3HyxSE1dbkRsdjceB8wRc/Nzd 50qY6gLs+xzLc8Cyz0MzMyRYjpY9UIV+Y22EhUtpaT2P+U6dbx1SMXaUupb8qlsI5x m1al+OeXpwDtac3pXnoGXoSo/YIQGwou/vYbOQNY= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Kito Cheng To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-5905] RISC-V: Add vmadc/vmsbc C/C++ API support X-Act-Checkin: gcc X-Git-Author: Ju-Zhe Zhong X-Git-Refname: refs/heads/master X-Git-Oldrev: b7e4f61c3e703f38c5621d5114e776d245abdf73 X-Git-Newrev: dca23bf0bbe68c3880c9793b401cfc03890e6a0d Message-Id: <20230212073414.890673858D32@sourceware.org> Date: Sun, 12 Feb 2023 07:34:14 +0000 (GMT) List-Id: https://gcc.gnu.org/g:dca23bf0bbe68c3880c9793b401cfc03890e6a0d commit r13-5905-gdca23bf0bbe68c3880c9793b401cfc03890e6a0d Author: Ju-Zhe Zhong Date: Thu Feb 9 04:52:36 2023 +0800 RISC-V: Add vmadc/vmsbc C/C++ API support gcc/ChangeLog: * config/riscv/riscv-vector-builtins-bases.cc (class vmadc): New class. (class vmsbc): Ditto. (BASE): Define new class. * config/riscv/riscv-vector-builtins-bases.h: Ditto. * config/riscv/riscv-vector-builtins-functions.def (vmadc): New define. (vmsbc): Ditto. * config/riscv/riscv-vector-builtins-shapes.cc (struct return_mask_def): New class. (SHAPE): Ditto. * config/riscv/riscv-vector-builtins-shapes.h: Ditto. * config/riscv/riscv-vector-builtins.cc (function_expander::use_exact_insn): Adjust for new support * config/riscv/riscv-vector-builtins.h (function_base::has_merge_operand_p): New function. * config/riscv/vector-iterators.md: New iterator. * config/riscv/vector.md (@pred_madc): New pattern. (@pred_msbc): Ditto. (@pred_madc_scalar): Ditto. (@pred_msbc_scalar): Ditto. (*pred_madc_scalar): Ditto. (*pred_madc_extended_scalar): Ditto. (*pred_msbc_scalar): Ditto. (*pred_msbc_extended_scalar): Ditto. (@pred_madc_overflow): Ditto. (@pred_msbc_overflow): Ditto. (@pred_madc_overflow_scalar): Ditto. (@pred_msbc_overflow_scalar): Ditto. (*pred_madc_overflow_scalar): Ditto. (*pred_madc_overflow_extended_scalar): Ditto. (*pred_msbc_overflow_scalar): Ditto. (*pred_msbc_overflow_extended_scalar): Ditto. Diff: --- gcc/config/riscv/riscv-vector-builtins-bases.cc | 62 +++ gcc/config/riscv/riscv-vector-builtins-bases.h | 2 + .../riscv/riscv-vector-builtins-functions.def | 8 + gcc/config/riscv/riscv-vector-builtins-shapes.cc | 28 ++ gcc/config/riscv/riscv-vector-builtins-shapes.h | 1 + gcc/config/riscv/riscv-vector-builtins.cc | 34 +- gcc/config/riscv/riscv-vector-builtins.h | 11 + gcc/config/riscv/vector-iterators.md | 3 + gcc/config/riscv/vector.md | 494 +++++++++++++++++++++ 9 files changed, 642 insertions(+), 1 deletion(-) diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc index 8bf5bb97ca1..bcf2dfe805a 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc @@ -338,6 +338,64 @@ public: } }; +/* Implements vmadc. */ +class vmadc : public function_base +{ +public: + bool apply_tail_policy_p () const override { return false; } + bool apply_mask_policy_p () const override { return false; } + bool use_mask_predication_p () const override { return false; } + bool has_merge_operand_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_madc (e.vector_mode ())); + case OP_TYPE_vxm: + return e.use_exact_insn (code_for_pred_madc_scalar (e.vector_mode ())); + case OP_TYPE_vv: + return e.use_exact_insn ( + code_for_pred_madc_overflow (e.vector_mode ())); + case OP_TYPE_vx: + return e.use_exact_insn ( + code_for_pred_madc_overflow_scalar (e.vector_mode ())); + default: + gcc_unreachable (); + } + } +}; + +/* Implements vmsbc. */ +class vmsbc : public function_base +{ +public: + bool apply_tail_policy_p () const override { return false; } + bool apply_mask_policy_p () const override { return false; } + bool use_mask_predication_p () const override { return false; } + bool has_merge_operand_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_msbc (e.vector_mode ())); + case OP_TYPE_vxm: + return e.use_exact_insn (code_for_pred_msbc_scalar (e.vector_mode ())); + case OP_TYPE_vv: + return e.use_exact_insn ( + code_for_pred_msbc_overflow (e.vector_mode ())); + case OP_TYPE_vx: + return e.use_exact_insn ( + code_for_pred_msbc_overflow_scalar (e.vector_mode ())); + default: + gcc_unreachable (); + } + } +}; + static CONSTEXPR const vsetvl vsetvl_obj; static CONSTEXPR const vsetvl vsetvlmax_obj; static CONSTEXPR const loadstore vle_obj; @@ -398,6 +456,8 @@ static CONSTEXPR const vwcvt vwcvt_x_obj; static CONSTEXPR const vwcvt vwcvtu_x_obj; 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 binop vsadd_obj; static CONSTEXPR const binop vssub_obj; static CONSTEXPR const binop vsaddu_obj; @@ -468,6 +528,8 @@ BASE (vwcvt_x) BASE (vwcvtu_x) BASE (vadc) BASE (vsbc) +BASE (vmadc) +BASE (vmsbc) 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 729c069c1eb..6a8747b184e 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.h +++ b/gcc/config/riscv/riscv-vector-builtins-bases.h @@ -84,6 +84,8 @@ extern const function_base *const vwcvt_x; extern const function_base *const vwcvtu_x; 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 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 3d8db35683b..6d328537ab8 100644 --- a/gcc/config/riscv/riscv-vector-builtins-functions.def +++ b/gcc/config/riscv/riscv-vector-builtins-functions.def @@ -140,6 +140,14 @@ DEF_RVV_FUNCTION (vadc, no_mask_policy, tu_preds, iu_vvvm_ops) DEF_RVV_FUNCTION (vsbc, no_mask_policy, tu_preds, iu_vvvm_ops) DEF_RVV_FUNCTION (vadc, no_mask_policy, tu_preds, iu_vvxm_ops) DEF_RVV_FUNCTION (vsbc, no_mask_policy, tu_preds, iu_vvxm_ops) +DEF_RVV_FUNCTION (vmadc, return_mask, none_preds, iu_mvvm_ops) +DEF_RVV_FUNCTION (vmsbc, return_mask, none_preds, iu_mvvm_ops) +DEF_RVV_FUNCTION (vmadc, return_mask, none_preds, iu_mvxm_ops) +DEF_RVV_FUNCTION (vmsbc, return_mask, none_preds, iu_mvxm_ops) +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) /* 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 91870077a0c..dae515cb5c3 100644 --- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc @@ -266,6 +266,33 @@ struct no_mask_policy_def : public build_base } }; +/* return_mask_def class. Such instructions belong to this class + is returning mask value. */ +struct return_mask_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) + b.append_name (operand_suffixes[instance.op_info->op]); + + /* vop_ --> vop___. */ + if (!overloaded_p) + { + b.append_name (type_suffixes[instance.type.index].vector); + 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); + } + + b.append_name (predication_suffixes[instance.pred]); + return b.finish_name (); + } +}; + SHAPE(vsetvl, vsetvl) SHAPE(vsetvl, vsetvlmax) SHAPE(loadstore, loadstore) @@ -273,5 +300,6 @@ SHAPE(indexed_loadstore, indexed_loadstore) SHAPE(alu, alu) SHAPE(widen_alu, widen_alu) SHAPE(no_mask_policy, no_mask_policy) +SHAPE(return_mask, return_mask) } // 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 6aadde3df6c..783b4712a45 100644 --- a/gcc/config/riscv/riscv-vector-builtins-shapes.h +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.h @@ -31,6 +31,7 @@ extern const function_shape *const indexed_loadstore; 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; } } // end namespace riscv_vector diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc index 0036c81b15d..ce62baec5ce 100644 --- a/gcc/config/riscv/riscv-vector-builtins.cc +++ b/gcc/config/riscv/riscv-vector-builtins.cc @@ -570,6 +570,38 @@ static CONSTEXPR const rvv_op_info iu_vvxm_ops rvv_arg_type_info (RVV_BASE_vector), /* Return type */ vxm_args /* Args */}; +/* A static operand information for mask_type func (vector_type, vector_type, + * mask_type) function registration. */ +static CONSTEXPR const rvv_op_info iu_mvvm_ops + = {iu_ops, /* Types */ + OP_TYPE_vvm, /* Suffix */ + rvv_arg_type_info (RVV_BASE_mask), /* Return type */ + vvm_args /* Args */}; + +/* A static operand information for mask_type func (vector_type, scalar_type, + * mask_type) function registration. */ +static CONSTEXPR const rvv_op_info iu_mvxm_ops + = {iu_ops, /* Types */ + OP_TYPE_vxm, /* Suffix */ + rvv_arg_type_info (RVV_BASE_mask), /* Return type */ + vxm_args /* Args */}; + +/* A static operand information for mask_type func (vector_type, vector_type) + * function registration. */ +static CONSTEXPR const rvv_op_info iu_mvv_ops + = {iu_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_mask), /* Return type */ + vv_args /* Args */}; + +/* A static operand information for mask_type func (vector_type, scalar_type) + * function registration. */ +static CONSTEXPR const rvv_op_info iu_mvx_ops + = {iu_ops, /* Types */ + OP_TYPE_vx, /* Suffix */ + rvv_arg_type_info (RVV_BASE_mask), /* Return type */ + vx_args /* Args */}; + /* A static operand information for vector_type func (vector_type, vector_type) * function registration. */ static CONSTEXPR const rvv_op_info i_vvv_ops @@ -1670,7 +1702,7 @@ function_expander::use_exact_insn (insn_code icode) } /* Store operation doesn't have merge operand. */ - if (!function_returns_void_p ()) + if (!function_returns_void_p () && base->has_merge_operand_p ()) { if (use_real_merge_p (pred)) add_input_operand (arg_offset++); diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h index 4f78c299e6f..f00b2c51020 100644 --- a/gcc/config/riscv/riscv-vector-builtins.h +++ b/gcc/config/riscv/riscv-vector-builtins.h @@ -388,6 +388,9 @@ public: /* Return true if intrinsics use mask predication. */ virtual bool use_mask_predication_p () const; + /* Return true if intrinsics has merge operand. */ + virtual bool has_merge_operand_p () const; + /* Expand the given call into rtl. Return the result of the function, or an arbitrary value if the function doesn't return a result. */ virtual rtx expand (function_expander &) const = 0; @@ -521,6 +524,14 @@ function_base::use_mask_predication_p () const return true; } +/* We choose to return true by default since most of the intrinsics use + has merge operand. */ +inline bool +function_base::has_merge_operand_p () const +{ + return true; +} + /* Since most of intrinsics can be overloaded, we set it true by default. */ inline bool function_base::can_be_overloaded_p (enum predication_type_index) const diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index c3f3f1b01f8..6b255c4ddb3 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -36,6 +36,9 @@ UNSPEC_VADC UNSPEC_VSBC + UNSPEC_VMADC + UNSPEC_VMSBC + UNSPEC_OVERFLOW ]) (define_mode_iterator V [ diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index 3cd87f8fc6f..b3f8c055a75 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -1962,6 +1962,7 @@ vadc.vim\t%0,%2,%v3,%4" [(set_attr "type" "vicalu") (set_attr "mode" "") + (set_attr "merge_op_idx" "1") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))]) @@ -1985,6 +1986,7 @@ "vsbc.vvm\t%0,%2,%3,%4" [(set_attr "type" "vicalu") (set_attr "mode" "") + (set_attr "merge_op_idx" "1") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))]) @@ -2009,6 +2011,7 @@ "vadc.vxm\t%0,%2,%3,%4" [(set_attr "type" "vicalu") (set_attr "mode" "") + (set_attr "merge_op_idx" "1") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))]) @@ -2033,6 +2036,7 @@ "vsbc.vxm\t%0,%2,%z3,%4" [(set_attr "type" "vicalu") (set_attr "mode" "") + (set_attr "merge_op_idx" "1") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))]) @@ -2102,6 +2106,7 @@ "vadc.vxm\t%0,%2,%3,%4" [(set_attr "type" "vicalu") (set_attr "mode" "") + (set_attr "merge_op_idx" "1") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))]) @@ -2127,6 +2132,7 @@ "vadc.vxm\t%0,%2,%3,%4" [(set_attr "type" "vicalu") (set_attr "mode" "") + (set_attr "merge_op_idx" "1") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))]) @@ -2200,6 +2206,7 @@ "vsbc.vxm\t%0,%2,%z3,%4" [(set_attr "type" "vicalu") (set_attr "mode" "") + (set_attr "merge_op_idx" "1") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))]) @@ -2225,10 +2232,497 @@ "vsbc.vxm\t%0,%2,%z3,%4" [(set_attr "type" "vicalu") (set_attr "mode" "") + (set_attr "merge_op_idx" "1") (set_attr "vl_op_idx" "5") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])")) (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))]) +(define_insn "@pred_madc" + [(set (match_operand: 0 "register_operand" "=&vr, &vr") + (unspec: + [(plus:VI + (match_operand:VI 1 "register_operand" " vr, vr") + (match_operand:VI 2 "vector_arith_operand" " vr, vi")) + (match_operand: 3 "register_operand" " vm, vm") + (unspec: + [(match_operand 4 "vector_length_operand" " rK, rK") + (match_operand 5 "const_int_operand" " i, i") + (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" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (set_attr "vl_op_idx" "4") + (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))]) + +(define_insn "@pred_msbc" + [(set (match_operand: 0 "register_operand" "=&vr") + (unspec: + [(minus:VI + (match_operand:VI 1 "register_operand" " vr") + (match_operand:VI 2 "register_operand" " vr")) + (match_operand: 3 "register_operand" " vm") + (unspec: + [(match_operand 4 "vector_length_operand" " rK") + (match_operand 5 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_VMSBC))] + "TARGET_VECTOR" + "vmsbc.vvm\t%0,%1,%2,%3" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (set_attr "vl_op_idx" "4") + (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))]) + +(define_insn "@pred_madc_scalar" + [(set (match_operand: 0 "register_operand" "=&vr") + (unspec: + [(plus:VI_QHS + (vec_duplicate:VI_QHS + (match_operand: 2 "register_operand" " r")) + (match_operand:VI_QHS 1 "register_operand" " vr")) + (match_operand: 3 "register_operand" " vm") + (unspec: + [(match_operand 4 "vector_length_operand" " rK") + (match_operand 5 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_VMADC))] + "TARGET_VECTOR" + "vmadc.vxm\t%0,%1,%2,%3" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (set_attr "vl_op_idx" "4") + (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))]) + +(define_insn "@pred_msbc_scalar" + [(set (match_operand: 0 "register_operand" "=&vr") + (unspec: + [(minus:VI_QHS + (vec_duplicate:VI_QHS + (match_operand: 2 "reg_or_0_operand" " rJ")) + (match_operand:VI_QHS 1 "register_operand" " vr")) + (match_operand: 3 "register_operand" " vm") + (unspec: + [(match_operand 4 "vector_length_operand" " rK") + (match_operand 5 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_VMSBC))] + "TARGET_VECTOR" + "vmsbc.vxm\t%0,%1,%z2,%3" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (set_attr "vl_op_idx" "4") + (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))]) + +(define_expand "@pred_madc_scalar" + [(set (match_operand: 0 "register_operand") + (unspec: + [(plus:VI_D + (vec_duplicate:VI_D + (match_operand: 2 "reg_or_int_operand")) + (match_operand:VI_D 1 "register_operand")) + (match_operand: 3 "register_operand") + (unspec: + [(match_operand 4 "vector_length_operand") + (match_operand 5 "const_int_operand") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_VMADC))] + "TARGET_VECTOR" + { + if (riscv_vector::simm5_p (operands[2])) + operands[2] = force_reg (mode, operands[2]); + else if (!TARGET_64BIT) + { + rtx v = gen_reg_rtx (mode); + + if (riscv_vector::simm32_p (operands[2])) + operands[2] = gen_rtx_SIGN_EXTEND (mode, + force_reg (Pmode, operands[2])); + else + { + if (CONST_INT_P (operands[2])) + operands[2] = force_reg (mode, operands[2]); + + riscv_vector::emit_nonvlmax_op (code_for_pred_broadcast (mode), + v, operands[2], operands[5], + mode); + emit_insn (gen_pred_madc (operands[0], operands[1], v, operands[3], + operands[4], operands[5])); + DONE; + } + } + else + operands[2] = force_reg (mode, operands[2]); + }) + +(define_insn "*pred_madc_scalar" + [(set (match_operand: 0 "register_operand" "=&vr") + (unspec: + [(plus:VI_D + (vec_duplicate:VI_D + (match_operand: 2 "register_operand" " r")) + (match_operand:VI_D 1 "register_operand" " vr")) + (match_operand: 3 "register_operand" " vm") + (unspec: + [(match_operand 4 "vector_length_operand" " rK") + (match_operand 5 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_VMADC))] + "TARGET_VECTOR" + "vmadc.vxm\t%0,%1,%2,%3" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (set_attr "vl_op_idx" "4") + (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))]) + +(define_insn "*pred_madc_extended_scalar" + [(set (match_operand: 0 "register_operand" "=&vr") + (unspec: + [(plus:VI_D + (vec_duplicate:VI_D + (sign_extend: + (match_operand: 2 "register_operand" " r"))) + (match_operand:VI_D 1 "register_operand" " vr")) + (match_operand: 3 "register_operand" " vm") + (unspec: + [(match_operand 4 "vector_length_operand" " rK") + (match_operand 5 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_VMADC))] + "TARGET_VECTOR" + "vmadc.vxm\t%0,%1,%2,%3" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (set_attr "vl_op_idx" "4") + (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))]) + +(define_expand "@pred_msbc_scalar" + [(set (match_operand: 0 "register_operand") + (unspec: + [(minus:VI_D + (vec_duplicate:VI_D + (match_operand: 2 "reg_or_int_operand")) + (match_operand:VI_D 1 "register_operand")) + (match_operand: 3 "register_operand") + (unspec: + [(match_operand 4 "vector_length_operand") + (match_operand 5 "const_int_operand") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_VMSBC))] + "TARGET_VECTOR" + { + if (!TARGET_64BIT) + { + rtx v = gen_reg_rtx (mode); + + if (riscv_vector::simm32_p (operands[2])) + { + if (!rtx_equal_p (operands[2], const0_rtx)) + operands[2] = force_reg (Pmode, operands[2]); + operands[2] = gen_rtx_SIGN_EXTEND (mode, operands[2]); + } + else + { + if (CONST_INT_P (operands[2])) + operands[2] = force_reg (mode, operands[2]); + + riscv_vector::emit_nonvlmax_op (code_for_pred_broadcast (mode), + v, operands[2], operands[5], + mode); + emit_insn (gen_pred_msbc (operands[0], operands[1], v, operands[3], + operands[4], operands[5])); + DONE; + } + } + else + { + if (!rtx_equal_p (operands[2], const0_rtx)) + operands[2] = force_reg (mode, operands[2]); + } + }) + +(define_insn "*pred_msbc_scalar" + [(set (match_operand: 0 "register_operand" "=&vr") + (unspec: + [(minus:VI_D + (vec_duplicate:VI_D + (match_operand: 2 "reg_or_0_operand" " rJ")) + (match_operand:VI_D 1 "register_operand" " vr")) + (match_operand: 3 "register_operand" " vm") + (unspec: + [(match_operand 4 "vector_length_operand" " rK") + (match_operand 5 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_VMSBC))] + "TARGET_VECTOR" + "vmsbc.vxm\t%0,%1,%z2,%3" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (set_attr "vl_op_idx" "4") + (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))]) + +(define_insn "*pred_msbc_extended_scalar" + [(set (match_operand: 0 "register_operand" "=&vr") + (unspec: + [(minus:VI_D + (vec_duplicate:VI_D + (sign_extend: + (match_operand: 2 "reg_or_0_operand" " rJ"))) + (match_operand:VI_D 1 "register_operand" " vr")) + (match_operand: 3 "register_operand" " vm") + (unspec: + [(match_operand 4 "vector_length_operand" " rK") + (match_operand 5 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_VMSBC))] + "TARGET_VECTOR" + "vmsbc.vxm\t%0,%1,%z2,%3" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (set_attr "vl_op_idx" "4") + (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))]) + +(define_insn "@pred_madc_overflow" + [(set (match_operand: 0 "register_operand" "=&vr, &vr") + (unspec: + [(plus:VI + (match_operand:VI 1 "register_operand" " vr, vr") + (match_operand:VI 2 "vector_arith_operand" " vr, vi")) + (unspec: + [(match_operand 3 "vector_length_operand" " rK, rK") + (match_operand 4 "const_int_operand" " i, i") + (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" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (set_attr "vl_op_idx" "3") + (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))]) + +(define_insn "@pred_msbc_overflow" + [(set (match_operand: 0 "register_operand" "=&vr") + (unspec: + [(minus:VI + (match_operand:VI 1 "register_operand" " vr") + (match_operand:VI 2 "register_operand" " vr")) + (unspec: + [(match_operand 3 "vector_length_operand" " rK") + (match_operand 4 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_OVERFLOW))] + "TARGET_VECTOR" + "vmsbc.vv\t%0,%1,%2" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (set_attr "vl_op_idx" "3") + (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))]) + +(define_insn "@pred_madc_overflow_scalar" + [(set (match_operand: 0 "register_operand" "=&vr") + (unspec: + [(plus:VI_QHS + (vec_duplicate:VI_QHS + (match_operand: 2 "register_operand" " r")) + (match_operand:VI_QHS 1 "register_operand" " vr")) + (unspec: + [(match_operand 3 "vector_length_operand" " rK") + (match_operand 4 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_OVERFLOW))] + "TARGET_VECTOR" + "vmadc.vx\t%0,%1,%2" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (set_attr "vl_op_idx" "3") + (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))]) + +(define_insn "@pred_msbc_overflow_scalar" + [(set (match_operand: 0 "register_operand" "=&vr") + (unspec: + [(minus:VI_QHS + (vec_duplicate:VI_QHS + (match_operand: 2 "reg_or_0_operand" " rJ")) + (match_operand:VI_QHS 1 "register_operand" " vr")) + (unspec: + [(match_operand 3 "vector_length_operand" " rK") + (match_operand 4 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_OVERFLOW))] + "TARGET_VECTOR" + "vmsbc.vx\t%0,%1,%z2" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (set_attr "vl_op_idx" "3") + (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))]) + +(define_expand "@pred_madc_overflow_scalar" + [(set (match_operand: 0 "register_operand") + (unspec: + [(plus:VI_D + (vec_duplicate:VI_D + (match_operand: 2 "reg_or_int_operand")) + (match_operand:VI_D 1 "register_operand")) + (unspec: + [(match_operand 3 "vector_length_operand") + (match_operand 4 "const_int_operand") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_OVERFLOW))] + "TARGET_VECTOR" + { + if (riscv_vector::simm5_p (operands[2])) + operands[2] = force_reg (mode, operands[2]); + else if (!TARGET_64BIT) + { + rtx v = gen_reg_rtx (mode); + + if (riscv_vector::simm32_p (operands[2])) + operands[2] = gen_rtx_SIGN_EXTEND (mode, + force_reg (Pmode, operands[2])); + else + { + if (CONST_INT_P (operands[2])) + operands[2] = force_reg (mode, operands[2]); + + riscv_vector::emit_nonvlmax_op (code_for_pred_broadcast (mode), + v, operands[2], operands[3], + mode); + emit_insn (gen_pred_madc_overflow (operands[0], operands[1], + v, operands[3], operands[4])); + DONE; + } + } + else + operands[2] = force_reg (mode, operands[2]); + }) + +(define_insn "*pred_madc_overflow_scalar" + [(set (match_operand: 0 "register_operand" "=&vr") + (unspec: + [(plus:VI_D + (vec_duplicate:VI_D + (match_operand: 2 "register_operand" " r")) + (match_operand:VI_D 1 "register_operand" " vr")) + (unspec: + [(match_operand 3 "vector_length_operand" " rK") + (match_operand 4 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_OVERFLOW))] + "TARGET_VECTOR" + "vmadc.vx\t%0,%1,%2" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (set_attr "vl_op_idx" "3") + (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))]) + +(define_insn "*pred_madc_overflow_extended_scalar" + [(set (match_operand: 0 "register_operand" "=&vr") + (unspec: + [(plus:VI_D + (vec_duplicate:VI_D + (sign_extend: + (match_operand: 2 "register_operand" " r"))) + (match_operand:VI_D 1 "register_operand" " vr")) + (unspec: + [(match_operand 3 "vector_length_operand" " rK") + (match_operand 4 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_OVERFLOW))] + "TARGET_VECTOR" + "vmadc.vx\t%0,%1,%2" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (set_attr "vl_op_idx" "3") + (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))]) + +(define_expand "@pred_msbc_overflow_scalar" + [(set (match_operand: 0 "register_operand") + (unspec: + [(minus:VI_D + (vec_duplicate:VI_D + (match_operand: 2 "reg_or_int_operand")) + (match_operand:VI_D 1 "register_operand")) + (unspec: + [(match_operand 3 "vector_length_operand") + (match_operand 4 "const_int_operand") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_OVERFLOW))] + "TARGET_VECTOR" + { + if (!TARGET_64BIT) + { + rtx v = gen_reg_rtx (mode); + + if (riscv_vector::simm32_p (operands[2])) + { + if (!rtx_equal_p (operands[2], const0_rtx)) + operands[2] = force_reg (Pmode, operands[2]); + operands[2] = gen_rtx_SIGN_EXTEND (mode, operands[2]); + } + else + { + if (CONST_INT_P (operands[2])) + operands[2] = force_reg (mode, operands[2]); + + riscv_vector::emit_nonvlmax_op (code_for_pred_broadcast (mode), + v, operands[2], operands[3], + mode); + emit_insn (gen_pred_msbc_overflow (operands[0], operands[1], + v, operands[3], operands[4])); + DONE; + } + } + else + { + if (!rtx_equal_p (operands[2], const0_rtx)) + operands[2] = force_reg (mode, operands[2]); + } + }) + +(define_insn "*pred_msbc_overflow_scalar" + [(set (match_operand: 0 "register_operand" "=&vr") + (unspec: + [(minus:VI_D + (vec_duplicate:VI_D + (match_operand: 2 "reg_or_0_operand" " rJ")) + (match_operand:VI_D 1 "register_operand" " vr")) + (unspec: + [(match_operand 3 "vector_length_operand" " rK") + (match_operand 4 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_OVERFLOW))] + "TARGET_VECTOR" + "vmsbc.vx\t%0,%1,%z2" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (set_attr "vl_op_idx" "3") + (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))]) + +(define_insn "*pred_msbc_overflow_extended_scalar" + [(set (match_operand: 0 "register_operand" "=&vr") + (unspec: + [(minus:VI_D + (vec_duplicate:VI_D + (sign_extend: + (match_operand: 2 "reg_or_0_operand" " rJ"))) + (match_operand:VI_D 1 "register_operand" " vr")) + (unspec: + [(match_operand 3 "vector_length_operand" " rK") + (match_operand 4 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_OVERFLOW))] + "TARGET_VECTOR" + "vmsbc.vx\t%0,%1,%z2" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (set_attr "vl_op_idx" "3") + (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))]) + ;; ------------------------------------------------------------------------------- ;; ---- Predicated integer unary operations ;; -------------------------------------------------------------------------------