From: Ju-Zhe Zhong <juzhe.zh...@rivai.ai> 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<mode>): New pattern. (@pred_sbc<mode>): Ditto. (@pred_adc<mode>_scalar): Ditto. (@pred_sbc<mode>_scalar): Ditto. (*pred_adc<mode>_scalar): Ditto. (*pred_adc<mode>_extended_scalar): Ditto. (*pred_sbc<mode>_scalar): Ditto. (*pred_sbc<mode>_extended_scalar): Ditto. --- gcc/config/riscv/riscv-protos.h | 1 + gcc/config/riscv/riscv-v.cc | 2 +- .../riscv/riscv-vector-builtins-bases.cc | 46 +++ .../riscv/riscv-vector-builtins-bases.h | 2 + .../riscv/riscv-vector-builtins-functions.def | 4 + .../riscv/riscv-vector-builtins-shapes.cc | 22 ++ .../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 | 295 +++++++++++++++++- 11 files changed, 430 insertions(+), 8 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<false> vsetvl_obj; static CONSTEXPR const vsetvl<true> vsetvlmax_obj; static CONSTEXPR const loadstore<false, LST_UNIT_STRIDE, false> vle_obj; @@ -354,6 +396,8 @@ static CONSTEXPR const widen_binop<MULT, ZERO_EXTEND>vwmulu_obj; static CONSTEXPR const vwmulsu vwmulsu_obj; static CONSTEXPR const vwcvt<SIGN_EXTEND> vwcvt_x_obj; static CONSTEXPR const vwcvt<ZERO_EXTEND> vwcvtu_x_obj; +static CONSTEXPR const vadc vadc_obj; +static CONSTEXPR const vsbc vsbc_obj; static CONSTEXPR const binop<SS_PLUS> vsadd_obj; static CONSTEXPR const binop<SS_MINUS> vssub_obj; static CONSTEXPR const binop<US_PLUS> 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<sew>_<op> --> vop<sew>_<op>_<type>. */ + 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 8462c8cdc7d..afdc3c4c6d6 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..858415bd6b1 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 d526c1fc5f1..aaac32efcce 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)") @@ -764,7 +765,7 @@ "@ vlm.v\t%0,%3 vsm.v\t%3,%0 - # +# vmclr.m\t%0 vmset.m\t%0" "&& register_operand (operands[0], <MODE>mode) @@ -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" "<MODE>")]) +;; Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions +(define_insn "@pred_adc<mode>" + [(set (match_operand:VI 0 "register_operand" "=&vr, &vr") + (if_then_else:VI + (unspec:<VM> + [(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:<VM> 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" "<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<mode>" + [(set (match_operand:VI 0 "register_operand" "=&vr") + (if_then_else:VI + (unspec:<VM> + [(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:<VM> 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" "<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<mode>_scalar" + [(set (match_operand:VI_QHS 0 "register_operand" "=&vr") + (if_then_else:VI_QHS + (unspec:<VM> + [(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:<VEL> 3 "register_operand" " r")) + (match_operand:VI_QHS 2 "register_operand" " vr")) + (match_operand:<VM> 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" "<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<mode>_scalar" + [(set (match_operand:VI_QHS 0 "register_operand" "=&vr") + (if_then_else:VI_QHS + (unspec:<VM> + [(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:<VEL> 3 "reg_or_0_operand" " rJ"))) + (match_operand:<VM> 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" "<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<mode>_scalar" + [(set (match_operand:VI_D 0 "register_operand") + (if_then_else:VI_D + (unspec:<VM> + [(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:<VEL> 3 "reg_or_int_operand")) + (match_operand:VI_D 2 "register_operand")) + (match_operand:<VM> 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 (<VEL>mode, operands[3]); + else if (!TARGET_64BIT) + { + rtx v = gen_reg_rtx (<MODE>mode); + + if (riscv_vector::simm32_p (operands[3])) + operands[3] = gen_rtx_SIGN_EXTEND (<VEL>mode, + force_reg (Pmode, operands[3])); + else + { + if (CONST_INT_P (operands[3])) + operands[3] = force_reg (<VEL>mode, operands[3]); + + riscv_vector::emit_nonvlmax_op (code_for_pred_broadcast (<MODE>mode), + v, operands[3], operands[5], + <VM>mode); + emit_insn (gen_pred_adc<mode> (operands[0], operands[1], operands[2], + v, operands[4], operands[5], + operands[6], operands[7])); + DONE; + } + } + else + operands[3] = force_reg (<VEL>mode, operands[3]); + }) + +(define_insn "*pred_adc<mode>_scalar" + [(set (match_operand:VI_D 0 "register_operand" "=&vr") + (if_then_else:VI_D + (unspec:<VM> + [(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:<VEL> 3 "register_operand" " r")) + (match_operand:VI_D 2 "register_operand" " vr")) + (match_operand:<VM> 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" "<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<mode>_extended_scalar" + [(set (match_operand:VI_D 0 "register_operand" "=&vr") + (if_then_else:VI_D + (unspec:<VM> + [(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:<VEL> + (match_operand:<VSUBEL> 3 "register_operand" " r"))) + (match_operand:VI_D 2 "register_operand" " vr")) + (match_operand:<VM> 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" "<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<mode>_scalar" + [(set (match_operand:VI_D 0 "register_operand") + (if_then_else:VI_D + (unspec:<VM> + [(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:<VEL> 3 "reg_or_int_operand"))) + (match_operand:<VM> 4 "register_operand")] UNSPEC_VSBC) + (match_operand:VI_D 1 "vector_merge_operand")))] + "TARGET_VECTOR" + { + if (!TARGET_64BIT) + { + rtx v = gen_reg_rtx (<MODE>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 (<VEL>mode, operands[3]); + } + else + { + if (CONST_INT_P (operands[3])) + operands[3] = force_reg (<VEL>mode, operands[3]); + + riscv_vector::emit_nonvlmax_op (code_for_pred_broadcast (<MODE>mode), + v, operands[3], operands[5], + <VM>mode); + emit_insn (gen_pred_sbc<mode> (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 (<VEL>mode, operands[3]); + } + }) + +(define_insn "*pred_sbc<mode>_scalar" + [(set (match_operand:VI_D 0 "register_operand" "=&vr") + (if_then_else:VI_D + (unspec:<VM> + [(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:<VEL> 3 "reg_or_0_operand" " rJ"))) + (match_operand:<VM> 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" "<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<mode>_extended_scalar" + [(set (match_operand:VI_D 0 "register_operand" "=&vr") + (if_then_else:VI_D + (unspec:<VM> + [(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:<VEL> + (match_operand:<VSUBEL> 3 "reg_or_0_operand" " rJ")))) + (match_operand:<VM> 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" "<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 ;; ------------------------------------------------------------------------------- -- 2.36.1