1 //===-- RISCVInstrInfoZvk.td - RISC-V 'Zvk' instructions ---*- tablegen -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file describes the RISC-V instructions from the standard 'Zvk',
10 // Vector Cryptography Instructions extension, version Release 1.0.0.
12 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 // Operand and SDNode transformation definitions.
16 //===----------------------------------------------------------------------===//
18 def tuimm5 : RISCVOp, TImmLeaf<XLenVT, [{return isUInt<5>(Imm);}]>;
20 //===----------------------------------------------------------------------===//
21 // Instruction class templates
22 //===----------------------------------------------------------------------===//
24 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
25 multiclass VCLMUL_MV_V_X<string opcodestr, bits<6> funct6> {
26 def V : VALUVV<funct6, OPMVV, opcodestr # "." # "vv">,
27 SchedBinaryMC<"WriteVCLMULV", "ReadVCLMULV", "ReadVCLMULV">;
28 def X : VALUVX<funct6, OPMVX, opcodestr # "." # "vx">,
29 SchedBinaryMC<"WriteVCLMULX", "ReadVCLMULV", "ReadVCLMULX">;
32 class RVInstIVI_VROR<bits<6> funct6, dag outs, dag ins, string opcodestr,
34 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
40 let Inst{31-27} = funct6{5-1};
41 let Inst{26} = imm{5};
43 let Inst{24-20} = vs2;
44 let Inst{19-15} = imm{4-0};
45 let Inst{14-12} = OPIVI.Value;
47 let Inst{6-0} = OPC_OP_V.Value;
49 let Uses = [VTYPE, VL];
50 let RVVConstraint = VMConstraint;
53 multiclass VROR_IV_V_X_I<string opcodestr, bits<6> funct6>
54 : VALU_IV_V_X<opcodestr, funct6> {
55 def I : RVInstIVI_VROR<funct6, (outs VR:$vd),
56 (ins VR:$vs2, uimm6:$imm, VMaskOp:$vm),
57 opcodestr # ".vi", "$vd, $vs2, $imm$vm">,
58 SchedUnaryMC<"WriteVRotI", "ReadVRotV">;
62 class PALUVVNoVm<bits<6> funct6, RISCVVFormat opv, string opcodestr>
63 : VALUVVNoVm<funct6, opv, opcodestr> {
64 let Inst{6-0} = OPC_OP_VE.Value;
68 class PALUVVNoVmTernary<bits<6> funct6, RISCVVFormat opv, string opcodestr>
69 : RVInstVV<funct6, opv, (outs VR:$vd_wb),
70 (ins VR:$vd, VR:$vs2, VR:$vs1),
71 opcodestr, "$vd, $vs2, $vs1"> {
72 let Constraints = "$vd = $vd_wb";
74 let Inst{6-0} = OPC_OP_VE.Value;
78 class PALUVINoVm<bits<6> funct6, string opcodestr, Operand optype>
79 : VALUVINoVm<funct6, opcodestr, optype> {
80 let Inst{6-0} = OPC_OP_VE.Value;
81 let Inst{14-12} = OPMVV.Value;
84 // op vd, vs2, imm where vd is also a source regardless of tail policy
85 class PALUVINoVmBinary<bits<6> funct6, string opcodestr, Operand optype>
86 : RVInstIVI<funct6, (outs VR:$vd_wb),
87 (ins VR:$vd, VR:$vs2, optype:$imm),
88 opcodestr, "$vd, $vs2, $imm"> {
89 let Constraints = "$vd = $vd_wb";
91 let Inst{6-0} = OPC_OP_VE.Value;
92 let Inst{14-12} = OPMVV.Value;
95 // op vd, vs2 (use vs1 as instruction encoding) where vd is also a source
96 // regardless of tail policy
97 class PALUVs2NoVmBinary<bits<6> funct6, bits<5> vs1, RISCVVFormat opv,
99 : RVInstV<funct6, vs1, opv, (outs VR:$vd_wb), (ins VR:$vd, VR:$vs2),
100 opcodestr, "$vd, $vs2"> {
101 let Constraints = "$vd = $vd_wb";
103 let Inst{6-0} = OPC_OP_VE.Value;
106 multiclass VAES_MV_V_S<bits<6> funct6_vv, bits<6> funct6_vs, bits<5> vs1,
107 RISCVVFormat opv, string opcodestr> {
108 let RVVConstraint = NoConstraint in
109 def NAME # _VV : PALUVs2NoVmBinary<funct6_vv, vs1, opv, opcodestr # ".vv">,
110 SchedBinaryMC<"WriteVAESMVV", "ReadVAESMVV", "ReadVAESMVV">;
111 let RVVConstraint = VS2Constraint in
112 def NAME # _VS : PALUVs2NoVmBinary<funct6_vs, vs1, opv, opcodestr # ".vs">,
113 SchedBinaryMC<"WriteVAESMVV", "ReadVAESMVV", "ReadVAESMVV">;
115 } // hasSideEffects = 0, mayLoad = 0, mayStore = 0
117 //===----------------------------------------------------------------------===//
119 //===----------------------------------------------------------------------===//
121 let Predicates = [HasStdExtZvbb] in {
122 def VBREV_V : VALUVs2<0b010010, 0b01010, OPMVV, "vbrev.v">;
123 def VCLZ_V : VALUVs2<0b010010, 0b01100, OPMVV, "vclz.v">;
124 def VCPOP_V : VALUVs2<0b010010, 0b01110, OPMVV, "vcpop.v">;
125 def VCTZ_V : VALUVs2<0b010010, 0b01101, OPMVV, "vctz.v">;
126 let Constraints = "@earlyclobber $vd", RVVConstraint = WidenV in
127 defm VWSLL_V : VSHT_IV_V_X_I<"vwsll", 0b110101>;
128 } // Predicates = [HasStdExtZvbb]
130 let Predicates = [HasStdExtZvbc] in {
131 defm VCLMUL_V : VCLMUL_MV_V_X<"vclmul", 0b001100>;
132 defm VCLMULH_V : VCLMUL_MV_V_X<"vclmulh", 0b001101>;
133 } // Predicates = [HasStdExtZvbc]
135 let Predicates = [HasStdExtZvkb] in {
136 defm VANDN_V : VALU_IV_V_X<"vandn", 0b000001>;
137 def VBREV8_V : VALUVs2<0b010010, 0b01000, OPMVV, "vbrev8.v">;
138 def VREV8_V : VALUVs2<0b010010, 0b01001, OPMVV, "vrev8.v">;
139 defm VROL_V : VALU_IV_V_X<"vrol", 0b010101>;
140 defm VROR_V : VROR_IV_V_X_I<"vror", 0b010100>;
141 } // Predicates = [HasStdExtZvkb]
143 let Predicates = [HasStdExtZvkg], RVVConstraint = NoConstraint in {
144 def VGHSH_VV : PALUVVNoVmTernary<0b101100, OPMVV, "vghsh.vv">,
145 SchedTernaryMC<"WriteVGHSHV", "ReadVGHSHV", "ReadVGHSHV",
147 def VGMUL_VV : PALUVs2NoVmBinary<0b101000, 0b10001, OPMVV, "vgmul.vv">,
148 SchedBinaryMC<"WriteVGMULV", "ReadVGMULV", "ReadVGMULV">;
149 } // Predicates = [HasStdExtZvkg]
151 let Predicates = [HasStdExtZvknhaOrZvknhb], RVVConstraint = Sha2Constraint in {
152 def VSHA2CH_VV : PALUVVNoVmTernary<0b101110, OPMVV, "vsha2ch.vv">,
153 SchedTernaryMC<"WriteVSHA2CHV", "ReadVSHA2CHV", "ReadVSHA2CHV",
155 def VSHA2CL_VV : PALUVVNoVmTernary<0b101111, OPMVV, "vsha2cl.vv">,
156 SchedTernaryMC<"WriteVSHA2CLV", "ReadVSHA2CLV", "ReadVSHA2CLV",
158 def VSHA2MS_VV : PALUVVNoVmTernary<0b101101, OPMVV, "vsha2ms.vv">,
159 SchedTernaryMC<"WriteVSHA2MSV", "ReadVSHA2MSV", "ReadVSHA2MSV",
161 } // Predicates = [HasStdExtZvknhaOrZvknhb]
163 let Predicates = [HasStdExtZvkned] in {
164 defm VAESDF : VAES_MV_V_S<0b101000, 0b101001, 0b00001, OPMVV, "vaesdf">;
165 defm VAESDM : VAES_MV_V_S<0b101000, 0b101001, 0b00000, OPMVV, "vaesdm">;
166 defm VAESEF : VAES_MV_V_S<0b101000, 0b101001, 0b00011, OPMVV, "vaesef">;
167 defm VAESEM : VAES_MV_V_S<0b101000, 0b101001, 0b00010, OPMVV, "vaesem">;
168 def VAESKF1_VI : PALUVINoVm<0b100010, "vaeskf1.vi", uimm5>,
169 SchedUnaryMC<"WriteVAESKF1V", "ReadVAESKF1V">;
170 def VAESKF2_VI : PALUVINoVmBinary<0b101010, "vaeskf2.vi", uimm5>,
171 SchedBinaryMC<"WriteVAESKF2V", "ReadVAESKF2V", "ReadVAESKF2V">;
172 let RVVConstraint = VS2Constraint in
173 def VAESZ_VS : PALUVs2NoVmBinary<0b101001, 0b00111, OPMVV, "vaesz.vs">,
174 SchedBinaryMC<"WriteVAESZV", "ReadVAESZV", "ReadVAESZV">;
175 } // Predicates = [HasStdExtZvkned]
177 let Predicates = [HasStdExtZvksed] in {
178 let RVVConstraint = NoConstraint in
179 def VSM4K_VI : PALUVINoVm<0b100001, "vsm4k.vi", uimm5>,
180 SchedUnaryMC<"WriteVSM4KV", "ReadVSM4KV">;
181 defm VSM4R : VAES_MV_V_S<0b101000, 0b101001, 0b10000, OPMVV, "vsm4r">;
182 } // Predicates = [HasStdExtZvksed]
184 let Predicates = [HasStdExtZvksh], RVVConstraint = VS2Constraint in {
185 def VSM3C_VI : PALUVINoVmBinary<0b101011, "vsm3c.vi", uimm5>,
186 SchedBinaryMC<"WriteVSM3CV", "ReadVSM3CV", "ReadVSM3CV">;
187 def VSM3ME_VV : PALUVVNoVm<0b100000, OPMVV, "vsm3me.vv">,
188 SchedUnaryMC<"WriteVSM3MEV", "ReadVSM3MEV">;
189 } // Predicates = [HasStdExtZvksh]
191 //===----------------------------------------------------------------------===//
192 // Pseudo instructions
193 //===----------------------------------------------------------------------===//
195 defvar I32IntegerVectors = !filter(vti, AllIntegerVectors, !eq(vti.SEW, 32));
196 defvar I32I64IntegerVectors = !filter(vti, AllIntegerVectors,
197 !or(!eq(vti.SEW, 32), !eq(vti.SEW, 64)));
199 class ZvkI32IntegerVectors<string vd_lmul> {
200 list<VTypeInfo> vs2_types = !cond(!eq(vd_lmul, "M8") : !filter(vti, I32IntegerVectors, !le(vti.LMul.octuple, 32)),
201 !eq(vd_lmul, "M4") : !filter(vti, I32IntegerVectors, !le(vti.LMul.octuple, 32)),
202 !eq(vd_lmul, "M2") : !filter(vti, I32IntegerVectors, !le(vti.LMul.octuple, 16)),
203 !eq(vd_lmul, "M1") : !filter(vti, I32IntegerVectors, !le(vti.LMul.octuple, 8)),
204 !eq(vd_lmul, "MF2") : !filter(vti, I32IntegerVectors, !le(vti.LMul.octuple, 4)),
205 !eq(vd_lmul, "MF4") : !filter(vti, I32IntegerVectors, !le(vti.LMul.octuple, 2)),
206 !eq(vd_lmul, "MF8") : !filter(vti, I32IntegerVectors, !le(vti.LMul.octuple, 1)));
209 class ZvkMxSet<string vd_lmul> {
210 list<LMULInfo> vs2_lmuls = !cond(!eq(vd_lmul, "M8") : [V_MF8, V_MF4, V_MF2, V_M1, V_M2, V_M4],
211 !eq(vd_lmul, "M4") : [V_MF8, V_MF4, V_MF2, V_M1, V_M2, V_M4],
212 !eq(vd_lmul, "M2") : [V_MF8, V_MF4, V_MF2, V_M1, V_M2],
213 !eq(vd_lmul, "M1") : [V_MF8, V_MF4, V_MF2, V_M1],
214 !eq(vd_lmul, "MF2") : [V_MF8, V_MF4, V_MF2],
215 !eq(vd_lmul, "MF4") : [V_MF8, V_MF4],
216 !eq(vd_lmul, "MF8") : [V_MF8]);
219 class VPseudoBinaryNoMask_Zvk<DAGOperand RetClass, VReg OpClass> :
220 Pseudo<(outs RetClass:$rd_wb),
221 (ins RetClass:$rd, OpClass:$rs2, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>,
225 let hasSideEffects = 0;
226 let Constraints = "$rd_wb = $rd";
229 let HasVecPolicyOp = 1;
230 let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
233 class VPseudoTernaryNoMask_Zvk<VReg RetClass,
235 DAGOperand Op2Class> :
236 Pseudo<(outs RetClass:$rd_wb),
237 (ins RetClass:$rd, Op1Class:$rs2, Op2Class:$rs1,
238 AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>,
242 let hasSideEffects = 0;
243 let Constraints = "$rd_wb = $rd";
246 let HasVecPolicyOp = 1;
247 let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
250 multiclass VPseudoBinaryNoMaskTU_Zvk<VReg RetClass,
254 string Constraint = "",
256 let VLMul = MInfo.value, SEW=sew in {
257 defvar suffix = !if(sew, "_" # MInfo.MX # "_E" # sew, "_" # MInfo.MX);
258 def suffix : VPseudoBinaryNoMaskTU<RetClass, Op1Class, Op2Class,
263 multiclass VPseudoTernaryNoMask_Zvk<VReg RetClass,
267 let VLMul = MInfo.value in
268 def "_" # MInfo.MX : VPseudoTernaryNoMask_Zvk<RetClass, Op1Class, Op2Class>;
271 multiclass VPseudoBinaryV_V_NoMask_Zvk<LMULInfo m> {
272 let VLMul = m.value in {
273 def "_VV_" # m.MX : VPseudoBinaryNoMask_Zvk<m.vrclass, m.vrclass>;
277 multiclass VPseudoBinaryV_S_NoMask_Zvk<LMULInfo m> {
278 let VLMul = m.value in
279 foreach vs2_lmul = ZvkMxSet<m.MX>.vs2_lmuls in
280 def "_VS_" # m.MX # "_" # vs2_lmul.MX : VPseudoBinaryNoMask_Zvk<m.vrclass, vs2_lmul.vrclass>;
283 multiclass VPseudoVGMUL {
284 foreach m = MxListVF4 in {
286 defm "" : VPseudoBinaryV_V_NoMask_Zvk<m>,
287 SchedBinary<"WriteVGMULV", "ReadVGMULV", "ReadVGMULV", mx>;
291 multiclass VPseudoVAESMV {
292 foreach m = MxListVF4 in {
294 defm "" : VPseudoBinaryV_V_NoMask_Zvk<m>,
295 SchedBinary<"WriteVAESMVV", "ReadVAESMVV", "ReadVAESMVV", mx>;
296 defm "" : VPseudoBinaryV_S_NoMask_Zvk<m>,
297 SchedBinary<"WriteVAESMVV", "ReadVAESMVV", "ReadVAESMVV", mx>;
302 multiclass VPseudoVSM4R {
303 foreach m = MxListVF4 in {
305 defm "" : VPseudoBinaryV_V_NoMask_Zvk<m>,
306 SchedBinary<"WriteVSM4RV", "ReadVSM4RV", "ReadVSM4RV", mx>;
307 defm "" : VPseudoBinaryV_S_NoMask_Zvk<m>,
308 SchedBinary<"WriteVSM4RV", "ReadVSM4RV", "ReadVSM4RV", mx>;
313 multiclass VPseudoVGHSH {
314 foreach m = MxListVF4 in {
316 defm _VV : VPseudoTernaryNoMask_Zvk<m.vrclass, m.vrclass, m.vrclass, m>,
317 SchedTernary<"WriteVGHSHV", "ReadVGHSHV", "ReadVGHSHV",
322 multiclass VPseudoVSHA2CH {
323 foreach m = MxListVF4 in {
325 defm _VV : VPseudoTernaryNoMask_Zvk<m.vrclass, m.vrclass, m.vrclass, m>,
326 SchedTernary<"WriteVSHA2CHV", "ReadVSHA2CHV", "ReadVSHA2CHV",
331 multiclass VPseudoVSHA2CL {
332 foreach m = MxListVF4 in {
334 defm _VV : VPseudoTernaryNoMask_Zvk<m.vrclass, m.vrclass, m.vrclass, m>,
335 SchedTernary<"WriteVSHA2CLV", "ReadVSHA2CLV", "ReadVSHA2CLV",
340 multiclass VPseudoVSHA2MS {
341 foreach m = MxListVF4 in {
343 defm _VV : VPseudoTernaryNoMask_Zvk<m.vrclass, m.vrclass, m.vrclass, m>,
344 SchedTernary<"WriteVSHA2MSV", "ReadVSHA2MSV", "ReadVSHA2MSV",
349 multiclass VPseudoVAESKF1 {
350 foreach m = MxListVF4 in {
352 defm _VI : VPseudoBinaryNoMaskTU_Zvk<m.vrclass, m.vrclass, uimm5, m>,
353 SchedBinary<"WriteVAESKF1V", "ReadVAESKF1V", "ReadVAESKF1V", mx,
354 forceMergeOpRead=true>;
358 multiclass VPseudoVAESKF2 {
359 foreach m = MxListVF4 in {
361 defm _VI : VPseudoTernaryNoMask_Zvk<m.vrclass, m.vrclass, uimm5, m>,
362 SchedTernary<"WriteVAESKF2V", "ReadVAESKF2V", "ReadVAESKF2V",
367 multiclass VPseudoVAESZ {
368 foreach m = MxListVF4 in {
370 defm "" : VPseudoBinaryV_S_NoMask_Zvk<m>,
371 SchedBinary<"WriteVAESZV", "ReadVAESZV", "ReadVAESZV", mx>;
375 multiclass VPseudoVSM3C {
376 foreach m = MxListVF4 in {
378 defm _VI : VPseudoTernaryNoMask_Zvk<m.vrclass, m.vrclass, uimm5, m>,
379 SchedTernary<"WriteVSM3CV", "ReadVSM3CV", "ReadVSM3CV",
384 multiclass VPseudoVSM4K {
385 foreach m = MxListVF4 in {
387 defm _VI : VPseudoBinaryNoMaskTU_Zvk<m.vrclass, m.vrclass, uimm5, m>,
388 SchedBinary<"WriteVSM4KV", "ReadVSM4KV", "ReadVSM4KV", mx,
389 forceMergeOpRead=true>;
393 multiclass VPseudoVSM3ME {
394 foreach m = MxListVF4 in {
396 defm _VV : VPseudoBinaryNoMaskTU_Zvk<m.vrclass, m.vrclass, m.vrclass, m>,
397 SchedBinary<"WriteVSM3MEV", "ReadVSM3MEV", "ReadVSM3MEV", mx,
398 forceMergeOpRead=true>;
402 multiclass VPseudoVCLMUL_VV_VX {
403 foreach m = MxList in {
405 defm "" : VPseudoBinaryV_VV<m>,
406 SchedBinary<"WriteVCLMULV", "ReadVCLMULV", "ReadVCLMULV", mx,
407 forceMergeOpRead=true>;
408 defm "" : VPseudoBinaryV_VX<m>,
409 SchedBinary<"WriteVCLMULX", "ReadVCLMULV", "ReadVCLMULX", mx,
410 forceMergeOpRead=true>;
414 multiclass VPseudoUnaryV_V<LMULInfo m> {
415 let VLMul = m.value in {
416 defvar suffix = "_V_" # m.MX;
417 def suffix : VPseudoUnaryNoMask<m.vrclass, m.vrclass>;
418 def suffix # "_MASK" : VPseudoUnaryMask<m.vrclass, m.vrclass>,
419 RISCVMaskedPseudo<MaskIdx=2>;
423 multiclass VPseudoVBREV {
424 foreach m = MxList in {
426 defm "" : VPseudoUnaryV_V<m>,
427 SchedUnary<"WriteVBREVV", "ReadVBREVV", mx, forceMergeOpRead=true>;
431 multiclass VPseudoVCLZ {
432 foreach m = MxList in {
434 defm "" : VPseudoUnaryV_V<m>,
435 SchedUnary<"WriteVCLZV", "ReadVCLZV", mx, forceMergeOpRead=true>;
439 multiclass VPseudoVCTZ {
440 foreach m = MxList in {
442 defm "" : VPseudoUnaryV_V<m>,
443 SchedUnary<"WriteVCTZV", "ReadVCTZV", mx, forceMergeOpRead=true>;
447 multiclass VPseudoVCPOP {
448 foreach m = MxList in {
450 defm "" : VPseudoUnaryV_V<m>,
451 SchedUnary<"WriteVCPOPV", "ReadVCPOPV", mx, forceMergeOpRead=true>;
455 multiclass VPseudoVWALU_VV_VX_VI<Operand ImmType> {
456 foreach m = MxListW in {
458 defm "" : VPseudoBinaryW_VV<m>,
459 SchedBinary<"WriteVWSLLV", "ReadVWSLLV", "ReadVWSLLV", mx,
460 forceMergeOpRead=true>;
461 defm "" : VPseudoBinaryW_VX<m>,
462 SchedBinary<"WriteVWSLLX", "ReadVWSLLV", "ReadVWSLLX", mx,
463 forceMergeOpRead=true>;
464 defm "" : VPseudoBinaryW_VI<ImmType, m>,
465 SchedUnary<"WriteVWSLLI", "ReadVWSLLV", mx,
466 forceMergeOpRead=true>;
470 multiclass VPseudoVANDN {
471 foreach m = MxList in {
472 defm "" : VPseudoBinaryV_VV<m>,
473 SchedBinary<"WriteVIALUV", "ReadVIALUV", "ReadVIALUV", m.MX,
474 forceMergeOpRead=true>;
475 defm "" : VPseudoBinaryV_VX<m>,
476 SchedBinary<"WriteVIALUX", "ReadVIALUV", "ReadVIALUX", m.MX,
477 forceMergeOpRead=true>;
481 multiclass VPseudoVBREV8 {
482 foreach m = MxList in {
484 defm "" : VPseudoUnaryV_V<m>,
485 SchedUnary<"WriteVBREV8V", "ReadVBREV8V", mx, forceMergeOpRead=true>;
489 multiclass VPseudoVREV8 {
490 foreach m = MxList in {
492 defm "" : VPseudoUnaryV_V<m>,
493 SchedUnary<"WriteVREV8V", "ReadVREV8V", mx, forceMergeOpRead=true>;
497 multiclass VPseudoVROL {
498 foreach m = MxList in {
499 defm "" : VPseudoBinaryV_VV<m>,
500 SchedBinary<"WriteVRotV", "ReadVRotV", "ReadVRotV", m.MX,
501 forceMergeOpRead=true>;
502 defm "" : VPseudoBinaryV_VX<m>,
503 SchedBinary<"WriteVRotX", "ReadVRotV", "ReadVRotX", m.MX,
504 forceMergeOpRead=true>;
508 multiclass VPseudoVROR<Operand ImmType> {
509 defvar Constraint = "";
510 foreach m = MxList in {
512 defm "" : VPseudoBinaryV_VV<m>,
513 SchedBinary<"WriteVRotV", "ReadVRotV", "ReadVRotV", mx,
514 forceMergeOpRead=true>;
515 defm "" : VPseudoBinaryV_VX<m>,
516 SchedBinary<"WriteVRotX", "ReadVRotV", "ReadVRotX", mx,
517 forceMergeOpRead=true>;
518 defm "" : VPseudoBinaryV_VI<ImmType, m>,
519 SchedUnary<"WriteVRotI", "ReadVRotV", mx, forceMergeOpRead=true>;
523 let Predicates = [HasStdExtZvbb] in {
524 defm PseudoVBREV : VPseudoVBREV;
525 defm PseudoVCLZ : VPseudoVCLZ;
526 defm PseudoVCTZ : VPseudoVCTZ;
527 defm PseudoVCPOP : VPseudoVCPOP;
528 defm PseudoVWSLL : VPseudoVWALU_VV_VX_VI<uimm5>;
529 } // Predicates = [HasStdExtZvbb]
531 let Predicates = [HasStdExtZvbc] in {
532 defm PseudoVCLMUL : VPseudoVCLMUL_VV_VX;
533 defm PseudoVCLMULH : VPseudoVCLMUL_VV_VX;
534 } // Predicates = [HasStdExtZvbc]
536 let Predicates = [HasStdExtZvkb] in {
537 defm PseudoVANDN : VPseudoVANDN;
538 defm PseudoVBREV8 : VPseudoVBREV8;
539 defm PseudoVREV8 : VPseudoVREV8;
540 defm PseudoVROL : VPseudoVROL;
541 defm PseudoVROR : VPseudoVROR<uimm6>;
542 } // Predicates = [HasStdExtZvkb]
544 let Predicates = [HasStdExtZvkg] in {
545 defm PseudoVGHSH : VPseudoVGHSH;
546 defm PseudoVGMUL : VPseudoVGMUL;
547 } // Predicates = [HasStdExtZvkg]
549 let Predicates = [HasStdExtZvkned] in {
550 defm PseudoVAESDF : VPseudoVAESMV;
551 defm PseudoVAESDM : VPseudoVAESMV;
552 defm PseudoVAESEF : VPseudoVAESMV;
553 defm PseudoVAESEM : VPseudoVAESMV;
554 defm PseudoVAESKF1 : VPseudoVAESKF1;
555 defm PseudoVAESKF2 : VPseudoVAESKF2;
556 defm PseudoVAESZ : VPseudoVAESZ;
557 } // Predicates = [HasStdExtZvkned]
559 let Predicates = [HasStdExtZvknhaOrZvknhb] in {
560 defm PseudoVSHA2CH : VPseudoVSHA2CH;
561 defm PseudoVSHA2CL : VPseudoVSHA2CL;
562 defm PseudoVSHA2MS : VPseudoVSHA2MS;
563 } // Predicates = [HasStdExtZvknhaOrZvknhb]
565 let Predicates = [HasStdExtZvksed] in {
566 defm PseudoVSM4K : VPseudoVSM4K;
567 defm PseudoVSM4R : VPseudoVSM4R;
568 } // Predicates = [HasStdExtZvksed]
570 let Predicates = [HasStdExtZvksh] in {
571 defm PseudoVSM3C : VPseudoVSM3C;
572 defm PseudoVSM3ME : VPseudoVSM3ME;
573 } // Predicates = [HasStdExtZvksh]
575 //===----------------------------------------------------------------------===//
577 //===----------------------------------------------------------------------===//
579 multiclass VPatUnarySDNode_V<SDPatternOperator op, string instruction_name,
580 Predicate predicate = HasStdExtZvbb> {
581 foreach vti = AllIntegerVectors in {
582 let Predicates = !listconcat([predicate],
583 GetVTypePredicates<vti>.Predicates) in {
584 def : Pat<(vti.Vector (op (vti.Vector vti.RegClass:$rs1))),
585 (!cast<Instruction>(instruction_name#"_V_"#vti.LMul.MX)
586 (vti.Vector (IMPLICIT_DEF)),
588 vti.AVL, vti.Log2SEW, TA_MA)>;
593 // Helpers for detecting splats since we preprocess splat_vector to vmv.v.x
594 // This should match the logic in RISCVDAGToDAGISel::selectVSplat
595 def riscv_splat_vector : PatFrag<(ops node:$rs1),
596 (riscv_vmv_v_x_vl undef, node:$rs1, srcvalue)>;
597 def riscv_vnot : PatFrag<(ops node:$rs1), (xor node:$rs1,
598 (riscv_splat_vector -1))>;
600 foreach vti = AllIntegerVectors in {
601 let Predicates = !listconcat([HasStdExtZvkb],
602 GetVTypePredicates<vti>.Predicates) in {
603 def : Pat<(vti.Vector (and (riscv_vnot vti.RegClass:$rs1),
605 (!cast<Instruction>("PseudoVANDN_VV_"#vti.LMul.MX)
606 (vti.Vector (IMPLICIT_DEF)),
609 vti.AVL, vti.Log2SEW, TA_MA)>;
610 def : Pat<(vti.Vector (and (riscv_splat_vector
611 (not vti.ScalarRegClass:$rs1)),
613 (!cast<Instruction>("PseudoVANDN_VX_"#vti.LMul.MX)
614 (vti.Vector (IMPLICIT_DEF)),
616 vti.ScalarRegClass:$rs1,
617 vti.AVL, vti.Log2SEW, TA_MA)>;
621 defm : VPatUnarySDNode_V<bitreverse, "PseudoVBREV">;
622 defm : VPatUnarySDNode_V<bswap, "PseudoVREV8", HasStdExtZvkb>;
623 defm : VPatUnarySDNode_V<ctlz, "PseudoVCLZ">;
624 defm : VPatUnarySDNode_V<cttz, "PseudoVCTZ">;
625 defm : VPatUnarySDNode_V<ctpop, "PseudoVCPOP">;
627 defm : VPatBinarySDNode_VV_VX<rotl, "PseudoVROL">;
629 // Invert the immediate and mask it to SEW for readability.
630 def InvRot8Imm : SDNodeXForm<imm, [{
631 return CurDAG->getTargetConstant(0x7 & (64 - N->getZExtValue()), SDLoc(N),
634 def InvRot16Imm : SDNodeXForm<imm, [{
635 return CurDAG->getTargetConstant(0xf & (64 - N->getZExtValue()), SDLoc(N),
638 def InvRot32Imm : SDNodeXForm<imm, [{
639 return CurDAG->getTargetConstant(0x1f & (64 - N->getZExtValue()), SDLoc(N),
642 def InvRot64Imm : SDNodeXForm<imm, [{
643 return CurDAG->getTargetConstant(0x3f & (64 - N->getZExtValue()), SDLoc(N),
647 // Although there is no vrol.vi, an immediate rotate left can be achieved by
648 // negating the immediate in vror.vi
649 foreach vti = AllIntegerVectors in {
650 let Predicates = !listconcat([HasStdExtZvkb],
651 GetVTypePredicates<vti>.Predicates) in {
652 def : Pat<(vti.Vector (rotl vti.RegClass:$rs2,
653 (vti.Vector (SplatPat_uimm6 uimm6:$rs1)))),
654 (!cast<Instruction>("PseudoVROR_VI_"#vti.LMul.MX)
655 (vti.Vector (IMPLICIT_DEF)),
657 (!cast<SDNodeXForm>("InvRot" # vti.SEW # "Imm") uimm6:$rs1),
658 vti.AVL, vti.Log2SEW, TA_MA)>;
661 defm : VPatBinarySDNode_VV_VX_VI<rotr, "PseudoVROR", uimm6>;
663 foreach vtiToWti = AllWidenableIntVectors in {
664 defvar vti = vtiToWti.Vti;
665 defvar wti = vtiToWti.Wti;
666 let Predicates = !listconcat([HasStdExtZvbb],
667 GetVTypePredicates<vti>.Predicates,
668 GetVTypePredicates<wti>.Predicates) in {
669 def : Pat<(shl (wti.Vector (zext_oneuse (vti.Vector vti.RegClass:$rs2))),
670 (wti.Vector (ext_oneuse (vti.Vector vti.RegClass:$rs1)))),
671 (!cast<Instruction>("PseudoVWSLL_VV_"#vti.LMul.MX)
672 (wti.Vector (IMPLICIT_DEF)),
673 vti.RegClass:$rs2, vti.RegClass:$rs1,
674 vti.AVL, vti.Log2SEW, TA_MA)>;
676 def : Pat<(shl (wti.Vector (zext_oneuse (vti.Vector vti.RegClass:$rs2))),
677 (wti.Vector (Low8BitsSplatPat (XLenVT GPR:$rs1)))),
678 (!cast<Instruction>("PseudoVWSLL_VX_"#vti.LMul.MX)
679 (wti.Vector (IMPLICIT_DEF)),
680 vti.RegClass:$rs2, GPR:$rs1,
681 vti.AVL, vti.Log2SEW, TA_MA)>;
683 def : Pat<(shl (wti.Vector (zext_oneuse (vti.Vector vti.RegClass:$rs2))),
684 (wti.Vector (SplatPat_uimm5 uimm5:$rs1))),
685 (!cast<Instruction>("PseudoVWSLL_VI_"#vti.LMul.MX)
686 (wti.Vector (IMPLICIT_DEF)),
687 vti.RegClass:$rs2, uimm5:$rs1,
688 vti.AVL, vti.Log2SEW, TA_MA)>;
692 //===----------------------------------------------------------------------===//
694 //===----------------------------------------------------------------------===//
696 multiclass VPatUnaryVL_V<SDPatternOperator op, string instruction_name,
697 Predicate predicate = HasStdExtZvbb> {
698 foreach vti = AllIntegerVectors in {
699 let Predicates = !listconcat([predicate],
700 GetVTypePredicates<vti>.Predicates) in {
701 def : Pat<(vti.Vector (op (vti.Vector vti.RegClass:$rs1),
702 (vti.Vector vti.RegClass:$merge),
705 (!cast<Instruction>(instruction_name#"_V_"#vti.LMul.MX#"_MASK")
716 foreach vti = AllIntegerVectors in {
717 let Predicates = !listconcat([HasStdExtZvkb],
718 GetVTypePredicates<vti>.Predicates) in {
719 def : Pat<(vti.Vector (riscv_and_vl (riscv_xor_vl
720 (vti.Vector vti.RegClass:$rs1),
721 (riscv_splat_vector -1),
722 (vti.Vector vti.RegClass:$merge),
725 (vti.Vector vti.RegClass:$rs2),
726 (vti.Vector vti.RegClass:$merge),
729 (!cast<Instruction>("PseudoVANDN_VV_"#vti.LMul.MX#"_MASK")
738 def : Pat<(vti.Vector (riscv_and_vl (riscv_splat_vector
739 (not vti.ScalarRegClass:$rs1)),
740 (vti.Vector vti.RegClass:$rs2),
741 (vti.Vector vti.RegClass:$merge),
744 (!cast<Instruction>("PseudoVANDN_VX_"#vti.LMul.MX#"_MASK")
747 vti.ScalarRegClass:$rs1,
755 defm : VPatUnaryVL_V<riscv_bitreverse_vl, "PseudoVBREV">;
756 defm : VPatUnaryVL_V<riscv_bswap_vl, "PseudoVREV8", HasStdExtZvkb>;
757 defm : VPatUnaryVL_V<riscv_ctlz_vl, "PseudoVCLZ">;
758 defm : VPatUnaryVL_V<riscv_cttz_vl, "PseudoVCTZ">;
759 defm : VPatUnaryVL_V<riscv_ctpop_vl, "PseudoVCPOP">;
761 defm : VPatBinaryVL_VV_VX<riscv_rotl_vl, "PseudoVROL">;
762 // Although there is no vrol.vi, an immediate rotate left can be achieved by
763 // negating the immediate in vror.vi
764 foreach vti = AllIntegerVectors in {
765 let Predicates = !listconcat([HasStdExtZvkb],
766 GetVTypePredicates<vti>.Predicates) in {
767 def : Pat<(riscv_rotl_vl vti.RegClass:$rs2,
768 (vti.Vector (SplatPat_uimm6 uimm6:$rs1)),
769 (vti.Vector vti.RegClass:$merge),
770 (vti.Mask V0), VLOpFrag),
771 (!cast<Instruction>("PseudoVROR_VI_"#vti.LMul.MX#"_MASK")
774 (!cast<SDNodeXForm>("InvRot" # vti.SEW # "Imm") uimm6:$rs1),
775 (vti.Mask V0), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>;
778 defm : VPatBinaryVL_VV_VX_VI<riscv_rotr_vl, "PseudoVROR", uimm6>;
780 foreach vtiToWti = AllWidenableIntVectors in {
781 defvar vti = vtiToWti.Vti;
782 defvar wti = vtiToWti.Wti;
783 let Predicates = !listconcat([HasStdExtZvbb],
784 GetVTypePredicates<vti>.Predicates,
785 GetVTypePredicates<wti>.Predicates) in {
786 def : Pat<(riscv_shl_vl
787 (wti.Vector (zext_oneuse (vti.Vector vti.RegClass:$rs2))),
788 (wti.Vector (ext_oneuse (vti.Vector vti.RegClass:$rs1))),
789 (wti.Vector wti.RegClass:$merge),
790 (vti.Mask V0), VLOpFrag),
791 (!cast<Instruction>("PseudoVWSLL_VV_"#vti.LMul.MX#"_MASK")
792 wti.RegClass:$merge, vti.RegClass:$rs2, vti.RegClass:$rs1,
793 (vti.Mask V0), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>;
795 def : Pat<(riscv_shl_vl
796 (wti.Vector (riscv_zext_vl_oneuse
797 (vti.Vector vti.RegClass:$rs2),
798 (vti.Mask V0), VLOpFrag)),
799 (wti.Vector (riscv_ext_vl_oneuse
800 (vti.Vector vti.RegClass:$rs1),
801 (vti.Mask V0), VLOpFrag)),
802 (wti.Vector wti.RegClass:$merge),
803 (vti.Mask V0), VLOpFrag),
804 (!cast<Instruction>("PseudoVWSLL_VV_"#vti.LMul.MX#"_MASK")
805 wti.RegClass:$merge, vti.RegClass:$rs2, vti.RegClass:$rs1,
806 (vti.Mask V0), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>;
808 def : Pat<(riscv_shl_vl
809 (wti.Vector (zext_oneuse (vti.Vector vti.RegClass:$rs2))),
810 (wti.Vector (Low8BitsSplatPat (XLenVT GPR:$rs1))),
811 (wti.Vector wti.RegClass:$merge),
812 (vti.Mask V0), VLOpFrag),
813 (!cast<Instruction>("PseudoVWSLL_VX_"#vti.LMul.MX#"_MASK")
814 wti.RegClass:$merge, vti.RegClass:$rs2, GPR:$rs1,
815 (vti.Mask V0), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>;
817 def : Pat<(riscv_shl_vl
818 (wti.Vector (riscv_zext_vl_oneuse
819 (vti.Vector vti.RegClass:$rs2),
820 (vti.Mask V0), VLOpFrag)),
821 (wti.Vector (Low8BitsSplatPat (XLenVT GPR:$rs1))),
822 (wti.Vector wti.RegClass:$merge),
823 (vti.Mask V0), VLOpFrag),
824 (!cast<Instruction>("PseudoVWSLL_VX_"#vti.LMul.MX#"_MASK")
825 wti.RegClass:$merge, vti.RegClass:$rs2, GPR:$rs1,
826 (vti.Mask V0), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>;
828 def : Pat<(riscv_shl_vl
829 (wti.Vector (zext_oneuse (vti.Vector vti.RegClass:$rs2))),
830 (wti.Vector (SplatPat_uimm5 uimm5:$rs1)),
831 (wti.Vector wti.RegClass:$merge),
832 (vti.Mask V0), VLOpFrag),
833 (!cast<Instruction>("PseudoVWSLL_VI_"#vti.LMul.MX#"_MASK")
834 wti.RegClass:$merge, vti.RegClass:$rs2, uimm5:$rs1,
835 (vti.Mask V0), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>;
837 def : Pat<(riscv_shl_vl
838 (wti.Vector (riscv_zext_vl_oneuse
839 (vti.Vector vti.RegClass:$rs2),
840 (vti.Mask V0), VLOpFrag)),
841 (wti.Vector (SplatPat_uimm5 uimm5:$rs1)),
842 (wti.Vector wti.RegClass:$merge),
843 (vti.Mask V0), VLOpFrag),
844 (!cast<Instruction>("PseudoVWSLL_VI_"#vti.LMul.MX#"_MASK")
845 wti.RegClass:$merge, vti.RegClass:$rs2, uimm5:$rs1,
846 (vti.Mask V0), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>;
848 def : Pat<(riscv_vwsll_vl
849 (vti.Vector vti.RegClass:$rs2),
850 (vti.Vector vti.RegClass:$rs1),
851 (wti.Vector wti.RegClass:$merge),
852 (vti.Mask V0), VLOpFrag),
853 (!cast<Instruction>("PseudoVWSLL_VV_"#vti.LMul.MX#"_MASK")
854 wti.RegClass:$merge, vti.RegClass:$rs2, vti.RegClass:$rs1,
855 (vti.Mask V0), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>;
857 def : Pat<(riscv_vwsll_vl
858 (vti.Vector vti.RegClass:$rs2),
859 (vti.Vector (Low8BitsSplatPat (XLenVT GPR:$rs1))),
860 (wti.Vector wti.RegClass:$merge),
861 (vti.Mask V0), VLOpFrag),
862 (!cast<Instruction>("PseudoVWSLL_VX_"#vti.LMul.MX#"_MASK")
863 wti.RegClass:$merge, vti.RegClass:$rs2, GPR:$rs1,
864 (vti.Mask V0), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>;
866 def : Pat<(riscv_vwsll_vl
867 (vti.Vector vti.RegClass:$rs2),
868 (vti.Vector (SplatPat_uimm5 uimm5:$rs1)),
869 (wti.Vector wti.RegClass:$merge),
870 (vti.Mask V0), VLOpFrag),
871 (!cast<Instruction>("PseudoVWSLL_VI_"#vti.LMul.MX#"_MASK")
872 wti.RegClass:$merge, vti.RegClass:$rs2, uimm5:$rs1,
873 (vti.Mask V0), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>;
877 //===----------------------------------------------------------------------===//
879 //===----------------------------------------------------------------------===//
881 class VPatUnaryNoMask_Zvk<string intrinsic_name,
884 ValueType result_type,
888 VReg result_reg_class,
889 VReg op2_reg_class> :
890 Pat<(result_type (!cast<Intrinsic>(intrinsic_name)
891 (result_type result_reg_class:$rd),
892 (op2_type op2_reg_class:$rs2),
893 VLOpFrag, (XLenVT timm:$policy))),
894 (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX)
895 (result_type result_reg_class:$rd),
896 (op2_type op2_reg_class:$rs2),
897 GPR:$vl, sew, (XLenVT timm:$policy))>;
899 class VPatUnaryNoMask_VS_Zvk<string intrinsic_name,
902 ValueType result_type,
907 VReg result_reg_class,
908 VReg op2_reg_class> :
909 Pat<(result_type (!cast<Intrinsic>(intrinsic_name)
910 (result_type result_reg_class:$rd),
911 (op2_type op2_reg_class:$rs2),
912 VLOpFrag, (XLenVT timm:$policy))),
913 (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX#"_"#vs2_lmul.MX)
914 (result_type result_reg_class:$rd),
915 (op2_type op2_reg_class:$rs2),
916 GPR:$vl, sew, (XLenVT timm:$policy))>;
918 multiclass VPatUnaryV_V_NoMask_Zvk<string intrinsic, string instruction,
919 list<VTypeInfo> vtilist> {
920 foreach vti = vtilist in
921 def : VPatUnaryNoMask_Zvk<intrinsic # "_vv", instruction, "VV",
922 vti.Vector, vti.Vector, vti.Log2SEW,
923 vti.LMul, vti.RegClass, vti.RegClass>;
926 multiclass VPatUnaryV_S_NoMaskVectorCrypto<string intrinsic, string instruction,
927 list<VTypeInfo> vtilist> {
928 foreach vti = vtilist in
929 foreach vti_vs2 = ZvkI32IntegerVectors<vti.LMul.MX>.vs2_types in
930 def : VPatUnaryNoMask_VS_Zvk<intrinsic # "_vs", instruction, "VS",
931 vti.Vector, vti_vs2.Vector, vti.Log2SEW,
932 vti.LMul, vti_vs2.LMul, vti.RegClass, vti_vs2.RegClass>;
935 multiclass VPatUnaryV_V_S_NoMask_Zvk<string intrinsic, string instruction,
936 list<VTypeInfo> vtilist> {
937 defm : VPatUnaryV_V_NoMask_Zvk<intrinsic, instruction, vtilist>;
938 defm : VPatUnaryV_S_NoMaskVectorCrypto<intrinsic, instruction, vtilist>;
941 multiclass VPatBinaryV_VV_NoMask<string intrinsic, string instruction,
942 list<VTypeInfo> vtilist> {
943 foreach vti = vtilist in
944 def : VPatTernaryNoMaskWithPolicy<intrinsic, instruction, "VV",
945 vti.Vector, vti.Vector, vti.Vector,
946 vti.Log2SEW, vti.LMul, vti.RegClass,
947 vti.RegClass, vti.RegClass>;
950 multiclass VPatBinaryV_VI_NoMask<string intrinsic, string instruction,
951 list<VTypeInfo> vtilist,
952 Operand imm_type = tuimm5> {
953 foreach vti = vtilist in
954 def : VPatTernaryNoMaskWithPolicy<intrinsic, instruction, "VI",
955 vti.Vector, vti.Vector, XLenVT,
956 vti.Log2SEW, vti.LMul, vti.RegClass,
957 vti.RegClass, imm_type>;
960 multiclass VPatBinaryV_VI_NoMaskTU<string intrinsic, string instruction,
961 list<VTypeInfo> vtilist,
962 Operand imm_type = tuimm5> {
963 foreach vti = vtilist in
964 def : VPatBinaryNoMaskTU<intrinsic, instruction # "_VI_" # vti.LMul.MX,
965 vti.Vector, vti.Vector, XLenVT, vti.Log2SEW,
966 vti.RegClass, vti.RegClass, imm_type>;
969 multiclass VPatBinaryV_VV_NoMaskTU<string intrinsic, string instruction,
970 list<VTypeInfo> vtilist> {
971 foreach vti = vtilist in
972 def : VPatBinaryNoMaskTU<intrinsic, instruction # "_VV_" # vti.LMul.MX,
973 vti.Vector, vti.Vector, vti.Vector, vti.Log2SEW,
974 vti.RegClass, vti.RegClass, vti.RegClass>;
977 multiclass VPatBinaryV_VX_VROTATE<string intrinsic, string instruction,
978 list<VTypeInfo> vtilist, bit isSEWAware = 0> {
979 foreach vti = vtilist in {
980 defvar kind = "V"#vti.ScalarSuffix;
981 let Predicates = GetVTypePredicates<vti>.Predicates in
982 defm : VPatBinary<intrinsic,
984 instruction#"_"#kind#"_"#vti.LMul.MX#"_E"#vti.SEW,
985 instruction#"_"#kind#"_"#vti.LMul.MX),
986 vti.Vector, vti.Vector, XLenVT, vti.Mask,
987 vti.Log2SEW, vti.RegClass,
988 vti.RegClass, vti.ScalarRegClass>;
992 multiclass VPatBinaryV_VI_VROL<string intrinsic, string instruction,
993 list<VTypeInfo> vtilist, bit isSEWAware = 0> {
994 foreach vti = vtilist in {
995 defvar Intr = !cast<Intrinsic>(intrinsic);
996 defvar Pseudo = !cast<Instruction>(
997 !if(isSEWAware, instruction#"_VI_"#vti.LMul.MX#"_E"#vti.SEW,
998 instruction#"_VI_"#vti.LMul.MX));
999 let Predicates = GetVTypePredicates<vti>.Predicates in
1000 def : Pat<(vti.Vector (Intr (vti.Vector vti.RegClass:$merge),
1001 (vti.Vector vti.RegClass:$rs2),
1002 (XLenVT uimm6:$rs1),
1004 (Pseudo (vti.Vector vti.RegClass:$merge),
1005 (vti.Vector vti.RegClass:$rs2),
1006 (InvRot64Imm uimm6:$rs1),
1007 GPR:$vl, vti.Log2SEW, TU_MU)>;
1009 defvar IntrMask = !cast<Intrinsic>(intrinsic#"_mask");
1010 defvar PseudoMask = !cast<Instruction>(
1011 !if(isSEWAware, instruction#"_VI_"#vti.LMul.MX#"_E"#vti.SEW#"_MASK",
1012 instruction#"_VI_"#vti.LMul.MX#"_MASK"));
1013 let Predicates = GetVTypePredicates<vti>.Predicates in
1014 def : Pat<(vti.Vector (IntrMask (vti.Vector vti.RegClass:$merge),
1015 (vti.Vector vti.RegClass:$rs2),
1016 (XLenVT uimm6:$rs1),
1018 VLOpFrag, (XLenVT timm:$policy))),
1019 (PseudoMask (vti.Vector vti.RegClass:$merge),
1020 (vti.Vector vti.RegClass:$rs2),
1021 (InvRot64Imm uimm6:$rs1),
1023 GPR:$vl, vti.Log2SEW, (XLenVT timm:$policy))>;
1027 multiclass VPatBinaryV_VV_VX_VROL<string intrinsic, string instruction,
1028 string instruction2, list<VTypeInfo> vtilist>
1029 : VPatBinaryV_VV<intrinsic, instruction, vtilist>,
1030 VPatBinaryV_VX_VROTATE<intrinsic, instruction, vtilist>,
1031 VPatBinaryV_VI_VROL<intrinsic, instruction2, vtilist>;
1033 multiclass VPatBinaryV_VV_VX_VI_VROR<string intrinsic, string instruction,
1034 list<VTypeInfo> vtilist,
1035 Operand ImmType = uimm6>
1036 : VPatBinaryV_VV<intrinsic, instruction, vtilist>,
1037 VPatBinaryV_VX_VROTATE<intrinsic, instruction, vtilist>,
1038 VPatBinaryV_VI<intrinsic, instruction, vtilist, ImmType>;
1040 multiclass VPatBinaryW_VI_VWSLL<string intrinsic, string instruction,
1041 list<VTypeInfoToWide> vtilist> {
1042 foreach VtiToWti = vtilist in {
1043 defvar Vti = VtiToWti.Vti;
1044 defvar Wti = VtiToWti.Wti;
1045 defm : VPatBinary<intrinsic, instruction # "_VI_" # Vti.LMul.MX,
1046 Wti.Vector, Vti.Vector, XLenVT, Vti.Mask,
1047 Vti.Log2SEW, Wti.RegClass,
1048 Vti.RegClass, uimm5>;
1052 multiclass VPatBinaryW_VX_VWSLL<string intrinsic, string instruction,
1053 list<VTypeInfoToWide> vtilist> {
1054 foreach VtiToWti = vtilist in {
1055 defvar Vti = VtiToWti.Vti;
1056 defvar Wti = VtiToWti.Wti;
1057 defvar kind = "V"#Vti.ScalarSuffix;
1058 let Predicates = !listconcat(GetVTypePredicates<Vti>.Predicates,
1059 GetVTypePredicates<Wti>.Predicates) in
1060 defm : VPatBinary<intrinsic, instruction#"_"#kind#"_"#Vti.LMul.MX,
1061 Wti.Vector, Vti.Vector, XLenVT, Vti.Mask,
1062 Vti.Log2SEW, Wti.RegClass,
1063 Vti.RegClass, Vti.ScalarRegClass>;
1067 multiclass VPatBinaryW_VV_VX_VI_VWSLL<string intrinsic, string instruction,
1068 list<VTypeInfoToWide> vtilist>
1069 : VPatBinaryW_VV<intrinsic, instruction, vtilist>,
1070 VPatBinaryW_VX_VWSLL<intrinsic, instruction, vtilist>,
1071 VPatBinaryW_VI_VWSLL<intrinsic, instruction, vtilist>;
1073 let Predicates = [HasStdExtZvbb] in {
1074 defm : VPatUnaryV_V<"int_riscv_vbrev", "PseudoVBREV", AllIntegerVectors>;
1075 defm : VPatUnaryV_V<"int_riscv_vclz", "PseudoVCLZ", AllIntegerVectors>;
1076 defm : VPatUnaryV_V<"int_riscv_vctz", "PseudoVCTZ", AllIntegerVectors>;
1077 defm : VPatUnaryV_V<"int_riscv_vcpopv", "PseudoVCPOP", AllIntegerVectors>;
1078 defm : VPatBinaryW_VV_VX_VI_VWSLL<"int_riscv_vwsll", "PseudoVWSLL", AllWidenableIntVectors>;
1079 } // Predicates = [HasStdExtZvbb]
1081 let Predicates = [HasStdExtZvbc] in {
1082 defm : VPatBinaryV_VV_VX<"int_riscv_vclmul", "PseudoVCLMUL", I64IntegerVectors>;
1083 defm : VPatBinaryV_VV_VX<"int_riscv_vclmulh", "PseudoVCLMULH", I64IntegerVectors>;
1084 } // Predicates = [HasStdExtZvbc]
1086 let Predicates = [HasStdExtZvkb] in {
1087 defm : VPatBinaryV_VV_VX<"int_riscv_vandn", "PseudoVANDN", AllIntegerVectors>;
1088 defm : VPatUnaryV_V<"int_riscv_vbrev8", "PseudoVBREV8", AllIntegerVectors>;
1089 defm : VPatUnaryV_V<"int_riscv_vrev8", "PseudoVREV8", AllIntegerVectors>;
1090 defm : VPatBinaryV_VV_VX_VROL<"int_riscv_vrol", "PseudoVROL", "PseudoVROR", AllIntegerVectors>;
1091 defm : VPatBinaryV_VV_VX_VI_VROR<"int_riscv_vror", "PseudoVROR", AllIntegerVectors>;
1092 } // Predicates = [HasStdExtZvkb]
1094 let Predicates = [HasStdExtZvkg] in {
1095 defm : VPatBinaryV_VV_NoMask<"int_riscv_vghsh", "PseudoVGHSH", I32IntegerVectors>;
1096 defm : VPatUnaryV_V_NoMask_Zvk<"int_riscv_vgmul", "PseudoVGMUL", I32IntegerVectors>;
1097 } // Predicates = [HasStdExtZvkg]
1099 let Predicates = [HasStdExtZvkned] in {
1100 defm : VPatUnaryV_V_S_NoMask_Zvk<"int_riscv_vaesdf", "PseudoVAESDF", I32IntegerVectors>;
1101 defm : VPatUnaryV_V_S_NoMask_Zvk<"int_riscv_vaesdm", "PseudoVAESDM", I32IntegerVectors>;
1102 defm : VPatUnaryV_V_S_NoMask_Zvk<"int_riscv_vaesef", "PseudoVAESEF", I32IntegerVectors>;
1103 defm : VPatUnaryV_V_S_NoMask_Zvk<"int_riscv_vaesem", "PseudoVAESEM", I32IntegerVectors>;
1104 defm : VPatBinaryV_VI_NoMaskTU<"int_riscv_vaeskf1", "PseudoVAESKF1", I32IntegerVectors>;
1105 defm : VPatBinaryV_VI_NoMask<"int_riscv_vaeskf2", "PseudoVAESKF2", I32IntegerVectors>;
1106 defm : VPatUnaryV_S_NoMaskVectorCrypto<"int_riscv_vaesz", "PseudoVAESZ", I32IntegerVectors>;
1107 } // Predicates = [HasStdExtZvkned]
1109 let Predicates = [HasStdExtZvknha] in {
1110 defm : VPatBinaryV_VV_NoMask<"int_riscv_vsha2ch", "PseudoVSHA2CH", I32IntegerVectors>;
1111 defm : VPatBinaryV_VV_NoMask<"int_riscv_vsha2cl", "PseudoVSHA2CH", I32IntegerVectors>;
1112 defm : VPatBinaryV_VV_NoMask<"int_riscv_vsha2ms", "PseudoVSHA2MS", I32IntegerVectors>;
1113 } // Predicates = [HasStdExtZvknha]
1115 let Predicates = [HasStdExtZvknhb] in {
1116 defm : VPatBinaryV_VV_NoMask<"int_riscv_vsha2ch", "PseudoVSHA2CH", I32I64IntegerVectors>;
1117 defm : VPatBinaryV_VV_NoMask<"int_riscv_vsha2cl", "PseudoVSHA2CH", I32I64IntegerVectors>;
1118 defm : VPatBinaryV_VV_NoMask<"int_riscv_vsha2ms", "PseudoVSHA2MS", I32I64IntegerVectors>;
1119 } // Predicates = [HasStdExtZvknhb]
1121 let Predicates = [HasStdExtZvksed] in {
1122 defm : VPatBinaryV_VI_NoMaskTU<"int_riscv_vsm4k", "PseudoVSM4K", I32IntegerVectors>;
1123 defm : VPatUnaryV_V_S_NoMask_Zvk<"int_riscv_vsm4r", "PseudoVSM4R", I32IntegerVectors>;
1124 } // Predicates = [HasStdExtZvksed]
1126 let Predicates = [HasStdExtZvksh] in {
1127 defm : VPatBinaryV_VI_NoMask<"int_riscv_vsm3c", "PseudoVSM3C", I32IntegerVectors>;
1128 defm : VPatBinaryV_VV_NoMaskTU<"int_riscv_vsm3me", "PseudoVSM3ME", I32IntegerVectors>;
1129 } // Predicates = [HasStdExtZvksh]