brintos

brintos / llvm-project-archived public Read only

0
0
Text · 79.2 KiB · f46455a Raw
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