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<mode>): New pattern.
	(@pred_msbc<mode>): Ditto.
	(@pred_madc<mode>_scalar): Ditto.
	(@pred_msbc<mode>_scalar): Ditto.
	(*pred_madc<mode>_scalar): Ditto.
	(*pred_madc<mode>_extended_scalar): Ditto.
	(*pred_msbc<mode>_scalar): Ditto.
	(*pred_msbc<mode>_extended_scalar): Ditto.
	(@pred_madc<mode>_overflow): Ditto.
	(@pred_msbc<mode>_overflow): Ditto.
	(@pred_madc<mode>_overflow_scalar): Ditto.
	(@pred_msbc<mode>_overflow_scalar): Ditto.
	(*pred_madc<mode>_overflow_scalar): Ditto.
	(*pred_madc<mode>_overflow_extended_scalar): Ditto.
	(*pred_msbc<mode>_overflow_scalar): Ditto.
	(*pred_msbc<mode>_overflow_extended_scalar): Ditto.
This commit is contained in:
Ju-Zhe Zhong 2023-02-09 04:52:36 +08:00 committed by Kito Cheng
parent b7e4f61c3e
commit dca23bf0bb
9 changed files with 642 additions and 1 deletions

View file

@ -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<false> vsetvl_obj;
static CONSTEXPR const vsetvl<true> vsetvlmax_obj;
static CONSTEXPR const loadstore<false, LST_UNIT_STRIDE, false> vle_obj;
@ -398,6 +456,8 @@ 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 vmadc vmadc_obj;
static CONSTEXPR const vmsbc vmsbc_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;
@ -468,6 +528,8 @@ BASE (vwcvt_x)
BASE (vwcvtu_x)
BASE (vadc)
BASE (vsbc)
BASE (vmadc)
BASE (vmsbc)
BASE (vsadd)
BASE (vssub)
BASE (vsaddu)

View file

@ -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;

View file

@ -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)

View file

@ -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<sew>_<op> --> vop<sew>_<op>_<type1>_<type2>. */
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

View file

@ -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

View file

@ -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++);

View file

@ -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

View file

@ -36,6 +36,9 @@
UNSPEC_VADC
UNSPEC_VSBC
UNSPEC_VMADC
UNSPEC_VMSBC
UNSPEC_OVERFLOW
])
(define_mode_iterator V [

View file

@ -1962,6 +1962,7 @@
vadc.vim\t%0,%2,%v3,%4"
[(set_attr "type" "vicalu")
(set_attr "mode" "<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" "<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" "<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" "<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" "<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" "<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" "<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" "<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<mode>"
[(set (match_operand:<VM> 0 "register_operand" "=&vr, &vr")
(unspec:<VM>
[(plus:VI
(match_operand:VI 1 "register_operand" " vr, vr")
(match_operand:VI 2 "vector_arith_operand" " vr, vi"))
(match_operand:<VM> 3 "register_operand" " vm, vm")
(unspec:<VM>
[(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" "<MODE>")
(set_attr "vl_op_idx" "4")
(set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
(define_insn "@pred_msbc<mode>"
[(set (match_operand:<VM> 0 "register_operand" "=&vr")
(unspec:<VM>
[(minus:VI
(match_operand:VI 1 "register_operand" " vr")
(match_operand:VI 2 "register_operand" " vr"))
(match_operand:<VM> 3 "register_operand" " vm")
(unspec:<VM>
[(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" "<MODE>")
(set_attr "vl_op_idx" "4")
(set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
(define_insn "@pred_madc<mode>_scalar"
[(set (match_operand:<VM> 0 "register_operand" "=&vr")
(unspec:<VM>
[(plus:VI_QHS
(vec_duplicate:VI_QHS
(match_operand:<VEL> 2 "register_operand" " r"))
(match_operand:VI_QHS 1 "register_operand" " vr"))
(match_operand:<VM> 3 "register_operand" " vm")
(unspec:<VM>
[(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" "<MODE>")
(set_attr "vl_op_idx" "4")
(set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
(define_insn "@pred_msbc<mode>_scalar"
[(set (match_operand:<VM> 0 "register_operand" "=&vr")
(unspec:<VM>
[(minus:VI_QHS
(vec_duplicate:VI_QHS
(match_operand:<VEL> 2 "reg_or_0_operand" " rJ"))
(match_operand:VI_QHS 1 "register_operand" " vr"))
(match_operand:<VM> 3 "register_operand" " vm")
(unspec:<VM>
[(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" "<MODE>")
(set_attr "vl_op_idx" "4")
(set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
(define_expand "@pred_madc<mode>_scalar"
[(set (match_operand:<VM> 0 "register_operand")
(unspec:<VM>
[(plus:VI_D
(vec_duplicate:VI_D
(match_operand:<VEL> 2 "reg_or_int_operand"))
(match_operand:VI_D 1 "register_operand"))
(match_operand:<VM> 3 "register_operand")
(unspec:<VM>
[(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 (<VEL>mode, operands[2]);
else if (!TARGET_64BIT)
{
rtx v = gen_reg_rtx (<MODE>mode);
if (riscv_vector::simm32_p (operands[2]))
operands[2] = gen_rtx_SIGN_EXTEND (<VEL>mode,
force_reg (Pmode, operands[2]));
else
{
if (CONST_INT_P (operands[2]))
operands[2] = force_reg (<VEL>mode, operands[2]);
riscv_vector::emit_nonvlmax_op (code_for_pred_broadcast (<MODE>mode),
v, operands[2], operands[5],
<VM>mode);
emit_insn (gen_pred_madc<mode> (operands[0], operands[1], v, operands[3],
operands[4], operands[5]));
DONE;
}
}
else
operands[2] = force_reg (<VEL>mode, operands[2]);
})
(define_insn "*pred_madc<mode>_scalar"
[(set (match_operand:<VM> 0 "register_operand" "=&vr")
(unspec:<VM>
[(plus:VI_D
(vec_duplicate:VI_D
(match_operand:<VEL> 2 "register_operand" " r"))
(match_operand:VI_D 1 "register_operand" " vr"))
(match_operand:<VM> 3 "register_operand" " vm")
(unspec:<VM>
[(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" "<MODE>")
(set_attr "vl_op_idx" "4")
(set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
(define_insn "*pred_madc<mode>_extended_scalar"
[(set (match_operand:<VM> 0 "register_operand" "=&vr")
(unspec:<VM>
[(plus:VI_D
(vec_duplicate:VI_D
(sign_extend:<VEL>
(match_operand:<VSUBEL> 2 "register_operand" " r")))
(match_operand:VI_D 1 "register_operand" " vr"))
(match_operand:<VM> 3 "register_operand" " vm")
(unspec:<VM>
[(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" "<MODE>")
(set_attr "vl_op_idx" "4")
(set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
(define_expand "@pred_msbc<mode>_scalar"
[(set (match_operand:<VM> 0 "register_operand")
(unspec:<VM>
[(minus:VI_D
(vec_duplicate:VI_D
(match_operand:<VEL> 2 "reg_or_int_operand"))
(match_operand:VI_D 1 "register_operand"))
(match_operand:<VM> 3 "register_operand")
(unspec:<VM>
[(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>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 (<VEL>mode, operands[2]);
}
else
{
if (CONST_INT_P (operands[2]))
operands[2] = force_reg (<VEL>mode, operands[2]);
riscv_vector::emit_nonvlmax_op (code_for_pred_broadcast (<MODE>mode),
v, operands[2], operands[5],
<VM>mode);
emit_insn (gen_pred_msbc<mode> (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 (<VEL>mode, operands[2]);
}
})
(define_insn "*pred_msbc<mode>_scalar"
[(set (match_operand:<VM> 0 "register_operand" "=&vr")
(unspec:<VM>
[(minus:VI_D
(vec_duplicate:VI_D
(match_operand:<VEL> 2 "reg_or_0_operand" " rJ"))
(match_operand:VI_D 1 "register_operand" " vr"))
(match_operand:<VM> 3 "register_operand" " vm")
(unspec:<VM>
[(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" "<MODE>")
(set_attr "vl_op_idx" "4")
(set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
(define_insn "*pred_msbc<mode>_extended_scalar"
[(set (match_operand:<VM> 0 "register_operand" "=&vr")
(unspec:<VM>
[(minus:VI_D
(vec_duplicate:VI_D
(sign_extend:<VEL>
(match_operand:<VSUBEL> 2 "reg_or_0_operand" " rJ")))
(match_operand:VI_D 1 "register_operand" " vr"))
(match_operand:<VM> 3 "register_operand" " vm")
(unspec:<VM>
[(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" "<MODE>")
(set_attr "vl_op_idx" "4")
(set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
(define_insn "@pred_madc<mode>_overflow"
[(set (match_operand:<VM> 0 "register_operand" "=&vr, &vr")
(unspec:<VM>
[(plus:VI
(match_operand:VI 1 "register_operand" " vr, vr")
(match_operand:VI 2 "vector_arith_operand" " vr, vi"))
(unspec:<VM>
[(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" "<MODE>")
(set_attr "vl_op_idx" "3")
(set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
(define_insn "@pred_msbc<mode>_overflow"
[(set (match_operand:<VM> 0 "register_operand" "=&vr")
(unspec:<VM>
[(minus:VI
(match_operand:VI 1 "register_operand" " vr")
(match_operand:VI 2 "register_operand" " vr"))
(unspec:<VM>
[(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" "<MODE>")
(set_attr "vl_op_idx" "3")
(set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
(define_insn "@pred_madc<mode>_overflow_scalar"
[(set (match_operand:<VM> 0 "register_operand" "=&vr")
(unspec:<VM>
[(plus:VI_QHS
(vec_duplicate:VI_QHS
(match_operand:<VEL> 2 "register_operand" " r"))
(match_operand:VI_QHS 1 "register_operand" " vr"))
(unspec:<VM>
[(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" "<MODE>")
(set_attr "vl_op_idx" "3")
(set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
(define_insn "@pred_msbc<mode>_overflow_scalar"
[(set (match_operand:<VM> 0 "register_operand" "=&vr")
(unspec:<VM>
[(minus:VI_QHS
(vec_duplicate:VI_QHS
(match_operand:<VEL> 2 "reg_or_0_operand" " rJ"))
(match_operand:VI_QHS 1 "register_operand" " vr"))
(unspec:<VM>
[(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" "<MODE>")
(set_attr "vl_op_idx" "3")
(set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
(define_expand "@pred_madc<mode>_overflow_scalar"
[(set (match_operand:<VM> 0 "register_operand")
(unspec:<VM>
[(plus:VI_D
(vec_duplicate:VI_D
(match_operand:<VEL> 2 "reg_or_int_operand"))
(match_operand:VI_D 1 "register_operand"))
(unspec:<VM>
[(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 (<VEL>mode, operands[2]);
else if (!TARGET_64BIT)
{
rtx v = gen_reg_rtx (<MODE>mode);
if (riscv_vector::simm32_p (operands[2]))
operands[2] = gen_rtx_SIGN_EXTEND (<VEL>mode,
force_reg (Pmode, operands[2]));
else
{
if (CONST_INT_P (operands[2]))
operands[2] = force_reg (<VEL>mode, operands[2]);
riscv_vector::emit_nonvlmax_op (code_for_pred_broadcast (<MODE>mode),
v, operands[2], operands[3],
<VM>mode);
emit_insn (gen_pred_madc<mode>_overflow (operands[0], operands[1],
v, operands[3], operands[4]));
DONE;
}
}
else
operands[2] = force_reg (<VEL>mode, operands[2]);
})
(define_insn "*pred_madc<mode>_overflow_scalar"
[(set (match_operand:<VM> 0 "register_operand" "=&vr")
(unspec:<VM>
[(plus:VI_D
(vec_duplicate:VI_D
(match_operand:<VEL> 2 "register_operand" " r"))
(match_operand:VI_D 1 "register_operand" " vr"))
(unspec:<VM>
[(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" "<MODE>")
(set_attr "vl_op_idx" "3")
(set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
(define_insn "*pred_madc<mode>_overflow_extended_scalar"
[(set (match_operand:<VM> 0 "register_operand" "=&vr")
(unspec:<VM>
[(plus:VI_D
(vec_duplicate:VI_D
(sign_extend:<VEL>
(match_operand:<VSUBEL> 2 "register_operand" " r")))
(match_operand:VI_D 1 "register_operand" " vr"))
(unspec:<VM>
[(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" "<MODE>")
(set_attr "vl_op_idx" "3")
(set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
(define_expand "@pred_msbc<mode>_overflow_scalar"
[(set (match_operand:<VM> 0 "register_operand")
(unspec:<VM>
[(minus:VI_D
(vec_duplicate:VI_D
(match_operand:<VEL> 2 "reg_or_int_operand"))
(match_operand:VI_D 1 "register_operand"))
(unspec:<VM>
[(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>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 (<VEL>mode, operands[2]);
}
else
{
if (CONST_INT_P (operands[2]))
operands[2] = force_reg (<VEL>mode, operands[2]);
riscv_vector::emit_nonvlmax_op (code_for_pred_broadcast (<MODE>mode),
v, operands[2], operands[3],
<VM>mode);
emit_insn (gen_pred_msbc<mode>_overflow (operands[0], operands[1],
v, operands[3], operands[4]));
DONE;
}
}
else
{
if (!rtx_equal_p (operands[2], const0_rtx))
operands[2] = force_reg (<VEL>mode, operands[2]);
}
})
(define_insn "*pred_msbc<mode>_overflow_scalar"
[(set (match_operand:<VM> 0 "register_operand" "=&vr")
(unspec:<VM>
[(minus:VI_D
(vec_duplicate:VI_D
(match_operand:<VEL> 2 "reg_or_0_operand" " rJ"))
(match_operand:VI_D 1 "register_operand" " vr"))
(unspec:<VM>
[(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" "<MODE>")
(set_attr "vl_op_idx" "3")
(set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
(define_insn "*pred_msbc<mode>_overflow_extended_scalar"
[(set (match_operand:<VM> 0 "register_operand" "=&vr")
(unspec:<VM>
[(minus:VI_D
(vec_duplicate:VI_D
(sign_extend:<VEL>
(match_operand:<VSUBEL> 2 "reg_or_0_operand" " rJ")))
(match_operand:VI_D 1 "register_operand" " vr"))
(unspec:<VM>
[(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" "<MODE>")
(set_attr "vl_op_idx" "3")
(set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
;; -------------------------------------------------------------------------------
;; ---- Predicated integer unary operations
;; -------------------------------------------------------------------------------