}
};
+/* Implements vmand/vmnand/vmandn/vmxor/vmor/vmnor/vmorn/vmxnor */
+template<rtx_code CODE>
+class mask_logic : public function_base
+{
+public:
+ bool apply_tail_policy_p () const override { return false; }
+ bool apply_mask_policy_p () const override { return false; }
+
+ rtx expand (function_expander &e) const override
+ {
+ return e.use_exact_insn (code_for_pred (CODE, e.vector_mode ()));
+ }
+};
+template<rtx_code CODE>
+class mask_nlogic : public function_base
+{
+public:
+ bool apply_tail_policy_p () const override { return false; }
+ bool apply_mask_policy_p () const override { return false; }
+
+ rtx expand (function_expander &e) const override
+ {
+ return e.use_exact_insn (code_for_pred_n (CODE, e.vector_mode ()));
+ }
+};
+template<rtx_code CODE>
+class mask_notlogic : public function_base
+{
+public:
+ bool apply_tail_policy_p () const override { return false; }
+ bool apply_mask_policy_p () const override { return false; }
+
+ rtx expand (function_expander &e) const override
+ {
+ return e.use_exact_insn (code_for_pred_not (CODE, e.vector_mode ()));
+ }
+};
+
+/* Implements vmmv. */
+class vmmv : public function_base
+{
+public:
+ bool apply_tail_policy_p () const override { return false; }
+ bool apply_mask_policy_p () const override { return false; }
+
+ rtx expand (function_expander &e) const override
+ {
+ return e.use_exact_insn (code_for_pred_mov (e.vector_mode ()));
+ }
+};
+
+/* Implements vmclr. */
+class vmclr : public function_base
+{
+public:
+ bool can_be_overloaded_p (enum predication_type_index) const override
+ {
+ return false;
+ }
+
+ rtx expand (function_expander &e) const override
+ {
+ machine_mode mode = TYPE_MODE (TREE_TYPE (e.exp));
+ e.add_all_one_mask_operand (mode);
+ e.add_vundef_operand (mode);
+ e.add_input_operand (mode, CONST0_RTX (mode));
+ e.add_input_operand (call_expr_nargs (e.exp) - 1);
+ e.add_input_operand (Pmode, get_avl_type_rtx (avl_type::NONVLMAX));
+ return e.generate_insn (code_for_pred_mov (e.vector_mode ()));
+ }
+};
+
+/* Implements vmset. */
+class vmset : public function_base
+{
+public:
+ bool can_be_overloaded_p (enum predication_type_index) const override
+ {
+ return false;
+ }
+
+ rtx expand (function_expander &e) const override
+ {
+ machine_mode mode = TYPE_MODE (TREE_TYPE (e.exp));
+ e.add_all_one_mask_operand (mode);
+ e.add_vundef_operand (mode);
+ e.add_input_operand (mode, CONSTM1_RTX (mode));
+ e.add_input_operand (call_expr_nargs (e.exp) - 1);
+ e.add_input_operand (Pmode, get_avl_type_rtx (avl_type::NONVLMAX));
+ return e.generate_insn (code_for_pred_mov (e.vector_mode ()));
+ }
+};
+
+/* Implements vmnot. */
+class vmnot : public function_base
+{
+public:
+ bool apply_tail_policy_p () const override { return false; }
+ bool apply_mask_policy_p () const override { return false; }
+
+ rtx expand (function_expander &e) const override
+ {
+ return e.use_exact_insn (code_for_pred_not (e.vector_mode ()));
+ }
+};
+
+/* Implements vcpop. */
+class vcpop : public function_base
+{
+public:
+ bool apply_tail_policy_p () const override { return false; }
+ bool apply_mask_policy_p () const override { return false; }
+ bool has_merge_operand_p () const override { return false; }
+
+ rtx expand (function_expander &e) const override
+ {
+ return e.use_exact_insn (code_for_pred_popcount (e.vector_mode (), Pmode));
+ }
+};
+
+/* Implements vfirst. */
+class vfirst : public function_base
+{
+public:
+ bool apply_tail_policy_p () const override { return false; }
+ bool apply_mask_policy_p () const override { return false; }
+ bool has_merge_operand_p () const override { return false; }
+
+ rtx expand (function_expander &e) const override
+ {
+ return e.use_exact_insn (code_for_pred_ffs (e.vector_mode (), Pmode));
+ }
+};
+
+/* Implements vmsbf/vmsif/vmsof. */
+template<int UNSPEC>
+class mask_misc : public function_base
+{
+public:
+ bool apply_tail_policy_p () const override { return false; }
+
+ rtx expand (function_expander &e) const override
+ {
+ return e.use_exact_insn (code_for_pred (UNSPEC, e.vector_mode ()));
+ }
+};
+
+/* Implements viota. */
+class viota : public function_base
+{
+public:
+ bool can_be_overloaded_p (enum predication_type_index pred) const override
+ {
+ return pred == PRED_TYPE_tu || pred == PRED_TYPE_tum
+ || pred == PRED_TYPE_tumu;
+ }
+
+ rtx expand (function_expander &e) const override
+ {
+ return e.use_exact_insn (code_for_pred_iota (e.vector_mode ()));
+ }
+};
+
+/* Implements vid. */
+class vid : public function_base
+{
+public:
+ bool can_be_overloaded_p (enum predication_type_index pred) const override
+ {
+ return pred == PRED_TYPE_tu || pred == PRED_TYPE_tum
+ || pred == PRED_TYPE_tumu;
+ }
+
+ rtx expand (function_expander &e) const override
+ {
+ return e.use_exact_insn (code_for_pred_series (e.vector_mode ()));
+ }
+};
+
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;
static CONSTEXPR const sat_op<UNSPEC_VSSRA> vssra_obj;
static CONSTEXPR const vnclip<UNSPEC_VNCLIP> vnclip_obj;
static CONSTEXPR const vnclip<UNSPEC_VNCLIPU> vnclipu_obj;
+static CONSTEXPR const mask_logic<AND> vmand_obj;
+static CONSTEXPR const mask_nlogic<AND> vmnand_obj;
+static CONSTEXPR const mask_notlogic<AND> vmandn_obj;
+static CONSTEXPR const mask_logic<XOR> vmxor_obj;
+static CONSTEXPR const mask_logic<IOR> vmor_obj;
+static CONSTEXPR const mask_nlogic<IOR> vmnor_obj;
+static CONSTEXPR const mask_notlogic<IOR> vmorn_obj;
+static CONSTEXPR const mask_nlogic<XOR> vmxnor_obj;
+static CONSTEXPR const vmmv vmmv_obj;
+static CONSTEXPR const vmclr vmclr_obj;
+static CONSTEXPR const vmset vmset_obj;
+static CONSTEXPR const vmnot vmnot_obj;
+static CONSTEXPR const vcpop vcpop_obj;
+static CONSTEXPR const vfirst vfirst_obj;
+static CONSTEXPR const mask_misc<UNSPEC_VMSBF> vmsbf_obj;
+static CONSTEXPR const mask_misc<UNSPEC_VMSIF> vmsif_obj;
+static CONSTEXPR const mask_misc<UNSPEC_VMSOF> vmsof_obj;
+static CONSTEXPR const viota viota_obj;
+static CONSTEXPR const vid vid_obj;
/* Declare the function base NAME, pointing it to an instance
of class <NAME>_obj. */
BASE (vssrl)
BASE (vnclip)
BASE (vnclipu)
+BASE (vmand)
+BASE (vmnand)
+BASE (vmandn)
+BASE (vmxor)
+BASE (vmor)
+BASE (vmnor)
+BASE (vmorn)
+BASE (vmxnor)
+BASE (vmmv)
+BASE (vmclr)
+BASE (vmset)
+BASE (vmnot)
+BASE (vcpop)
+BASE (vfirst)
+BASE (vmsbf)
+BASE (vmsif)
+BASE (vmsof)
+BASE (viota)
+BASE (vid)
} // end namespace riscv_vector
extern const function_base *const vnclip;
extern const function_base *const vnclipu;
extern const function_base *const vnclipu;
+extern const function_base *const vmand;
+extern const function_base *const vmnand;
+extern const function_base *const vmandn;
+extern const function_base *const vmxor;
+extern const function_base *const vmor;
+extern const function_base *const vmnor;
+extern const function_base *const vmorn;
+extern const function_base *const vmxnor;
+extern const function_base *const vmmv;
+extern const function_base *const vmclr;
+extern const function_base *const vmset;
+extern const function_base *const vmnot;
+extern const function_base *const vcpop;
+extern const function_base *const vfirst;
+extern const function_base *const vmsbf;
+extern const function_base *const vmsif;
+extern const function_base *const vmsof;
+extern const function_base *const viota;
+extern const function_base *const vid;
}
} // end namespace riscv_vector
/* TODO: 13. Vector Floating-Point Instructions. */
/* TODO: 14. Vector Reduction Operations. */
-/* TODO: 15. Vector Mask Instructions. */
+
+/* 15. Vector Mask Instructions. */
+
+// 15.1. Vector Mask-Register Logical Instructions
+DEF_RVV_FUNCTION (vmand, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmnand, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmandn, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmxor, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmor, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmnor, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmorn, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmxnor, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmmv, mask_alu, none_preds, b_mm_ops)
+DEF_RVV_FUNCTION (vmclr, mask_alu, none_preds, b_m_ops)
+DEF_RVV_FUNCTION (vmset, mask_alu, none_preds, b_m_ops)
+DEF_RVV_FUNCTION (vmnot, mask_alu, none_preds, b_mm_ops)
+// 15.2. Vector count population in mask vcpop.m
+DEF_RVV_FUNCTION (vcpop, mask_alu, none_m_preds, b_ulong_m_ops)
+// 15.3. vfirst find-first-set mask bit
+DEF_RVV_FUNCTION (vfirst, mask_alu, none_m_preds, b_long_m_ops)
+// 15.4. vmsbf.m set-before-first mask bit
+DEF_RVV_FUNCTION (vmsbf, mask_alu, none_m_mu_preds, b_mm_ops)
+// 15.5. vmsif.m set-including-first mask bit
+DEF_RVV_FUNCTION (vmsif, mask_alu, none_m_mu_preds, b_mm_ops)
+// 15.6. vmsof.m set-only-first mask bit
+DEF_RVV_FUNCTION (vmsof, mask_alu, none_m_mu_preds, b_mm_ops)
+// 15.8. Vector Iota Instruction
+DEF_RVV_FUNCTION (viota, mask_alu, full_preds, u_vm_ops)
+// 15.9. Vector Element Index Instruction
+DEF_RVV_FUNCTION (vid, alu, full_preds, u_v_ops)
+
/* TODO: 16. Vector Permutation Instructions. */
#undef DEF_RVV_FUNCTION
char *get_name (function_builder &b, const function_instance &instance,
bool overloaded_p) const override
{
+ /* Return nullptr if it can not be overloaded. */
+ if (overloaded_p && !instance.base->can_be_overloaded_p (instance.pred))
+ return nullptr;
+
b.append_base_name (instance.base_name);
/* vop<sew> --> vop<sew>_<op>. According to rvv-intrinsic-doc, _vv/_vx/_v
b.append_name (type_suffixes[instance.type.index].vector);
}
+ /* According to rvv-intrinsic-doc, it does not add "_m" suffix
+ for vop_m C++ overloaded API. */
+ if (overloaded_p && instance.pred == PRED_TYPE_m)
+ return b.finish_name ();
+ b.append_name (predication_suffixes[instance.pred]);
+ return b.finish_name ();
+ }
+};
+
+/* mask_alu_def class. */
+struct mask_alu_def : public build_base
+{
+ char *get_name (function_builder &b, const function_instance &instance,
+ bool overloaded_p) const override
+ {
+ /* Return nullptr if it can not be overloaded. */
+ if (overloaded_p && !instance.base->can_be_overloaded_p (instance.pred))
+ return nullptr;
+
+ b.append_base_name (instance.base_name);
+
+ if (instance.op_info->op == OP_TYPE_mm || instance.op_info->op == OP_TYPE_m)
+ 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);
+
+ /* According to rvv-intrinsic-doc, it does not add "_m" suffix
+ for vop_m C++ overloaded API. */
+ if (overloaded_p && instance.pred == PRED_TYPE_m)
+ return b.finish_name ();
b.append_name (predication_suffixes[instance.pred]);
return b.finish_name ();
}
SHAPE(return_mask, return_mask)
SHAPE(narrow_alu, narrow_alu)
SHAPE(move, move)
+SHAPE(mask_alu, mask_alu)
} // end namespace riscv_vector
extern const function_shape *const return_mask;
extern const function_shape *const narrow_alu;
extern const function_shape *const move;
+extern const function_shape *const mask_alu;
}
} // end namespace riscv_vector
static CONSTEXPR const rvv_arg_type_info void_args[]
= {rvv_arg_type_info (RVV_BASE_void), rvv_arg_type_info_end};
+/* A list of args for size_t func () function. */
+static CONSTEXPR const rvv_arg_type_info end_args[]
+ = {rvv_arg_type_info_end};
+
/* A list of args for size_t func (size_t) function. */
static CONSTEXPR const rvv_arg_type_info size_args[]
= {rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info_end};
static CONSTEXPR const rvv_arg_type_info v_args[]
= {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info_end};
+/* A list of args for vector_type func (vector_type) function. */
+static CONSTEXPR const rvv_arg_type_info m_args[]
+ = {rvv_arg_type_info (RVV_BASE_mask), rvv_arg_type_info_end};
+
/* A list of args for vector_type func (scalar_type) function. */
static CONSTEXPR const rvv_arg_type_info x_args[]
= {rvv_arg_type_info (RVV_BASE_scalar), rvv_arg_type_info_end};
rvv_arg_type_info (RVV_BASE_void), /* Return type */
scalar_ptr_args /* Args */};
+/* A static operand information for vector_type func (vector_type, vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info b_mmm_ops
+ = {b_ops, /* Types */
+ OP_TYPE_mm, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ vv_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info b_mm_ops
+ = {b_ops, /* Types */
+ OP_TYPE_m, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ v_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info u_vm_ops
+ = {u_ops, /* Types */
+ OP_TYPE_m, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ m_args /* Args */};
+
+/* A static operand information for vector_type func ()
+ * function registration. */
+static CONSTEXPR const rvv_op_info b_m_ops
+ = {b_ops, /* Types */
+ OP_TYPE_m, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ end_args /* Args */};
+
+/* A static operand information for vector_type func ()
+ * function registration. */
+static CONSTEXPR const rvv_op_info u_v_ops
+ = {u_ops, /* Types */
+ OP_TYPE_v, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ end_args /* Args */};
+
+/* A static operand information for unsigned long func (vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info b_ulong_m_ops
+ = {b_ops, /* Types */
+ OP_TYPE_m, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_unsigned_long), /* Return type */
+ v_args /* Args */};
+
+/* A static operand information for long func (vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info b_long_m_ops
+ = {b_ops, /* Types */
+ OP_TYPE_m, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_long), /* Return type */
+ v_args /* Args */};
+
/* A static operand information for vector_type func (const scalar_type *,
* ptrdiff_t) function registration. */
static CONSTEXPR const rvv_op_info all_v_scalar_const_ptr_ptrdiff_ops
if (!has_vl_op (rinsn) || !REG_P (get_vl (rinsn)))
continue;
rtx avl = get_vl (rinsn);
- if (count_occurrences (PATTERN (rinsn), avl, true) == 1)
+ if (count_occurrences (PATTERN (rinsn), avl, 0) == 1)
{
/* Get the list of uses for the new instruction. */
auto attempt = crtl->ssa->new_change_attempt ();
use_array new_uses = use_array (uses_builder.finish ());
change.new_uses = new_uses;
change.move_range = insn->ebb ()->insn_range ();
- rtx pat = simplify_replace_rtx (PATTERN (rinsn), avl, const0_rtx);
+ rtx set = single_set (rinsn);
+ rtx src = simplify_replace_rtx (SET_SRC (set), avl, const0_rtx);
+ rtx pat = gen_rtx_SET (SET_DEST (set), src);
gcc_assert (change_insn (crtl->ssa, change, insn, pat));
}
}
UNSPEC_VASUBU
UNSPEC_VASUB
UNSPEC_VSMUL
+
+ UNSPEC_VMSBF
+ UNSPEC_VMSIF
+ UNSPEC_VMSOF
+ UNSPEC_VIOTA
])
(define_mode_iterator V [
UNSPEC_VASUBU UNSPEC_VASUB UNSPEC_VSMUL])
(define_int_iterator VSAT_SHIFT_OP [UNSPEC_VSSRL UNSPEC_VSSRA])
+(define_int_iterator VMISC [UNSPEC_VMSBF UNSPEC_VMSIF UNSPEC_VMSOF])
+
(define_int_attr order [
(UNSPEC_ORDERED "o") (UNSPEC_UNORDERED "u")
])
(UNSPEC_VSSRA "vsshift") (UNSPEC_VNCLIP "vnclip")
(UNSPEC_VNCLIPU "vnclip")])
+(define_int_attr misc_op [(UNSPEC_VMSBF "sbf") (UNSPEC_VMSIF "sif") (UNSPEC_VMSOF "sof")])
+
(define_code_iterator any_int_binop [plus minus and ior xor ashift ashiftrt lshiftrt
smax umax smin umin mult div udiv mod umod
])
vialu,vshift,vicmp,vimul,vidiv,vsalu,\
vext,viwalu,viwmul,vicalu,vnshift,\
vimuladd,vimerge,vaalu,vsmul,vsshift,\
- vnclip,viminmax,viwmuladd")
+ vnclip,viminmax,viwmuladd,vmpop,vmffs,vmsfs,\
+ vmiota,vmidx")
(const_int INVALID_ATTRIBUTE)
(eq_attr "mode" "VNx1QI,VNx1BI")
(symbol_ref "riscv_vector::get_ratio(E_VNx1QImode)")
(define_attr "merge_op_idx" ""
(cond [(eq_attr "type" "vlde,vimov,vfmov,vldm,vlds,vmalu,vldux,vldox,vicmp,\
vialu,vshift,viminmax,vimul,vidiv,vsalu,vext,viwalu,\
- viwmul,vnshift,vaalu,vsmul,vsshift,vnclip")
+ viwmul,vnshift,vaalu,vsmul,vsshift,vnclip,vmsfs,\
+ vmiota,vmidx")
(const_int 2)
(eq_attr "type" "vimerge")
;; The index of operand[] to get the avl op.
(define_attr "vl_op_idx" ""
(cond [(eq_attr "type" "vlde,vste,vimov,vfmov,vldm,vstm,vmalu,vsts,vstux,\
- vstox,vext")
+ vstox,vext,vmsfs,vmiota")
(const_int 4)
;; If operands[3] of "vlds" is not vector mode, it is pred_broadcast.
vsshift,vnclip")
(const_int 5)
- (eq_attr "type" "vicmp")
+ (eq_attr "type" "vicmp,vimuladd,viwmuladd")
(const_int 6)
- (eq_attr "type" "vimuladd,viwmuladd")
- (const_int 6)]
+ (eq_attr "type" "vmpop,vmffs,vmidx")
+ (const_int 3)]
(const_int INVALID_ATTRIBUTE)))
;; The tail policy op value.
(define_attr "ta" ""
- (cond [(eq_attr "type" "vlde,vimov,vfmov,vext")
+ (cond [(eq_attr "type" "vlde,vimov,vfmov,vext,vmiota")
(symbol_ref "riscv_vector::get_ta(operands[5])")
;; If operands[3] of "vlds" is not vector mode, it is pred_broadcast.
(symbol_ref "riscv_vector::get_ta(operands[6])")
(eq_attr "type" "vimuladd,viwmuladd")
- (symbol_ref "riscv_vector::get_ta(operands[7])")]
+ (symbol_ref "riscv_vector::get_ta(operands[7])")
+
+ (eq_attr "type" "vmidx")
+ (symbol_ref "riscv_vector::get_ta(operands[4])")]
(const_int INVALID_ATTRIBUTE)))
;; The mask policy op value.
(define_attr "ma" ""
- (cond [(eq_attr "type" "vlde,vext")
+ (cond [(eq_attr "type" "vlde,vext,vmiota")
(symbol_ref "riscv_vector::get_ma(operands[6])")
;; If operands[3] of "vlds" is not vector mode, it is pred_broadcast.
(symbol_ref "riscv_vector::get_ma(operands[7])")
(eq_attr "type" "vimuladd,viwmuladd")
- (symbol_ref "riscv_vector::get_ma(operands[8])")]
+ (symbol_ref "riscv_vector::get_ma(operands[8])")
+
+ (eq_attr "type" "vmsfs,vmidx")
+ (symbol_ref "riscv_vector::get_ma(operands[5])")]
(const_int INVALID_ATTRIBUTE)))
;; The avl type value.
(symbol_ref "INTVAL (operands[5])")
(eq_attr "type" "vimuladd,viwmuladd")
- (symbol_ref "INTVAL (operands[9])")]
+ (symbol_ref "INTVAL (operands[9])")
+
+ (eq_attr "type" "vmsfs,vmidx")
+ (symbol_ref "INTVAL (operands[6])")
+
+ (eq_attr "type" "vmpop,vmffs")
+ (symbol_ref "INTVAL (operands[4])")]
(const_int INVALID_ATTRIBUTE)))
;; -----------------------------------------------------------------
"@
vlm.v\t%0,%3
vsm.v\t%3,%0
- #
+ vmmv.m\t%0,%3
vmclr.m\t%0
vmset.m\t%0"
"&& register_operand (operands[0], <MODE>mode)
- && register_operand (operands[3], <MODE>mode)"
+ && register_operand (operands[3], <MODE>mode)
+ && INTVAL (operands[5]) == riscv_vector::VLMAX"
[(set (match_dup 0) (match_dup 3))]
""
- [(set_attr "type" "vldm,vstm,vimov,vmalu,vmalu")
+ [(set_attr "type" "vldm,vstm,vmalu,vmalu,vmalu")
(set_attr "mode" "<MODE>")])
;; Dedicated pattern for vsm.v instruction since we can't reuse pred_mov pattern to include
reg, CONSTM1_RTX (<VM>mode), undef, operands[3], operands[4],
operands[5], operands[6], operands[7], operands[8]));
emit_insn (
- gen_pred_andn<vm> (operands[0], CONSTM1_RTX (<VM>mode), undef,
+ gen_pred_andnot<vm> (operands[0], CONSTM1_RTX (<VM>mode), undef,
operands[1], reg, operands[6], operands[8]));
}
else
;; -------------------------------------------------------------------------------
;; Includes:
;; - 15.1 Vector Mask-Register Logical Instructions
+;; - 15.2 Vector count population in mask vcpop.m
+;; - 15.3 vfirst find-first-set mask bit
+;; - 15.4 vmsbf.m set-before-first mask bit
+;; - 15.5 vmsif.m set-including-first mask bit
+;; - 15.6 vmsof.m set-only-first mask bit
+;; - 15.8 Vector Iota Instruction
+;; - 15.9 Vector Element Index Instruction
;; -------------------------------------------------------------------------------
;; We keep this pattern same as pred_mov so that we can gain more optimizations.
(set_attr "vl_op_idx" "5")
(set (attr "avl_type") (symbol_ref "INTVAL (operands[6])"))])
-(define_insn "@pred_<optab>n<mode>"
+(define_insn "@pred_<optab>not<mode>"
[(set (match_operand:VB 0 "register_operand" "=vr")
(if_then_else:VB
(unspec:VB
(match_operand:VB 3 "register_operand" " vr"))
(match_operand:VB 2 "vector_undef_operand" " vu")))]
"TARGET_VECTOR"
- "vmnot.mm\t%0,%3"
+ "vmnot.m\t%0,%3"
[(set_attr "type" "vmalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "4")
(set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
+
+(define_insn "@pred_popcount<VB:mode><P:mode>"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (popcount:P
+ (unspec:VB
+ [(and:VB
+ (match_operand:VB 1 "vector_mask_operand" "vmWc1")
+ (match_operand:VB 2 "register_operand" " vr"))
+ (match_operand 3 "vector_length_operand" " rK")
+ (match_operand 4 "const_int_operand" " i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)))]
+ "TARGET_VECTOR"
+ "vcpop.m\t%0,%2%p1"
+ [(set_attr "type" "vmpop")
+ (set_attr "mode" "<VB:MODE>")])
+
+(define_insn "@pred_ffs<VB:mode><P:mode>"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (plus:P
+ (ffs:P
+ (unspec:VB
+ [(and:VB
+ (match_operand:VB 1 "vector_mask_operand" "vmWc1")
+ (match_operand:VB 2 "register_operand" " vr"))
+ (match_operand 3 "vector_length_operand" " rK")
+ (match_operand 4 "const_int_operand" " i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE))
+ (const_int -1)))]
+ "TARGET_VECTOR"
+ "vfirst.m\t%0,%2%p1"
+ [(set_attr "type" "vmffs")
+ (set_attr "mode" "<VB:MODE>")])
+
+(define_insn "@pred_<misc_op><mode>"
+ [(set (match_operand:VB 0 "register_operand" "=&vr")
+ (if_then_else:VB
+ (unspec:VB
+ [(match_operand:VB 1 "vector_mask_operand" "vmWc1")
+ (match_operand 4 "vector_length_operand" " rK")
+ (match_operand 5 "const_int_operand" " i")
+ (match_operand 6 "const_int_operand" " i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (unspec:VB
+ [(match_operand:VB 3 "register_operand" " vr")] VMISC)
+ (match_operand:VB 2 "vector_merge_operand" " 0vu")))]
+ "TARGET_VECTOR"
+ "vm<misc_op>.m\t%0,%3%p1"
+ [(set_attr "type" "vmsfs")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_iota<mode>"
+ [(set (match_operand:VI 0 "register_operand" "=&vr")
+ (if_then_else:VI
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
+ (match_operand 4 "vector_length_operand" " rK")
+ (match_operand 5 "const_int_operand" " i")
+ (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
+ [(match_operand:<VM> 3 "register_operand" " vr")] UNSPEC_VIOTA)
+ (match_operand:VI 2 "vector_merge_operand" " 0vu")))]
+ "TARGET_VECTOR"
+ "viota.m\t%0,%3%p1"
+ [(set_attr "type" "vmiota")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_series<mode>"
+ [(set (match_operand:VI 0 "register_operand" "=vd, vr")
+ (if_then_else:VI
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1")
+ (match_operand 3 "vector_length_operand" " rK, rK")
+ (match_operand 4 "const_int_operand" " i, i")
+ (match_operand 5 "const_int_operand" " i, i")
+ (match_operand 6 "const_int_operand" " i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (vec_series:VI (const_int 0) (const_int 1))
+ (match_operand:VI 2 "vector_merge_operand" "0vu,0vu")))]
+ "TARGET_VECTOR"
+ "vid.v\t%0%p1"
+ [(set_attr "type" "vmidx")
+ (set_attr "mode" "<MODE>")])