DEF_RVV_FUNCTION (vor, alu, full_preds, iu_vvv_ops)
DEF_RVV_FUNCTION (vxor, alu, full_preds, iu_vvv_ops)
DEF_RVV_FUNCTION (vsll, alu, full_preds, iu_shift_vvv_ops)
-DEF_RVV_FUNCTION (vsra, alu, full_preds, iu_shift_vvv_ops)
-DEF_RVV_FUNCTION (vsrl, alu, full_preds, iu_shift_vvv_ops)
+DEF_RVV_FUNCTION (vsra, alu, full_preds, i_shift_vvv_ops)
+DEF_RVV_FUNCTION (vsrl, alu, full_preds, u_shift_vvv_ops)
DEF_RVV_FUNCTION (vmin, alu, full_preds, i_vvv_ops)
DEF_RVV_FUNCTION (vmax, alu, full_preds, i_vvv_ops)
DEF_RVV_FUNCTION (vminu, alu, full_preds, u_vvv_ops)
DEF_RVV_FUNCTION (vor, alu, full_preds, iu_vvx_ops)
DEF_RVV_FUNCTION (vxor, alu, full_preds, iu_vvx_ops)
DEF_RVV_FUNCTION (vsll, alu, full_preds, iu_shift_vvx_ops)
-DEF_RVV_FUNCTION (vsra, alu, full_preds, iu_shift_vvx_ops)
-DEF_RVV_FUNCTION (vsrl, alu, full_preds, iu_shift_vvx_ops)
+DEF_RVV_FUNCTION (vsra, alu, full_preds, i_shift_vvx_ops)
+DEF_RVV_FUNCTION (vsrl, alu, full_preds, u_shift_vvx_ops)
DEF_RVV_FUNCTION (vmin, alu, full_preds, i_vvx_ops)
DEF_RVV_FUNCTION (vmax, alu, full_preds, i_vvx_ops)
DEF_RVV_FUNCTION (vminu, alu, full_preds, u_vvx_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)
+DEF_RVV_FUNCTION (vnsrl, narrow_alu, full_preds, u_narrow_shift_vwv_ops)
+DEF_RVV_FUNCTION (vnsra, narrow_alu, full_preds, i_narrow_shift_vwv_ops)
+DEF_RVV_FUNCTION (vnsrl, narrow_alu, full_preds, u_narrow_shift_vwx_ops)
+DEF_RVV_FUNCTION (vnsra, narrow_alu, full_preds, i_narrow_shift_vwx_ops)
+DEF_RVV_FUNCTION (vncvt_x, narrow_alu, full_preds, iu_trunc_ops)
+DEF_RVV_FUNCTION (vmerge, no_mask_policy, tu_preds, all_vvvm_ops)
+DEF_RVV_FUNCTION (vmerge, no_mask_policy, tu_preds, iu_vvxm_ops)
+DEF_RVV_FUNCTION (vmv_v, move, tu_preds, all_v_ops)
+DEF_RVV_FUNCTION (vmv_v, move, tu_preds, iu_x_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)
#include "riscv-vector-builtins-types.def"
{NUM_VECTOR_TYPES, 0}};
+/* A list of Double-Widening all integer will be registered for intrinsic
+ * functions. */
+static const rvv_type_info wextiu_ops[] = {
+#define DEF_RVV_WEXTI_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#define DEF_RVV_WEXTU_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#include "riscv-vector-builtins-types.def"
+ {NUM_VECTOR_TYPES, 0}};
+
/* A list of Quad-Widening unsigned integer will be registered for intrinsic
* functions. */
static const rvv_type_info qextu_ops[] = {
= {rvv_arg_type_info (RVV_BASE_vector),
rvv_arg_type_info (RVV_BASE_shift_vector), rvv_arg_type_info_end};
+/* A list of args for double demote type func (vector_type, shift_type)
+ * function. */
+static CONSTEXPR const rvv_arg_type_info shift_wv_args[]
+ = {rvv_arg_type_info (RVV_BASE_vector),
+ rvv_arg_type_info (RVV_BASE_double_trunc_unsigned_vector),
+ rvv_arg_type_info_end};
+
/* A list of args for vector_type func (vector_type) function. */
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 (scalar_type) function. */
+static CONSTEXPR const rvv_arg_type_info x_args[]
+ = {rvv_arg_type_info (RVV_BASE_scalar), rvv_arg_type_info_end};
+
/* A list of args for vector_type func (vector_type, size) function. */
static CONSTEXPR const rvv_arg_type_info vector_size_args[]
= {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info (RVV_BASE_size),
rvv_arg_type_info (RVV_BASE_vector), /* Return type */
vvm_args /* Args */};
+/* A static operand information for vector_type func (vector_type, vector_type,
+ * mask_type) function registration. */
+static CONSTEXPR const rvv_op_info all_vvvm_ops
+ = {all_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
rvv_arg_type_info (RVV_BASE_vector), /* Return type */
vector_size_args /* Args */};
+/* A static operand information for vector_type func (vector_type, shift_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info i_shift_vvv_ops
+ = {i_ops, /* Types */
+ OP_TYPE_vv, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ shift_vv_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type, size_t)
+ * function registration. */
+static CONSTEXPR const rvv_op_info i_shift_vvx_ops
+ = {i_ops, /* Types */
+ OP_TYPE_vx, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ vector_size_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type, shift_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info u_shift_vvv_ops
+ = {u_ops, /* Types */
+ OP_TYPE_vv, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ shift_vv_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type, size_t)
+ * function registration. */
+static CONSTEXPR const rvv_op_info u_shift_vvx_ops
+ = {u_ops, /* Types */
+ OP_TYPE_vx, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ vector_size_args /* Args */};
+
/* A static operand information for vector_type func (vector_type)
* function registration. */
static CONSTEXPR const rvv_op_info iu_v_ops
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 all_v_ops
+ = {all_ops, /* Types */
+ OP_TYPE_v, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ v_args /* Args */};
+
+/* A static operand information for vector_type func (scalar_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info iu_x_ops
+ = {iu_ops, /* Types */
+ OP_TYPE_x, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ x_args /* Args */};
+
/* A static operand information for vector_type func (double demote type)
* function registration. */
static CONSTEXPR const rvv_op_info i_vf2_ops
rvv_arg_type_info (RVV_BASE_vector), /* Return type */
x_x_v_args /* Args */};
+/* A static operand information for double demote type func (vector_type,
+ * shift_type) function registration. */
+static CONSTEXPR const rvv_op_info i_narrow_shift_vwv_ops
+ = {wexti_ops, /* Types */
+ OP_TYPE_wv, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_double_trunc_vector), /* Return type */
+ shift_wv_args /* Args */};
+
+/* A static operand information for double demote type func (vector_type,
+ * shift_type) function registration. */
+static CONSTEXPR const rvv_op_info u_narrow_shift_vwv_ops
+ = {wextu_ops, /* Types */
+ OP_TYPE_wv, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_double_trunc_vector), /* Return type */
+ shift_wv_args /* Args */};
+
+/* A static operand information for double demote type func (vector_type,
+ * size_t) function registration. */
+static CONSTEXPR const rvv_op_info i_narrow_shift_vwx_ops
+ = {wexti_ops, /* Types */
+ OP_TYPE_wx, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_double_trunc_vector), /* Return type */
+ vector_size_args /* Args */};
+
+/* A static operand information for double demote type func (vector_type,
+ * size_t) function registration. */
+static CONSTEXPR const rvv_op_info u_narrow_shift_vwx_ops
+ = {wextu_ops, /* Types */
+ OP_TYPE_wx, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_double_trunc_vector), /* Return type */
+ vector_size_args /* Args */};
+
+/* A static operand information for double demote type func (vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info iu_trunc_ops
+ = {wextiu_ops, /* Types */
+ OP_TYPE_x_w, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_double_trunc_vector), /* Return type */
+ v_args /* Args */};
+
/* A list of all RVV intrinsic functions. */
static function_group_info function_groups[] = {
#define DEF_RVV_FUNCTION(NAME, SHAPE, PREDS, OPS_INFO) \
(define_attr "ratio" ""
(cond [(eq_attr "type" "vimov,vfmov,vldux,vldox,vstux,vstox,\
vialu,vshift,vicmp,vimul,vidiv,vsalu,\
- vext,viwalu,viwmul,vicalu")
+ vext,viwalu,viwmul,vicalu,vnshift,\
+ vimuladd,vimerge")
(const_int INVALID_ATTRIBUTE)
(eq_attr "mode" "VNx1QI,VNx1BI")
(symbol_ref "riscv_vector::get_ratio(E_VNx1QImode)")
;; The index of operand[] to get the merge op.
(define_attr "merge_op_idx" ""
(cond [(eq_attr "type" "vlde,vimov,vfmov,vldm,vlds,vmalu,vldux,vldox,\
- vialu,vshift,vicmp,vimul,vidiv,vsalu,vext,viwalu,viwmul")
- (const_int 2)]
+ vialu,vshift,vicmp,vimul,vidiv,vsalu,vext,viwalu,\
+ viwmul,vnshift,vimuladd")
+ (const_int 2)
+
+ (eq_attr "type" "vimerge")
+ (const_int 1)]
(const_int INVALID_ATTRIBUTE)))
;; The index of operand[] to get the avl op.
(const_int 4))
(eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu,\
- viwalu,viwmul")
+ viwalu,viwmul,vnshift,vimuladd,vimerge")
(const_int 5)]
(const_int INVALID_ATTRIBUTE)))
(symbol_ref "riscv_vector::get_ta(operands[5])"))
(eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu,\
- viwalu,viwmul")
+ viwalu,viwmul,vnshift,vimuladd,vimerge")
(symbol_ref "riscv_vector::get_ta(operands[6])")]
(const_int INVALID_ATTRIBUTE)))
(symbol_ref "riscv_vector::get_ma(operands[6])"))
(eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu,\
- viwalu,viwmul")
+ viwalu,viwmul,vnshift,vimuladd")
(symbol_ref "riscv_vector::get_ma(operands[7])")]
(const_int INVALID_ATTRIBUTE)))
;; The avl type value.
(define_attr "avl_type" ""
- (cond [(eq_attr "type" "vlde,vlde,vste,vimov,vimov,vimov,vfmov,vext")
+ (cond [(eq_attr "type" "vlde,vlde,vste,vimov,vimov,vimov,vfmov,vext,vimerge")
(symbol_ref "INTVAL (operands[7])")
(eq_attr "type" "vldm,vstm,vimov,vmalu,vmalu")
(symbol_ref "INTVAL (operands[5])")
(symbol_ref "INTVAL (operands[7])"))
(eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu,\
- viwalu,viwmul")
+ viwalu,viwmul,vnshift,vimuladd")
(symbol_ref "INTVAL (operands[8])")
(eq_attr "type" "vstux,vstox")
(symbol_ref "INTVAL (operands[5])")]
;; -------------------------------------------------------------------------------
;; Includes:
;; - 7.4. Vector Unit-Stride Instructions
+;; - 11.15 Vector Integer Merge Instructions
;; - 11.16 Vector Integer Move Instructions
;; - 13.16 Vector Floating-Point Move Instruction
;; - 15.1 Vector Mask-Register Logical Instructions
vmv.v.i\t%0,%v3"
"&& register_operand (operands[0], <MODE>mode)
&& register_operand (operands[3], <MODE>mode)
- && satisfies_constraint_vu (operands[2])"
+ && satisfies_constraint_vu (operands[2])
+ && INTVAL (operands[7]) == riscv_vector::VLMAX"
[(set (match_dup 0) (match_dup 3))]
""
[(set_attr "type" "vlde,vlde,vlde,vste,vimov,vimov")
(set (attr "avl_type") (symbol_ref "riscv_vector::NONVLMAX"))
(set_attr "vl_op_idx" "3")])
+(define_insn "@pred_merge<mode>"
+ [(set (match_operand:V 0 "register_operand" "=vd, vd")
+ (if_then_else:V
+ (match_operand:<VM> 4 "register_operand" " vm, vm")
+ (if_then_else:V
+ (unspec:<VM>
+ [(match_dup 4)
+ (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)
+ (match_operand:V 3 "vector_arith_operand" " vr, vi")
+ (match_operand:V 2 "register_operand" " vr, vr"))
+ (match_operand:V 1 "vector_merge_operand" " 0vu, 0vu")))]
+ "TARGET_VECTOR"
+ "vmerge.v%o3m\t%0,%2,%v3,%4"
+ [(set_attr "type" "vimerge")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_merge<mode>_scalar"
+ [(set (match_operand:VI_QHS 0 "register_operand" "=vd")
+ (if_then_else:VI_QHS
+ (match_operand:<VM> 4 "register_operand" " vm")
+ (if_then_else:VI_QHS
+ (unspec:<VM>
+ [(match_dup 4)
+ (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)
+ (vec_duplicate:VI_QHS
+ (match_operand:<VEL> 3 "register_operand" " r"))
+ (match_operand:VI_QHS 2 "register_operand" " vr"))
+ (match_operand:VI_QHS 1 "vector_merge_operand" "0vu")))]
+ "TARGET_VECTOR"
+ "vmerge.vxm\t%0,%2,%3,%4"
+ [(set_attr "type" "vimerge")
+ (set_attr "mode" "<MODE>")])
+
+(define_expand "@pred_merge<mode>_scalar"
+ [(set (match_operand:VI_D 0 "register_operand")
+ (if_then_else:VI_D
+ (match_operand:<VM> 4 "register_operand")
+ (if_then_else:VI_D
+ (unspec:<VM>
+ [(match_dup 4)
+ (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)
+ (vec_duplicate:VI_D
+ (match_operand:<VEL> 3 "reg_or_int_operand"))
+ (match_operand:VI_D 2 "register_operand"))
+ (match_operand:VI_D 1 "vector_merge_operand")))]
+ "TARGET_VECTOR"
+ {
+ if (riscv_vector::neg_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_merge<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_merge<mode>_scalar"
+ [(set (match_operand:VI_D 0 "register_operand" "=vd")
+ (if_then_else:VI_D
+ (match_operand:<VM> 4 "register_operand" " vm")
+ (if_then_else:VI_D
+ (unspec:<VM>
+ [(match_dup 4)
+ (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)
+ (vec_duplicate:VI_D
+ (match_operand:<VEL> 3 "register_operand" " r"))
+ (match_operand:VI_D 2 "register_operand" " vr"))
+ (match_operand:VI_D 1 "vector_merge_operand" "0vu")))]
+ "TARGET_VECTOR"
+ "vmerge.vxm\t%0,%2,%3,%4"
+ [(set_attr "type" "vimerge")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "*pred_merge<mode>_extended_scalar"
+ [(set (match_operand:VI_D 0 "register_operand" "=vd")
+ (if_then_else:VI_D
+ (match_operand:<VM> 4 "register_operand" " vm")
+ (if_then_else:VI_D
+ (unspec:<VM>
+ [(match_dup 4)
+ (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)
+ (vec_duplicate:VI_D
+ (sign_extend:<VEL>
+ (match_operand:<VSUBEL> 3 "register_operand" " r")))
+ (match_operand:VI_D 2 "register_operand" " vr"))
+ (match_operand:VI_D 1 "vector_merge_operand" "0vu")))]
+ "TARGET_VECTOR"
+ "vmerge.vxm\t%0,%2,%3,%4"
+ [(set_attr "type" "vimerge")
+ (set_attr "mode" "<MODE>")])
+
;; -------------------------------------------------------------------------------
;; ---- Predicated Broadcast
;; -------------------------------------------------------------------------------
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
(vec_duplicate:V
- (match_operand:<VEL> 3 "direct_broadcast_operand" "Wbr, f, Wdm, Wdm"))
+ (match_operand:<VEL> 3 "direct_broadcast_operand" " r, f, Wdm, Wdm"))
(match_operand:V 2 "vector_merge_operand" "0vu, 0vu, 0vu, 0vu")))]
"TARGET_VECTOR"
"@
(match_operand 4 "pmode_reg_or_uimm5_operand" " r, r, K, K"))
(match_operand:VI 2 "vector_merge_operand" "0vu,0vu,0vu,0vu")))]
"TARGET_VECTOR"
- "@
- v<insn>.vx\t%0,%3,%4%p1
- v<insn>.vx\t%0,%3,%4%p1
- v<insn>.vi\t%0,%3,%4%p1
- v<insn>.vi\t%0,%3,%4%p1"
+ "v<insn>.v%o4\t%0,%3,%4%p1"
[(set_attr "type" "vshift")
(set_attr "mode" "<MODE>")])
(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"
+ "vadc.v%o3m\t%0,%2,%v3,%4"
[(set_attr "type" "vicalu")
(set_attr "mode" "<MODE>")
(set_attr "merge_op_idx" "1")
(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"
+ "vmadc.v%o2m\t%0,%1,%v2,%3"
[(set_attr "type" "vicalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "4")
(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"
+ "vmadc.v%o2\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[7])"))])
;; -------------------------------------------------------------------------------
-;; ---- Predicated integer widening operations
+;; ---- Predicated integer widening binary operations
;; -------------------------------------------------------------------------------
;; Includes:
;; - 11.2 Vector Widening Integer Add/Subtract
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[5])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
(set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+
+;; -------------------------------------------------------------------------------
+;; ---- Predicated integer Narrowing operations
+;; -------------------------------------------------------------------------------
+;; Includes:
+;; - 11.7 Vector Narrowing Integer Right Shift Instructions
+;; -------------------------------------------------------------------------------
+
+;; The destination EEW is smaller than the source EEW and the overlap is in the
+;; lowest-numbered part of the source register group
+;; e.g, when LMUL = 1, vnsrl.wi v0,v0,3 is legal but a destination of v1 is not.
+(define_insn "@pred_narrow_<optab><mode>"
+ [(set (match_operand:<V_DOUBLE_TRUNC> 0 "register_operand" "=vd, vr, &vr, vd, vr, &vr")
+ (if_then_else:<V_DOUBLE_TRUNC>
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1,vmWc1, vm,Wc1,vmWc1")
+ (match_operand 5 "vector_length_operand" " rK, rK, rK, rK, rK, rK")
+ (match_operand 6 "const_int_operand" " i, i, i, i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i, i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i, i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (truncate:<V_DOUBLE_TRUNC>
+ (any_shiftrt:VWEXTI
+ (match_operand:VWEXTI 3 "register_operand" " 0, 0, vr, 0, 0, vr")
+ (match_operand:<V_DOUBLE_TRUNC> 4 "vector_shift_operand" " vr, vr, vr, vk, vk, vk")))
+ (match_operand:<V_DOUBLE_TRUNC> 2 "vector_merge_operand" "0vu,0vu, 0vu,0vu,0vu, 0vu")))]
+ "TARGET_VECTOR"
+ "vn<insn>.w%o4\t%0,%3,%v4%p1"
+ [(set_attr "type" "vnshift")
+ (set_attr "mode" "<V_DOUBLE_TRUNC>")])
+
+(define_insn "@pred_narrow_<optab><mode>_scalar"
+ [(set (match_operand:<V_DOUBLE_TRUNC> 0 "register_operand" "=vd, vr, &vr, vd, vr, &vr")
+ (if_then_else:<V_DOUBLE_TRUNC>
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1,vmWc1, vm,Wc1,vmWc1")
+ (match_operand 5 "vector_length_operand" " rK, rK, rK, rK, rK, rK")
+ (match_operand 6 "const_int_operand" " i, i, i, i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i, i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i, i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (truncate:<V_DOUBLE_TRUNC>
+ (any_shiftrt:VWEXTI
+ (match_operand:VWEXTI 3 "register_operand" " 0, 0, vr, 0, 0, vr")
+ (match_operand 4 "pmode_reg_or_uimm5_operand" " r, r, r, K, K, K")))
+ (match_operand:<V_DOUBLE_TRUNC> 2 "vector_merge_operand" "0vu,0vu, 0vu,0vu,0vu, 0vu")))]
+ "TARGET_VECTOR"
+ "vn<insn>.w%o4\t%0,%3,%4%p1"
+ [(set_attr "type" "vnshift")
+ (set_attr "mode" "<V_DOUBLE_TRUNC>")])
+
+;; vncvt.x.x.w
+(define_insn "@pred_trunc<mode>"
+ [(set (match_operand:<V_DOUBLE_TRUNC> 0 "register_operand" "=vd, vr, &vr")
+ (if_then_else:<V_DOUBLE_TRUNC>
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1,vmWc1")
+ (match_operand 4 "vector_length_operand" " rK, rK, rK")
+ (match_operand 5 "const_int_operand" " i, i, i")
+ (match_operand 6 "const_int_operand" " i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (truncate:<V_DOUBLE_TRUNC>
+ (match_operand:VWEXTI 3 "register_operand" " 0, 0, vr"))
+ (match_operand:<V_DOUBLE_TRUNC> 2 "vector_merge_operand" "0vu,0vu, 0vu")))]
+ "TARGET_VECTOR"
+ "vncvt.x.x.w\t%0,%3%p1"
+ [(set_attr "type" "vnshift")
+ (set_attr "mode" "<V_DOUBLE_TRUNC>")
+ (set_attr "vl_op_idx" "4")
+ (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[5])"))
+ (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
+ (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])