1843 lines · plain
1//===-- RISCVInstrInfoV.td - RISC-V 'V' instructions -------*- tablegen -*-===//2//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-exception6//7//===----------------------------------------------------------------------===//8///9/// This file describes the RISC-V instructions from the standard 'V' Vector10/// extension, version 1.0.11///12//===----------------------------------------------------------------------===//13 14//===----------------------------------------------------------------------===//15// Operand and SDNode transformation definitions.16//===----------------------------------------------------------------------===//17 18class VTypeIAsmOperand<int VTypeINum> : AsmOperandClass {19 let Name = "VTypeI" # VTypeINum;20 let ParserMethod = "parseVTypeI";21 let DiagnosticType = "InvalidVTypeI";22 let RenderMethod = "addVTypeIOperands";23}24 25class VTypeIOp<int VTypeINum> : RISCVOp {26 let ParserMatchClass = VTypeIAsmOperand<VTypeINum>;27 let PrintMethod = "printVTypeI";28 let DecoderMethod = "decodeUImmOperand<"#VTypeINum#">";29 let OperandType = "OPERAND_VTYPEI" # VTypeINum;30 let MCOperandPredicate = [{31 int64_t Imm;32 if (MCOp.evaluateAsConstantImm(Imm))33 return isUInt<}] # VTypeINum # [{>(Imm);34 return MCOp.Kind == KindTy::VType;35 }];36}37 38def VTypeIOp10 : VTypeIOp<10>;39def VTypeIOp11 : VTypeIOp<11>;40 41def VMaskAsmOperand : AsmOperandClass {42 let Name = "RVVMaskRegOpOperand";43 let RenderMethod = "addRegOperands";44 let PredicateMethod = "isV0Reg";45 let ParserMethod = "parseMaskReg";46 let IsOptional = 1;47 let DefaultMethod = "defaultMaskRegOp";48 let DiagnosticType = "InvalidVMaskRegister";49 let DiagnosticString = "operand must be v0.t";50}51 52def VMaskCarryInAsmOperand : AsmOperandClass {53 let Name = "RVVMaskCarryInRegOpOperand";54 let RenderMethod = "addRegOperands";55 let PredicateMethod = "isV0Reg";56 let DiagnosticType = "InvalidVMaskCarryInRegister";57 let DiagnosticString = "operand must be v0";58}59 60def VMaskOp : RegisterOperand<VMV0> {61 let ParserMatchClass = VMaskAsmOperand;62 let PrintMethod = "printVMaskReg";63 let EncoderMethod = "getVMaskReg";64 let DecoderMethod = "decodeVMaskReg";65}66 67def VMaskCarryInOp : RegisterOperand<VMV0> {68 let ParserMatchClass = VMaskCarryInAsmOperand;69 let EncoderMethod = "getVMaskReg";70}71 72def simm5 : RISCVSImmLeafOp<5> {73 let MCOperandPredicate = [{74 int64_t Imm;75 if (MCOp.evaluateAsConstantImm(Imm))76 return isInt<5>(Imm);77 return MCOp.isBareSymbolRef();78 }];79}80 81def simm5_plus1 : RISCVOp, ImmLeaf<XLenVT,82 [{return (isInt<5>(Imm) && Imm != -16) || Imm == 16;}]> {83 let ParserMatchClass = SImmAsmOperand<5, "Plus1">;84 let OperandType = "OPERAND_SIMM5_PLUS1";85 let MCOperandPredicate = [{86 int64_t Imm;87 if (MCOp.evaluateAsConstantImm(Imm))88 return (isInt<5>(Imm) && Imm != -16) || Imm == 16;89 return MCOp.isBareSymbolRef();90 }];91}92 93def simm5_plus1_nonzero : ImmLeaf<XLenVT,94 [{return Imm != 0 && ((isInt<5>(Imm) && Imm != -16) || Imm == 16);}]>;95 96//===----------------------------------------------------------------------===//97// Scheduling definitions.98//===----------------------------------------------------------------------===//99 100// Common class of scheduling definitions.101// `ReadVPassthru` will be prepended to reads if instruction is masked.102// `ReadVMask` will be appended to reads if instruction is masked.103// Operands:104// `writes` SchedWrites that are listed for each explicit def operand105// in order.106// `reads` SchedReads that are listed for each explicit use operand.107// `forceMasked` Forced to be masked (e.g. Add-with-Carry Instructions).108// `forcePassthruRead` Force to have read for passthru operand.109class SchedCommon<list<SchedWrite> writes, list<SchedRead> reads,110 string mx = "WorstCase", int sew = 0, bit forceMasked = 0,111 bit forcePassthruRead = 0> : Sched<[]> {112 defvar isMasked = !ne(!find(NAME, "_MASK"), -1);113 defvar isTied = !ne(!find(NAME, "_TIED"), -1);114 defvar isMaskedOrForceMasked = !or(forceMasked, isMasked);115 defvar isTiedMasked = !and(isMaskedOrForceMasked, isTied);116 defvar passthruRead = !if(!or(!eq(mx, "WorstCase"), !eq(sew, 0)),117 !cast<SchedRead>("ReadVPassthru_" # mx),118 !cast<SchedRead>("ReadVPassthru_" # mx # "_E" #sew));119 // We don't need passthru operand if it's already _TIED without mask.120 defvar needsForcePassthruRead = !and(forcePassthruRead, !not(isTied));121 defvar needsPassthruRead = !or(isMaskedOrForceMasked, needsForcePassthruRead);122 // If this is a _TIED + masked operation, $rs2 (i.e. the first operand) is123 // merged with the mask.124 // NOTE: the following if statement is written in such a weird way because125 // should we want to write something like126 // `!if(!and(!not(!empty(reads), isTiedMasked), !tail(reads), reads)`127 // since `!if` doesn't have a proper short-circuit behavior, if the128 // condition of this `!if` cannot be resolved right away, `!tail(reads)` will129 // be immediately evaluated anyway even when `reads` is empty, which leads to130 // an assertion failure.131 defvar readsWithTiedMask =132 !if(isTiedMasked, !if(!not(!empty(reads)), !tail(reads), reads), reads);133 defvar readsWithMask =134 !if(isMaskedOrForceMasked, !listconcat(readsWithTiedMask, [ReadVMask]), reads);135 defvar allReads =136 !if(needsPassthruRead, !listconcat([passthruRead], readsWithMask), reads);137 let SchedRW = !listconcat(writes, allReads);138}139 140// Common class of scheduling definitions for n-ary instructions.141// The scheduling resources are relevant to LMUL and may be relevant to SEW.142class SchedNary<string write, list<string> reads, string mx, int sew = 0,143 bit forceMasked = 0, bit forcePassthruRead = 0>144 : SchedCommon<[!cast<SchedWrite>(145 !if(sew,146 write # "_" # mx # "_E" # sew,147 write # "_" # mx))],148 !foreach(read, reads,149 !cast<SchedRead>(!if(sew,150 read # "_" # mx # "_E" #sew,151 read # "_" # mx))),152 mx, sew, forceMasked, forcePassthruRead>;153 154// Classes with postfix "MC" are only used in MC layer.155// For these classes, we assume that they are with the worst case costs and156// `ReadVMask` is always needed (with some exceptions).157 158// For instructions with no operand.159class SchedNullary<string write, string mx, int sew = 0, bit forceMasked = 0,160 bit forcePassthruRead = 0>:161 SchedNary<write, [], mx, sew, forceMasked, forcePassthruRead>;162class SchedNullaryMC<string write, bit forceMasked = 1>:163 SchedNullary<write, "WorstCase", forceMasked=forceMasked>;164 165// For instructions with one operand.166class SchedUnary<string write, string read0, string mx, int sew = 0,167 bit forceMasked = 0, bit forcePassthruRead = 0>:168 SchedNary<write, [read0], mx, sew, forceMasked, forcePassthruRead>;169class SchedUnaryMC<string write, string read0, bit forceMasked = 1>:170 SchedUnary<write, read0, "WorstCase", forceMasked=forceMasked>;171 172// For instructions with two operands.173class SchedBinary<string write, string read0, string read1, string mx,174 int sew = 0, bit forceMasked = 0, bit forcePassthruRead = 0>175 : SchedNary<write, [read0, read1], mx, sew, forceMasked, forcePassthruRead>;176class SchedBinaryMC<string write, string read0, string read1,177 bit forceMasked = 1>:178 SchedBinary<write, read0, read1, "WorstCase", forceMasked=forceMasked>;179 180// For instructions with three operands.181class SchedTernary<string write, string read0, string read1, string read2,182 string mx, int sew = 0, bit forceMasked = 0>183 : SchedNary<write, [read0, read1, read2], mx, sew, forceMasked>;184class SchedTernaryMC<string write, string read0, string read1, string read2,185 int sew = 0, bit forceMasked = 1>:186 SchedNary<write, [read0, read1, read2], "WorstCase", sew, forceMasked>;187 188// For reduction instructions.189class SchedReduction<string write, string read, string mx, int sew,190 bit forcePassthruRead = 0>191 : SchedCommon<[!cast<SchedWrite>(write #"_" #mx #"_E" #sew)],192 !listsplat(!cast<SchedRead>(read), 3), mx, sew, forcePassthruRead>;193class SchedReductionMC<string write, string readV, string readV0>:194 SchedCommon<[!cast<SchedWrite>(write # "_WorstCase")],195 [!cast<SchedRead>(readV), !cast<SchedRead>(readV0)],196 forceMasked=1>;197 198// Whole Vector Register Move199class VMVRSched<int n> : SchedCommon<200 [!cast<SchedWrite>("WriteVMov" # n # "V")],201 [!cast<SchedRead>("ReadVMov" # n # "V")]202>;203 204// Vector Unit-Stride Loads and Stores205class VLESched<string lmul, bit forceMasked = 0> : SchedCommon<206 [!cast<SchedWrite>("WriteVLDE_" # lmul)],207 [ReadVLDX], mx=lmul, forceMasked=forceMasked208>;209class VLESchedMC : VLESched<"WorstCase", forceMasked=1>;210 211class VSESched<string lmul, bit forceMasked = 0> : SchedCommon<212 [!cast<SchedWrite>("WriteVSTE_" # lmul)],213 [!cast<SchedRead>("ReadVSTEV_" # lmul), ReadVSTX], mx=lmul,214 forceMasked=forceMasked215>;216class VSESchedMC : VSESched<"WorstCase", forceMasked=1>;217 218// Vector Strided Loads and Stores219class VLSSched<int eew, string emul, bit forceMasked = 0> : SchedCommon<220 [!cast<SchedWrite>("WriteVLDS" # eew # "_" # emul)],221 [ReadVLDX, ReadVLDSX], emul, eew, forceMasked222>;223class VLSSchedMC<int eew> : VLSSched<eew, "WorstCase", forceMasked=1>;224 225class VSSSched<int eew, string emul, bit forceMasked = 0> : SchedCommon<226 [!cast<SchedWrite>("WriteVSTS" # eew # "_" # emul)],227 [!cast<SchedRead>("ReadVSTS" # eew # "V_" # emul), ReadVSTX, ReadVSTSX],228 emul, eew, forceMasked229>;230class VSSSchedMC<int eew> : VSSSched<eew, "WorstCase", forceMasked=1>;231 232// Vector Indexed Loads and Stores233class VLXSched<int dataEEW, bit isOrdered, string dataEMUL, string idxEMUL,234 bit forceMasked = 0> : SchedCommon<235 [!cast<SchedWrite>("WriteVLD" # !if(isOrdered, "O", "U") # "X" # dataEEW # "_" # dataEMUL)],236 [ReadVLDX, !cast<SchedRead>("ReadVLD" # !if(isOrdered, "O", "U") # "XV_" # idxEMUL)],237 dataEMUL, dataEEW, forceMasked238>;239class VLXSchedMC<int dataEEW, bit isOrdered>:240 VLXSched<dataEEW, isOrdered, "WorstCase", "WorstCase", forceMasked=1>;241 242class VSXSched<int dataEEW, bit isOrdered, string dataEMUL, string idxEMUL,243 bit forceMasked = 0> : SchedCommon<244 [!cast<SchedWrite>("WriteVST" # !if(isOrdered, "O", "U") # "X" # dataEEW # "_" # dataEMUL)],245 [!cast<SchedRead>("ReadVST" # !if(isOrdered, "O", "U") #"X" # dataEEW # "_" # dataEMUL),246 ReadVSTX, !cast<SchedRead>("ReadVST" # !if(isOrdered, "O", "U") # "XV_" # idxEMUL)],247 dataEMUL, dataEEW, forceMasked248>;249class VSXSchedMC<int dataEEW, bit isOrdered>:250 VSXSched<dataEEW, isOrdered, "WorstCase", "WorstCase", forceMasked=1>;251 252// Unit-stride Fault-Only-First Loads253class VLFSched<string lmul, bit forceMasked = 0> : SchedCommon<254 [!cast<SchedWrite>("WriteVLDFF_" # lmul)],255 [ReadVLDX], mx=lmul, forceMasked=forceMasked256>;257class VLFSchedMC: VLFSched<"WorstCase", forceMasked=1>;258 259// Unit-Stride Segment Loads and Stores260class VLSEGSched<int nf, int eew, string emul, bit forceMasked = 0> : SchedCommon<261 [!cast<SchedWrite>("WriteVLSEG" #nf #"e" #eew #"_" #emul)],262 [ReadVLDX], emul, eew, forceMasked263>;264class VLSEGSchedMC<int nf, int eew> : VLSEGSched<nf, eew, "WorstCase",265 forceMasked=1>;266 267class VSSEGSched<int nf, int eew, string emul, bit forceMasked = 0> : SchedCommon<268 [!cast<SchedWrite>("WriteVSSEG" # nf # "e" # eew # "_" # emul)],269 [!cast<SchedRead>("ReadVSTEV_" #emul), ReadVSTX], emul, eew, forceMasked270>;271class VSSEGSchedMC<int nf, int eew> : VSSEGSched<nf, eew, "WorstCase",272 forceMasked=1>;273 274class VLSEGFFSched<int nf, int eew, string emul, bit forceMasked = 0> : SchedCommon<275 [!cast<SchedWrite>("WriteVLSEGFF" # nf # "e" # eew # "_" # emul)],276 [ReadVLDX], emul, eew, forceMasked277>;278class VLSEGFFSchedMC<int nf, int eew> : VLSEGFFSched<nf, eew, "WorstCase",279 forceMasked=1>;280 281// Strided Segment Loads and Stores282class VLSSEGSched<int nf, int eew, string emul, bit forceMasked = 0> : SchedCommon<283 [!cast<SchedWrite>("WriteVLSSEG" #nf #"e" #eew #"_" #emul)],284 [ReadVLDX, ReadVLDSX], emul, eew, forceMasked285>;286class VLSSEGSchedMC<int nf, int eew> : VLSSEGSched<nf, eew, "WorstCase",287 forceMasked=1>;288 289class VSSSEGSched<int nf, int eew, string emul, bit forceMasked = 0> : SchedCommon<290 [!cast<SchedWrite>("WriteVSSSEG" #nf #"e" #eew #"_" #emul)],291 [!cast<SchedRead>("ReadVSTS" #eew #"V_" #emul),292 ReadVSTX, ReadVSTSX], emul, eew, forceMasked293>;294class VSSSEGSchedMC<int nf, int eew> : VSSSEGSched<nf, eew, "WorstCase",295 forceMasked=1>;296 297// Indexed Segment Loads and Stores298class VLXSEGSched<int nf, int eew, bit isOrdered, string emul,299 bit forceMasked = 0> : SchedCommon<300 [!cast<SchedWrite>("WriteVL" #!if(isOrdered, "O", "U") #"XSEG" #nf #"e" #eew #"_" #emul)],301 [ReadVLDX, !cast<SchedRead>("ReadVLD" #!if(isOrdered, "O", "U") #"XV_" #emul)],302 emul, eew, forceMasked303>;304class VLXSEGSchedMC<int nf, int eew, bit isOrdered>:305 VLXSEGSched<nf, eew, isOrdered, "WorstCase", forceMasked=1>;306 307// Passes sew=0 instead of eew=0 since this pseudo does not follow MX_E form.308class VSXSEGSched<int nf, int eew, bit isOrdered, string emul,309 bit forceMasked = 0> : SchedCommon<310 [!cast<SchedWrite>("WriteVS" #!if(isOrdered, "O", "U") #"XSEG" #nf #"e" #eew #"_" #emul)],311 [!cast<SchedRead>("ReadVST" #!if(isOrdered, "O", "U") #"X" #eew #"_" #emul),312 ReadVSTX, !cast<SchedRead>("ReadVST" #!if(isOrdered, "O", "U") #"XV_" #emul)],313 emul, sew=0, forceMasked=forceMasked314>;315class VSXSEGSchedMC<int nf, int eew, bit isOrdered>:316 VSXSEGSched<nf, eew, isOrdered, "WorstCase", forceMasked=1>;317 318class RISCVVXMemOpMC<bits<3> E, bit Ordered, bit Store, bits<4> N = 0> {319 bits<3> Log2EEW = E;320 bits<1> IsOrdered = Ordered;321 bits<1> IsStore = Store;322 bits<4> NF = N;323 Instruction BaseInstr = !cast<Instruction>(NAME);324}325 326def RISCVBaseVXMemOpTable : GenericTable {327 let FilterClass = "RISCVVXMemOpMC";328 let CppTypeName = "VXMemOpInfo";329 let Fields = ["Log2EEW", "IsOrdered", "IsStore", "NF", "BaseInstr"];330 let PrimaryKey = ["BaseInstr"];331 let PrimaryKeyName = "getVXMemOpInfo";332}333 334//===----------------------------------------------------------------------===//335// Instruction class templates336//===----------------------------------------------------------------------===//337 338let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {339// unit-stride load vd, (rs1), vm340class VUnitStrideLoad<RISCVWidth width, string opcodestr>341 : RVInstVLU<0b000, width.Value{3}, LUMOPUnitStride, width.Value{2-0},342 (outs VR:$vd),343 (ins GPRMemZeroOffset:$rs1, VMaskOp:$vm), opcodestr, "$vd, ${rs1}$vm">;344 345let vm = 1, RVVConstraint = NoConstraint in {346// unit-stride whole register load vl<nf>r.v vd, (rs1)347class VWholeLoad<bits<3> nf, RISCVWidth width, string opcodestr, RegisterClass VRC>348 : RVInstVLU<nf, width.Value{3}, LUMOPUnitStrideWholeReg,349 width.Value{2-0}, (outs VRC:$vd), (ins GPRMemZeroOffset:$rs1),350 opcodestr, "$vd, $rs1"> {351 let Uses = [];352}353 354// unit-stride mask load vd, (rs1)355class VUnitStrideLoadMask<string opcodestr>356 : RVInstVLU<0b000, LSWidth8.Value{3}, LUMOPUnitStrideMask, LSWidth8.Value{2-0},357 (outs VR:$vd),358 (ins GPRMemZeroOffset:$rs1), opcodestr, "$vd, $rs1">;359} // vm = 1, RVVConstraint = NoConstraint360 361// unit-stride fault-only-first load vd, (rs1), vm362class VUnitStrideLoadFF<RISCVWidth width, string opcodestr>363 : RVInstVLU<0b000, width.Value{3}, LUMOPUnitStrideFF, width.Value{2-0},364 (outs VR:$vd),365 (ins GPRMemZeroOffset:$rs1, VMaskOp:$vm), opcodestr, "$vd, ${rs1}$vm">;366 367// strided load vd, (rs1), rs2, vm368class VStridedLoad<RISCVWidth width, string opcodestr>369 : RVInstVLS<0b000, width.Value{3}, width.Value{2-0},370 (outs VR:$vd),371 (ins GPRMemZeroOffset:$rs1, GPR:$rs2, VMaskOp:$vm), opcodestr,372 "$vd, $rs1, $rs2$vm">;373 374// indexed load vd, (rs1), vs2, vm375class VIndexedLoad<RISCVMOP mop, RISCVWidth width, string opcodestr>376 : RVInstVLX<0b000, width.Value{3}, mop, width.Value{2-0},377 (outs VR:$vd),378 (ins GPRMemZeroOffset:$rs1, VR:$vs2, VMaskOp:$vm), opcodestr,379 "$vd, $rs1, $vs2$vm">;380 381// unit-stride segment load vd, (rs1), vm382class VUnitStrideSegmentLoad<bits<3> nf, RISCVWidth width, string opcodestr>383 : RVInstVLU<nf, width.Value{3}, LUMOPUnitStride, width.Value{2-0},384 (outs VR:$vd),385 (ins GPRMemZeroOffset:$rs1, VMaskOp:$vm), opcodestr, "$vd, ${rs1}$vm">;386 387// segment fault-only-first load vd, (rs1), vm388class VUnitStrideSegmentLoadFF<bits<3> nf, RISCVWidth width, string opcodestr>389 : RVInstVLU<nf, width.Value{3}, LUMOPUnitStrideFF, width.Value{2-0},390 (outs VR:$vd),391 (ins GPRMemZeroOffset:$rs1, VMaskOp:$vm), opcodestr, "$vd, ${rs1}$vm">;392 393// strided segment load vd, (rs1), rs2, vm394class VStridedSegmentLoad<bits<3> nf, RISCVWidth width, string opcodestr>395 : RVInstVLS<nf, width.Value{3}, width.Value{2-0},396 (outs VR:$vd),397 (ins GPRMemZeroOffset:$rs1, GPR:$rs2, VMaskOp:$vm), opcodestr,398 "$vd, $rs1, $rs2$vm">;399 400// indexed segment load vd, (rs1), vs2, vm401class VIndexedSegmentLoad<bits<3> nf, RISCVMOP mop, RISCVWidth width,402 string opcodestr>403 : RVInstVLX<nf, width.Value{3}, mop, width.Value{2-0},404 (outs VR:$vd),405 (ins GPRMemZeroOffset:$rs1, VR:$vs2, VMaskOp:$vm), opcodestr,406 "$vd, $rs1, $vs2$vm">;407} // hasSideEffects = 0, mayLoad = 1, mayStore = 0408 409let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {410// unit-stride store vd, vs3, (rs1), vm411class VUnitStrideStore<RISCVWidth width, string opcodestr>412 : RVInstVSU<0b000, width.Value{3}, SUMOPUnitStride, width.Value{2-0},413 (outs), (ins VR:$vs3, GPRMemZeroOffset:$rs1, VMaskOp:$vm), opcodestr,414 "$vs3, ${rs1}$vm">;415 416let vm = 1 in {417// vs<nf>r.v vd, (rs1)418class VWholeStore<bits<3> nf, string opcodestr, RegisterClass VRC>419 : RVInstVSU<nf, 0, SUMOPUnitStrideWholeReg,420 0b000, (outs), (ins VRC:$vs3, GPRMemZeroOffset:$rs1),421 opcodestr, "$vs3, $rs1"> {422 let Uses = [];423}424 425// unit-stride mask store vd, vs3, (rs1)426class VUnitStrideStoreMask<string opcodestr>427 : RVInstVSU<0b000, LSWidth8.Value{3}, SUMOPUnitStrideMask, LSWidth8.Value{2-0},428 (outs), (ins VR:$vs3, GPRMemZeroOffset:$rs1), opcodestr,429 "$vs3, $rs1">;430} // vm = 1431 432// strided store vd, vs3, (rs1), rs2, vm433class VStridedStore<RISCVWidth width, string opcodestr>434 : RVInstVSS<0b000, width.Value{3}, width.Value{2-0}, (outs),435 (ins VR:$vs3, GPRMemZeroOffset:$rs1, GPR:$rs2, VMaskOp:$vm),436 opcodestr, "$vs3, $rs1, $rs2$vm">;437 438// indexed store vd, vs3, (rs1), vs2, vm439class VIndexedStore<RISCVMOP mop, RISCVWidth width, string opcodestr>440 : RVInstVSX<0b000, width.Value{3}, mop, width.Value{2-0}, (outs),441 (ins VR:$vs3, GPRMemZeroOffset:$rs1, VR:$vs2, VMaskOp:$vm),442 opcodestr, "$vs3, $rs1, $vs2$vm">;443 444// segment store vd, vs3, (rs1), vm445class VUnitStrideSegmentStore<bits<3> nf, RISCVWidth width, string opcodestr>446 : RVInstVSU<nf, width.Value{3}, SUMOPUnitStride, width.Value{2-0},447 (outs), (ins VR:$vs3, GPRMemZeroOffset:$rs1, VMaskOp:$vm), opcodestr,448 "$vs3, ${rs1}$vm">;449 450// segment store vd, vs3, (rs1), rs2, vm451class VStridedSegmentStore<bits<3> nf, RISCVWidth width, string opcodestr>452 : RVInstVSS<nf, width.Value{3}, width.Value{2-0}, (outs),453 (ins VR:$vs3, GPRMemZeroOffset:$rs1, GPR:$rs2, VMaskOp:$vm),454 opcodestr, "$vs3, $rs1, $rs2$vm">;455 456// segment store vd, vs3, (rs1), vs2, vm457class VIndexedSegmentStore<bits<3> nf, RISCVMOP mop, RISCVWidth width,458 string opcodestr>459 : RVInstVSX<nf, width.Value{3}, mop, width.Value{2-0}, (outs),460 (ins VR:$vs3, GPRMemZeroOffset:$rs1, VR:$vs2, VMaskOp:$vm),461 opcodestr, "$vs3, $rs1, $vs2$vm">;462} // hasSideEffects = 0, mayLoad = 0, mayStore = 1463 464let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {465// op vd, vs2, vs1, vm466class VALUVV<bits<6> funct6, RISCVVFormat opv, string opcodestr>467 : RVInstVV<funct6, opv, (outs VR:$vd),468 (ins VR:$vs2, VR:$vs1, VMaskOp:$vm),469 opcodestr, "$vd, $vs2, $vs1$vm">;470 471// op vd, vs2, vs1, v0 (without mask, use v0 as carry input)472class VALUmVV<bits<6> funct6, RISCVVFormat opv, string opcodestr>473 : RVInstVV<funct6, opv, (outs VR:$vd),474 (ins VR:$vs2, VR:$vs1, VMaskCarryInOp:$vm),475 opcodestr, "$vd, $vs2, $vs1, $vm">;476 477// op vd, vs1, vs2, vm (reverse the order of vs1 and vs2)478class VMACVV<bits<6> funct6, RISCVVFormat opv, string opcodestr,479 bit EarlyClobber = 0>480 : RVInstVV<funct6, opv, (outs VR:$vd_wb),481 (ins VR:$vd, VR:$vs1, VR:$vs2, VMaskOp:$vm),482 opcodestr, "$vd, $vs1, $vs2$vm"> {483 let Constraints = !if(EarlyClobber, "@earlyclobber $vd_wb, $vd = $vd_wb",484 "$vd = $vd_wb");485}486 487// op vd, vs2, vs1488class VALUVVNoVm<bits<6> funct6, RISCVVFormat opv, string opcodestr>489 : RVInstVV<funct6, opv, (outs VR:$vd),490 (ins VR:$vs2, VR:$vs1),491 opcodestr, "$vd, $vs2, $vs1"> {492 let vm = 1;493}494 495// op vd, vs2, rs1, vm496class VALUVX<bits<6> funct6, RISCVVFormat opv, string opcodestr>497 : RVInstVX<funct6, opv, (outs VR:$vd),498 (ins VR:$vs2, GPR:$rs1, VMaskOp:$vm),499 opcodestr, "$vd, $vs2, $rs1$vm">;500 501// op vd, vs2, rs1, v0 (without mask, use v0 as carry input)502class VALUmVX<bits<6> funct6, RISCVVFormat opv, string opcodestr>503 : RVInstVX<funct6, opv, (outs VR:$vd),504 (ins VR:$vs2, GPR:$rs1, VMaskCarryInOp:$vm),505 opcodestr, "$vd, $vs2, $rs1, $vm">;506 507// op vd, rs1, vs2, vm (reverse the order of rs1 and vs2)508class VMACVX<bits<6> funct6, RISCVVFormat opv, string opcodestr,509 bit EarlyClobber = 0>510 : RVInstVX<funct6, opv, (outs VR:$vd_wb),511 (ins VR:$vd, GPR:$rs1, VR:$vs2, VMaskOp:$vm),512 opcodestr, "$vd, $rs1, $vs2$vm"> {513 let Constraints = !if(EarlyClobber, "@earlyclobber $vd_wb, $vd = $vd_wb",514 "$vd = $vd_wb");515}516 517// op vd, vs1, vs2518class VALUVXNoVm<bits<6> funct6, RISCVVFormat opv, string opcodestr>519 : RVInstVX<funct6, opv, (outs VR:$vd),520 (ins VR:$vs2, GPR:$rs1),521 opcodestr, "$vd, $vs2, $rs1"> {522 let vm = 1;523}524 525// op vd, vs2, imm, vm526class VALUVI<bits<6> funct6, string opcodestr, Operand optype = simm5>527 : RVInstIVI<funct6, (outs VR:$vd),528 (ins VR:$vs2, optype:$imm, VMaskOp:$vm),529 opcodestr, "$vd, $vs2, $imm$vm">;530 531// op vd, vs2, imm, v0 (without mask, use v0 as carry input)532class VALUmVI<bits<6> funct6, string opcodestr, Operand optype = simm5>533 : RVInstIVI<funct6, (outs VR:$vd),534 (ins VR:$vs2, optype:$imm, VMaskCarryInOp:$vm),535 opcodestr, "$vd, $vs2, $imm, $vm">;536 537// op vd, vs2, imm538class VALUVINoVm<bits<6> funct6, string opcodestr, Operand optype = simm5>539 : RVInstIVI<funct6, (outs VR:$vd),540 (ins VR:$vs2, optype:$imm),541 opcodestr, "$vd, $vs2, $imm"> {542 let vm = 1;543}544 545// op vd, vs2, rs1, vm (Float)546class VALUVF<bits<6> funct6, RISCVVFormat opv, string opcodestr>547 : RVInstVX<funct6, opv, (outs VR:$vd),548 (ins VR:$vs2, FPR32:$rs1, VMaskOp:$vm),549 opcodestr, "$vd, $vs2, $rs1$vm">;550 551// op vd, rs1, vs2, vm (Float) (with mask, reverse the order of rs1 and vs2)552class VMACVF<bits<6> funct6, RISCVVFormat opv, string opcodestr,553 bit EarlyClobber = 0>554 : RVInstVX<funct6, opv, (outs VR:$vd_wb),555 (ins VR:$vd, FPR32:$rs1, VR:$vs2, VMaskOp:$vm),556 opcodestr, "$vd, $rs1, $vs2$vm"> {557 let Constraints = !if(EarlyClobber, "@earlyclobber $vd_wb, $vd = $vd_wb",558 "$vd = $vd_wb");559}560 561// op vd, vs2, vm (use vs1 as instruction encoding)562class VALUVs2<bits<6> funct6, bits<5> vs1, RISCVVFormat opv, string opcodestr>563 : RVInstV<funct6, vs1, opv, (outs VR:$vd),564 (ins VR:$vs2, VMaskOp:$vm),565 opcodestr, "$vd, $vs2$vm">;566} // hasSideEffects = 0, mayLoad = 0, mayStore = 0567 568//===----------------------------------------------------------------------===//569// Combination of instruction classes.570// Use these multiclasses to define instructions more easily.571//===----------------------------------------------------------------------===//572 573multiclass VIndexLoadStore<int eew> {574 defvar w = !cast<RISCVWidth>("LSWidth" # eew);575 576 def VLUXEI # eew # _V :577 VIndexedLoad<MOPLDIndexedUnord, w, "vluxei" # eew # ".v">,578 RISCVVXMemOpMC<!logtwo(eew), Ordered=false, Store=false>,579 VLXSchedMC<eew, isOrdered=0>;580 def VLOXEI # eew # _V :581 VIndexedLoad<MOPLDIndexedOrder, w, "vloxei" # eew # ".v">,582 RISCVVXMemOpMC<!logtwo(eew), Ordered=true, Store=false>,583 VLXSchedMC<eew, isOrdered=1>;584 585 def VSUXEI # eew # _V :586 VIndexedStore<MOPSTIndexedUnord, w, "vsuxei" # eew # ".v">,587 RISCVVXMemOpMC<!logtwo(eew), Ordered=false, Store=true>,588 VSXSchedMC<eew, isOrdered=0>;589 def VSOXEI # eew # _V :590 VIndexedStore<MOPSTIndexedOrder, w, "vsoxei" # eew # ".v">,591 RISCVVXMemOpMC<!logtwo(eew), Ordered=true, Store=true>,592 VSXSchedMC<eew, isOrdered=1>;593}594 595multiclass VALU_IV_V<string opcodestr, bits<6> funct6> {596 def V : VALUVV<funct6, OPIVV, opcodestr # ".vv">,597 SchedBinaryMC<"WriteVIALUV", "ReadVIALUV", "ReadVIALUV">;598}599 600multiclass VALU_IV_X<string opcodestr, bits<6> funct6> {601 def X : VALUVX<funct6, OPIVX, opcodestr # ".vx">,602 SchedBinaryMC<"WriteVIALUX", "ReadVIALUV", "ReadVIALUX">;603}604 605multiclass VALU_IV_I<string opcodestr, bits<6> funct6> {606 def I : VALUVI<funct6, opcodestr # ".vi">,607 SchedUnaryMC<"WriteVIALUI", "ReadVIALUV">;608}609 610multiclass VALU_IV_V_X_I<string opcodestr, bits<6> funct6>611 : VALU_IV_V<opcodestr, funct6>,612 VALU_IV_X<opcodestr, funct6>,613 VALU_IV_I<opcodestr, funct6>;614 615multiclass VALU_IV_V_X<string opcodestr, bits<6> funct6>616 : VALU_IV_V<opcodestr, funct6>,617 VALU_IV_X<opcodestr, funct6>;618 619multiclass VALU_IV_X_I<string opcodestr, bits<6> funct6>620 : VALU_IV_X<opcodestr, funct6>,621 VALU_IV_I<opcodestr, funct6>;622 623multiclass VALU_MV_V_X<string opcodestr, bits<6> funct6, string vw> {624 def V : VALUVV<funct6, OPMVV, opcodestr # "." # vw # "v">,625 SchedBinaryMC<"WriteVIWALUV", "ReadVIWALUV", "ReadVIWALUV">;626 def X : VALUVX<funct6, OPMVX, opcodestr # "." # vw # "x">,627 SchedBinaryMC<"WriteVIWALUX", "ReadVIWALUV", "ReadVIWALUX">;628}629 630multiclass VMAC_MV_V_X<string opcodestr, bits<6> funct6> {631 def V : VMACVV<funct6, OPMVV, opcodestr # ".vv">,632 SchedTernaryMC<"WriteVIMulAddV", "ReadVIMulAddV", "ReadVIMulAddV",633 "ReadVIMulAddV">;634 def X : VMACVX<funct6, OPMVX, opcodestr # ".vx">,635 SchedTernaryMC<"WriteVIMulAddX", "ReadVIMulAddV", "ReadVIMulAddX",636 "ReadVIMulAddV">;637}638 639multiclass VWMAC_MV_X<string opcodestr, bits<6> funct6> {640 let RVVConstraint = WidenV in641 def X : VMACVX<funct6, OPMVX, opcodestr # ".vx", EarlyClobber=1>,642 SchedTernaryMC<"WriteVIWMulAddX", "ReadVIWMulAddV", "ReadVIWMulAddX",643 "ReadVIWMulAddV">;644}645 646multiclass VWMAC_MV_V_X<string opcodestr, bits<6> funct6>647 : VWMAC_MV_X<opcodestr, funct6> {648 let RVVConstraint = WidenV in649 def V : VMACVV<funct6, OPMVV, opcodestr # ".vv", EarlyClobber=1>,650 SchedTernaryMC<"WriteVIWMulAddV", "ReadVIWMulAddV", "ReadVIWMulAddV",651 "ReadVIWMulAddV">;652}653 654multiclass VALU_MV_VS2<string opcodestr, bits<6> funct6, bits<5> vs1> {655 def "" : VALUVs2<funct6, vs1, OPMVV, opcodestr>,656 SchedUnaryMC<"WriteVExtV", "ReadVExtV">;657}658 659multiclass VMRG_IV_V_X_I<string opcodestr, bits<6> funct6> {660 def VM : VALUmVV<funct6, OPIVV, opcodestr # ".vvm">,661 SchedBinaryMC<"WriteVIMergeV", "ReadVIMergeV", "ReadVIMergeV">;662 def XM : VALUmVX<funct6, OPIVX, opcodestr # ".vxm">,663 SchedBinaryMC<"WriteVIMergeX", "ReadVIMergeV", "ReadVIMergeX">;664 def IM : VALUmVI<funct6, opcodestr # ".vim">,665 SchedUnaryMC<"WriteVIMergeI", "ReadVIMergeV">;666}667 668multiclass VALUm_IV_V_X<string opcodestr, bits<6> funct6> {669 // if LSB of funct6 is 1, it's a mask-producing instruction that670 // uses a different scheduling class.671 defvar WritePrefix = !if(funct6{0}, "WriteVICALUM", "WriteVICALU");672 def VM : VALUmVV<funct6, OPIVV, opcodestr # ".vvm">,673 SchedBinaryMC<WritePrefix#"V", "ReadVICALUV", "ReadVICALUV">;674 def XM : VALUmVX<funct6, OPIVX, opcodestr # ".vxm">,675 SchedBinaryMC<WritePrefix#"X", "ReadVICALUV", "ReadVICALUX">;676}677 678multiclass VALUm_IV_V_X_I<string opcodestr, bits<6> funct6>679 : VALUm_IV_V_X<opcodestr, funct6> {680 // if LSB of funct6 is 1, it's a mask-producing instruction that681 // uses a different scheduling class.682 defvar WriteSched = !if(funct6{0}, "WriteVICALUMI", "WriteVICALUI");683 def IM : VALUmVI<funct6, opcodestr # ".vim">,684 SchedUnaryMC<WriteSched, "ReadVICALUV">;685}686 687multiclass VALUNoVm_IV_V_X<string opcodestr, bits<6> funct6> {688 def V : VALUVVNoVm<funct6, OPIVV, opcodestr # ".vv">,689 SchedBinaryMC<"WriteVICALUMV", "ReadVICALUV", "ReadVICALUV",690 forceMasked=0>;691 def X : VALUVXNoVm<funct6, OPIVX, opcodestr # ".vx">,692 SchedBinaryMC<"WriteVICALUMX", "ReadVICALUV", "ReadVICALUX",693 forceMasked=0>;694}695 696multiclass VALUNoVm_IV_V_X_I<string opcodestr, bits<6> funct6>697 : VALUNoVm_IV_V_X<opcodestr, funct6> {698 def I : VALUVINoVm<funct6, opcodestr # ".vi">,699 SchedUnaryMC<"WriteVICALUMI", "ReadVICALUV", forceMasked=0>;700}701 702multiclass VALU_FV_F<string opcodestr, bits<6> funct6> {703 def F : VALUVF<funct6, OPFVF, opcodestr # ".vf">,704 SchedBinaryMC<"WriteVFALUF", "ReadVFALUV", "ReadVFALUF">;705}706 707multiclass VALU_FV_V_F<string opcodestr, bits<6> funct6>708 : VALU_FV_F<opcodestr, funct6> {709 def V : VALUVV<funct6, OPFVV, opcodestr # ".vv">,710 SchedBinaryMC<"WriteVFALUV", "ReadVFALUV", "ReadVFALUV">;711}712 713multiclass VWALU_FV_V_F<string opcodestr, bits<6> funct6, string vw> {714 def V : VALUVV<funct6, OPFVV, opcodestr # "." # vw # "v">,715 SchedBinaryMC<"WriteVFWALUV", "ReadVFWALUV", "ReadVFWALUV">;716 def F : VALUVF<funct6, OPFVF, opcodestr # "." # vw # "f">,717 SchedBinaryMC<"WriteVFWALUF", "ReadVFWALUV", "ReadVFWALUF">;718}719 720multiclass VMUL_FV_V_F<string opcodestr, bits<6> funct6> {721 def V : VALUVV<funct6, OPFVV, opcodestr # ".vv">,722 SchedBinaryMC<"WriteVFMulV", "ReadVFMulV", "ReadVFMulV">;723 def F : VALUVF<funct6, OPFVF, opcodestr # ".vf">,724 SchedBinaryMC<"WriteVFMulF", "ReadVFMulV", "ReadVFMulF">;725}726 727multiclass VDIV_FV_F<string opcodestr, bits<6> funct6> {728 def F : VALUVF<funct6, OPFVF, opcodestr # ".vf">,729 SchedBinaryMC<"WriteVFDivF", "ReadVFDivV", "ReadVFDivF">;730}731 732multiclass VDIV_FV_V_F<string opcodestr, bits<6> funct6>733 : VDIV_FV_F<opcodestr, funct6> {734 def V : VALUVV<funct6, OPFVV, opcodestr # ".vv">,735 SchedBinaryMC<"WriteVFDivV", "ReadVFDivV", "ReadVFDivV">;736}737 738multiclass VWMUL_FV_V_F<string opcodestr, bits<6> funct6> {739 def V : VALUVV<funct6, OPFVV, opcodestr # ".vv">,740 SchedBinaryMC<"WriteVFWMulV", "ReadVFWMulV", "ReadVFWMulV">;741 def F : VALUVF<funct6, OPFVF, opcodestr # ".vf">,742 SchedBinaryMC<"WriteVFWMulF", "ReadVFWMulV", "ReadVFWMulF">;743}744 745multiclass VMAC_FV_V_F<string opcodestr, bits<6> funct6> {746 def V : VMACVV<funct6, OPFVV, opcodestr # ".vv">,747 SchedTernaryMC<"WriteVFMulAddV", "ReadVFMulAddV", "ReadVFMulAddV",748 "ReadVFMulAddV">;749 def F : VMACVF<funct6, OPFVF, opcodestr # ".vf">,750 SchedTernaryMC<"WriteVFMulAddF", "ReadVFMulAddV", "ReadVFMulAddF",751 "ReadVFMulAddV">;752}753 754multiclass VWMAC_FV_V_F<string opcodestr, bits<6> funct6> {755 let RVVConstraint = WidenV in {756 def V : VMACVV<funct6, OPFVV, opcodestr # ".vv", EarlyClobber=1>,757 SchedTernaryMC<"WriteVFWMulAddV", "ReadVFWMulAddV", "ReadVFWMulAddV",758 "ReadVFWMulAddV">;759 def F : VMACVF<funct6, OPFVF, opcodestr # ".vf", EarlyClobber=1>,760 SchedTernaryMC<"WriteVFWMulAddF", "ReadVFWMulAddV", "ReadVFWMulAddF",761 "ReadVFWMulAddV">;762 }763}764 765multiclass VSQR_FV_VS2<string opcodestr, bits<6> funct6, bits<5> vs1> {766 def "" : VALUVs2<funct6, vs1, OPFVV, opcodestr>,767 SchedUnaryMC<"WriteVFSqrtV", "ReadVFSqrtV">;768}769 770multiclass VRCP_FV_VS2<string opcodestr, bits<6> funct6, bits<5> vs1> {771 def "" : VALUVs2<funct6, vs1, OPFVV, opcodestr>,772 SchedUnaryMC<"WriteVFRecpV", "ReadVFRecpV">;773}774 775multiclass VMINMAX_FV_V_F<string opcodestr, bits<6> funct6> {776 def V : VALUVV<funct6, OPFVV, opcodestr # ".vv">,777 SchedBinaryMC<"WriteVFMinMaxV", "ReadVFMinMaxV", "ReadVFMinMaxV">;778 def F : VALUVF<funct6, OPFVF, opcodestr # ".vf">,779 SchedBinaryMC<"WriteVFMinMaxF", "ReadVFMinMaxV", "ReadVFMinMaxF">;780}781 782multiclass VCMP_FV_F<string opcodestr, bits<6> funct6> {783 def F : VALUVF<funct6, OPFVF, opcodestr # ".vf">,784 SchedBinaryMC<"WriteVFCmpF", "ReadVFCmpV", "ReadVFCmpF">;785}786 787multiclass VCMP_FV_V_F<string opcodestr, bits<6> funct6>788 : VCMP_FV_F<opcodestr, funct6> {789 def V : VALUVV<funct6, OPFVV, opcodestr # ".vv">,790 SchedBinaryMC<"WriteVFCmpV", "ReadVFCmpV", "ReadVFCmpV">;791}792 793multiclass VSGNJ_FV_V_F<string opcodestr, bits<6> funct6> {794 def V : VALUVV<funct6, OPFVV, opcodestr # ".vv">,795 SchedBinaryMC<"WriteVFSgnjV", "ReadVFSgnjV", "ReadVFSgnjV">;796 def F : VALUVF<funct6, OPFVF, opcodestr # ".vf">,797 SchedBinaryMC<"WriteVFSgnjF", "ReadVFSgnjV", "ReadVFSgnjF">;798}799 800multiclass VCLS_FV_VS2<string opcodestr, bits<6> funct6, bits<5> vs1> {801 def "" : VALUVs2<funct6, vs1, OPFVV, opcodestr>,802 SchedUnaryMC<"WriteVFClassV", "ReadVFClassV">;803}804 805multiclass VCVTF_IV_VS2<string opcodestr, bits<6> funct6, bits<5> vs1> {806 def "" : VALUVs2<funct6, vs1, OPFVV, opcodestr>,807 SchedUnaryMC<"WriteVFCvtIToFV", "ReadVFCvtIToFV">;808}809 810multiclass VCVTI_FV_VS2<string opcodestr, bits<6> funct6, bits<5> vs1> {811 def "" : VALUVs2<funct6, vs1, OPFVV, opcodestr>,812 SchedUnaryMC<"WriteVFCvtFToIV", "ReadVFCvtFToIV">;813}814 815multiclass VWCVTF_IV_VS2<string opcodestr, bits<6> funct6, bits<5> vs1> {816 def "" : VALUVs2<funct6, vs1, OPFVV, opcodestr>,817 SchedUnaryMC<"WriteVFWCvtIToFV", "ReadVFWCvtIToFV">;818}819 820multiclass VWCVTI_FV_VS2<string opcodestr, bits<6> funct6, bits<5> vs1> {821 def "" : VALUVs2<funct6, vs1, OPFVV, opcodestr>,822 SchedUnaryMC<"WriteVFWCvtFToIV", "ReadVFWCvtFToIV">;823}824 825multiclass VWCVTF_FV_VS2<string opcodestr, bits<6> funct6, bits<5> vs1> {826 def "" : VALUVs2<funct6, vs1, OPFVV, opcodestr>,827 SchedUnaryMC<"WriteVFWCvtFToFV", "ReadVFWCvtFToFV">;828}829 830multiclass VNCVTF_IV_VS2<string opcodestr, bits<6> funct6, bits<5> vs1> {831 def "" : VALUVs2<funct6, vs1, OPFVV, opcodestr>,832 SchedUnaryMC<"WriteVFNCvtIToFV", "ReadVFNCvtIToFV">;833}834 835multiclass VNCVTI_FV_VS2<string opcodestr, bits<6> funct6, bits<5> vs1> {836 def "" : VALUVs2<funct6, vs1, OPFVV, opcodestr>,837 SchedUnaryMC<"WriteVFNCvtFToIV", "ReadVFNCvtFToIV">;838}839 840multiclass VNCVTF_FV_VS2<string opcodestr, bits<6> funct6, bits<5> vs1> {841 def "" : VALUVs2<funct6, vs1, OPFVV, opcodestr>,842 SchedUnaryMC<"WriteVFNCvtFToFV", "ReadVFNCvtFToFV">;843}844 845multiclass VRED_MV_V<string opcodestr, bits<6> funct6> {846 def _VS : VALUVV<funct6, OPMVV, opcodestr # ".vs">,847 SchedReductionMC<"WriteVIRedV_From", "ReadVIRedV", "ReadVIRedV0">;848}849 850multiclass VREDMINMAX_MV_V<string opcodestr, bits<6> funct6> {851 def _VS : VALUVV<funct6, OPMVV, opcodestr # ".vs">,852 SchedReductionMC<"WriteVIRedMinMaxV_From", "ReadVIRedV", "ReadVIRedV0">;853}854 855multiclass VWRED_IV_V<string opcodestr, bits<6> funct6> {856 def _VS : VALUVV<funct6, OPIVV, opcodestr # ".vs">,857 SchedReductionMC<"WriteVIWRedV_From", "ReadVIWRedV", "ReadVIWRedV0">;858}859 860multiclass VRED_FV_V<string opcodestr, bits<6> funct6> {861 def _VS : VALUVV<funct6, OPFVV, opcodestr # ".vs">,862 SchedReductionMC<"WriteVFRedV_From", "ReadVFRedV", "ReadVFRedV0">;863}864 865multiclass VREDMINMAX_FV_V<string opcodestr, bits<6> funct6> {866 def _VS : VALUVV<funct6, OPFVV, opcodestr # ".vs">,867 SchedReductionMC<"WriteVFRedMinMaxV_From", "ReadVFRedV", "ReadVFRedV0">;868}869 870multiclass VREDO_FV_V<string opcodestr, bits<6> funct6> {871 def _VS : VALUVV<funct6, OPFVV, opcodestr # ".vs">,872 SchedReductionMC<"WriteVFRedOV_From", "ReadVFRedOV", "ReadVFRedOV0">;873}874 875multiclass VWRED_FV_V<string opcodestr, bits<6> funct6> {876 def _VS : VALUVV<funct6, OPFVV, opcodestr # ".vs">,877 SchedReductionMC<"WriteVFWRedV_From", "ReadVFWRedV", "ReadVFWRedV0">;878}879 880multiclass VWREDO_FV_V<string opcodestr, bits<6> funct6> {881 def _VS : VALUVV<funct6, OPFVV, opcodestr # ".vs">,882 SchedReductionMC<"WriteVFWRedOV_From", "ReadVFWRedOV", "ReadVFWRedOV0">;883}884 885multiclass VMALU_MV_Mask<string opcodestr, bits<6> funct6, string vm = "v"> {886 def M : VALUVVNoVm<funct6, OPMVV, opcodestr #"." #vm #"m">,887 SchedBinaryMC<"WriteVMALUV", "ReadVMALUV", "ReadVMALUV",888 forceMasked=0>;889}890 891multiclass VMSFS_MV_V<string opcodestr, bits<6> funct6, bits<5> vs1> {892 def "" : VALUVs2<funct6, vs1, OPMVV, opcodestr>,893 SchedUnaryMC<"WriteVMSFSV", "ReadVMSFSV">;894}895 896multiclass VIOTA_MV_V<string opcodestr, bits<6> funct6, bits<5> vs1> {897 def "" : VALUVs2<funct6, vs1, OPMVV, opcodestr>,898 SchedUnaryMC<"WriteVIotaV", "ReadVIotaV">;899}900 901multiclass VSHT_IV_V_X_I<string opcodestr, bits<6> funct6> {902 def V : VALUVV<funct6, OPIVV, opcodestr # ".vv">,903 SchedBinaryMC<"WriteVShiftV", "ReadVShiftV", "ReadVShiftV">;904 def X : VALUVX<funct6, OPIVX, opcodestr # ".vx">,905 SchedBinaryMC<"WriteVShiftX", "ReadVShiftV", "ReadVShiftX">;906 def I : VALUVI<funct6, opcodestr # ".vi", uimm5>,907 SchedUnaryMC<"WriteVShiftI", "ReadVShiftV">;908}909 910multiclass VNSHT_IV_V_X_I<string opcodestr, bits<6> funct6> {911 def V : VALUVV<funct6, OPIVV, opcodestr # ".wv">,912 SchedBinaryMC<"WriteVNShiftV", "ReadVNShiftV", "ReadVNShiftV">;913 def X : VALUVX<funct6, OPIVX, opcodestr # ".wx">,914 SchedBinaryMC<"WriteVNShiftX", "ReadVNShiftV", "ReadVNShiftX">;915 def I : VALUVI<funct6, opcodestr # ".wi", uimm5>,916 SchedUnaryMC<"WriteVNShiftI", "ReadVNShiftV">;917}918 919multiclass VMINMAX_IV_V_X<string opcodestr, bits<6> funct6> {920 def V : VALUVV<funct6, OPIVV, opcodestr # ".vv">,921 SchedBinaryMC<"WriteVIMinMaxV", "ReadVIMinMaxV", "ReadVIMinMaxV">;922 def X : VALUVX<funct6, OPIVX, opcodestr # ".vx">,923 SchedBinaryMC<"WriteVIMinMaxX", "ReadVIMinMaxV", "ReadVIMinMaxX">;924}925 926multiclass VCMP_IV_V<string opcodestr, bits<6> funct6> {927 def V : VALUVV<funct6, OPIVV, opcodestr # ".vv">,928 SchedBinaryMC<"WriteVICmpV", "ReadVICmpV", "ReadVICmpV">;929}930 931multiclass VCMP_IV_X<string opcodestr, bits<6> funct6> {932 def X : VALUVX<funct6, OPIVX, opcodestr # ".vx">,933 SchedBinaryMC<"WriteVICmpX", "ReadVICmpV", "ReadVICmpX">;934}935 936multiclass VCMP_IV_I<string opcodestr, bits<6> funct6> {937 def I : VALUVI<funct6, opcodestr # ".vi">,938 SchedUnaryMC<"WriteVICmpI", "ReadVICmpV">;939}940 941multiclass VCMP_IV_V_X_I<string opcodestr, bits<6> funct6>942 : VCMP_IV_V<opcodestr, funct6>,943 VCMP_IV_X<opcodestr, funct6>,944 VCMP_IV_I<opcodestr, funct6>;945 946multiclass VCMP_IV_X_I<string opcodestr, bits<6> funct6>947 : VCMP_IV_X<opcodestr, funct6>,948 VCMP_IV_I<opcodestr, funct6>;949 950multiclass VCMP_IV_V_X<string opcodestr, bits<6> funct6>951 : VCMP_IV_V<opcodestr, funct6>,952 VCMP_IV_X<opcodestr, funct6>;953 954multiclass VMUL_MV_V_X<string opcodestr, bits<6> funct6> {955 def V : VALUVV<funct6, OPMVV, opcodestr # ".vv">,956 SchedBinaryMC<"WriteVIMulV", "ReadVIMulV", "ReadVIMulV">;957 def X : VALUVX<funct6, OPMVX, opcodestr # ".vx">,958 SchedBinaryMC<"WriteVIMulX", "ReadVIMulV", "ReadVIMulX">;959}960 961multiclass VWMUL_MV_V_X<string opcodestr, bits<6> funct6> {962 def V : VALUVV<funct6, OPMVV, opcodestr # ".vv">,963 SchedBinaryMC<"WriteVIWMulV", "ReadVIWMulV", "ReadVIWMulV">;964 def X : VALUVX<funct6, OPMVX, opcodestr # ".vx">,965 SchedBinaryMC<"WriteVIWMulX", "ReadVIWMulV", "ReadVIWMulX">;966}967 968multiclass VDIV_MV_V_X<string opcodestr, bits<6> funct6> {969 def V : VALUVV<funct6, OPMVV, opcodestr # ".vv">,970 SchedBinaryMC<"WriteVIDivV", "ReadVIDivV", "ReadVIDivV">;971 def X : VALUVX<funct6, OPMVX, opcodestr # ".vx">,972 SchedBinaryMC<"WriteVIDivX", "ReadVIDivV", "ReadVIDivX">;973}974 975multiclass VSALU_IV_V_X<string opcodestr, bits<6> funct6> {976 def V : VALUVV<funct6, OPIVV, opcodestr # ".vv">,977 SchedBinaryMC<"WriteVSALUV", "ReadVSALUV", "ReadVSALUV">;978 def X : VALUVX<funct6, OPIVX, opcodestr # ".vx">,979 SchedBinaryMC<"WriteVSALUX", "ReadVSALUV", "ReadVSALUX">;980}981 982multiclass VSALU_IV_V_X_I<string opcodestr, bits<6> funct6>983 : VSALU_IV_V_X<opcodestr, funct6> {984 def I : VALUVI<funct6, opcodestr # ".vi">,985 SchedUnaryMC<"WriteVSALUI", "ReadVSALUV">;986}987 988multiclass VAALU_MV_V_X<string opcodestr, bits<6> funct6> {989 def V : VALUVV<funct6, OPMVV, opcodestr # ".vv">,990 SchedBinaryMC<"WriteVAALUV", "ReadVAALUV", "ReadVAALUV">;991 def X : VALUVX<funct6, OPMVX, opcodestr # ".vx">,992 SchedBinaryMC<"WriteVAALUX", "ReadVAALUV", "ReadVAALUX">;993}994 995multiclass VSMUL_IV_V_X<string opcodestr, bits<6> funct6> {996 def V : VALUVV<funct6, OPIVV, opcodestr # ".vv">,997 SchedBinaryMC<"WriteVSMulV", "ReadVSMulV", "ReadVSMulV">;998 def X : VALUVX<funct6, OPIVX, opcodestr # ".vx">,999 SchedBinaryMC<"WriteVSMulX", "ReadVSMulV", "ReadVSMulX">;1000}1001 1002multiclass VSSHF_IV_V_X_I<string opcodestr, bits<6> funct6> {1003 def V : VALUVV<funct6, OPIVV, opcodestr # ".vv">,1004 SchedBinaryMC<"WriteVSShiftV", "ReadVSShiftV", "ReadVSShiftV">;1005 def X : VALUVX<funct6, OPIVX, opcodestr # ".vx">,1006 SchedBinaryMC<"WriteVSShiftX", "ReadVSShiftV", "ReadVSShiftX">;1007 def I : VALUVI<funct6, opcodestr # ".vi", uimm5>,1008 SchedUnaryMC<"WriteVSShiftI", "ReadVSShiftV">;1009}1010 1011multiclass VNCLP_IV_V_X_I<string opcodestr, bits<6> funct6> {1012 def V : VALUVV<funct6, OPIVV, opcodestr # ".wv">,1013 SchedBinaryMC<"WriteVNClipV", "ReadVNClipV", "ReadVNClipV">;1014 def X : VALUVX<funct6, OPIVX, opcodestr # ".wx">,1015 SchedBinaryMC<"WriteVNClipX", "ReadVNClipV", "ReadVNClipX">;1016 def I : VALUVI<funct6, opcodestr # ".wi", uimm5>,1017 SchedUnaryMC<"WriteVNClipI", "ReadVNClipV">;1018}1019 1020multiclass VSLD_IV_X_I<string opcodestr, bits<6> funct6, bit slidesUp> {1021 // Note: In the future, if VISlideI is also split into VSlideUpI and1022 // VSlideDownI, it'll probably better to use two separate multiclasses.1023 defvar WriteSlideX = !if(slidesUp, "WriteVSlideUpX", "WriteVSlideDownX");1024 def X : VALUVX<funct6, OPIVX, opcodestr # ".vx">,1025 SchedBinaryMC<WriteSlideX, "ReadVISlideV", "ReadVISlideX">;1026 def I : VALUVI<funct6, opcodestr # ".vi", uimm5>,1027 SchedUnaryMC<"WriteVSlideI", "ReadVISlideV">;1028}1029 1030multiclass VSLD1_MV_X<string opcodestr, bits<6> funct6> {1031 def X : VALUVX<funct6, OPMVX, opcodestr # ".vx">,1032 SchedBinaryMC<"WriteVISlide1X", "ReadVISlideV", "ReadVISlideX">;1033}1034 1035multiclass VSLD1_FV_F<string opcodestr, bits<6> funct6> {1036 def F : VALUVF<funct6, OPFVF, opcodestr # ".vf">,1037 SchedBinaryMC<"WriteVFSlide1F", "ReadVFSlideV", "ReadVFSlideF">;1038}1039 1040multiclass VGTR_IV_V_X_I<string opcodestr, bits<6> funct6> {1041 def V : VALUVV<funct6, OPIVV, opcodestr # ".vv">,1042 SchedBinaryMC<"WriteVRGatherVV", "ReadVRGatherVV_data",1043 "ReadVRGatherVV_index">;1044 def X : VALUVX<funct6, OPIVX, opcodestr # ".vx">,1045 SchedBinaryMC<"WriteVRGatherVX", "ReadVRGatherVX_data",1046 "ReadVRGatherVX_index">;1047 def I : VALUVI<funct6, opcodestr # ".vi", uimm5>,1048 SchedUnaryMC<"WriteVRGatherVI", "ReadVRGatherVI_data">;1049}1050 1051multiclass VCPR_MV_Mask<string opcodestr, bits<6> funct6, string vm = "v"> {1052 def M : VALUVVNoVm<funct6, OPMVV, opcodestr # "." # vm # "m">,1053 SchedBinaryMC<"WriteVCompressV", "ReadVCompressV", "ReadVCompressV">;1054}1055 1056multiclass VWholeLoadN<int l, bits<3> nf, string opcodestr, RegisterClass VRC> {1057 defvar w = !cast<RISCVWidth>("LSWidth" # l);1058 defvar s = !cast<SchedWrite>("WriteVLD" # !add(nf, 1) # "R");1059 1060 def E # l # _V : VWholeLoad<nf, w, opcodestr # "e" # l # ".v", VRC>,1061 Sched<[s, ReadVLDX]>;1062}1063 1064//===----------------------------------------------------------------------===//1065// Instructions1066//===----------------------------------------------------------------------===//1067 1068let Predicates = [HasVInstructions] in {1069let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in {1070def VSETVLI : RVInstSetVLi<(outs GPR:$rd), (ins GPR:$rs1, VTypeIOp11:$vtypei),1071 "vsetvli", "$rd, $rs1, $vtypei">,1072 Sched<[WriteVSETVLI, ReadVSETVLI]>;1073def VSETIVLI : RVInstSetiVLi<(outs GPR:$rd), (ins uimm5:$uimm, VTypeIOp10:$vtypei),1074 "vsetivli", "$rd, $uimm, $vtypei">,1075 Sched<[WriteVSETIVLI]>;1076 1077def VSETVL : RVInstSetVL<(outs GPR:$rd), (ins GPR:$rs1, GPR:$rs2),1078 "vsetvl", "$rd, $rs1, $rs2">,1079 Sched<[WriteVSETVL, ReadVSETVL, ReadVSETVL]>;1080} // hasSideEffects = 1, mayLoad = 0, mayStore = 01081} // Predicates = [HasVInstructions]1082 1083foreach eew = [8, 16, 32, 64] in {1084 defvar w = !cast<RISCVWidth>("LSWidth" # eew);1085 1086 let Predicates = !if(!eq(eew, 64), [HasVInstructionsI64],1087 [HasVInstructions]) in {1088 // Vector Unit-Stride Instructions1089 def VLE#eew#_V : VUnitStrideLoad<w, "vle"#eew#".v">, VLESchedMC;1090 def VSE#eew#_V : VUnitStrideStore<w, "vse"#eew#".v">, VSESchedMC;1091 1092 // Vector Unit-Stride Fault-only-First Loads1093 def VLE#eew#FF_V : VUnitStrideLoadFF<w, "vle"#eew#"ff.v">, VLFSchedMC;1094 1095 // Vector Strided Instructions1096 def VLSE#eew#_V : VStridedLoad<w, "vlse"#eew#".v">, VLSSchedMC<eew>;1097 def VSSE#eew#_V : VStridedStore<w, "vsse"#eew#".v">, VSSSchedMC<eew>;1098 1099 defm VL1R : VWholeLoadN<eew, 0, "vl1r", VR>;1100 defm VL2R : VWholeLoadN<eew, 1, "vl2r", VRM2>;1101 defm VL4R : VWholeLoadN<eew, 3, "vl4r", VRM4>;1102 defm VL8R : VWholeLoadN<eew, 7, "vl8r", VRM8>;1103 }1104 1105 let Predicates = !if(!eq(eew, 64), [IsRV64, HasVInstructionsI64],1106 [HasVInstructions]) in1107 defm "" : VIndexLoadStore<eew>;1108}1109 1110let Predicates = [HasVInstructions] in {1111def VLM_V : VUnitStrideLoadMask<"vlm.v">,1112 Sched<[WriteVLDM_WorstCase, ReadVLDX]>;1113def VSM_V : VUnitStrideStoreMask<"vsm.v">,1114 Sched<[WriteVSTM_WorstCase, ReadVSTM_WorstCase, ReadVSTX]>;1115def : MnemonicAlias<"vle1.v", "vlm.v">;1116def : MnemonicAlias<"vse1.v", "vsm.v">;1117 1118def VS1R_V : VWholeStore<0, "vs1r.v", VR>,1119 Sched<[WriteVST1R, ReadVST1R, ReadVSTX]>;1120def VS2R_V : VWholeStore<1, "vs2r.v", VRM2>,1121 Sched<[WriteVST2R, ReadVST2R, ReadVSTX]>;1122def VS4R_V : VWholeStore<3, "vs4r.v", VRM4>,1123 Sched<[WriteVST4R, ReadVST4R, ReadVSTX]>;1124def VS8R_V : VWholeStore<7, "vs8r.v", VRM8>,1125 Sched<[WriteVST8R, ReadVST8R, ReadVSTX]>;1126 1127def : InstAlias<"vl1r.v $vd, $rs1", (VL1RE8_V VR:$vd, GPRMemZeroOffset:$rs1)>;1128def : InstAlias<"vl2r.v $vd, $rs1", (VL2RE8_V VRM2:$vd, GPRMemZeroOffset:$rs1)>;1129def : InstAlias<"vl4r.v $vd, $rs1", (VL4RE8_V VRM4:$vd, GPRMemZeroOffset:$rs1)>;1130def : InstAlias<"vl8r.v $vd, $rs1", (VL8RE8_V VRM8:$vd, GPRMemZeroOffset:$rs1)>;1131} // Predicates = [HasVInstructions]1132 1133let Predicates = [HasVInstructions] in {1134// Vector Single-Width Integer Add and Subtract1135defm VADD_V : VALU_IV_V_X_I<"vadd", 0b000000>;1136defm VSUB_V : VALU_IV_V_X<"vsub", 0b000010>;1137defm VRSUB_V : VALU_IV_X_I<"vrsub", 0b000011>;1138 1139def : InstAlias<"vneg.v $vd, $vs$vm", (VRSUB_VX VR:$vd, VR:$vs, X0, VMaskOp:$vm)>;1140def : InstAlias<"vneg.v $vd, $vs", (VRSUB_VX VR:$vd, VR:$vs, X0, zero_reg)>;1141 1142// Vector Widening Integer Add/Subtract1143// Refer to 11.2 Widening Vector Arithmetic Instructions1144// The destination vector register group cannot overlap a source vector1145// register group of a different element width (including the mask register1146// if masked), otherwise an illegal instruction exception is raised.1147let Constraints = "@earlyclobber $vd", DestEEW = EEWSEWx2 in {1148let RVVConstraint = WidenV in {1149defm VWADDU_V : VALU_MV_V_X<"vwaddu", 0b110000, "v">;1150defm VWSUBU_V : VALU_MV_V_X<"vwsubu", 0b110010, "v">;1151defm VWADD_V : VALU_MV_V_X<"vwadd", 0b110001, "v">;1152defm VWSUB_V : VALU_MV_V_X<"vwsub", 0b110011, "v">;1153} // RVVConstraint = WidenV1154// Set earlyclobber for following instructions for second and mask operands.1155// This has the downside that the earlyclobber constraint is too coarse and1156// will impose unnecessary restrictions by not allowing the destination to1157// overlap with the first (wide) operand.1158let RVVConstraint = WidenW in {1159defm VWADDU_W : VALU_MV_V_X<"vwaddu", 0b110100, "w">;1160defm VWSUBU_W : VALU_MV_V_X<"vwsubu", 0b110110, "w">;1161defm VWADD_W : VALU_MV_V_X<"vwadd", 0b110101, "w">;1162defm VWSUB_W : VALU_MV_V_X<"vwsub", 0b110111, "w">;1163} // RVVConstraint = WidenW1164} // Constraints = "@earlyclobber $vd", DestEEW = EEWSEWx21165 1166def : InstAlias<"vwcvt.x.x.v $vd, $vs$vm",1167 (VWADD_VX VR:$vd, VR:$vs, X0, VMaskOp:$vm)>;1168def : InstAlias<"vwcvt.x.x.v $vd, $vs",1169 (VWADD_VX VR:$vd, VR:$vs, X0, zero_reg)>;1170def : InstAlias<"vwcvtu.x.x.v $vd, $vs$vm",1171 (VWADDU_VX VR:$vd, VR:$vs, X0, VMaskOp:$vm)>;1172def : InstAlias<"vwcvtu.x.x.v $vd, $vs",1173 (VWADDU_VX VR:$vd, VR:$vs, X0, zero_reg)>;1174 1175// Vector Integer Extension1176defm VZEXT_VF8 : VALU_MV_VS2<"vzext.vf8", 0b010010, 0b00010>;1177defm VSEXT_VF8 : VALU_MV_VS2<"vsext.vf8", 0b010010, 0b00011>;1178defm VZEXT_VF4 : VALU_MV_VS2<"vzext.vf4", 0b010010, 0b00100>;1179defm VSEXT_VF4 : VALU_MV_VS2<"vsext.vf4", 0b010010, 0b00101>;1180defm VZEXT_VF2 : VALU_MV_VS2<"vzext.vf2", 0b010010, 0b00110>;1181defm VSEXT_VF2 : VALU_MV_VS2<"vsext.vf2", 0b010010, 0b00111>;1182 1183// Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions1184defm VADC_V : VALUm_IV_V_X_I<"vadc", 0b010000>;1185defm VSBC_V : VALUm_IV_V_X<"vsbc", 0b010010>;1186let Constraints = "@earlyclobber $vd", RVVConstraint = NoConstraint,1187 DestEEW = EEW1 in {1188defm VMADC_V : VALUm_IV_V_X_I<"vmadc", 0b010001>;1189defm VMADC_V : VALUNoVm_IV_V_X_I<"vmadc", 0b010001>;1190defm VMSBC_V : VALUm_IV_V_X<"vmsbc", 0b010011>;1191defm VMSBC_V : VALUNoVm_IV_V_X<"vmsbc", 0b010011>;1192} // Constraints = "@earlyclobber $vd", RVVConstraint = NoConstraint, DestEEW = EEW11193 1194// Vector Bitwise Logical Instructions1195defm VAND_V : VALU_IV_V_X_I<"vand", 0b001001>;1196defm VOR_V : VALU_IV_V_X_I<"vor", 0b001010>;1197defm VXOR_V : VALU_IV_V_X_I<"vxor", 0b001011>;1198 1199def : InstAlias<"vnot.v $vd, $vs$vm",1200 (VXOR_VI VR:$vd, VR:$vs, -1, VMaskOp:$vm)>;1201def : InstAlias<"vnot.v $vd, $vs",1202 (VXOR_VI VR:$vd, VR:$vs, -1, zero_reg)>;1203 1204// Vector Single-Width Bit Shift Instructions1205defm VSLL_V : VSHT_IV_V_X_I<"vsll", 0b100101>;1206defm VSRL_V : VSHT_IV_V_X_I<"vsrl", 0b101000>;1207defm VSRA_V : VSHT_IV_V_X_I<"vsra", 0b101001>;1208 1209// Vector Narrowing Integer Right Shift Instructions1210// Refer to 11.3. Narrowing Vector Arithmetic Instructions1211// The destination vector register group cannot overlap the first source1212// vector register group (specified by vs2). The destination vector register1213// group cannot overlap the mask register if used, unless LMUL=1.1214let Constraints = "@earlyclobber $vd" in {1215defm VNSRL_W : VNSHT_IV_V_X_I<"vnsrl", 0b101100>;1216defm VNSRA_W : VNSHT_IV_V_X_I<"vnsra", 0b101101>;1217} // Constraints = "@earlyclobber $vd"1218 1219def : InstAlias<"vncvt.x.x.w $vd, $vs$vm",1220 (VNSRL_WX VR:$vd, VR:$vs, X0, VMaskOp:$vm)>;1221def : InstAlias<"vncvt.x.x.w $vd, $vs",1222 (VNSRL_WX VR:$vd, VR:$vs, X0, zero_reg)>;1223 1224// Vector Integer Comparison Instructions1225let RVVConstraint = NoConstraint, DestEEW = EEW1 in {1226defm VMSEQ_V : VCMP_IV_V_X_I<"vmseq", 0b011000>;1227defm VMSNE_V : VCMP_IV_V_X_I<"vmsne", 0b011001>;1228defm VMSLTU_V : VCMP_IV_V_X<"vmsltu", 0b011010>;1229defm VMSLT_V : VCMP_IV_V_X<"vmslt", 0b011011>;1230defm VMSLEU_V : VCMP_IV_V_X_I<"vmsleu", 0b011100>;1231defm VMSLE_V : VCMP_IV_V_X_I<"vmsle", 0b011101>;1232defm VMSGTU_V : VCMP_IV_X_I<"vmsgtu", 0b011110>;1233defm VMSGT_V : VCMP_IV_X_I<"vmsgt", 0b011111>;1234} // RVVConstraint = NoConstraint, DestEEW = EEW11235 1236def : InstAlias<"vmsgtu.vv $vd, $va, $vb$vm",1237 (VMSLTU_VV VR:$vd, VR:$vb, VR:$va, VMaskOp:$vm), 0>;1238def : InstAlias<"vmsgt.vv $vd, $va, $vb$vm",1239 (VMSLT_VV VR:$vd, VR:$vb, VR:$va, VMaskOp:$vm), 0>;1240def : InstAlias<"vmsgeu.vv $vd, $va, $vb$vm",1241 (VMSLEU_VV VR:$vd, VR:$vb, VR:$va, VMaskOp:$vm), 0>;1242def : InstAlias<"vmsge.vv $vd, $va, $vb$vm",1243 (VMSLE_VV VR:$vd, VR:$vb, VR:$va, VMaskOp:$vm), 0>;1244 1245let isCodeGenOnly = 0, isAsmParserOnly = 1, hasSideEffects = 0, mayLoad = 0,1246 mayStore = 0, DestEEW = EEW1 in {1247// For unsigned comparisons we need to special case 0 immediate to maintain1248// the always true/false semantics we would invert if we just decremented the1249// immediate like we do for signed. To match the GNU assembler we will use1250// vmseq/vmsne.vv with the same register for both operands which we can't do1251// from an InstAlias.1252def PseudoVMSGEU_VI : Pseudo<(outs VR:$vd),1253 (ins VR:$vs2, simm5_plus1:$imm, VMaskOp:$vm),1254 [], "vmsgeu.vi", "$vd, $vs2, $imm$vm">;1255def PseudoVMSLTU_VI : Pseudo<(outs VR:$vd),1256 (ins VR:$vs2, simm5_plus1:$imm, VMaskOp:$vm),1257 [], "vmsltu.vi", "$vd, $vs2, $imm$vm">;1258// Handle signed with pseudos as well for more consistency in the1259// implementation.1260def PseudoVMSGE_VI : Pseudo<(outs VR:$vd),1261 (ins VR:$vs2, simm5_plus1:$imm, VMaskOp:$vm),1262 [], "vmsge.vi", "$vd, $vs2, $imm$vm">;1263def PseudoVMSLT_VI : Pseudo<(outs VR:$vd),1264 (ins VR:$vs2, simm5_plus1:$imm, VMaskOp:$vm),1265 [], "vmslt.vi", "$vd, $vs2, $imm$vm">;1266}1267 1268let isCodeGenOnly = 0, isAsmParserOnly = 1, hasSideEffects = 0, mayLoad = 0,1269 mayStore = 0, DestEEW = EEW1 in {1270def PseudoVMSGEU_VX : Pseudo<(outs VR:$vd),1271 (ins VR:$vs2, GPR:$rs1),1272 [], "vmsgeu.vx", "$vd, $vs2, $rs1">;1273def PseudoVMSGE_VX : Pseudo<(outs VR:$vd),1274 (ins VR:$vs2, GPR:$rs1),1275 [], "vmsge.vx", "$vd, $vs2, $rs1">;1276def PseudoVMSGEU_VX_M : Pseudo<(outs VRNoV0:$vd),1277 (ins VR:$vs2, GPR:$rs1, VMaskOp:$vm),1278 [], "vmsgeu.vx", "$vd, $vs2, $rs1$vm">;1279def PseudoVMSGE_VX_M : Pseudo<(outs VRNoV0:$vd),1280 (ins VR:$vs2, GPR:$rs1, VMaskOp:$vm),1281 [], "vmsge.vx", "$vd, $vs2, $rs1$vm">;1282def PseudoVMSGEU_VX_M_T : Pseudo<(outs VR:$vd, VRNoV0:$scratch),1283 (ins VR:$vs2, GPR:$rs1, VMaskOp:$vm),1284 [], "vmsgeu.vx", "$vd, $vs2, $rs1$vm, $scratch">;1285def PseudoVMSGE_VX_M_T : Pseudo<(outs VR:$vd, VRNoV0:$scratch),1286 (ins VR:$vs2, GPR:$rs1, VMaskOp:$vm),1287 [], "vmsge.vx", "$vd, $vs2, $rs1$vm, $scratch">;1288}1289 1290// Vector Integer Min/Max Instructions1291defm VMINU_V : VMINMAX_IV_V_X<"vminu", 0b000100>;1292defm VMIN_V : VMINMAX_IV_V_X<"vmin", 0b000101>;1293defm VMAXU_V : VMINMAX_IV_V_X<"vmaxu", 0b000110>;1294defm VMAX_V : VMINMAX_IV_V_X<"vmax", 0b000111>;1295 1296// Vector Single-Width Integer Multiply Instructions1297defm VMUL_V : VMUL_MV_V_X<"vmul", 0b100101>;1298defm VMULH_V : VMUL_MV_V_X<"vmulh", 0b100111>;1299defm VMULHU_V : VMUL_MV_V_X<"vmulhu", 0b100100>;1300defm VMULHSU_V : VMUL_MV_V_X<"vmulhsu", 0b100110>;1301 1302// Vector Integer Divide Instructions1303defm VDIVU_V : VDIV_MV_V_X<"vdivu", 0b100000>;1304defm VDIV_V : VDIV_MV_V_X<"vdiv", 0b100001>;1305defm VREMU_V : VDIV_MV_V_X<"vremu", 0b100010>;1306defm VREM_V : VDIV_MV_V_X<"vrem", 0b100011>;1307 1308// Vector Widening Integer Multiply Instructions1309let Constraints = "@earlyclobber $vd", RVVConstraint = WidenV,1310 DestEEW = EEWSEWx2 in {1311defm VWMUL_V : VWMUL_MV_V_X<"vwmul", 0b111011>;1312defm VWMULU_V : VWMUL_MV_V_X<"vwmulu", 0b111000>;1313defm VWMULSU_V : VWMUL_MV_V_X<"vwmulsu", 0b111010>;1314} // Constraints = "@earlyclobber $vd", RVVConstraint = WidenV, DestEEW = EEWSEWx21315 1316// Vector Single-Width Integer Multiply-Add Instructions1317defm VMACC_V : VMAC_MV_V_X<"vmacc", 0b101101>;1318defm VNMSAC_V : VMAC_MV_V_X<"vnmsac", 0b101111>;1319defm VMADD_V : VMAC_MV_V_X<"vmadd", 0b101001>;1320defm VNMSUB_V : VMAC_MV_V_X<"vnmsub", 0b101011>;1321 1322// Vector Widening Integer Multiply-Add Instructions1323let DestEEW = EEWSEWx2 in {1324defm VWMACCU_V : VWMAC_MV_V_X<"vwmaccu", 0b111100>;1325defm VWMACC_V : VWMAC_MV_V_X<"vwmacc", 0b111101>;1326defm VWMACCSU_V : VWMAC_MV_V_X<"vwmaccsu", 0b111111>;1327defm VWMACCUS_V : VWMAC_MV_X<"vwmaccus", 0b111110>;1328} // DestEEW = EEWSEWx21329 1330// Vector Integer Merge Instructions1331defm VMERGE_V : VMRG_IV_V_X_I<"vmerge", 0b010111>;1332 1333// Vector Integer Move Instructions1334let hasSideEffects = 0, mayLoad = 0, mayStore = 0, vs2 = 0, vm = 1,1335 RVVConstraint = NoConstraint in {1336// op vd, vs11337def VMV_V_V : RVInstVV<0b010111, OPIVV, (outs VR:$vd),1338 (ins VR:$vs1), "vmv.v.v", "$vd, $vs1">,1339 SchedUnaryMC<"WriteVIMovV", "ReadVIMovV", forceMasked=0>;1340// op vd, rs11341def VMV_V_X : RVInstVX<0b010111, OPIVX, (outs VR:$vd),1342 (ins GPR:$rs1), "vmv.v.x", "$vd, $rs1">,1343 SchedUnaryMC<"WriteVIMovX", "ReadVIMovX", forceMasked=0>;1344// op vd, imm1345def VMV_V_I : RVInstIVI<0b010111, (outs VR:$vd),1346 (ins simm5:$imm), "vmv.v.i", "$vd, $imm">,1347 SchedNullaryMC<"WriteVIMovI", forceMasked=0>;1348} // hasSideEffects = 0, mayLoad = 0, mayStore = 01349 1350// Vector Fixed-Point Arithmetic Instructions1351defm VSADDU_V : VSALU_IV_V_X_I<"vsaddu", 0b100000>;1352defm VSADD_V : VSALU_IV_V_X_I<"vsadd", 0b100001>;1353defm VSSUBU_V : VSALU_IV_V_X<"vssubu", 0b100010>;1354defm VSSUB_V : VSALU_IV_V_X<"vssub", 0b100011>;1355 1356// Vector Single-Width Averaging Add and Subtract1357defm VAADDU_V : VAALU_MV_V_X<"vaaddu", 0b001000>;1358defm VAADD_V : VAALU_MV_V_X<"vaadd", 0b001001>;1359defm VASUBU_V : VAALU_MV_V_X<"vasubu", 0b001010>;1360defm VASUB_V : VAALU_MV_V_X<"vasub", 0b001011>;1361 1362// Vector Single-Width Fractional Multiply with Rounding and Saturation1363defm VSMUL_V : VSMUL_IV_V_X<"vsmul", 0b100111>;1364 1365// Vector Single-Width Scaling Shift Instructions1366defm VSSRL_V : VSSHF_IV_V_X_I<"vssrl", 0b101010>;1367defm VSSRA_V : VSSHF_IV_V_X_I<"vssra", 0b101011>;1368 1369// Vector Narrowing Fixed-Point Clip Instructions1370let Constraints = "@earlyclobber $vd" in {1371defm VNCLIPU_W : VNCLP_IV_V_X_I<"vnclipu", 0b101110>;1372defm VNCLIP_W : VNCLP_IV_V_X_I<"vnclip", 0b101111>;1373} // Constraints = "@earlyclobber $vd"1374} // Predicates = [HasVInstructions]1375 1376let Predicates = [HasVInstructionsAnyF] in {1377// Vector Single-Width Floating-Point Add/Subtract Instructions1378let Uses = [FRM, VL, VTYPE], mayRaiseFPException = true in {1379defm VFADD_V : VALU_FV_V_F<"vfadd", 0b000000>;1380defm VFSUB_V : VALU_FV_V_F<"vfsub", 0b000010>;1381defm VFRSUB_V : VALU_FV_F<"vfrsub", 0b100111>;1382}1383 1384// Vector Widening Floating-Point Add/Subtract Instructions1385let Constraints = "@earlyclobber $vd",1386 Uses = [FRM, VL, VTYPE],1387 mayRaiseFPException = true,1388 DestEEW = EEWSEWx2 in {1389let RVVConstraint = WidenV in {1390defm VFWADD_V : VWALU_FV_V_F<"vfwadd", 0b110000, "v">;1391defm VFWSUB_V : VWALU_FV_V_F<"vfwsub", 0b110010, "v">;1392} // RVVConstraint = WidenV1393// Set earlyclobber for following instructions for second and mask operands.1394// This has the downside that the earlyclobber constraint is too coarse and1395// will impose unnecessary restrictions by not allowing the destination to1396// overlap with the first (wide) operand.1397let RVVConstraint = WidenW in {1398defm VFWADD_W : VWALU_FV_V_F<"vfwadd", 0b110100, "w">;1399defm VFWSUB_W : VWALU_FV_V_F<"vfwsub", 0b110110, "w">;1400} // RVVConstraint = WidenW1401} // Constraints = "@earlyclobber $vd", Uses = [FRM, VL, VTYPE], mayRaiseFPException = true, DestEEW = EEWSEWx21402 1403// Vector Single-Width Floating-Point Multiply/Divide Instructions1404let Uses = [FRM, VL, VTYPE], mayRaiseFPException = true in {1405defm VFMUL_V : VMUL_FV_V_F<"vfmul", 0b100100>;1406defm VFDIV_V : VDIV_FV_V_F<"vfdiv", 0b100000>;1407defm VFRDIV_V : VDIV_FV_F<"vfrdiv", 0b100001>;1408}1409 1410// Vector Widening Floating-Point Multiply1411let Constraints = "@earlyclobber $vd", RVVConstraint = WidenV,1412 Uses = [FRM, VL, VTYPE], mayRaiseFPException = true, DestEEW = EEWSEWx2 in {1413defm VFWMUL_V : VWMUL_FV_V_F<"vfwmul", 0b111000>;1414} // Constraints = "@earlyclobber $vd", RVVConstraint = WidenV, Uses = [FRM, VL, VTYPE], mayRaiseFPException = true, DestEEW = EEWSEWx21415 1416// Vector Single-Width Floating-Point Fused Multiply-Add Instructions1417let Uses = [FRM, VL, VTYPE], mayRaiseFPException = true in {1418defm VFMACC_V : VMAC_FV_V_F<"vfmacc", 0b101100>;1419defm VFNMACC_V : VMAC_FV_V_F<"vfnmacc", 0b101101>;1420defm VFMSAC_V : VMAC_FV_V_F<"vfmsac", 0b101110>;1421defm VFNMSAC_V : VMAC_FV_V_F<"vfnmsac", 0b101111>;1422defm VFMADD_V : VMAC_FV_V_F<"vfmadd", 0b101000>;1423defm VFNMADD_V : VMAC_FV_V_F<"vfnmadd", 0b101001>;1424defm VFMSUB_V : VMAC_FV_V_F<"vfmsub", 0b101010>;1425defm VFNMSUB_V : VMAC_FV_V_F<"vfnmsub", 0b101011>;1426}1427 1428// Vector Widening Floating-Point Fused Multiply-Add Instructions1429let Uses = [FRM, VL, VTYPE], mayRaiseFPException = true, DestEEW = EEWSEWx2 in {1430defm VFWMACC_V : VWMAC_FV_V_F<"vfwmacc", 0b111100>;1431defm VFWNMACC_V : VWMAC_FV_V_F<"vfwnmacc", 0b111101>;1432defm VFWMSAC_V : VWMAC_FV_V_F<"vfwmsac", 0b111110>;1433defm VFWNMSAC_V : VWMAC_FV_V_F<"vfwnmsac", 0b111111>;1434} // Constraints = "@earlyclobber $vd", RVVConstraint = WidenV, Uses = [FRM, VL, VTYPE], mayRaiseFPException = true, DestEEW = EEWSEWx21435 1436// Vector Floating-Point Square-Root Instruction1437let Uses = [FRM, VL, VTYPE], mayRaiseFPException = true in {1438defm VFSQRT_V : VSQR_FV_VS2<"vfsqrt.v", 0b010011, 0b00000>;1439defm VFREC7_V : VRCP_FV_VS2<"vfrec7.v", 0b010011, 0b00101>;1440}1441 1442let mayRaiseFPException = true in1443defm VFRSQRT7_V : VRCP_FV_VS2<"vfrsqrt7.v", 0b010011, 0b00100>;1444 1445// Vector Floating-Point MIN/MAX Instructions1446let mayRaiseFPException = true in {1447defm VFMIN_V : VMINMAX_FV_V_F<"vfmin", 0b000100>;1448defm VFMAX_V : VMINMAX_FV_V_F<"vfmax", 0b000110>;1449}1450 1451// Vector Floating-Point Sign-Injection Instructions1452defm VFSGNJ_V : VSGNJ_FV_V_F<"vfsgnj", 0b001000>;1453defm VFSGNJN_V : VSGNJ_FV_V_F<"vfsgnjn", 0b001001>;1454defm VFSGNJX_V : VSGNJ_FV_V_F<"vfsgnjx", 0b001010>;1455 1456def : InstAlias<"vfneg.v $vd, $vs$vm",1457 (VFSGNJN_VV VR:$vd, VR:$vs, VR:$vs, VMaskOp:$vm)>;1458def : InstAlias<"vfneg.v $vd, $vs",1459 (VFSGNJN_VV VR:$vd, VR:$vs, VR:$vs, zero_reg)>;1460def : InstAlias<"vfabs.v $vd, $vs$vm",1461 (VFSGNJX_VV VR:$vd, VR:$vs, VR:$vs, VMaskOp:$vm)>;1462def : InstAlias<"vfabs.v $vd, $vs",1463 (VFSGNJX_VV VR:$vd, VR:$vs, VR:$vs, zero_reg)>;1464 1465// Vector Floating-Point Compare Instructions1466let RVVConstraint = NoConstraint, mayRaiseFPException = true, DestEEW = EEW1 in {1467defm VMFEQ_V : VCMP_FV_V_F<"vmfeq", 0b011000>;1468defm VMFNE_V : VCMP_FV_V_F<"vmfne", 0b011100>;1469defm VMFLT_V : VCMP_FV_V_F<"vmflt", 0b011011>;1470defm VMFLE_V : VCMP_FV_V_F<"vmfle", 0b011001>;1471defm VMFGT_V : VCMP_FV_F<"vmfgt", 0b011101>;1472defm VMFGE_V : VCMP_FV_F<"vmfge", 0b011111>;1473} // RVVConstraint = NoConstraint, mayRaiseFPException = true, DestEEW = EEW11474 1475def : InstAlias<"vmfgt.vv $vd, $va, $vb$vm",1476 (VMFLT_VV VR:$vd, VR:$vb, VR:$va, VMaskOp:$vm), 0>;1477def : InstAlias<"vmfge.vv $vd, $va, $vb$vm",1478 (VMFLE_VV VR:$vd, VR:$vb, VR:$va, VMaskOp:$vm), 0>;1479 1480// Vector Floating-Point Classify Instruction1481defm VFCLASS_V : VCLS_FV_VS2<"vfclass.v", 0b010011, 0b10000>;1482 1483let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {1484 1485// Vector Floating-Point Merge Instruction1486def VFMERGE_VFM : RVInstVX<0b010111, OPFVF, (outs VR:$vd),1487 (ins VR:$vs2, FPR32:$rs1, VMaskCarryInOp:$vm),1488 "vfmerge.vfm", "$vd, $vs2, $rs1, $vm">,1489 SchedBinaryMC<"WriteVFMergeV", "ReadVFMergeV", "ReadVFMergeF">;1490 1491// Vector Floating-Point Move Instruction1492let RVVConstraint = NoConstraint in1493let vm = 1, vs2 = 0 in1494def VFMV_V_F : RVInstVX<0b010111, OPFVF, (outs VR:$vd),1495 (ins FPR32:$rs1), "vfmv.v.f", "$vd, $rs1">,1496 SchedUnaryMC<"WriteVFMovV", "ReadVFMovF", forceMasked=0>;1497 1498} // hasSideEffects = 0, mayLoad = 0, mayStore = 01499 1500// Single-Width Floating-Point/Integer Type-Convert Instructions1501let mayRaiseFPException = true in {1502let Uses = [FRM, VL, VTYPE] in {1503defm VFCVT_XU_F_V : VCVTI_FV_VS2<"vfcvt.xu.f.v", 0b010010, 0b00000>;1504defm VFCVT_X_F_V : VCVTI_FV_VS2<"vfcvt.x.f.v", 0b010010, 0b00001>;1505}1506defm VFCVT_RTZ_XU_F_V : VCVTI_FV_VS2<"vfcvt.rtz.xu.f.v", 0b010010, 0b00110>;1507defm VFCVT_RTZ_X_F_V : VCVTI_FV_VS2<"vfcvt.rtz.x.f.v", 0b010010, 0b00111>;1508let Uses = [FRM, VL, VTYPE] in {1509defm VFCVT_F_XU_V : VCVTF_IV_VS2<"vfcvt.f.xu.v", 0b010010, 0b00010>;1510defm VFCVT_F_X_V : VCVTF_IV_VS2<"vfcvt.f.x.v", 0b010010, 0b00011>;1511}1512} // mayRaiseFPException = true1513 1514// Widening Floating-Point/Integer Type-Convert Instructions1515let Constraints = "@earlyclobber $vd", RVVConstraint = WidenCvt,1516 mayRaiseFPException = true, DestEEW = EEWSEWx2 in {1517let Uses = [FRM, VL, VTYPE] in {1518defm VFWCVT_XU_F_V : VWCVTI_FV_VS2<"vfwcvt.xu.f.v", 0b010010, 0b01000>;1519defm VFWCVT_X_F_V : VWCVTI_FV_VS2<"vfwcvt.x.f.v", 0b010010, 0b01001>;1520}1521defm VFWCVT_RTZ_XU_F_V : VWCVTI_FV_VS2<"vfwcvt.rtz.xu.f.v", 0b010010, 0b01110>;1522defm VFWCVT_RTZ_X_F_V : VWCVTI_FV_VS2<"vfwcvt.rtz.x.f.v", 0b010010, 0b01111>;1523defm VFWCVT_F_XU_V : VWCVTF_IV_VS2<"vfwcvt.f.xu.v", 0b010010, 0b01010>;1524defm VFWCVT_F_X_V : VWCVTF_IV_VS2<"vfwcvt.f.x.v", 0b010010, 0b01011>;1525defm VFWCVT_F_F_V : VWCVTF_FV_VS2<"vfwcvt.f.f.v", 0b010010, 0b01100>;1526} // Constraints = "@earlyclobber $vd", RVVConstraint = WidenCvt, DestEEW = EEWSEWx21527 1528// Narrowing Floating-Point/Integer Type-Convert Instructions1529let Constraints = "@earlyclobber $vd", mayRaiseFPException = true in {1530let Uses = [FRM, VL, VTYPE] in {1531defm VFNCVT_XU_F_W : VNCVTI_FV_VS2<"vfncvt.xu.f.w", 0b010010, 0b10000>;1532defm VFNCVT_X_F_W : VNCVTI_FV_VS2<"vfncvt.x.f.w", 0b010010, 0b10001>;1533}1534defm VFNCVT_RTZ_XU_F_W : VNCVTI_FV_VS2<"vfncvt.rtz.xu.f.w", 0b010010, 0b10110>;1535defm VFNCVT_RTZ_X_F_W : VNCVTI_FV_VS2<"vfncvt.rtz.x.f.w", 0b010010, 0b10111>;1536let Uses = [FRM, VL, VTYPE] in {1537defm VFNCVT_F_XU_W : VNCVTF_IV_VS2<"vfncvt.f.xu.w", 0b010010, 0b10010>;1538defm VFNCVT_F_X_W : VNCVTF_IV_VS2<"vfncvt.f.x.w", 0b010010, 0b10011>;1539defm VFNCVT_F_F_W : VNCVTF_FV_VS2<"vfncvt.f.f.w", 0b010010, 0b10100>;1540}1541defm VFNCVT_ROD_F_F_W : VNCVTF_FV_VS2<"vfncvt.rod.f.f.w", 0b010010, 0b10101>;1542} // Constraints = "@earlyclobber $vd", mayRaiseFPException = true1543} // Predicates = HasVInstructionsAnyF]1544 1545let Predicates = [HasVInstructions] in {1546 1547// Vector Single-Width Integer Reduction Instructions1548let RVVConstraint = NoConstraint, ElementsDependOn = EltDepsVLMask in {1549defm VREDSUM : VRED_MV_V<"vredsum", 0b000000>;1550defm VREDMAXU : VREDMINMAX_MV_V<"vredmaxu", 0b000110>;1551defm VREDMAX : VREDMINMAX_MV_V<"vredmax", 0b000111>;1552defm VREDMINU : VREDMINMAX_MV_V<"vredminu", 0b000100>;1553defm VREDMIN : VREDMINMAX_MV_V<"vredmin", 0b000101>;1554defm VREDAND : VRED_MV_V<"vredand", 0b000001>;1555defm VREDOR : VRED_MV_V<"vredor", 0b000010>;1556defm VREDXOR : VRED_MV_V<"vredxor", 0b000011>;1557} // RVVConstraint = NoConstraint, ElementsDependOn = EltDepsVLMask1558 1559// Vector Widening Integer Reduction Instructions1560let Constraints = "@earlyclobber $vd", RVVConstraint = NoConstraint, ElementsDependOn = EltDepsVLMask, DestEEW = EEWSEWx2 in {1561// Set earlyclobber for following instructions for second and mask operands.1562// This has the downside that the earlyclobber constraint is too coarse and1563// will impose unnecessary restrictions by not allowing the destination to1564// overlap with the first (wide) operand.1565defm VWREDSUMU : VWRED_IV_V<"vwredsumu", 0b110000>;1566defm VWREDSUM : VWRED_IV_V<"vwredsum", 0b110001>;1567} // Constraints = "@earlyclobber $vd", RVVConstraint = NoConstraint, ElementsDependOn = EltDepsVLMask, DestEEW = EEWSEWx21568 1569} // Predicates = [HasVInstructions]1570 1571let Predicates = [HasVInstructionsAnyF] in {1572// Vector Single-Width Floating-Point Reduction Instructions1573let RVVConstraint = NoConstraint, ElementsDependOn = EltDepsVLMask in {1574let Uses = [FRM, VL, VTYPE], mayRaiseFPException = true in {1575defm VFREDOSUM : VREDO_FV_V<"vfredosum", 0b000011>;1576defm VFREDUSUM : VRED_FV_V<"vfredusum", 0b000001>;1577}1578let mayRaiseFPException = true in {1579defm VFREDMAX : VREDMINMAX_FV_V<"vfredmax", 0b000111>;1580defm VFREDMIN : VREDMINMAX_FV_V<"vfredmin", 0b000101>;1581}1582} // RVVConstraint = NoConstraint, ElementsDependOn = EltDepsVLMask1583 1584def : MnemonicAlias<"vfredsum.vs", "vfredusum.vs">;1585 1586// Vector Widening Floating-Point Reduction Instructions1587let Constraints = "@earlyclobber $vd", RVVConstraint = NoConstraint, ElementsDependOn = EltDepsVLMask, DestEEW = EEWSEWx2 in {1588// Set earlyclobber for following instructions for second and mask operands.1589// This has the downside that the earlyclobber constraint is too coarse and1590// will impose unnecessary restrictions by not allowing the destination to1591// overlap with the first (wide) operand.1592let Uses = [FRM, VL, VTYPE], mayRaiseFPException = true in {1593defm VFWREDOSUM : VWREDO_FV_V<"vfwredosum", 0b110011>;1594defm VFWREDUSUM : VWRED_FV_V<"vfwredusum", 0b110001>;1595}1596} // Constraints = "@earlyclobber $vd", RVVConstraint = NoConstraint, ElementsDependOn = EltDepsVLMask, DestEEW = EEWSEWx21597 1598def : MnemonicAlias<"vfwredsum.vs", "vfwredusum.vs">;1599} // Predicates = [HasVInstructionsAnyF]1600 1601let Predicates = [HasVInstructions] in {1602// Vector Mask-Register Logical Instructions1603let RVVConstraint = NoConstraint, DestEEW = EEW1 in {1604defm VMAND_M : VMALU_MV_Mask<"vmand", 0b011001, "m">;1605defm VMNAND_M : VMALU_MV_Mask<"vmnand", 0b011101, "m">;1606defm VMANDN_M : VMALU_MV_Mask<"vmandn", 0b011000, "m">;1607defm VMXOR_M : VMALU_MV_Mask<"vmxor", 0b011011, "m">;1608defm VMOR_M : VMALU_MV_Mask<"vmor", 0b011010, "m">;1609defm VMNOR_M : VMALU_MV_Mask<"vmnor", 0b011110, "m">;1610defm VMORN_M : VMALU_MV_Mask<"vmorn", 0b011100, "m">;1611defm VMXNOR_M : VMALU_MV_Mask<"vmxnor", 0b011111, "m">;1612}1613 1614def : InstAlias<"vmmv.m $vd, $vs",1615 (VMAND_MM VR:$vd, VR:$vs, VR:$vs)>;1616def : InstAlias<"vmclr.m $vd",1617 (VMXOR_MM VR:$vd, VR:$vd, VR:$vd)>;1618def : InstAlias<"vmset.m $vd",1619 (VMXNOR_MM VR:$vd, VR:$vd, VR:$vd)>;1620def : InstAlias<"vmnot.m $vd, $vs",1621 (VMNAND_MM VR:$vd, VR:$vs, VR:$vs)>;1622 1623def : MnemonicAlias<"vmandnot.mm", "vmandn.mm">;1624def : MnemonicAlias<"vmornot.mm", "vmorn.mm">;1625 1626let hasSideEffects = 0, mayLoad = 0, mayStore = 0,1627 RVVConstraint = NoConstraint, ElementsDependOn = EltDepsVLMask in {1628 1629// Vector mask population count vcpop1630def VCPOP_M : RVInstV<0b010000, 0b10000, OPMVV, (outs GPR:$vd),1631 (ins VR:$vs2, VMaskOp:$vm),1632 "vcpop.m", "$vd, $vs2$vm">,1633 SchedUnaryMC<"WriteVMPopV", "ReadVMPopV">;1634 1635// vfirst find-first-set mask bit1636def VFIRST_M : RVInstV<0b010000, 0b10001, OPMVV, (outs GPR:$vd),1637 (ins VR:$vs2, VMaskOp:$vm),1638 "vfirst.m", "$vd, $vs2$vm">,1639 SchedUnaryMC<"WriteVMFFSV", "ReadVMFFSV">;1640 1641} // hasSideEffects = 0, mayLoad = 0, mayStore = 0, RVVConstraint = NoConstraint, ElementsDependOn = EltDepsVLMask1642 1643def : MnemonicAlias<"vpopc.m", "vcpop.m">;1644 1645let Constraints = "@earlyclobber $vd", RVVConstraint = Iota, ElementsDependOn = EltDepsMask in {1646 1647let DestEEW = EEW1 in {1648// vmsbf.m set-before-first mask bit1649defm VMSBF_M : VMSFS_MV_V<"vmsbf.m", 0b010100, 0b00001>;1650// vmsif.m set-including-first mask bit1651defm VMSIF_M : VMSFS_MV_V<"vmsif.m", 0b010100, 0b00011>;1652// vmsof.m set-only-first mask bit1653defm VMSOF_M : VMSFS_MV_V<"vmsof.m", 0b010100, 0b00010>;1654} // DestEEW = EEW11655// Vector Iota Instruction1656defm VIOTA_M : VIOTA_MV_V<"viota.m", 0b010100, 0b10000>;1657 1658} // Constraints = "@earlyclobber $vd", RVVConstraint = Iota, ElementsDependOn = EltDepsMask1659 1660// Vector Element Index Instruction1661let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {1662 1663let vs2 = 0 in1664def VID_V : RVInstV<0b010100, 0b10001, OPMVV, (outs VR:$vd),1665 (ins VMaskOp:$vm), "vid.v", "$vd$vm">,1666 SchedNullaryMC<"WriteVIdxV">;1667 1668// Integer Scalar Move Instructions1669let vm = 1, RVVConstraint = NoConstraint in {1670def VMV_X_S : RVInstV<0b010000, 0b00000, OPMVV, (outs GPR:$vd),1671 (ins VR:$vs2), "vmv.x.s", "$vd, $vs2">,1672 Sched<[WriteVMovXS, ReadVMovXS]>;1673let Constraints = "$vd = $vd_wb" in1674def VMV_S_X : RVInstV2<0b010000, 0b00000, OPMVX, (outs VR:$vd_wb),1675 (ins VR:$vd, GPR:$rs1), "vmv.s.x", "$vd, $rs1">,1676 Sched<[WriteVMovSX, ReadVMovSX_V, ReadVMovSX_X]>;1677}1678 1679} // hasSideEffects = 0, mayLoad = 0, mayStore = 01680 1681} // Predicates = [HasVInstructions]1682 1683let Predicates = [HasVInstructionsAnyF] in {1684 1685let hasSideEffects = 0, mayLoad = 0, mayStore = 0, vm = 1,1686 RVVConstraint = NoConstraint in {1687// Floating-Point Scalar Move Instructions1688def VFMV_F_S : RVInstV<0b010000, 0b00000, OPFVV, (outs FPR32:$vd),1689 (ins VR:$vs2), "vfmv.f.s", "$vd, $vs2">,1690 Sched<[WriteVMovFS, ReadVMovFS]>;1691let Constraints = "$vd = $vd_wb" in1692def VFMV_S_F : RVInstV2<0b010000, 0b00000, OPFVF, (outs VR:$vd_wb),1693 (ins VR:$vd, FPR32:$rs1), "vfmv.s.f", "$vd, $rs1">,1694 Sched<[WriteVMovSF, ReadVMovSF_V, ReadVMovSF_F]>;1695 1696} // hasSideEffects = 0, mayLoad = 0, mayStore = 0, vm = 11697 1698} // Predicates = [HasVInstructionsAnyF]1699 1700let Predicates = [HasVInstructions] in {1701// Vector Slide Instructions1702let Constraints = "@earlyclobber $vd", RVVConstraint = SlideUp in {1703defm VSLIDEUP_V : VSLD_IV_X_I<"vslideup", 0b001110, /*slidesUp=*/true>;1704defm VSLIDE1UP_V : VSLD1_MV_X<"vslide1up", 0b001110>;1705} // Constraints = "@earlyclobber $vd", RVVConstraint = SlideUp1706let ReadsPastVL = 1 in1707defm VSLIDEDOWN_V : VSLD_IV_X_I<"vslidedown", 0b001111, /*slidesUp=*/false>;1708let ElementsDependOn = EltDepsVL, ReadsPastVL = 1 in1709defm VSLIDE1DOWN_V : VSLD1_MV_X<"vslide1down", 0b001111>;1710} // Predicates = [HasVInstructions]1711 1712let Predicates = [HasVInstructionsAnyF] in {1713let Constraints = "@earlyclobber $vd", RVVConstraint = SlideUp in {1714defm VFSLIDE1UP_V : VSLD1_FV_F<"vfslide1up", 0b001110>;1715} // Constraints = "@earlyclobber $vd", RVVConstraint = SlideUp1716let ElementsDependOn = EltDepsVL, ReadsPastVL = 1 in1717defm VFSLIDE1DOWN_V : VSLD1_FV_F<"vfslide1down", 0b001111>;1718} // Predicates = [HasVInstructionsAnyF]1719 1720let Predicates = [HasVInstructions] in {1721// Vector Register Gather Instruction1722let Constraints = "@earlyclobber $vd", RVVConstraint = Vrgather, ReadsPastVL = 1 in {1723defm VRGATHER_V : VGTR_IV_V_X_I<"vrgather", 0b001100>;1724def VRGATHEREI16_VV : VALUVV<0b001110, OPIVV, "vrgatherei16.vv">,1725 SchedBinaryMC<"WriteVRGatherEI16VV",1726 "ReadVRGatherEI16VV_data",1727 "ReadVRGatherEI16VV_index">;1728} // Constraints = "@earlyclobber $vd", RVVConstraint = Vrgather, ReadsPastVL = 11729 1730// Vector Compress Instruction1731let Constraints = "@earlyclobber $vd", RVVConstraint = Vcompress, ElementsDependOn = EltDepsVLMask in {1732defm VCOMPRESS_V : VCPR_MV_Mask<"vcompress", 0b010111>;1733} // Constraints = "@earlyclobber $vd", RVVConstraint = Vcompress, ElementsDependOn = EltDepsVLMask1734 1735let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isMoveReg = 1,1736 RVVConstraint = NoConstraint in {1737// A future extension may relax the vector register alignment restrictions.1738foreach n = [1, 2, 4, 8] in {1739 defvar vrc = !cast<VReg>(!if(!eq(n, 1), "VR", "VRM"#n));1740 def VMV#n#R_V : RVInstV<0b100111, !add(n, -1), OPIVI, (outs vrc:$vd),1741 (ins vrc:$vs2), "vmv" # n # "r.v", "$vd, $vs2">,1742 VMVRSched<n> {1743 let Uses = [VTYPE];1744 let vm = 1;1745 }1746}1747} // hasSideEffects = 0, mayLoad = 0, mayStore = 01748} // Predicates = [HasVInstructions]1749 1750let Predicates = [HasVInstructions] in {1751 foreach nf=2-8 in {1752 foreach eew = [8, 16, 32] in {1753 defvar w = !cast<RISCVWidth>("LSWidth"#eew);1754 1755 def VLSEG#nf#E#eew#_V :1756 VUnitStrideSegmentLoad<!add(nf, -1), w, "vlseg"#nf#"e"#eew#".v">,1757 VLSEGSchedMC<nf, eew>;1758 def VLSEG#nf#E#eew#FF_V :1759 VUnitStrideSegmentLoadFF<!add(nf, -1), w, "vlseg"#nf#"e"#eew#"ff.v">,1760 VLSEGFFSchedMC<nf, eew>;1761 def VSSEG#nf#E#eew#_V :1762 VUnitStrideSegmentStore<!add(nf, -1), w, "vsseg"#nf#"e"#eew#".v">,1763 VSSEGSchedMC<nf, eew>;1764 // Vector Strided Instructions1765 def VLSSEG#nf#E#eew#_V :1766 VStridedSegmentLoad<!add(nf, -1), w, "vlsseg"#nf#"e"#eew#".v">,1767 VLSSEGSchedMC<nf, eew>;1768 def VSSSEG#nf#E#eew#_V :1769 VStridedSegmentStore<!add(nf, -1), w, "vssseg"#nf#"e"#eew#".v">,1770 VSSSEGSchedMC<nf, eew>;1771 1772 // Vector Indexed Instructions1773 def VLUXSEG#nf#EI#eew#_V :1774 VIndexedSegmentLoad<!add(nf, -1), MOPLDIndexedUnord, w,1775 "vluxseg"#nf#"ei"#eew#".v">,1776 RISCVVXMemOpMC<!logtwo(eew), Ordered=false, Store=false, N=nf>,1777 VLXSEGSchedMC<nf, eew, isOrdered=0>;1778 def VLOXSEG#nf#EI#eew#_V :1779 VIndexedSegmentLoad<!add(nf, -1), MOPLDIndexedOrder, w,1780 "vloxseg"#nf#"ei"#eew#".v">,1781 RISCVVXMemOpMC<!logtwo(eew), Ordered=true, Store=false, N=nf>,1782 VLXSEGSchedMC<nf, eew, isOrdered=1>;1783 def VSUXSEG#nf#EI#eew#_V :1784 VIndexedSegmentStore<!add(nf, -1), MOPSTIndexedUnord, w,1785 "vsuxseg"#nf#"ei"#eew#".v">,1786 RISCVVXMemOpMC<!logtwo(eew), Ordered=false, Store=true, N=nf>,1787 VSXSEGSchedMC<nf, eew, isOrdered=0>;1788 def VSOXSEG#nf#EI#eew#_V :1789 VIndexedSegmentStore<!add(nf, -1), MOPSTIndexedOrder, w,1790 "vsoxseg"#nf#"ei"#eew#".v">,1791 RISCVVXMemOpMC<!logtwo(eew), Ordered=true, Store=true, N=nf>,1792 VSXSEGSchedMC<nf, eew, isOrdered=1>;1793 }1794 }1795} // Predicates = [HasVInstructions]1796 1797let Predicates = [HasVInstructionsI64] in {1798 foreach nf=2-8 in {1799 // Vector Unit-strided Segment Instructions1800 def VLSEG#nf#E64_V :1801 VUnitStrideSegmentLoad<!add(nf, -1), LSWidth64, "vlseg"#nf#"e64.v">,1802 VLSEGSchedMC<nf, 64>;1803 def VLSEG#nf#E64FF_V :1804 VUnitStrideSegmentLoadFF<!add(nf, -1), LSWidth64, "vlseg"#nf#"e64ff.v">,1805 VLSEGFFSchedMC<nf, 64>;1806 def VSSEG#nf#E64_V :1807 VUnitStrideSegmentStore<!add(nf, -1), LSWidth64, "vsseg"#nf#"e64.v">,1808 VSSEGSchedMC<nf, 64>;1809 1810 // Vector Strided Segment Instructions1811 def VLSSEG#nf#E64_V :1812 VStridedSegmentLoad<!add(nf, -1), LSWidth64, "vlsseg"#nf#"e64.v">,1813 VLSSEGSchedMC<nf, 64>;1814 def VSSSEG#nf#E64_V :1815 VStridedSegmentStore<!add(nf, -1), LSWidth64, "vssseg"#nf#"e64.v">,1816 VSSSEGSchedMC<nf, 64>;1817 }1818} // Predicates = [HasVInstructionsI64]1819let Predicates = [HasVInstructionsI64, IsRV64] in {1820 foreach nf = 2 - 8 in {1821 // Vector Indexed Segment Instructions1822 def VLUXSEG #nf #EI64_V1823 : VIndexedSegmentLoad<!add(nf, -1), MOPLDIndexedUnord, LSWidth64,1824 "vluxseg" #nf #"ei64.v">,1825 VLXSEGSchedMC<nf, 64, isOrdered=0>;1826 def VLOXSEG #nf #EI64_V1827 : VIndexedSegmentLoad<!add(nf, -1), MOPLDIndexedOrder, LSWidth64,1828 "vloxseg" #nf #"ei64.v">,1829 VLXSEGSchedMC<nf, 64, isOrdered=1>;1830 def VSUXSEG #nf #EI64_V1831 : VIndexedSegmentStore<!add(nf, -1), MOPSTIndexedUnord, LSWidth64,1832 "vsuxseg" #nf #"ei64.v">,1833 VSXSEGSchedMC<nf, 64, isOrdered=0>;1834 def VSOXSEG #nf #EI64_V1835 : VIndexedSegmentStore<!add(nf, -1), MOPSTIndexedOrder, LSWidth64,1836 "vsoxseg" #nf #"ei64.v">,1837 VSXSEGSchedMC<nf, 64, isOrdered=1>;1838 }1839} // Predicates = [HasVInstructionsI64, IsRV64]1840 1841include "RISCVInstrInfoVPseudos.td"1842include "RISCVInstrInfoZvfbf.td"1843