Hi Jiawei, > +;; Source modes for Zvzip instructions whose destination/source operand has > +;; 2x LMUL, without exposing forms that would require LMUL > 8. > +(define_mode_iterator VLMULX2 [ > + (RVVMF8QI "TARGET_VECTOR_ELEN_64") > + RVVMF4QI RVVMF2QI RVVM1QI RVVM2QI RVVM4QI > + > + (RVVMF4HI "TARGET_VECTOR_ELEN_64") > + RVVMF2HI RVVM1HI RVVM2HI RVVM4HI > + > + (RVVMF4BF "TARGET_VECTOR_ELEN_BF_16 && TARGET_VECTOR_ELEN_64") > + (RVVMF2BF "TARGET_VECTOR_ELEN_BF_16") > + (RVVM1BF "TARGET_VECTOR_ELEN_BF_16") > + (RVVM2BF "TARGET_VECTOR_ELEN_BF_16") > + (RVVM4BF "TARGET_VECTOR_ELEN_BF_16") > + > + (RVVMF4HF "TARGET_VECTOR_ELEN_FP_16 && TARGET_VECTOR_ELEN_64") > + (RVVMF2HF "TARGET_VECTOR_ELEN_FP_16") > + (RVVM1HF "TARGET_VECTOR_ELEN_FP_16") > + (RVVM2HF "TARGET_VECTOR_ELEN_FP_16") > + (RVVM4HF "TARGET_VECTOR_ELEN_FP_16") > + > + (RVVMF2SI "TARGET_VECTOR_ELEN_64") > + RVVM1SI RVVM2SI RVVM4SI > + > + (RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_VECTOR_ELEN_64") > + (RVVM1SF "TARGET_VECTOR_ELEN_FP_32") > + (RVVM2SF "TARGET_VECTOR_ELEN_FP_32") > + (RVVM4SF "TARGET_VECTOR_ELEN_FP_32") > + > + (RVVM1DI "TARGET_VECTOR_ELEN_64") > + (RVVM2DI "TARGET_VECTOR_ELEN_64") > + (RVVM4DI "TARGET_VECTOR_ELEN_64") > + > + (RVVM1DF "TARGET_VECTOR_ELEN_FP_64") > + (RVVM2DF "TARGET_VECTOR_ELEN_FP_64") > + (RVVM4DF "TARGET_VECTOR_ELEN_FP_64") > +])
I'm afraid we need VLS modes as well here :) And once we have those, we might need to think about the naming, as LMUL might not make a lot of sense for e.g. V4QI -> V8QI. Maybe just V_DOUBLE? Also, we already have VI_QHS_NO_M8. You could re-use that and just add the missing modes in a new combined iterator. Then, HF modes, are these in scope? > +;; Zvzip v0.1 draft. > +(define_insn "@pred_vzip<mode>" > + [(set (match_operand:<VLMUL_EXT2> 0 "register_operand" "=&vr, &vr") > + (if_then_else:<VLMUL_EXT2> > + (unspec:<VM> > + [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1,vmWc1") > + (match_operand 5 "vector_length_operand" " rvl, rvl") > + (match_operand 6 "const_int_operand" " i, i") > + (match_operand 7 "const_int_operand" " i, i") > + (match_operand 8 "const_int_operand" " i, i") > + (reg:SI VL_REGNUM) > + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) > + (unspec:<VLMUL_EXT2> > + [(match_operand:VLMULX2 3 "register_operand" " vr, vr") > + (match_operand:VLMULX2 4 "register_operand" " vr, vr")] > UNSPEC_VZIP) > + (match_operand:<VLMUL_EXT2> 2 "vector_merge_operand" " vu, 0")))] > + "TARGET_ZVZIP" > + "vzip.vv\t%0,%3,%4%p1" > + [(set_attr "type" "vgather") > + (set_attr "mode" "<MODE>")]) Does the vgather type work with a "widening" instruction type? Like mode_idx for example would come from operand[0] but operand[3] and operand[4] have a smaller mode. Such kinds of issues will likely only occur in more complicated scenarios and might not be caught in simpler tests. I guess the earlyclobber is alright for now, until we have more fine-grained options. > +(define_insn "@pred_vunzipe<mode>" > + [(set (match_operand:VLMULX2 0 "register_operand" "=&vr, &vr") > + (if_then_else:VLMULX2 > + (unspec:<VM> > + [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1,vmWc1") > + (match_operand 4 "vector_length_operand" " rvl, rvl") > + (match_operand 5 "const_int_operand" " i, i") > + (match_operand 6 "const_int_operand" " i, i") > + (match_operand 7 "const_int_operand" " i, i") > + (reg:SI VL_REGNUM) > + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) > + (unspec:VLMULX2 > + [(match_operand:<VLMUL_EXT2> 3 "register_operand" " vr, vr")] > UNSPEC_VUNZIPE) > + (match_operand:VLMULX2 2 "vector_merge_operand" " vu, 0")))] > + "TARGET_ZVZIP" > + "vunzipe.v\t%0,%3%p1" > + [(set_attr "type" "vgather") > + (set_attr "mode" "<MODE>") > + (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_idx" "7")]) Same question here about the attributes. I haven't checked in detail, just wanted to make sure. -- Regards Robin
