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