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:
parent
b7e4f61c3e
commit
dca23bf0bb
9 changed files with 642 additions and 1 deletions
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -36,6 +36,9 @@
|
|||
|
||||
UNSPEC_VADC
|
||||
UNSPEC_VSBC
|
||||
UNSPEC_VMADC
|
||||
UNSPEC_VMSBC
|
||||
UNSPEC_OVERFLOW
|
||||
])
|
||||
|
||||
(define_mode_iterator V [
|
||||
|
|
|
@ -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
|
||||
;; -------------------------------------------------------------------------------
|
||||
|
|
Loading…
Add table
Reference in a new issue