From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2093) id 37FD3385842D; Sun, 12 Feb 2023 06:57:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 37FD3385842D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1676185053; bh=5vftrEbVWsqT0XNataWYFGX1QkAhcH6VheheqN/e5Qs=; h=From:To:Subject:Date:From; b=YsZQB1JCERcJhrxETNTPfxxfx7qfjUbcUT5jRun2F7oMGBvySgzXvwolIldaJNB6G bstLWs7nethEYncIuZi8TORICmPcgCKx9dbV4B6y1+x2qjZCHjz3R4Sy+PqUIc85/J pAccpUS89iMm3fR+euYBqDk0jxmeHg9dZ6rTWB5o= 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-5900] RISC-V: Add vadc/vsbc C/C++ API support X-Act-Checkin: gcc X-Git-Author: Ju-Zhe Zhong X-Git-Refname: refs/heads/master X-Git-Oldrev: 5e620b36cd34b85b0e28c34160245d84bc5acd68 X-Git-Newrev: cb44a16d212e9d0c402340fe6627501ca2e50fb8 Message-Id: <20230212065733.37FD3385842D@sourceware.org> Date: Sun, 12 Feb 2023 06:57:33 +0000 (GMT) List-Id: https://gcc.gnu.org/g:cb44a16d212e9d0c402340fe6627501ca2e50fb8 commit r13-5900-gcb44a16d212e9d0c402340fe6627501ca2e50fb8 Author: Ju-Zhe Zhong Date: Wed Feb 8 10:30:24 2023 +0800 RISC-V: Add vadc/vsbc C/C++ API support gcc/ChangeLog: * config/riscv/riscv-protos.h (simm5_p): Add vadc/vsbc support. * config/riscv/riscv-v.cc (simm32_p): Ditto. * config/riscv/riscv-vector-builtins-bases.cc (class vadc): New class. (class vsbc): Ditto. (BASE): Ditto. * config/riscv/riscv-vector-builtins-bases.h: Ditto. * config/riscv/riscv-vector-builtins-functions.def (vadc): Ditto. (vsbc): Ditto. * config/riscv/riscv-vector-builtins-shapes.cc (struct no_mask_policy_def): Ditto. (SHAPE): Ditto. * config/riscv/riscv-vector-builtins-shapes.h: Ditto. * config/riscv/riscv-vector-builtins.cc (rvv_arg_type_info::get_base_vector_type): Add vadc/vsbc support. (rvv_arg_type_info::get_tree_type): Ditto. (function_expander::use_exact_insn): Ditto. * config/riscv/riscv-vector-builtins.h (enum rvv_base_type): Ditto. (function_base::use_mask_predication_p): New function. * config/riscv/vector-iterators.md: New iterator. * config/riscv/vector.md (@pred_adc): New pattern. (@pred_sbc): Ditto. (@pred_adc_scalar): Ditto. (@pred_sbc_scalar): Ditto. (*pred_adc_scalar): Ditto. (*pred_adc_extended_scalar): Ditto. (*pred_sbc_scalar): Ditto. (*pred_sbc_extended_scalar): Ditto. Diff: --- gcc/config/riscv/riscv-protos.h | 1 + gcc/config/riscv/riscv-v.cc | 2 +- gcc/config/riscv/riscv-vector-builtins-bases.cc | 46 ++++ gcc/config/riscv/riscv-vector-builtins-bases.h | 2 + .../riscv/riscv-vector-builtins-functions.def | 4 + gcc/config/riscv/riscv-vector-builtins-shapes.cc | 22 ++ gcc/config/riscv/riscv-vector-builtins-shapes.h | 1 + gcc/config/riscv/riscv-vector-builtins.cc | 50 +++- gcc/config/riscv/riscv-vector-builtins.h | 12 + gcc/config/riscv/vector-iterators.md | 3 + gcc/config/riscv/vector.md | 293 ++++++++++++++++++++- 11 files changed, 429 insertions(+), 7 deletions(-) diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index e090c61a3e3..a4476e6235f 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -175,6 +175,7 @@ enum mask_policy get_prefer_mask_policy (); rtx get_avl_type_rtx (enum avl_type); opt_machine_mode get_vector_mode (scalar_mode, poly_uint64); extern bool simm32_p (rtx); +extern bool simm5_p (rtx); extern bool neg_simm5_p (rtx); #ifdef RTX_CODE extern bool has_vi_variant_p (rtx_code, rtx); diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index df89c9be308..83cb1f83606 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -408,7 +408,7 @@ simm32_p (rtx x) return val <= 0x7FFFFFFFULL || val >= 0xFFFFFFFF80000000ULL; } -static bool +bool simm5_p (rtx x) { if (!CONST_INT_P (x)) diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc index e14a1854eee..8bf5bb97ca1 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc @@ -296,6 +296,48 @@ public: } }; +/* Implements vadc. */ +class vadc : 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_adc (e.vector_mode ())); + case OP_TYPE_vxm: + return e.use_exact_insn (code_for_pred_adc_scalar (e.vector_mode ())); + default: + gcc_unreachable (); + } + } +}; + +/* Implements vsbc. */ +class vsbc : 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_sbc (e.vector_mode ())); + case OP_TYPE_vxm: + return e.use_exact_insn (code_for_pred_sbc_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; @@ -354,6 +396,8 @@ static CONSTEXPR const widen_binopvwmulu_obj; static CONSTEXPR const vwmulsu vwmulsu_obj; 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 binop vsadd_obj; static CONSTEXPR const binop vssub_obj; static CONSTEXPR const binop vsaddu_obj; @@ -422,6 +466,8 @@ BASE (vwmulu) BASE (vwmulsu) BASE (vwcvt_x) BASE (vwcvtu_x) +BASE (vadc) +BASE (vsbc) 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 51ec940a5aa..729c069c1eb 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.h +++ b/gcc/config/riscv/riscv-vector-builtins-bases.h @@ -82,6 +82,8 @@ extern const function_base *const vwmulu; extern const function_base *const vwmulsu; 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 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 e53fcb5546b..3d8db35683b 100644 --- a/gcc/config/riscv/riscv-vector-builtins-functions.def +++ b/gcc/config/riscv/riscv-vector-builtins-functions.def @@ -136,6 +136,10 @@ DEF_RVV_FUNCTION (vwaddu, widen_alu, full_preds, u_wwx_ops) DEF_RVV_FUNCTION (vwsubu, widen_alu, full_preds, u_wwx_ops) DEF_RVV_FUNCTION (vwcvt_x, alu, full_preds, i_x_x_v_ops) DEF_RVV_FUNCTION (vwcvtu_x, alu, full_preds, u_x_x_v_ops) +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) /* 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 62170f607ba..91870077a0c 100644 --- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc @@ -245,11 +245,33 @@ struct widen_alu_def : public build_base } }; +/* no_mask_policy_def class. Such instructions belong to this class + doesn't need mask policy. */ +struct no_mask_policy_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); + + b.append_name (predication_suffixes[instance.pred]); + return b.finish_name (); + } +}; + SHAPE(vsetvl, vsetvl) SHAPE(vsetvl, vsetvlmax) SHAPE(loadstore, loadstore) SHAPE(indexed_loadstore, indexed_loadstore) SHAPE(alu, alu) SHAPE(widen_alu, widen_alu) +SHAPE(no_mask_policy, no_mask_policy) } // 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 af5474ab36e..6aadde3df6c 100644 --- a/gcc/config/riscv/riscv-vector-builtins-shapes.h +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.h @@ -30,6 +30,7 @@ extern const function_shape *const loadstore; 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; } } // end namespace riscv_vector diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc index fea2f801028..0036c81b15d 100644 --- a/gcc/config/riscv/riscv-vector-builtins.cc +++ b/gcc/config/riscv/riscv-vector-builtins.cc @@ -306,6 +306,18 @@ static CONSTEXPR const rvv_arg_type_info vv_args[] = {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info_end}; +/* A list of args for vector_type func (vector_type, vector_type, mask_type) + * function. */ +static CONSTEXPR const rvv_arg_type_info vvm_args[] + = {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info (RVV_BASE_vector), + rvv_arg_type_info (RVV_BASE_mask), rvv_arg_type_info_end}; + +/* A list of args for vector_type func (vector_type, scalar_type, mask_type) + * function. */ +static CONSTEXPR const rvv_arg_type_info vxm_args[] + = {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info (RVV_BASE_scalar), + rvv_arg_type_info (RVV_BASE_mask), rvv_arg_type_info_end}; + /* A list of args for vector_type func (signed vector_type, unsigned * vector_type) function. */ static CONSTEXPR const rvv_arg_type_info su_vv_args[] @@ -399,6 +411,10 @@ static CONSTEXPR const predication_type_index full_preds[] = {PRED_TYPE_none, PRED_TYPE_m, PRED_TYPE_tu, PRED_TYPE_tum, PRED_TYPE_tumu, PRED_TYPE_mu, NUM_PRED_TYPES}; +/* vop/vop_tu will be registered. */ +static CONSTEXPR const predication_type_index tu_preds[] + = {PRED_TYPE_none, PRED_TYPE_tu, NUM_PRED_TYPES}; + /* vop/vop_m will be registered. */ static CONSTEXPR const predication_type_index none_m_preds[] = {PRED_TYPE_none, PRED_TYPE_m, NUM_PRED_TYPES}; @@ -538,6 +554,22 @@ static CONSTEXPR const rvv_op_info iu_vvv_ops rvv_arg_type_info (RVV_BASE_vector), /* Return type */ vv_args /* Args */}; +/* A static operand information for vector_type func (vector_type, vector_type, + * mask_type) function registration. */ +static CONSTEXPR const rvv_op_info iu_vvvm_ops + = {iu_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 + = {iu_ops, /* Types */ + OP_TYPE_vxm, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + vxm_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 @@ -1086,6 +1118,9 @@ rvv_arg_type_info::get_base_vector_type (tree type) const unsigned_p = true; switch (base_type) { + case RVV_BASE_mask: + inner_mode = E_BImode; + break; case RVV_BASE_uint8_index: inner_mode = E_QImode; unsigned_p = true; @@ -1148,7 +1183,8 @@ rvv_arg_type_info::get_base_vector_type (tree type) const if (!vector_type) continue; - if (TYPE_UNSIGNED (vector_type) != unsigned_p) + if (GET_MODE_CLASS (TYPE_MODE (vector_type)) != MODE_VECTOR_BOOL + && TYPE_UNSIGNED (vector_type) != unsigned_p) continue; if (TYPE_MODE (vector_type) == mode.require ()) @@ -1217,6 +1253,7 @@ rvv_arg_type_info::get_tree_type (vector_type_index type_idx) const case RVV_BASE_quad_trunc_vector: case RVV_BASE_oct_trunc_vector: case RVV_BASE_double_trunc_unsigned_vector: + case RVV_BASE_mask: if (get_base_vector_type (builtin_types[type_idx].vector) != NUM_VECTOR_TYPES) return builtin_types[get_base_vector_type ( @@ -1624,10 +1661,13 @@ function_expander::use_exact_insn (insn_code icode) /* Record the offset to get the argument. */ int arg_offset = 0; - if (use_real_mask_p (pred)) - add_input_operand (arg_offset++); - else - add_all_one_mask_operand (mask_mode); + if (base->use_mask_predication_p ()) + { + if (use_real_mask_p (pred)) + add_input_operand (arg_offset++); + else + add_all_one_mask_operand (mask_mode); + } /* Store operation doesn't have merge operand. */ if (!function_returns_void_p ()) diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h index d033a2ea83f..4f78c299e6f 100644 --- a/gcc/config/riscv/riscv-vector-builtins.h +++ b/gcc/config/riscv/riscv-vector-builtins.h @@ -140,6 +140,7 @@ enum rvv_base_type { RVV_BASE_vector, RVV_BASE_scalar, + RVV_BASE_mask, RVV_BASE_unsigned_vector, RVV_BASE_unsigned_scalar, RVV_BASE_vector_ptr, @@ -384,6 +385,9 @@ public: /* Return true if intrinsic can be overloaded. */ virtual bool can_be_overloaded_p (enum predication_type_index) const; + /* Return true if intrinsics use mask predication. */ + virtual bool use_mask_predication_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; @@ -509,6 +513,14 @@ function_base::apply_mask_policy_p () const return true; } +/* We choose to return true by default since most of the intrinsics use + mask predication. */ +inline bool +function_base::use_mask_predication_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 cef9832d583..c3f3f1b01f8 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -33,6 +33,9 @@ UNSPEC_VMULHS UNSPEC_VMULHU UNSPEC_VMULHSU + + UNSPEC_VADC + UNSPEC_VSBC ]) (define_mode_iterator V [ diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index f9c39adb5da..3cd87f8fc6f 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -143,7 +143,8 @@ ;; 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,vext,viwalu,viwmul") + vialu,vshift,vicmp,vimul,vidiv,vsalu,\ + vext,viwalu,viwmul,vicalu") (const_int INVALID_ATTRIBUTE) (eq_attr "mode" "VNx1QI,VNx1BI") (symbol_ref "riscv_vector::get_ratio(E_VNx1QImode)") @@ -1171,6 +1172,7 @@ ;; ------------------------------------------------------------------------------- ;; Includes: ;; - 11.1 Vector Single-Width Integer Add and Subtract +;; - 11.4 Vector Integer Add-with-Carry/Subtract-with-Borrow Instructions ;; - 11.5 Vector Bitwise Logical Instructions ;; - 11.6 Vector Single-Width Bit Shift Instructions ;; - 11.9 Vector Integer Min/Max Instructions @@ -1938,6 +1940,295 @@ [(set_attr "type" "vimul") (set_attr "mode" "")]) +;; Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions +(define_insn "@pred_adc" + [(set (match_operand:VI 0 "register_operand" "=&vr, &vr") + (if_then_else:VI + (unspec: + [(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) + (unspec:VI + [(plus:VI + (match_operand:VI 2 "register_operand" " vr, vr") + (match_operand:VI 3 "vector_arith_operand" " vr, vi")) + (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" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (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_sbc" + [(set (match_operand:VI 0 "register_operand" "=&vr") + (if_then_else:VI + (unspec: + [(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) + (unspec:VI + [(minus:VI + (match_operand:VI 2 "register_operand" " vr") + (match_operand:VI 3 "register_operand" " vr")) + (match_operand: 4 "register_operand" " vm")] UNSPEC_VSBC) + (match_operand:VI 1 "vector_merge_operand" " 0vu")))] + "TARGET_VECTOR" + "vsbc.vvm\t%0,%2,%3,%4" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (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_adc_scalar" + [(set (match_operand:VI_QHS 0 "register_operand" "=&vr") + (if_then_else:VI_QHS + (unspec: + [(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) + (unspec:VI_QHS + [(plus:VI_QHS + (vec_duplicate:VI_QHS + (match_operand: 3 "register_operand" " r")) + (match_operand:VI_QHS 2 "register_operand" " vr")) + (match_operand: 4 "register_operand" " vm")] UNSPEC_VADC) + (match_operand:VI_QHS 1 "vector_merge_operand" "0vu")))] + "TARGET_VECTOR" + "vadc.vxm\t%0,%2,%3,%4" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (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_sbc_scalar" + [(set (match_operand:VI_QHS 0 "register_operand" "=&vr") + (if_then_else:VI_QHS + (unspec: + [(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) + (unspec:VI_QHS + [(minus:VI_QHS + (match_operand:VI_QHS 2 "register_operand" " vr") + (vec_duplicate:VI_QHS + (match_operand: 3 "reg_or_0_operand" " rJ"))) + (match_operand: 4 "register_operand" " vm")] UNSPEC_VSBC) + (match_operand:VI_QHS 1 "vector_merge_operand" " 0vu")))] + "TARGET_VECTOR" + "vsbc.vxm\t%0,%2,%z3,%4" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (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_expand "@pred_adc_scalar" + [(set (match_operand:VI_D 0 "register_operand") + (if_then_else:VI_D + (unspec: + [(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) + (unspec:VI_D + [(plus:VI_D + (vec_duplicate:VI_D + (match_operand: 3 "reg_or_int_operand")) + (match_operand:VI_D 2 "register_operand")) + (match_operand: 4 "register_operand")] UNSPEC_VADC) + (match_operand:VI_D 1 "vector_merge_operand")))] + "TARGET_VECTOR" + { + if (riscv_vector::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_adc (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_adc_scalar" + [(set (match_operand:VI_D 0 "register_operand" "=&vr") + (if_then_else:VI_D + (unspec: + [(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) + (unspec:VI_D + [(plus:VI_D + (vec_duplicate:VI_D + (match_operand: 3 "register_operand" " r")) + (match_operand:VI_D 2 "register_operand" " vr")) + (match_operand: 4 "register_operand" " vm")] UNSPEC_VADC) + (match_operand:VI_D 1 "vector_merge_operand" "0vu")))] + "TARGET_VECTOR" + "vadc.vxm\t%0,%2,%3,%4" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (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_adc_extended_scalar" + [(set (match_operand:VI_D 0 "register_operand" "=&vr") + (if_then_else:VI_D + (unspec: + [(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) + (unspec:VI_D + [(plus:VI_D + (vec_duplicate:VI_D + (sign_extend: + (match_operand: 3 "register_operand" " r"))) + (match_operand:VI_D 2 "register_operand" " vr")) + (match_operand: 4 "register_operand" " vm")] UNSPEC_VADC) + (match_operand:VI_D 1 "vector_merge_operand" "0vu")))] + "TARGET_VECTOR" + "vadc.vxm\t%0,%2,%3,%4" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (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_expand "@pred_sbc_scalar" + [(set (match_operand:VI_D 0 "register_operand") + (if_then_else:VI_D + (unspec: + [(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) + (unspec:VI_D + [(minus:VI_D + (match_operand:VI_D 2 "register_operand") + (vec_duplicate:VI_D + (match_operand: 3 "reg_or_int_operand"))) + (match_operand: 4 "register_operand")] UNSPEC_VSBC) + (match_operand:VI_D 1 "vector_merge_operand")))] + "TARGET_VECTOR" + { + if (!TARGET_64BIT) + { + rtx v = gen_reg_rtx (mode); + + if (riscv_vector::simm32_p (operands[3])) + { + if (!rtx_equal_p (operands[3], const0_rtx)) + operands[3] = force_reg (Pmode, operands[3]); + operands[3] = gen_rtx_SIGN_EXTEND (mode, 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_sbc (operands[0], operands[1], operands[2], + v, operands[4], operands[5], + operands[6], operands[7])); + DONE; + } + } + else + { + if (!rtx_equal_p (operands[3], const0_rtx)) + operands[3] = force_reg (mode, operands[3]); + } + }) + +(define_insn "*pred_sbc_scalar" + [(set (match_operand:VI_D 0 "register_operand" "=&vr") + (if_then_else:VI_D + (unspec: + [(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) + (unspec:VI_D + [(minus:VI_D + (match_operand:VI_D 2 "register_operand" " vr") + (vec_duplicate:VI_D + (match_operand: 3 "reg_or_0_operand" " rJ"))) + (match_operand: 4 "register_operand" " vm")] UNSPEC_VSBC) + (match_operand:VI_D 1 "vector_merge_operand" "0vu")))] + "TARGET_VECTOR" + "vsbc.vxm\t%0,%2,%z3,%4" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (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_sbc_extended_scalar" + [(set (match_operand:VI_D 0 "register_operand" "=&vr") + (if_then_else:VI_D + (unspec: + [(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) + (unspec:VI_D + [(minus:VI_D + (match_operand:VI_D 2 "register_operand" " vr") + (vec_duplicate:VI_D + (sign_extend: + (match_operand: 3 "reg_or_0_operand" " rJ")))) + (match_operand: 4 "register_operand" " vm")] UNSPEC_VSBC) + (match_operand:VI_D 1 "vector_merge_operand" "0vu")))] + "TARGET_VECTOR" + "vsbc.vxm\t%0,%2,%z3,%4" + [(set_attr "type" "vicalu") + (set_attr "mode" "") + (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])"))]) + ;; ------------------------------------------------------------------------------- ;; ---- Predicated integer unary operations ;; -------------------------------------------------------------------------------