1658 lines · plain
1//==- RISCVSchedSiFive7.td - SiFive7 Scheduling Definitions --*- 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//===----------------------------------------------------------------------===//10 11/// c is true if mx has the worst case behavior compared to LMULs in MxList.12/// On the SiFive7, the worst case LMUL is the Largest LMUL13/// and the worst case sew is the smallest SEW for that LMUL.14class SiFive7IsWorstCaseMX<string mx, list<string> MxList> {15 defvar LLMUL = LargestLMUL<MxList>.r;16 bit c = !eq(mx, LLMUL);17}18 19/// c is true if mx and sew have the worst case behavior compared to LMULs in20/// MxList. On the SiFive7, the worst case LMUL is the Largest LMUL21/// and the worst case sew is the smallest SEW for that LMUL.22class SiFive7IsWorstCaseMXSEW<string mx, int sew, list<string> MxList,23 bit isF = 0> {24 defvar LLMUL = LargestLMUL<MxList>.r;25 defvar SSEW = SmallestSEW<mx, isF>.r;26 bit c = !and(!eq(mx, LLMUL), !eq(sew, SSEW));27}28 29/// Number of DLEN parts = (LMUL * VLEN) / DLEN.30/// Since DLEN = VLEN / 2, Num DLEN parts = 2 * LMUL.31class SiFive7GetCyclesDefault<string mx> {32 int c = !cond(33 !eq(mx, "M1") : 2,34 !eq(mx, "M2") : 4,35 !eq(mx, "M4") : 8,36 !eq(mx, "M8") : 16,37 !eq(mx, "MF2") : 1,38 !eq(mx, "MF4") : 1,39 !eq(mx, "MF8") : 140 );41}42 43class SiFive7GetCyclesNarrowing<string mx> {44 int c = !cond(45 !eq(mx, "M1") : 4,46 !eq(mx, "M2") : 8,47 !eq(mx, "M4") : 16,48 !eq(mx, "MF2") : 2,49 !eq(mx, "MF4") : 1,50 !eq(mx, "MF8") : 151 );52}53 54class SiFive7GetCyclesVMask<string mx> {55 int c = !cond(56 !eq(mx, "M1") : 1,57 !eq(mx, "M2") : 1,58 !eq(mx, "M4") : 1,59 !eq(mx, "M8") : 2,60 !eq(mx, "MF2") : 1,61 !eq(mx, "MF4") : 1,62 !eq(mx, "MF8") : 163 );64}65 66/// VLDM and VSTM can't read/write more than 2 DLENs of data.67/// 2 DLENs when LMUL=8. 1 DLEN for all other DLENs68class SiFive7GetMaskLoadStoreCycles<string mx> {69 int c = !cond(70 !eq(mx, "M8") : 2,71 true : 172 );73}74 75// Cycles for nf=2 segmented loads and stores are calculated using the76// formula (2 * VLEN * LMUL) / DLEN = 4 * LMUL77class SiFive7GetCyclesSegmentedSeg2<string mx> {78 int c = !cond(79 !eq(mx, "M1") : 4,80 !eq(mx, "M2") : 8,81 !eq(mx, "M4") : 16,82 !eq(mx, "M8") : 32,83 !eq(mx, "MF2") : 2,84 !eq(mx, "MF4") : 1,85 !eq(mx, "MF8") : 186 );87}88 89// Cycles for segmented loads and stores are calculated using the90// formula vl * ceil((SEW * nf) / DLEN), where SEW * nf is the segment size.91class SiFive7GetCyclesSegmented<string mx, int sew, int nf, int VLEN> {92 defvar DLEN = !div(VLEN, 2);93 // (VLEN * LMUL) / SEW94 defvar VLUpperBound = !cond(95 !eq(mx, "M1") : !div(VLEN, sew),96 !eq(mx, "M2") : !div(!mul(VLEN, 2), sew),97 !eq(mx, "M4") : !div(!mul(VLEN, 4), sew),98 !eq(mx, "M8") : !div(!mul(VLEN, 8), sew),99 !eq(mx, "MF2") : !div(!div(VLEN, 2), sew),100 !eq(mx, "MF4") : !div(!div(VLEN, 4), sew),101 !eq(mx, "MF8") : !div(!div(VLEN, 8), sew),102 );103 // We can calculate ceil(a/b) using (a + b - 1) / b.104 defvar a = !mul(sew, nf);105 defvar b = DLEN;106 int c = !mul(VLUpperBound, !div(!sub(!add(a, b), 1), b));107}108 109class SiFive7GetCyclesOnePerElement<string mx, int sew, int VLEN> {110 // c = ceil(VLEN / SEW) * LMUL111 // Note: c >= 1 since the smallest VLEN is 512 / 8 = 8, and the112 // largest division performed on VLEN is in MF8 case with division113 // by 8. Therefore, there is no need to ceil the result.114 int numElements = !div(VLEN, sew);115 int c = !cond(116 !eq(mx, "M1") : numElements,117 !eq(mx, "M2") : !mul(numElements, 2),118 !eq(mx, "M4") : !mul(numElements, 4),119 !eq(mx, "M8") : !mul(numElements, 8),120 !eq(mx, "MF2") : !div(numElements, 2),121 !eq(mx, "MF4") : !div(numElements, 4),122 !eq(mx, "MF8") : !div(numElements, 8)123 );124}125 126class SiFive7GetDivOrSqrtFactor<int sew> {127 int c = !cond(128 // TODO: Add SchedSEWSetFP upstream and remove the SEW=8 case.129 !eq(sew, 8) : 15,130 !eq(sew, 16) : 15,131 !eq(sew, 32) : 28,132 !eq(sew, 64) : 57133 );134}135 136/// Cycles for reductions take approximately VL*SEW/DLEN + 5(4 + log(DLEN/SEW))137/// cycles.138class SiFive7GetReductionCycles<string mx, int sew, int VLEN> {139 // VLUpperBound*SEW/DLEN is equivalent to 2*LMUL since140 // VLUpperBound=(VLEN*LMUL)/SEW.141 defvar DLEN = !div(VLEN, 2);142 defvar TwoTimesLMUL = !cond(143 !eq(mx, "M1") : 2,144 !eq(mx, "M2") : 4,145 !eq(mx, "M4") : 8,146 !eq(mx, "M8") : 16,147 !eq(mx, "MF2") : 1,148 !eq(mx, "MF4") : 1,149 !eq(mx, "MF8") : 1150 );151 int c = !add(152 TwoTimesLMUL,153 !mul(5, !add(4, !logtwo(!div(DLEN, sew))))154 );155}156 157/// Cycles for ordered reductions take approximately 6*VL cycles158class SiFive7GetOrderedReductionCycles<string mx, int sew, int VLEN> {159 // (VLEN * LMUL) / SEW160 defvar VLUpperBound = !cond(161 !eq(mx, "M1") : !div(VLEN, sew),162 !eq(mx, "M2") : !div(!mul(VLEN, 2), sew),163 !eq(mx, "M4") : !div(!mul(VLEN, 4), sew),164 !eq(mx, "M8") : !div(!mul(VLEN, 8), sew),165 !eq(mx, "MF2") : !div(!div(VLEN, 2), sew),166 !eq(mx, "MF4") : !div(!div(VLEN, 4), sew),167 !eq(mx, "MF8") : !div(!div(VLEN, 8), sew),168 );169 int c = !mul(6, VLUpperBound);170}171 172class isSingleDLEN<string mx> {173 bit c = !or(!eq(mx, "MF2"), !or(!eq(mx, "MF4"), !eq(mx, "MF8")));174}175 176class SiFive7GetCyclesVRGatherVV<string mx, int sew, int VLEN,177 bit hasFastGather> {178 // if (hasFastGather && isSingleDLEN(mx))179 // c = 1;180 // else if (hasFastGather && (log2(SEW/8) + log2(LMUL) <= log2(DLEN / 32))181 // c = LMUL * 2 * ceil(vl * SEW / DLEN);182 // else183 // c = vl;184 185 defvar y = !logtwo(!div(sew, 8));186 defvar x = !cond(187 !eq(mx, "M1") : y,188 !eq(mx, "M2") : !add(y, 1),189 !eq(mx, "M4") : !add(y, 2),190 !eq(mx, "M8") : !add(y, 3),191 // Give isSingleDLEN(mx) cases a garbage value to avoid build failures,192 // even though x will go unused.193 true : 1194 );195 // LMUL * 2 * ceil(vl * SEW / DLEN) = LMUL * 2 * ceil(2 * LMUL)196 defvar z = !cond(197 !eq(mx, "M1") : 4,198 !eq(mx, "M2") : 16,199 !eq(mx, "M4") : 64,200 !eq(mx, "M8") : 256,201 // Give isSingleDLEN(mx) cases a garbage value to avoid build failures,202 // even though z will go unused.203 true : 1204 );205 defvar VLUpperBound = SiFive7GetCyclesOnePerElement<mx, sew, VLEN>.c;206 bit IsSingleDLEN = isSingleDLEN<mx>.c;207 208 int c = !cond(209 !and(hasFastGather, IsSingleDLEN) : 1,210 !and(hasFastGather, !le(x, !logtwo(!div(VLEN, 64)))) : z,211 true: VLUpperBound212 );213}214 215class SiFive7GetCyclesVCompress<string mx, int sew, int VLEN,216 bit hasFastGather> {217 218 // if (hasFastGather && isSingleDLEN(mx))219 // c = 1220 // else221 // c = vl222 defvar VLUpperBound = SiFive7GetCyclesOnePerElement<mx, sew, VLEN>.c;223 bit IsSingleDLEN = isSingleDLEN<mx>.c;224 225 int c = !if(!and(hasFastGather, IsSingleDLEN),226 1,227 VLUpperBound);228}229 230class SiFive7GetSiFiveVFNRClipCycles<string mx, int VLEN> {231 int latency = !cond(232 !eq(mx, "MF8"): 7,233 !eq(mx, "MF4"): 8,234 !eq(mx, "MF2"): 10,235 !eq(mx, "M1"): 13,236 !eq(mx, "M2"): 19,237 );238 239 defvar DLEN = !div(VLEN, 2);240 int occupancy = SiFive7GetCyclesOnePerElement<mx, sew=!div(DLEN, 4),241 VLEN=VLEN>.c;242}243 244class SiFive7FPLatencies {245 int BasicFP16ALU;246 int BasicFP32ALU;247 int BasicFP64ALU;248}249 250class SiFive7AnyToGPRBypass<SchedRead read, int cycles = 2>251 : ReadAdvance<read, cycles, [WriteIALU, WriteIALU32,252 WriteShiftImm, WriteShiftImm32,253 WriteShiftReg, WriteShiftReg32,254 WriteSHXADD, WriteSHXADD32,255 WriteRotateImm, WriteRotateImm32,256 WriteRotateReg, WriteRotateReg32,257 WriteSingleBit, WriteSingleBitImm,258 WriteBEXT, WriteBEXTI,259 WriteCLZ, WriteCLZ32, WriteCTZ, WriteCTZ32,260 WriteCPOP, WriteCPOP32,261 WriteREV8, WriteORCB, WriteIMinMax, WriteSFB,262 WriteIMul, WriteIMul32,263 WriteIDiv, WriteIDiv32,264 WriteIRem, WriteIRem32,265 WriteLDB, WriteLDH, WriteLDW, WriteLDD]>;266 267// The SiFive7 microarchitecture has three kinds of pipelines: A, B, V.268// Pipe A can handle memory, integer alu and vector operations.269// Pipe B can handle integer alu, control flow, integer multiply and divide,270// and floating point computation.271// The V pipeline is modeled by the VCQ, VA, VL, and VS resources. There can272// be one or two VA (Vector Arithmetic).273multiclass SiFive7ProcResources<bit dualVALU = false> {274 let BufferSize = 0 in {275 def PipeA : ProcResource<1>;276 def PipeB : ProcResource<1>;277 278 def IDiv : ProcResource<1>; // Int Division279 def FDiv : ProcResource<1>; // FP Division/Sqrt280 281 // Arithmetic sequencer(s)282 if dualVALU then {283 // VA1 can handle any vector airthmetic instruction.284 def VA1 : ProcResource<1>;285 // VA2 generally can only handle simple vector arithmetic.286 def VA2 : ProcResource<1>;287 } else {288 def VA : ProcResource<1>;289 }290 291 def VL : ProcResource<1>; // Load sequencer292 def VS : ProcResource<1>; // Store sequencer293 // The VCQ accepts instructions from the the A Pipe and holds them until the294 // vector unit is ready to dequeue them. The unit dequeues up to one instruction295 // per cycle, in order, as soon as the sequencer for that type of instruction is296 // available. This resource is meant to be used for 1 cycle by all vector297 // instructions, to model that only one vector instruction may be dequeued at a298 // time. The actual dequeueing into the sequencer is modeled by the VA, VL, and299 // VS sequencer resources below. Each of them will only accept a single300 // instruction at a time and remain busy for the number of cycles associated301 // with that instruction.302 def VCQ : ProcResource<1>; // Vector Command Queue303 }304 305 def PipeAB : ProcResGroup<[!cast<ProcResource>(NAME#"PipeA"),306 !cast<ProcResource>(NAME#"PipeB")]>;307 308 if dualVALU then309 def VA1OrVA2 : ProcResGroup<[!cast<ProcResource>(NAME#"VA1"),310 !cast<ProcResource>(NAME#"VA2")]>;311}312 313multiclass SiFive7WriteResBase<int VLEN,314 ProcResourceKind PipeA, ProcResourceKind PipeB, ProcResourceKind PipeAB,315 ProcResourceKind IDiv, ProcResourceKind FDiv,316 ProcResourceKind VA1, ProcResourceKind VA1OrVA2,317 ProcResourceKind VL, ProcResourceKind VS,318 ProcResourceKind VCQ,319 SiFive7FPLatencies fpLatencies,320 bit hasFastGather = false> {321 322 // Branching323 let Latency = 3 in {324 def : WriteRes<WriteJmp, [PipeB]>;325 def : WriteRes<WriteJal, [PipeB]>;326 def : WriteRes<WriteJalr, [PipeB]>;327 }328 329 //Short forward branch330 def : WriteRes<WriteSFB, [PipeA, PipeB]> {331 let Latency = 3;332 let NumMicroOps = 2;333 }334 335 // Integer arithmetic and logic336 let Latency = 3 in {337 def : WriteRes<WriteIALU, [PipeAB]>;338 def : WriteRes<WriteIALU32, [PipeAB]>;339 def : WriteRes<WriteShiftImm, [PipeAB]>;340 def : WriteRes<WriteShiftImm32, [PipeAB]>;341 def : WriteRes<WriteShiftReg, [PipeAB]>;342 def : WriteRes<WriteShiftReg32, [PipeAB]>;343 }344 345 // Integer multiplication346 let Latency = 3 in {347 def : WriteRes<WriteIMul, [PipeB]>;348 def : WriteRes<WriteIMul32, [PipeB]>;349 }350 351 // Integer division352 def : WriteRes<WriteIDiv, [PipeB, IDiv]> {353 let Latency = 66;354 let ReleaseAtCycles = [1, 65];355 }356 def : WriteRes<WriteIDiv32, [PipeB, IDiv]> {357 let Latency = 34;358 let ReleaseAtCycles = [1, 33];359 }360 361 // Integer remainder362 def : WriteRes<WriteIRem, [PipeB, IDiv]> {363 let Latency = 66;364 let ReleaseAtCycles = [1, 65];365 }366 def : WriteRes<WriteIRem32, [PipeB, IDiv]> {367 let Latency = 34;368 let ReleaseAtCycles = [1, 33];369 }370 371 // Bitmanip372 let Latency = 3 in {373 // Rotates are in the late-B ALU.374 def : WriteRes<WriteRotateImm, [PipeB]>;375 def : WriteRes<WriteRotateImm32, [PipeB]>;376 def : WriteRes<WriteRotateReg, [PipeB]>;377 def : WriteRes<WriteRotateReg32, [PipeB]>;378 379 // clz[w]/ctz[w] are in the late-B ALU.380 def : WriteRes<WriteCLZ, [PipeB]>;381 def : WriteRes<WriteCLZ32, [PipeB]>;382 def : WriteRes<WriteCTZ, [PipeB]>;383 def : WriteRes<WriteCTZ32, [PipeB]>;384 385 // cpop[w] look exactly like multiply.386 def : WriteRes<WriteCPOP, [PipeB]>;387 def : WriteRes<WriteCPOP32, [PipeB]>;388 389 // orc.b is in the late-B ALU.390 def : WriteRes<WriteORCB, [PipeB]>;391 392 // min/max are in the late-B ALU393 def : WriteRes<WriteIMinMax, [PipeB]>;394 395 // rev8 is in the late-A and late-B ALUs.396 def : WriteRes<WriteREV8, [PipeAB]>;397 398 // shNadd[.uw] is on the early-B and late-B ALUs.399 def : WriteRes<WriteSHXADD, [PipeB]>;400 def : WriteRes<WriteSHXADD32, [PipeB]>;401 }402 403 // Single-bit instructions404 // BEXT[I] instruction is available on all ALUs and the other instructions405 // are only available on the B pipe.406 let Latency = 3 in {407 def : WriteRes<WriteSingleBit, [PipeB]>;408 def : WriteRes<WriteSingleBitImm, [PipeB]>;409 def : WriteRes<WriteBEXT, [PipeAB]>;410 def : WriteRes<WriteBEXTI, [PipeAB]>;411 }412 413 // Memory414 def : WriteRes<WriteSTB, [PipeA]>;415 def : WriteRes<WriteSTH, [PipeA]>;416 def : WriteRes<WriteSTW, [PipeA]>;417 def : WriteRes<WriteSTD, [PipeA]>;418 def : WriteRes<WriteFST16, [PipeA]>;419 def : WriteRes<WriteFST32, [PipeA]>;420 def : WriteRes<WriteFST64, [PipeA]>;421 422 let Latency = 3 in {423 def : WriteRes<WriteLDB, [PipeA]>;424 def : WriteRes<WriteLDH, [PipeA]>;425 def : WriteRes<WriteLDW, [PipeA]>;426 def : WriteRes<WriteLDD, [PipeA]>;427 428 def : WriteRes<WriteFLD16, [PipeA]>;429 def : WriteRes<WriteFLD32, [PipeA]>;430 def : WriteRes<WriteFLD64, [PipeA]>;431 }432 433 // Atomic memory434 def : WriteRes<WriteAtomicSTW, [PipeA]>;435 def : WriteRes<WriteAtomicSTD, [PipeA]>;436 437 let Latency = 3 in {438 def : WriteRes<WriteAtomicW, [PipeA]>;439 def : WriteRes<WriteAtomicD, [PipeA]>;440 def : WriteRes<WriteAtomicLDW, [PipeA]>;441 def : WriteRes<WriteAtomicLDD, [PipeA]>;442 }443 444 // Half precision.445 let Latency = fpLatencies.BasicFP16ALU in {446 def : WriteRes<WriteFAdd16, [PipeB]>;447 def : WriteRes<WriteFMul16, [PipeB]>;448 def : WriteRes<WriteFMA16, [PipeB]>;449 }450 let Latency = 3 in {451 def : WriteRes<WriteFSGNJ16, [PipeB]>;452 def : WriteRes<WriteFMinMax16, [PipeB]>;453 }454 455 let Latency = 14, ReleaseAtCycles = [1, 13] in {456 def : WriteRes<WriteFDiv16, [PipeB, FDiv]>;457 def : WriteRes<WriteFSqrt16, [PipeB, FDiv]>;458 }459 460 // Single precision.461 let Latency = fpLatencies.BasicFP32ALU in {462 def : WriteRes<WriteFAdd32, [PipeB]>;463 def : WriteRes<WriteFMul32, [PipeB]>;464 def : WriteRes<WriteFMA32, [PipeB]>;465 }466 let Latency = 3 in {467 def : WriteRes<WriteFSGNJ32, [PipeB]>;468 def : WriteRes<WriteFMinMax32, [PipeB]>;469 }470 471 let Latency = 27, ReleaseAtCycles = [1, 26] in {472 def : WriteRes<WriteFDiv32, [PipeB, FDiv]>;473 def : WriteRes<WriteFSqrt32, [PipeB, FDiv]>;474 }475 476 // Double precision477 let Latency = fpLatencies.BasicFP64ALU in {478 def : WriteRes<WriteFAdd64, [PipeB]>;479 def : WriteRes<WriteFMul64, [PipeB]>;480 def : WriteRes<WriteFMA64, [PipeB]>;481 }482 let Latency = 3 in {483 def : WriteRes<WriteFSGNJ64, [PipeB]>;484 def : WriteRes<WriteFMinMax64, [PipeB]>;485 }486 487 let Latency = 56, ReleaseAtCycles = [1, 55] in {488 def : WriteRes<WriteFDiv64, [PipeB, FDiv]>;489 def : WriteRes<WriteFSqrt64, [PipeB, FDiv]>;490 }491 492 // Conversions493 let Latency = 3 in {494 def : WriteRes<WriteFCvtI32ToF16, [PipeB]>;495 def : WriteRes<WriteFCvtI32ToF32, [PipeB]>;496 def : WriteRes<WriteFCvtI32ToF64, [PipeB]>;497 def : WriteRes<WriteFCvtI64ToF16, [PipeB]>;498 def : WriteRes<WriteFCvtI64ToF32, [PipeB]>;499 def : WriteRes<WriteFCvtI64ToF64, [PipeB]>;500 def : WriteRes<WriteFCvtF16ToI32, [PipeB]>;501 def : WriteRes<WriteFCvtF16ToI64, [PipeB]>;502 def : WriteRes<WriteFCvtF16ToF32, [PipeB]>;503 def : WriteRes<WriteFCvtF16ToF64, [PipeB]>;504 def : WriteRes<WriteFCvtF32ToI32, [PipeB]>;505 def : WriteRes<WriteFCvtF32ToI64, [PipeB]>;506 def : WriteRes<WriteFCvtF32ToF16, [PipeB]>;507 def : WriteRes<WriteFCvtF32ToF64, [PipeB]>;508 def : WriteRes<WriteFCvtF64ToI32, [PipeB]>;509 def : WriteRes<WriteFCvtF64ToI64, [PipeB]>;510 def : WriteRes<WriteFCvtF64ToF16, [PipeB]>;511 def : WriteRes<WriteFCvtF64ToF32, [PipeB]>;512 513 def : WriteRes<WriteFClass16, [PipeB]>;514 def : WriteRes<WriteFClass32, [PipeB]>;515 def : WriteRes<WriteFClass64, [PipeB]>;516 def : WriteRes<WriteFCmp16, [PipeB]>;517 def : WriteRes<WriteFCmp32, [PipeB]>;518 def : WriteRes<WriteFCmp64, [PipeB]>;519 def : WriteRes<WriteFMovI16ToF16, [PipeB]>;520 def : WriteRes<WriteFMovF16ToI16, [PipeB]>;521 def : WriteRes<WriteFMovI32ToF32, [PipeB]>;522 def : WriteRes<WriteFMovF32ToI32, [PipeB]>;523 def : WriteRes<WriteFMovI64ToF64, [PipeB]>;524 def : WriteRes<WriteFMovF64ToI64, [PipeB]>;525 }526 527 // 6. Configuration-Setting Instructions528 let Latency = 3 in {529 def : WriteRes<WriteVSETVLI, [PipeA]>;530 def : WriteRes<WriteVSETIVLI, [PipeA]>;531 def : WriteRes<WriteVSETVL, [PipeA]>;532 }533 534 // 7. Vector Loads and Stores535 // Unit-stride loads and stores can operate at the full bandwidth of the memory536 // pipe. The memory pipe is DLEN bits wide on x280.537 foreach mx = SchedMxList in {538 defvar Cycles = SiFive7GetCyclesDefault<mx>.c;539 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxList>.c;540 let Latency = 4, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {541 defm : LMULWriteResMX<"WriteVLDE", [VCQ, VL], mx, IsWorstCase>;542 defm : LMULWriteResMX<"WriteVLDFF", [VCQ, VL], mx, IsWorstCase>;543 }544 let Latency = 1, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in545 defm : LMULWriteResMX<"WriteVSTE", [VCQ, VS], mx, IsWorstCase>;546 }547 548 foreach mx = SchedMxList in {549 defvar Cycles = SiFive7GetMaskLoadStoreCycles<mx>.c;550 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxList>.c;551 let Latency = 4, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in552 defm : LMULWriteResMX<"WriteVLDM", [VCQ, VL], mx, IsWorstCase>;553 let Latency = 1, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in554 defm : LMULWriteResMX<"WriteVSTM", [VCQ, VS], mx, IsWorstCase>;555 }556 557 // Strided loads and stores operate at one element per cycle and should be558 // scheduled accordingly. Indexed loads and stores operate at one element per559 // cycle, and they stall the machine until all addresses have been generated,560 // so they cannot be scheduled. Indexed and strided loads and stores have LMUL561 // specific suffixes, but since SEW is already encoded in the name of the562 // resource, we do not need to use LMULSEWXXX constructors. However, we do563 // use the SEW from the name to determine the number of Cycles.564 565 foreach mx = SchedMxList in {566 defvar VLDSX0Cycles = SiFive7GetCyclesDefault<mx>.c;567 defvar Cycles = SiFive7GetCyclesOnePerElement<mx, 8, VLEN>.c;568 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxList>.c;569 defm : LMULWriteResMXVariant<"WriteVLDS8", VLDSX0Pred,570 // Predicated571 [VCQ, VL], 4, [0, 1], [1, !add(1, VLDSX0Cycles)],572 // Not Predicated573 [VCQ, VL], !add(3, Cycles), [0, 1], [1, !add(1, Cycles)],574 mx, IsWorstCase>;575 let Latency = !add(3, Cycles), AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {576 defm : LMULWriteResMX<"WriteVLDUX8", [VCQ, VL], mx, IsWorstCase>;577 defm : LMULWriteResMX<"WriteVLDOX8", [VCQ, VL], mx, IsWorstCase>;578 }579 let Latency = 1, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {580 defm : LMULWriteResMX<"WriteVSTS8", [VCQ, VS], mx, IsWorstCase>;581 defm : LMULWriteResMX<"WriteVSTUX8", [VCQ, VS], mx, IsWorstCase>;582 defm : LMULWriteResMX<"WriteVSTOX8", [VCQ, VS], mx, IsWorstCase>;583 }584 }585 // TODO: The MxLists need to be filtered by EEW. We only need to support586 // LMUL >= SEW_min/ELEN. Here, the smallest EEW prevents us from having MF8587 // since LMUL >= 16/64.588 foreach mx = ["MF4", "MF2", "M1", "M2", "M4", "M8"] in {589 defvar VLDSX0Cycles = SiFive7GetCyclesDefault<mx>.c;590 defvar Cycles = SiFive7GetCyclesOnePerElement<mx, 16, VLEN>.c;591 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxList>.c;592 defm : LMULWriteResMXVariant<"WriteVLDS16", VLDSX0Pred,593 // Predicated594 [VCQ, VL], 4, [0, 1], [1, !add(1, VLDSX0Cycles)],595 // Not Predicated596 [VCQ, VL], !add(3, Cycles), [0, 1], [1, !add(1, Cycles)],597 mx, IsWorstCase>;598 let Latency = !add(3, Cycles), AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {599 defm : LMULWriteResMX<"WriteVLDUX16", [VCQ, VL], mx, IsWorstCase>;600 defm : LMULWriteResMX<"WriteVLDOX16", [VCQ, VL], mx, IsWorstCase>;601 }602 let Latency = 1, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {603 defm : LMULWriteResMX<"WriteVSTS16", [VCQ, VS], mx, IsWorstCase>;604 defm : LMULWriteResMX<"WriteVSTUX16", [VCQ, VS], mx, IsWorstCase>;605 defm : LMULWriteResMX<"WriteVSTOX16", [VCQ, VS], mx, IsWorstCase>;606 }607 }608 foreach mx = ["MF2", "M1", "M2", "M4", "M8"] in {609 defvar VLDSX0Cycles = SiFive7GetCyclesDefault<mx>.c;610 defvar Cycles = SiFive7GetCyclesOnePerElement<mx, 32, VLEN>.c;611 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxList>.c;612 defm : LMULWriteResMXVariant<"WriteVLDS32", VLDSX0Pred,613 // Predicated614 [VCQ, VL], 4, [0, 1], [1, !add(1, VLDSX0Cycles)],615 // Not Predicated616 [VCQ, VL], !add(3, Cycles), [0, 1], [1, !add(1, Cycles)],617 mx, IsWorstCase>;618 let Latency = !add(3, Cycles), AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {619 defm : LMULWriteResMX<"WriteVLDUX32", [VCQ, VL], mx, IsWorstCase>;620 defm : LMULWriteResMX<"WriteVLDOX32", [VCQ, VL], mx, IsWorstCase>;621 }622 let Latency = 1, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {623 defm : LMULWriteResMX<"WriteVSTS32", [VCQ, VS], mx, IsWorstCase>;624 defm : LMULWriteResMX<"WriteVSTUX32", [VCQ, VS], mx, IsWorstCase>;625 defm : LMULWriteResMX<"WriteVSTOX32", [VCQ, VS], mx, IsWorstCase>;626 }627 }628 foreach mx = ["M1", "M2", "M4", "M8"] in {629 defvar VLDSX0Cycles = SiFive7GetCyclesDefault<mx>.c;630 defvar Cycles = SiFive7GetCyclesOnePerElement<mx, 64, VLEN>.c;631 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxList>.c;632 defm : LMULWriteResMXVariant<"WriteVLDS64", VLDSX0Pred,633 // Predicated634 [VCQ, VL], 4, [0, 1], [1, !add(1, VLDSX0Cycles)],635 // Not Predicated636 [VCQ, VL], !add(3, Cycles), [0, 1], [1, !add(1, Cycles)],637 mx, IsWorstCase>;638 let Latency = !add(3, Cycles), AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {639 defm : LMULWriteResMX<"WriteVLDUX64", [VCQ, VL], mx, IsWorstCase>;640 defm : LMULWriteResMX<"WriteVLDOX64", [VCQ, VL], mx, IsWorstCase>;641 }642 let Latency = 1, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {643 defm : LMULWriteResMX<"WriteVSTS64", [VCQ, VS], mx, IsWorstCase>;644 defm : LMULWriteResMX<"WriteVSTUX64", [VCQ, VS], mx, IsWorstCase>;645 defm : LMULWriteResMX<"WriteVSTOX64", [VCQ, VS], mx, IsWorstCase>;646 }647 }648 649 // VLD*R is LMUL aware650 let Latency = 4, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, 2)] in651 def : WriteRes<WriteVLD1R, [VCQ, VL]>;652 let Latency = 4, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, 4)] in653 def : WriteRes<WriteVLD2R, [VCQ, VL]>;654 let Latency = 4, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, 8)] in655 def : WriteRes<WriteVLD4R, [VCQ, VL]>;656 let Latency = 4, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, 16)] in657 def : WriteRes<WriteVLD8R, [VCQ, VL]>;658 // VST*R is LMUL aware659 let Latency = 1, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, 2)] in660 def : WriteRes<WriteVST1R, [VCQ, VS]>;661 let Latency = 1, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, 4)] in662 def : WriteRes<WriteVST2R, [VCQ, VS]>;663 let Latency = 1, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, 8)] in664 def : WriteRes<WriteVST4R, [VCQ, VS]>;665 let Latency = 1, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, 16)] in666 def : WriteRes<WriteVST8R, [VCQ, VS]>;667 668 // Segmented Loads and Stores669 // Unit-stride segmented loads and stores are effectively converted into strided670 // segment loads and stores. Strided segment loads and stores operate at up to671 // one segment per cycle if the segment fits within one aligned memory beat.672 // Indexed segment loads and stores operate at the same rate as strided ones,673 // but they stall the machine until all addresses have been generated.674 foreach mx = SchedMxList in {675 foreach eew = [8, 16, 32, 64] in {676 defvar Cycles = SiFive7GetCyclesSegmentedSeg2<mx>.c;677 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxList>.c;678 // Does not chain so set latency high679 let Latency = !add(3, Cycles), AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {680 defm : LMULWriteResMX<"WriteVLSEG2e" # eew, [VCQ, VL], mx, IsWorstCase>;681 defm : LMULWriteResMX<"WriteVLSEGFF2e" # eew, [VCQ, VL], mx, IsWorstCase>;682 }683 let Latency = 1, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in684 defm : LMULWriteResMX<"WriteVSSEG2e" # eew, [VCQ, VS], mx, IsWorstCase>;685 foreach nf=3-8 in {686 defvar Cycles = SiFive7GetCyclesSegmented<mx, eew, nf, VLEN>.c;687 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxList>.c;688 // Does not chain so set latency high689 let Latency = !add(3, Cycles), AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {690 defm : LMULWriteResMX<"WriteVLSEG" # nf # "e" # eew, [VCQ, VL], mx, IsWorstCase>;691 defm : LMULWriteResMX<"WriteVLSEGFF" # nf # "e" # eew, [VCQ, VL], mx, IsWorstCase>;692 }693 let Latency = 1, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in694 defm : LMULWriteResMX<"WriteVSSEG" # nf # "e" # eew, [VCQ, VS], mx, IsWorstCase>;695 }696 }697 }698 foreach mx = SchedMxList in {699 foreach nf=2-8 in {700 foreach eew = [8, 16, 32, 64] in {701 defvar Cycles = SiFive7GetCyclesSegmented<mx, eew, nf, VLEN>.c;702 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxList>.c;703 // Does not chain so set latency high704 let Latency = !add(3, Cycles), AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {705 defm : LMULWriteResMX<"WriteVLSSEG" # nf # "e" # eew, [VCQ, VL], mx, IsWorstCase>;706 defm : LMULWriteResMX<"WriteVLUXSEG" # nf # "e" # eew, [VCQ, VL], mx, IsWorstCase>;707 defm : LMULWriteResMX<"WriteVLOXSEG" # nf # "e" # eew, [VCQ, VL], mx, IsWorstCase>;708 }709 let Latency = 1, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {710 defm : LMULWriteResMX<"WriteVSSSEG" # nf # "e" # eew, [VCQ, VS], mx, IsWorstCase>;711 defm : LMULWriteResMX<"WriteVSUXSEG" # nf # "e" # eew, [VCQ, VS], mx, IsWorstCase>;712 defm : LMULWriteResMX<"WriteVSOXSEG" # nf # "e" # eew, [VCQ, VS], mx, IsWorstCase>;713 }714 }715 }716 }717 718 // 11. Vector Integer Arithmetic Instructions719 foreach mx = SchedMxList in {720 defvar Cycles = SiFive7GetCyclesDefault<mx>.c;721 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxList>.c;722 let Latency = 4, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {723 defm : LMULWriteResMX<"WriteVIALUV", [VCQ, VA1OrVA2], mx, IsWorstCase>;724 defm : LMULWriteResMX<"WriteVIALUX", [VCQ, VA1OrVA2], mx, IsWorstCase>;725 defm : LMULWriteResMX<"WriteVIALUI", [VCQ, VA1OrVA2], mx, IsWorstCase>;726 // vmadc requires mask727 defm : LMULWriteResMX<"WriteVICALUV", [VCQ, VA1], mx, IsWorstCase>;728 defm : LMULWriteResMX<"WriteVICALUX", [VCQ, VA1], mx, IsWorstCase>;729 defm : LMULWriteResMX<"WriteVICALUI", [VCQ, VA1], mx, IsWorstCase>;730 defm : LMULWriteResMX<"WriteVICALUMV", [VCQ, VA1], mx, IsWorstCase>;731 defm : LMULWriteResMX<"WriteVICALUMX", [VCQ, VA1], mx, IsWorstCase>;732 defm : LMULWriteResMX<"WriteVICALUMI", [VCQ, VA1], mx, IsWorstCase>;733 // min max require merge734 defm : LMULWriteResMX<"WriteVIMinMaxV", [VCQ, VA1], mx, IsWorstCase>;735 defm : LMULWriteResMX<"WriteVIMinMaxX", [VCQ, VA1], mx, IsWorstCase>;736 defm : LMULWriteResMX<"WriteVIMergeV", [VCQ, VA1], mx, IsWorstCase>;737 defm : LMULWriteResMX<"WriteVIMergeX", [VCQ, VA1], mx, IsWorstCase>;738 defm : LMULWriteResMX<"WriteVIMergeI", [VCQ, VA1], mx, IsWorstCase>;739 740 defm : LMULWriteResMX<"WriteVIMovV", [VCQ, VA1OrVA2], mx, IsWorstCase>;741 defm : LMULWriteResMX<"WriteVIMovX", [VCQ, VA1OrVA2], mx, IsWorstCase>;742 defm : LMULWriteResMX<"WriteVIMovI", [VCQ, VA1OrVA2], mx, IsWorstCase>;743 744 defm : LMULWriteResMX<"WriteVExtV", [VCQ, VA1], mx, IsWorstCase>;745 }746 let Latency = 8, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {747 defm : LMULWriteResMX<"WriteVShiftV", [VCQ, VA1OrVA2], mx, IsWorstCase>;748 defm : LMULWriteResMX<"WriteVShiftX", [VCQ, VA1OrVA2], mx, IsWorstCase>;749 defm : LMULWriteResMX<"WriteVShiftI", [VCQ, VA1OrVA2], mx, IsWorstCase>;750 defm : LMULWriteResMX<"WriteVIMulV", [VCQ, VA1OrVA2], mx, IsWorstCase>;751 defm : LMULWriteResMX<"WriteVIMulX", [VCQ, VA1OrVA2], mx, IsWorstCase>;752 defm : LMULWriteResMX<"WriteVIMulAddV", [VCQ, VA1OrVA2], mx, IsWorstCase>;753 defm : LMULWriteResMX<"WriteVIMulAddX", [VCQ, VA1OrVA2], mx, IsWorstCase>;754 }755 // Mask results can't chain.756 let Latency = !add(Cycles, 3), AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {757 defm : LMULWriteResMX<"WriteVICmpV", [VCQ, VA1], mx, IsWorstCase>;758 defm : LMULWriteResMX<"WriteVICmpX", [VCQ, VA1], mx, IsWorstCase>;759 defm : LMULWriteResMX<"WriteVICmpI", [VCQ, VA1], mx, IsWorstCase>;760 }761 }762 763 foreach mx = SchedMxList in {764 foreach sew = SchedSEWSet<mx>.val in {765 // One bit at a time, but up to four elements can be processed at a time.766 // Add 3 to number of elements to ensure the group formed by remainder767 // elements are accounted for.768 defvar Cycles =769 !mul(sew, !div(!add(3, SiFive7GetCyclesOnePerElement<mx, sew, VLEN>.c), 4));770 defvar IsWorstCase = SiFive7IsWorstCaseMXSEW<mx, sew, SchedMxList>.c;771 let Latency = Cycles, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {772 defm : LMULSEWWriteResMXSEW<"WriteVIDivV", [VCQ, VA1], mx, sew, IsWorstCase>;773 defm : LMULSEWWriteResMXSEW<"WriteVIDivX", [VCQ, VA1], mx, sew, IsWorstCase>;774 }775 }776 }777 778 // Widening779 foreach mx = SchedMxListW in {780 defvar Cycles = SiFive7GetCyclesDefault<mx>.c;781 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxListW>.c;782 let Latency = 8, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {783 defm : LMULWriteResMX<"WriteVIWALUV", [VCQ, VA1OrVA2], mx, IsWorstCase>;784 defm : LMULWriteResMX<"WriteVIWALUX", [VCQ, VA1OrVA2], mx, IsWorstCase>;785 defm : LMULWriteResMX<"WriteVIWALUI", [VCQ, VA1OrVA2], mx, IsWorstCase>;786 defm : LMULWriteResMX<"WriteVIWMulV", [VCQ, VA1OrVA2], mx, IsWorstCase>;787 defm : LMULWriteResMX<"WriteVIWMulX", [VCQ, VA1OrVA2], mx, IsWorstCase>;788 defm : LMULWriteResMX<"WriteVIWMulAddV", [VCQ, VA1OrVA2], mx, IsWorstCase>;789 defm : LMULWriteResMX<"WriteVIWMulAddX", [VCQ, VA1OrVA2], mx, IsWorstCase>;790 }791 }792 // Narrowing793 foreach mx = SchedMxListW in {794 defvar Cycles = SiFive7GetCyclesNarrowing<mx>.c;795 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxListW>.c;796 let Latency = 8, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {797 defm : LMULWriteResMX<"WriteVNShiftV", [VCQ, VA1OrVA2], mx, IsWorstCase>;798 defm : LMULWriteResMX<"WriteVNShiftX", [VCQ, VA1OrVA2], mx, IsWorstCase>;799 defm : LMULWriteResMX<"WriteVNShiftI", [VCQ, VA1OrVA2], mx, IsWorstCase>;800 }801 }802 803 // 12. Vector Fixed-Point Arithmetic Instructions804 foreach mx = SchedMxList in {805 defvar Cycles = SiFive7GetCyclesDefault<mx>.c;806 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxList>.c;807 let Latency = 8, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {808 defm : LMULWriteResMX<"WriteVSALUV", [VCQ, VA1OrVA2], mx, IsWorstCase>;809 defm : LMULWriteResMX<"WriteVSALUX", [VCQ, VA1OrVA2], mx, IsWorstCase>;810 defm : LMULWriteResMX<"WriteVSALUI", [VCQ, VA1OrVA2], mx, IsWorstCase>;811 defm : LMULWriteResMX<"WriteVAALUV", [VCQ, VA1OrVA2], mx, IsWorstCase>;812 defm : LMULWriteResMX<"WriteVAALUX", [VCQ, VA1OrVA2], mx, IsWorstCase>;813 defm : LMULWriteResMX<"WriteVSMulV", [VCQ, VA1OrVA2], mx, IsWorstCase>;814 defm : LMULWriteResMX<"WriteVSMulX", [VCQ, VA1OrVA2], mx, IsWorstCase>;815 defm : LMULWriteResMX<"WriteVSShiftV", [VCQ, VA1OrVA2], mx, IsWorstCase>;816 defm : LMULWriteResMX<"WriteVSShiftX", [VCQ, VA1OrVA2], mx, IsWorstCase>;817 defm : LMULWriteResMX<"WriteVSShiftI", [VCQ, VA1OrVA2], mx, IsWorstCase>;818 }819 }820 // Narrowing821 foreach mx = SchedMxListW in {822 defvar Cycles = SiFive7GetCyclesNarrowing<mx>.c;823 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxListW>.c;824 let Latency = 8, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {825 defm : LMULWriteResMX<"WriteVNClipV", [VCQ, VA1OrVA2], mx, IsWorstCase>;826 defm : LMULWriteResMX<"WriteVNClipX", [VCQ, VA1OrVA2], mx, IsWorstCase>;827 defm : LMULWriteResMX<"WriteVNClipI", [VCQ, VA1OrVA2], mx, IsWorstCase>;828 }829 }830 831 // 13. Vector Floating-Point Instructions832 foreach mx = SchedMxListF in {833 foreach sew = SchedSEWSet<mx, isF=1>.val in {834 defvar IsWorstCase = SiFive7IsWorstCaseMXSEW<mx, sew, SchedMxListF, isF=1>.c;835 if !eq(sew, 64) then {836 defvar SingleElementCycles = SiFive7GetCyclesOnePerElement<mx, sew, VLEN>.c;837 foreach SchedWriteName = ["WriteVFALUV", "WriteVFALUF", "WriteVFMulV", "WriteVFMulF",838 "WriteVFMulAddV", "WriteVFMulAddF"] in839 defm : LMULSEWWriteResMXSEWVariant<SchedWriteName, SingleElementVecFP64SchedPred,840 // Predicated841 [VCQ, VA1], !add(SingleElementCycles, 7), [0, 1], [1, !add(1, SingleElementCycles)],842 // Not Predicated843 [VCQ, VA1OrVA2], 8, [0, 1], [1, !add(1, SiFive7GetCyclesDefault<mx>.c)],844 mx, sew, IsWorstCase>;845 foreach SchedWriteName = ["WriteVFRecpV", "WriteVFCvtIToFV"] in846 defm : LMULSEWWriteResMXSEWVariant<SchedWriteName, SingleElementVecFP64SchedPred,847 // Predicated848 [VCQ, VA1], !add(SingleElementCycles, 7), [0, 1], [1, !add(1, SingleElementCycles)],849 // Not Predicated850 [VCQ, VA1], 8, [0, 1], [1, !add(1, SiFive7GetCyclesDefault<mx>.c)],851 mx, sew, IsWorstCase>;852 foreach SchedWriteName = ["WriteVFSgnjV", "WriteVFSgnjF"] in853 defm : LMULSEWWriteResMXSEWVariant<SchedWriteName, SingleElementVecFP64SchedPred,854 // Predicated855 [VCQ, VA1], !add(SingleElementCycles, 3), [0, 1], [1, !add(1, SingleElementCycles)],856 // Not Predicated857 [VCQ, VA1OrVA2], 4, [0, 1], [1, !add(1, SiFive7GetCyclesDefault<mx>.c)],858 mx, sew, IsWorstCase>;859 foreach SchedWriteName = ["WriteVFMinMaxV", "WriteVFMinMaxF"] in860 defm : LMULSEWWriteResMXSEWVariant<SchedWriteName, SingleElementVecFP64SchedPred,861 // Predicated862 [VCQ, VA1], !add(SingleElementCycles, 3), [0, 1], [1, !add(1, SingleElementCycles)],863 // Not Predicated864 [VCQ, VA1], 4, [0, 1], [1, !add(1, SiFive7GetCyclesDefault<mx>.c)],865 mx, sew, IsWorstCase>;866 } else {867 let Latency = 8, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, SiFive7GetCyclesDefault<mx>.c)] in {868 defm : LMULSEWWriteResMXSEW<"WriteVFALUV", [VCQ, VA1OrVA2], mx, sew, IsWorstCase>;869 defm : LMULSEWWriteResMXSEW<"WriteVFALUF", [VCQ, VA1OrVA2], mx, sew, IsWorstCase>;870 defm : LMULSEWWriteResMXSEW<"WriteVFMulV", [VCQ, VA1OrVA2], mx, sew, IsWorstCase>;871 defm : LMULSEWWriteResMXSEW<"WriteVFMulF", [VCQ, VA1OrVA2], mx, sew, IsWorstCase>;872 defm : LMULSEWWriteResMXSEW<"WriteVFMulAddV", [VCQ, VA1OrVA2], mx, sew, IsWorstCase>;873 defm : LMULSEWWriteResMXSEW<"WriteVFMulAddF", [VCQ, VA1OrVA2], mx, sew, IsWorstCase>;874 defm : LMULSEWWriteResMXSEW<"WriteVFRecpV", [VCQ, VA1], mx, sew, IsWorstCase>;875 defm : LMULSEWWriteResMXSEW<"WriteVFCvtIToFV", [VCQ, VA1], mx, sew, IsWorstCase>;876 }877 let Latency = 4, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, SiFive7GetCyclesDefault<mx>.c)] in {878 defm : LMULSEWWriteResMXSEW<"WriteVFSgnjV", [VCQ, VA1OrVA2], mx, sew, IsWorstCase>;879 defm : LMULSEWWriteResMXSEW<"WriteVFSgnjF", [VCQ, VA1OrVA2], mx, sew, IsWorstCase>;880 // min max require merge881 defm : LMULSEWWriteResMXSEW<"WriteVFMinMaxV", [VCQ, VA1], mx, sew, IsWorstCase>;882 defm : LMULSEWWriteResMXSEW<"WriteVFMinMaxF", [VCQ, VA1], mx, sew, IsWorstCase>;883 }884 }885 }886 }887 foreach mx = SchedMxList in {888 defvar Cycles = SiFive7GetCyclesDefault<mx>.c;889 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxList>.c;890 let Latency = 8, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {891 defm : LMULWriteResMX<"WriteVFCvtFToIV", [VCQ, VA1], mx, IsWorstCase>;892 }893 let Latency = 4, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {894 defm : LMULWriteResMX<"WriteVFClassV", [VCQ, VA1OrVA2], mx, IsWorstCase>;895 defm : LMULWriteResMX<"WriteVFMergeV", [VCQ, VA1OrVA2], mx, IsWorstCase>;896 defm : LMULWriteResMX<"WriteVFMovV", [VCQ, VA1OrVA2], mx, IsWorstCase>;897 }898 // Mask results can't chain.899 let Latency = !add(Cycles, 3), AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {900 // fcmp requires mask901 defm : LMULWriteResMX<"WriteVFCmpV", [VCQ, VA1], mx, IsWorstCase>;902 defm : LMULWriteResMX<"WriteVFCmpF", [VCQ, VA1], mx, IsWorstCase>;903 }904 }905 foreach mx = SchedMxListF in {906 foreach sew = SchedSEWSet<mx, isF=1>.val in {907 defvar Cycles = !mul(SiFive7GetDivOrSqrtFactor<sew>.c,908 !div(SiFive7GetCyclesOnePerElement<mx, sew, VLEN>.c, 4));909 defvar IsWorstCase = SiFive7IsWorstCaseMXSEW<mx, sew, SchedMxListF, 1>.c;910 let Latency = Cycles, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {911 defm : LMULSEWWriteResMXSEW<"WriteVFSqrtV", [VCQ, VA1], mx, sew, IsWorstCase>;912 defm : LMULSEWWriteResMXSEW<"WriteVFDivV", [VCQ, VA1], mx, sew, IsWorstCase>;913 defm : LMULSEWWriteResMXSEW<"WriteVFDivF", [VCQ, VA1], mx, sew, IsWorstCase>;914 }915 }916 }917 918 // Widening919 foreach mx = SchedMxListW in {920 foreach sew = SchedSEWSet<mx, isF=0, isWidening=1>.val in {921 defvar IsWorstCase = SiFive7IsWorstCaseMXSEW<mx, sew, SchedMxListW>.c;922 defvar DefaultCycles = SiFive7GetCyclesDefault<mx>.c;923 if !eq(sew, 32) then {924 defvar SingleElementCycles = SiFive7GetCyclesOnePerElement<mx, sew, VLEN>.c;925 defm : LMULSEWWriteResMXSEWVariant<"WriteVFWCvtIToFV", SingleElementVecFP64SchedPred,926 // Predicated927 [VCQ, VA1], 8, [0, 1], [1, !add(1, SingleElementCycles)],928 // Not Predicated929 [VCQ, VA1], 8, [0, 1], [1, !add(1, DefaultCycles)],930 mx, sew, IsWorstCase>;931 } else {932 let Latency = 8,933 AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, DefaultCycles)] in934 defm : LMULSEWWriteResMXSEW<"WriteVFWCvtIToFV", [VCQ, VA1], mx, sew, IsWorstCase>;935 }936 }937 }938 foreach mx = SchedMxListFW in {939 foreach sew = SchedSEWSet<mx, isF=1, isWidening=1>.val in {940 defvar DefaultCycles = SiFive7GetCyclesDefault<mx>.c;941 defvar IsWorstCase = SiFive7IsWorstCaseMXSEW<mx, sew, SchedMxListFW, isF=1>.c;942 let Latency = 8, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, DefaultCycles)] in {943 defm : LMULSEWWriteResMXSEW<"WriteVFWALUV", [VCQ, VA1OrVA2], mx, sew, IsWorstCase>;944 defm : LMULSEWWriteResMXSEW<"WriteVFWALUF", [VCQ, VA1OrVA2], mx, sew, IsWorstCase>;945 defm : LMULSEWWriteResMXSEW<"WriteVFWMulV", [VCQ, VA1OrVA2], mx, sew, IsWorstCase>;946 defm : LMULSEWWriteResMXSEW<"WriteVFWMulF", [VCQ, VA1OrVA2], mx, sew, IsWorstCase>;947 defm : LMULSEWWriteResMXSEW<"WriteVFWMulAddV", [VCQ, VA1OrVA2], mx, sew, IsWorstCase>;948 defm : LMULSEWWriteResMXSEW<"WriteVFWMulAddF", [VCQ, VA1OrVA2], mx, sew, IsWorstCase>;949 }950 if !eq(sew, 32) then {951 defvar SingleElementCycles = SiFive7GetCyclesOnePerElement<mx, sew, VLEN>.c;952 defm : LMULSEWWriteResMXSEWVariant<"WriteVFWCvtFToFV", SingleElementVecFP64SchedPred,953 // Predicated954 [VCQ, VA1], 8, [0, 1], [1, !add(1, SingleElementCycles)],955 // Not Predicated956 [VCQ, VA1], 8, [0, 1], [1, !add(1, DefaultCycles)],957 mx, sew, IsWorstCase>;958 } else {959 let Latency = 8,960 AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, DefaultCycles)] in961 defm : LMULSEWWriteResMXSEW<"WriteVFWCvtFToFV", [VCQ, VA1], mx, sew, IsWorstCase>;962 }963 }964 defvar Cycles = SiFive7GetCyclesDefault<mx>.c;965 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxListFW>.c;966 let Latency = 8, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in967 defm : LMULWriteResMX<"WriteVFWCvtFToIV", [VCQ, VA1], mx, IsWorstCase>;968 }969 // Narrowing970 foreach mx = SchedMxListW in {971 defvar Cycles = SiFive7GetCyclesNarrowing<mx>.c;972 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxListW>.c;973 let Latency = 8, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {974 defm : LMULWriteResMX<"WriteVFNCvtFToIV", [VCQ, VA1], mx, IsWorstCase>;975 }976 }977 foreach mx = SchedMxListFW in {978 foreach sew = SchedSEWSet<mx, isF=1, isWidening=1>.val in {979 defvar IsWorstCase = SiFive7IsWorstCaseMXSEW<mx, sew, SchedMxListFW, isF=1>.c;980 defvar DefaultCycles = SiFive7GetCyclesNarrowing<mx>.c;981 if !eq(sew, 32) then {982 defvar SingleElementCycles = SiFive7GetCyclesOnePerElement<mx, sew, VLEN>.c;983 foreach SchedWriteName = ["WriteVFNCvtIToFV", "WriteVFNCvtFToFV"] in984 defm : LMULSEWWriteResMXSEWVariant<SchedWriteName, SingleElementVecFP64SchedPred,985 // Predicated986 [VCQ, VA1], 8, [0, 1], [1, !add(1, SingleElementCycles)],987 // Not Predicated988 [VCQ, VA1], 8, [0, 1], [1, !add(1, DefaultCycles)],989 mx, sew, IsWorstCase>;990 } else {991 let Latency = 8,992 AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, DefaultCycles)] in {993 defm : LMULSEWWriteResMXSEW<"WriteVFNCvtIToFV", [VCQ, VA1], mx, sew, IsWorstCase>;994 defm : LMULSEWWriteResMXSEW<"WriteVFNCvtFToFV", [VCQ, VA1], mx, sew, IsWorstCase>;995 }996 }997 }998 }999 1000 // 14. Vector Reduction Operations1001 foreach mx = SchedMxList in {1002 foreach sew = SchedSEWSet<mx>.val in {1003 defvar Cycles = SiFive7GetReductionCycles<mx, sew, VLEN>.c;1004 defvar IsWorstCase = SiFive7IsWorstCaseMXSEW<mx, sew, SchedMxList>.c;1005 let Latency = Cycles, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {1006 defm : LMULSEWWriteResMXSEW<"WriteVIRedV_From", [VCQ, VA1],1007 mx, sew, IsWorstCase>;1008 defm : LMULSEWWriteResMXSEW<"WriteVIRedMinMaxV_From", [VCQ, VA1],1009 mx, sew, IsWorstCase>;1010 }1011 }1012 }1013 1014 foreach mx = SchedMxListWRed in {1015 foreach sew = SchedSEWSet<mx, 0, 1>.val in {1016 defvar Cycles = SiFive7GetReductionCycles<mx, sew, VLEN>.c;1017 defvar IsWorstCase = SiFive7IsWorstCaseMXSEW<mx, sew, SchedMxListWRed>.c;1018 let Latency = Cycles, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in1019 defm : LMULSEWWriteResMXSEW<"WriteVIWRedV_From", [VCQ, VA1],1020 mx, sew, IsWorstCase>;1021 }1022 }1023 1024 foreach mx = SchedMxListF in {1025 foreach sew = SchedSEWSet<mx, 1>.val in {1026 defvar RedCycles = SiFive7GetReductionCycles<mx, sew, VLEN>.c;1027 defvar IsWorstCase = SiFive7IsWorstCaseMXSEW<mx, sew, SchedMxListF, 1>.c;1028 let Latency = RedCycles, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, RedCycles)] in {1029 defm : LMULSEWWriteResMXSEW<"WriteVFRedV_From", [VCQ, VA1],1030 mx, sew, IsWorstCase>;1031 defm : LMULSEWWriteResMXSEW<"WriteVFRedMinMaxV_From", [VCQ, VA1],1032 mx, sew, IsWorstCase>;1033 }1034 defvar OrdRedCycles = SiFive7GetOrderedReductionCycles<mx, sew, VLEN>.c;1035 let Latency = OrdRedCycles, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, OrdRedCycles)] in1036 defm : LMULSEWWriteResMXSEW<"WriteVFRedOV_From", [VCQ, VA1],1037 mx, sew, IsWorstCase>;1038 }1039 }1040 1041 foreach mx = SchedMxListFWRed in {1042 foreach sew = SchedSEWSet<mx, 1, 1>.val in {1043 defvar RedCycles = SiFive7GetReductionCycles<mx, sew, VLEN>.c;1044 defvar IsWorstCase = SiFive7IsWorstCaseMXSEW<mx, sew, SchedMxListFWRed, 1>.c;1045 let Latency = RedCycles, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, RedCycles)] in1046 defm : LMULSEWWriteResMXSEW<"WriteVFWRedV_From", [VCQ, VA1],1047 mx, sew, IsWorstCase>;1048 defvar OrdRedCycles = SiFive7GetOrderedReductionCycles<mx, sew, VLEN>.c;1049 let Latency = OrdRedCycles, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, OrdRedCycles)] in1050 defm : LMULSEWWriteResMXSEW<"WriteVFWRedOV_From", [VCQ, VA1],1051 mx, sew, IsWorstCase>;1052 }1053 }1054 1055 // 15. Vector Mask Instructions1056 // Simple mask logical1057 foreach mx = SchedMxList in {1058 defvar Cycles = SiFive7GetCyclesVMask<mx>.c;1059 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxList>.c;1060 let Latency = 4, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {1061 defm : LMULWriteResMX<"WriteVMALUV", [VCQ, VA1], mx, IsWorstCase>;1062 defm : LMULWriteResMX<"WriteVMSFSV", [VCQ, VA1], mx, IsWorstCase>;1063 }1064 }1065 // Simple mask logical used in series1066 foreach mx = SchedMxList in {1067 defvar Cycles = SiFive7GetCyclesDefault<mx>.c;1068 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxList>.c;1069 let Latency = 4, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {1070 defm : LMULWriteResMX<"WriteVIotaV", [VCQ, VA1], mx, IsWorstCase>;1071 defm : LMULWriteResMX<"WriteVIdxV", [VCQ, VA1], mx, IsWorstCase>;1072 }1073 }1074 // Mask reduction1075 foreach mx = SchedMxList in {1076 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxList>.c;1077 let Latency = 11, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, 3)] in {1078 defm "" : LMULWriteResMX<"WriteVMFFSV", [VCQ, VA1], mx, IsWorstCase>;1079 defm "" : LMULWriteResMX<"WriteVMPopV", [VCQ, VA1], mx, IsWorstCase>;1080 }1081 }1082 1083 // 16. Vector Permutation Instructions1084 let Latency = 11, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, 3)] in {1085 def : WriteRes<WriteVMovXS, [VCQ, VA1]>;1086 def : WriteRes<WriteVMovFS, [VCQ, VA1]>;1087 }1088 let Latency = 4, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, 1)] in {1089 def : WriteRes<WriteVMovSX, [VCQ, VA1OrVA2]>;1090 def : WriteRes<WriteVMovSF, [VCQ, VA1OrVA2]>;1091 }1092 foreach mx = SchedMxList in {1093 defvar Cycles = SiFive7GetCyclesDefault<mx>.c;1094 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxList>.c;1095 let Latency = 8, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {1096 defm : LMULWriteResMX<"WriteVRGatherVX", [VCQ, VA1], mx, IsWorstCase>;1097 defm : LMULWriteResMX<"WriteVRGatherVI", [VCQ, VA1], mx, IsWorstCase>;1098 }1099 }1100 1101 foreach mx = SchedMxList in {1102 foreach sew = SchedSEWSet<mx>.val in {1103 defvar IsWorstCase = SiFive7IsWorstCaseMXSEW<mx, sew, SchedMxList>.c;1104 defvar IsSingleDLEN = isSingleDLEN<mx>.c;1105 1106 defvar GatherVVCycles =1107 SiFive7GetCyclesVRGatherVV<mx, sew, VLEN, hasFastGather>.c;1108 // 7 + DLEN/ SEW1109 defvar SlowGatherLat = !add(7, !div(!div(VLEN, 2), sew));1110 defvar GatherVVLat = !if(hasFastGather,1111 !add(3, GatherVVCycles), SlowGatherLat);1112 1113 let Latency = GatherVVLat, AcquireAtCycles = [0, 1],1114 ReleaseAtCycles = [1, !add(5, GatherVVCycles)] in1115 defm "" : LMULSEWWriteResMXSEW<"WriteVRGatherVV", [VCQ, VA1], mx, sew, IsWorstCase>;1116 1117 // VRGatherEI16VV is not improved by fastGather.1118 defvar GatherEI16VVCycles = SiFive7GetCyclesOnePerElement<mx, sew, VLEN>.c;1119 let Latency = SlowGatherLat, AcquireAtCycles = [0, 1],1120 ReleaseAtCycles = [1, !add(5, GatherEI16VVCycles)] in1121 defm "" : LMULSEWWriteResMXSEW<"WriteVRGatherEI16VV", [VCQ, VA1], mx, sew, IsWorstCase>;1122 1123 defvar CompressCycles = SiFive7GetCyclesVCompress<mx, sew, VLEN, hasFastGather>.c;1124 defvar CompressLat = !if(!and(hasFastGather, IsSingleDLEN),1125 4,1126 !add(7, CompressCycles)); // 7 + VL1127 let Latency = CompressLat, AcquireAtCycles = [0, 1],1128 ReleaseAtCycles = [1, !add(8, CompressCycles)] in1129 defm "" : LMULSEWWriteResMXSEW<"WriteVCompressV", [VCQ, VA1], mx, sew, IsWorstCase>;1130 }1131 }1132 1133 foreach mx = SchedMxList in {1134 defvar Cycles = SiFive7GetCyclesDefault<mx>.c;1135 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxList>.c;1136 let Latency = 4, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, Cycles)] in {1137 defm : LMULWriteResMX<"WriteVSlideUpX", [VCQ, VA1], mx, IsWorstCase>;1138 defm : LMULWriteResMX<"WriteVSlideDownX", [VCQ, VA1], mx, IsWorstCase>;1139 defm : LMULWriteResMX<"WriteVSlideI", [VCQ, VA1], mx, IsWorstCase>;1140 defm : LMULWriteResMX<"WriteVISlide1X", [VCQ, VA1], mx, IsWorstCase>;1141 defm : LMULWriteResMX<"WriteVFSlide1F", [VCQ, VA1], mx, IsWorstCase>;1142 }1143 }1144 1145 // VMov*V is LMUL Aware1146 let Latency = 4, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, 2)] in1147 def : WriteRes<WriteVMov1V, [VCQ, VA1OrVA2]>;1148 let Latency = 4, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, 4)] in1149 def : WriteRes<WriteVMov2V, [VCQ, VA1OrVA2]>;1150 let Latency = 4, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, 8)] in1151 def : WriteRes<WriteVMov4V, [VCQ, VA1OrVA2]>;1152 let Latency = 4, AcquireAtCycles = [0, 1], ReleaseAtCycles = [1, !add(1, 16)] in1153 def : WriteRes<WriteVMov8V, [VCQ, VA1OrVA2]>;1154 1155 // Others1156 def : WriteRes<WriteCSR, [PipeB]>;1157 def : WriteRes<WriteNop, []>;1158 let Latency = 3 in1159 def : WriteRes<WriteRdVLENB, [PipeB]>;1160 1161 def : InstRW<[WriteIALU], (instrs COPY)>;1162 1163 // VCIX1164 //1165 // In principle we don't know the latency of any VCIX instructions (they1166 // depends on a particular coprocessor implementation). However, the default1167 // latency of 1 can lead to issues [1]. So instead we set the latency to the1168 // default provided by `SiFive7GetCyclesDefault`. This is still not accurate1169 // and can lead to suboptimal codegen, but should hopefully be a better1170 // starting point.1171 //1172 // [1] https://github.com/llvm/llvm-project/issues/833911173 foreach mx = SchedMxList in {1174 defvar Cycles = SiFive7GetCyclesDefault<mx>.c;1175 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxList>.c;1176 let Latency = Cycles,1177 AcquireAtCycles = [0, 1],1178 ReleaseAtCycles = [1, !add(1, Cycles)] in {1179 defm : LMULWriteResMX<"WriteVC_V_I", [VCQ, VA1OrVA2], mx, IsWorstCase>;1180 defm : LMULWriteResMX<"WriteVC_V_X", [VCQ, VA1OrVA2], mx, IsWorstCase>;1181 defm : LMULWriteResMX<"WriteVC_V_IV", [VCQ, VA1OrVA2], mx, IsWorstCase>;1182 defm : LMULWriteResMX<"WriteVC_V_VV", [VCQ, VA1OrVA2], mx, IsWorstCase>;1183 defm : LMULWriteResMX<"WriteVC_V_XV", [VCQ, VA1OrVA2], mx, IsWorstCase>;1184 defm : LMULWriteResMX<"WriteVC_V_IVV", [VCQ, VA1OrVA2], mx, IsWorstCase>;1185 defm : LMULWriteResMX<"WriteVC_V_IVW", [VCQ, VA1OrVA2], mx, IsWorstCase>;1186 defm : LMULWriteResMX<"WriteVC_V_VVV", [VCQ, VA1OrVA2], mx, IsWorstCase>;1187 defm : LMULWriteResMX<"WriteVC_V_VVW", [VCQ, VA1OrVA2], mx, IsWorstCase>;1188 defm : LMULWriteResMX<"WriteVC_V_XVV", [VCQ, VA1OrVA2], mx, IsWorstCase>;1189 defm : LMULWriteResMX<"WriteVC_V_XVW", [VCQ, VA1OrVA2], mx, IsWorstCase>;1190 foreach f = ["FPR16", "FPR32", "FPR64"] in {1191 defm : LMULWriteResMX<"WriteVC_V_" # f # "V", [VCQ, VA1OrVA2], mx, IsWorstCase>;1192 defm : LMULWriteResMX<"WriteVC_V_" # f # "VV", [VCQ, VA1OrVA2], mx, IsWorstCase>;1193 defm : LMULWriteResMX<"WriteVC_V_" # f # "VW", [VCQ, VA1OrVA2], mx, IsWorstCase>;1194 }1195 defm : LMULWriteResMX<"WriteVC_I", [VCQ, VA1OrVA2], mx, IsWorstCase>;1196 defm : LMULWriteResMX<"WriteVC_X", [VCQ, VA1OrVA2], mx, IsWorstCase>;1197 defm : LMULWriteResMX<"WriteVC_IV", [VCQ, VA1OrVA2], mx, IsWorstCase>;1198 defm : LMULWriteResMX<"WriteVC_VV", [VCQ, VA1OrVA2], mx, IsWorstCase>;1199 defm : LMULWriteResMX<"WriteVC_XV", [VCQ, VA1OrVA2], mx, IsWorstCase>;1200 defm : LMULWriteResMX<"WriteVC_IVV", [VCQ, VA1OrVA2], mx, IsWorstCase>;1201 defm : LMULWriteResMX<"WriteVC_IVW", [VCQ, VA1OrVA2], mx, IsWorstCase>;1202 defm : LMULWriteResMX<"WriteVC_VVV", [VCQ, VA1OrVA2], mx, IsWorstCase>;1203 defm : LMULWriteResMX<"WriteVC_VVW", [VCQ, VA1OrVA2], mx, IsWorstCase>;1204 defm : LMULWriteResMX<"WriteVC_XVV", [VCQ, VA1OrVA2], mx, IsWorstCase>;1205 defm : LMULWriteResMX<"WriteVC_XVW", [VCQ, VA1OrVA2], mx, IsWorstCase>;1206 foreach f = ["FPR16", "FPR32", "FPR64"] in {1207 defm : LMULWriteResMX<"WriteVC_" # f # "V", [VCQ, VA1OrVA2], mx, IsWorstCase>;1208 defm : LMULWriteResMX<"WriteVC_" # f # "VV", [VCQ, VA1OrVA2], mx, IsWorstCase>;1209 defm : LMULWriteResMX<"WriteVC_" # f # "VW", [VCQ, VA1OrVA2], mx, IsWorstCase>;1210 }1211 }1212 }1213 1214 foreach mx = !listremove(SchedMxListW, ["M4"]) in {1215 defvar Cycles = SiFive7GetSiFiveVFNRClipCycles<mx, VLEN>;1216 let Latency = Cycles.latency,1217 AcquireAtCycles = [0, 1],1218 ReleaseAtCycles = [1, !add(1, Cycles.occupancy)] in1219 defm : LMULWriteResMX<"WriteSF_VFNRClipV", [VCQ, VA1], mx,1220 IsWorstCase=!eq(mx, "M2")>;1221 }1222 1223 // XSfvqmaccdod1224 foreach mx = ["M1", "M2", "M4", "M8"] in {1225 defvar Cycles = SiFive7GetCyclesDefault<mx>.c;1226 let Latency = 8,1227 AcquireAtCycles = [0, 1],1228 ReleaseAtCycles = [1, !add(1, Cycles)] in1229 defm : LMULWriteResMX<"WriteSF_VQMACC_DOD", [VCQ, VA1], mx,1230 IsWorstCase=!eq(mx, "M8")>;1231 }1232 1233 // XSfvqmaccqoq1234 foreach mx = ["MF2", "M1", "M2", "M4"] in {1235 defvar Cycles = SiFive7GetCyclesDefault<mx>.c;1236 let Latency = 8,1237 AcquireAtCycles = [0, 1],1238 ReleaseAtCycles = [1, !add(1, Cycles)] in1239 defm : LMULWriteResMX<"WriteSF_VQMACC_QOQ", [VCQ, VA1], mx,1240 IsWorstCase=!eq(mx, "M4")>;1241 }1242 1243 // XSfvfwmaccqqq1244 foreach mx = SchedMxListFW in {1245 defvar Cycles = SiFive7GetCyclesDefault<mx>.c;1246 defvar IsWorstCase = SiFive7IsWorstCaseMX<mx, SchedMxListFW>.c;1247 let Latency = 8,1248 AcquireAtCycles = [0, 1],1249 ReleaseAtCycles = [1, !add(1, Cycles)] in1250 defm : LMULWriteResMX<"WriteSF_VFWMACC_QQQ", [VCQ, VA1], mx, IsWorstCase>;1251 }1252}1253 1254//===----------------------------------------------------------------------===//1255 1256multiclass SiFive7ReadAdvance {1257 // Bypass and advance1258 def : SiFive7AnyToGPRBypass<ReadJmp>;1259 def : SiFive7AnyToGPRBypass<ReadJalr>;1260 def : ReadAdvance<ReadCSR, 0>;1261 def : SiFive7AnyToGPRBypass<ReadStoreData>;1262 def : ReadAdvance<ReadMemBase, 0>;1263 def : SiFive7AnyToGPRBypass<ReadIALU>;1264 def : SiFive7AnyToGPRBypass<ReadIALU32>;1265 def : SiFive7AnyToGPRBypass<ReadShiftImm>;1266 def : SiFive7AnyToGPRBypass<ReadShiftImm32>;1267 def : SiFive7AnyToGPRBypass<ReadShiftReg>;1268 def : SiFive7AnyToGPRBypass<ReadShiftReg32>;1269 def : ReadAdvance<ReadIDiv, 0>;1270 def : ReadAdvance<ReadIDiv32, 0>;1271 def : ReadAdvance<ReadIRem, 0>;1272 def : ReadAdvance<ReadIRem32, 0>;1273 def : ReadAdvance<ReadIMul, 0>;1274 def : ReadAdvance<ReadIMul32, 0>;1275 def : ReadAdvance<ReadAtomicWA, 0>;1276 def : ReadAdvance<ReadAtomicWD, 0>;1277 def : ReadAdvance<ReadAtomicDA, 0>;1278 def : ReadAdvance<ReadAtomicDD, 0>;1279 def : ReadAdvance<ReadAtomicLDW, 0>;1280 def : ReadAdvance<ReadAtomicLDD, 0>;1281 def : ReadAdvance<ReadAtomicSTW, 0>;1282 def : ReadAdvance<ReadAtomicSTD, 0>;1283 def : ReadAdvance<ReadFStoreData, 0>;1284 def : ReadAdvance<ReadFMemBase, 0>;1285 def : ReadAdvance<ReadFAdd16, 0>;1286 def : ReadAdvance<ReadFAdd32, 0>;1287 def : ReadAdvance<ReadFAdd64, 0>;1288 def : ReadAdvance<ReadFMul16, 0>;1289 def : ReadAdvance<ReadFMA16, 0>;1290 def : ReadAdvance<ReadFMA16Addend, 0>;1291 def : ReadAdvance<ReadFMul32, 0>;1292 def : ReadAdvance<ReadFMul64, 0>;1293 def : ReadAdvance<ReadFMA32, 0>;1294 def : ReadAdvance<ReadFMA32Addend, 0>;1295 def : ReadAdvance<ReadFMA64, 0>;1296 def : ReadAdvance<ReadFMA64Addend, 0>;1297 def : ReadAdvance<ReadFDiv16, 0>;1298 def : ReadAdvance<ReadFDiv32, 0>;1299 def : ReadAdvance<ReadFDiv64, 0>;1300 def : ReadAdvance<ReadFSqrt16, 0>;1301 def : ReadAdvance<ReadFSqrt32, 0>;1302 def : ReadAdvance<ReadFSqrt64, 0>;1303 def : ReadAdvance<ReadFCmp16, 0>;1304 def : ReadAdvance<ReadFCmp32, 0>;1305 def : ReadAdvance<ReadFCmp64, 0>;1306 def : ReadAdvance<ReadFSGNJ16, 0>;1307 def : ReadAdvance<ReadFSGNJ32, 0>;1308 def : ReadAdvance<ReadFSGNJ64, 0>;1309 def : ReadAdvance<ReadFMinMax16, 0>;1310 def : ReadAdvance<ReadFMinMax32, 0>;1311 def : ReadAdvance<ReadFMinMax64, 0>;1312 def : ReadAdvance<ReadFCvtF16ToI32, 0>;1313 def : ReadAdvance<ReadFCvtF16ToI64, 0>;1314 def : ReadAdvance<ReadFCvtF32ToI32, 0>;1315 def : ReadAdvance<ReadFCvtF32ToI64, 0>;1316 def : ReadAdvance<ReadFCvtF64ToI32, 0>;1317 def : ReadAdvance<ReadFCvtF64ToI64, 0>;1318 def : ReadAdvance<ReadFCvtI32ToF16, 0>;1319 def : ReadAdvance<ReadFCvtI32ToF32, 0>;1320 def : ReadAdvance<ReadFCvtI32ToF64, 0>;1321 def : ReadAdvance<ReadFCvtI64ToF16, 0>;1322 def : ReadAdvance<ReadFCvtI64ToF32, 0>;1323 def : ReadAdvance<ReadFCvtI64ToF64, 0>;1324 def : ReadAdvance<ReadFCvtF32ToF64, 0>;1325 def : ReadAdvance<ReadFCvtF64ToF32, 0>;1326 def : ReadAdvance<ReadFCvtF16ToF32, 0>;1327 def : ReadAdvance<ReadFCvtF32ToF16, 0>;1328 def : ReadAdvance<ReadFCvtF16ToF64, 0>;1329 def : ReadAdvance<ReadFCvtF64ToF16, 0>;1330 def : ReadAdvance<ReadFMovF16ToI16, 0>;1331 def : ReadAdvance<ReadFMovI16ToF16, 0>;1332 def : ReadAdvance<ReadFMovF32ToI32, 0>;1333 def : ReadAdvance<ReadFMovI32ToF32, 0>;1334 def : ReadAdvance<ReadFMovF64ToI64, 0>;1335 def : ReadAdvance<ReadFMovI64ToF64, 0>;1336 def : ReadAdvance<ReadFClass16, 0>;1337 def : ReadAdvance<ReadFClass32, 0>;1338 def : ReadAdvance<ReadFClass64, 0>;1339 1340 def : SiFive7AnyToGPRBypass<ReadSFBJmp, 0>;1341 def : SiFive7AnyToGPRBypass<ReadSFBALU, 0>;1342 1343 // Bitmanip1344 def : SiFive7AnyToGPRBypass<ReadRotateImm>;1345 def : SiFive7AnyToGPRBypass<ReadRotateImm32>;1346 def : SiFive7AnyToGPRBypass<ReadRotateReg>;1347 def : SiFive7AnyToGPRBypass<ReadRotateReg32>;1348 def : SiFive7AnyToGPRBypass<ReadCLZ>;1349 def : SiFive7AnyToGPRBypass<ReadCLZ32>;1350 def : SiFive7AnyToGPRBypass<ReadCTZ>;1351 def : SiFive7AnyToGPRBypass<ReadCTZ32>;1352 def : ReadAdvance<ReadCPOP, 0>;1353 def : ReadAdvance<ReadCPOP32, 0>;1354 def : SiFive7AnyToGPRBypass<ReadORCB>;1355 def : SiFive7AnyToGPRBypass<ReadIMinMax>;1356 def : SiFive7AnyToGPRBypass<ReadREV8>;1357 def : SiFive7AnyToGPRBypass<ReadSHXADD>;1358 def : SiFive7AnyToGPRBypass<ReadSHXADD32>;1359 // Single-bit instructions1360 def : SiFive7AnyToGPRBypass<ReadSingleBit>;1361 def : SiFive7AnyToGPRBypass<ReadSingleBitImm>;1362 1363 // 6. Configuration-Setting Instructions1364 def : ReadAdvance<ReadVSETVLI, 2>;1365 def : ReadAdvance<ReadVSETVL, 2>;1366 1367 // 7. Vector Loads and Stores1368 def : ReadAdvance<ReadVLDX, 0>;1369 def : ReadAdvance<ReadVSTX, 0>;1370 defm : LMULReadAdvance<"ReadVSTEV", 0>;1371 defm : LMULReadAdvance<"ReadVSTM", 0>;1372 def : ReadAdvance<ReadVLDSX, 0>;1373 def : ReadAdvance<ReadVSTSX, 0>;1374 defm : LMULReadAdvance<"ReadVSTS8V", 0>;1375 defm : LMULReadAdvance<"ReadVSTS16V", 0>;1376 defm : LMULReadAdvance<"ReadVSTS32V", 0>;1377 defm : LMULReadAdvance<"ReadVSTS64V", 0>;1378 defm : LMULReadAdvance<"ReadVLDUXV", 0>;1379 defm : LMULReadAdvance<"ReadVLDOXV", 0>;1380 defm : LMULReadAdvance<"ReadVSTUX8", 0>;1381 defm : LMULReadAdvance<"ReadVSTUX16", 0>;1382 defm : LMULReadAdvance<"ReadVSTUX32", 0>;1383 defm : LMULReadAdvance<"ReadVSTUX64", 0>;1384 defm : LMULReadAdvance<"ReadVSTUXV", 0>;1385 defm : LMULReadAdvance<"ReadVSTUX8V", 0>;1386 defm : LMULReadAdvance<"ReadVSTUX16V", 0>;1387 defm : LMULReadAdvance<"ReadVSTUX32V", 0>;1388 defm : LMULReadAdvance<"ReadVSTUX64V", 0>;1389 defm : LMULReadAdvance<"ReadVSTOX8", 0>;1390 defm : LMULReadAdvance<"ReadVSTOX16", 0>;1391 defm : LMULReadAdvance<"ReadVSTOX32", 0>;1392 defm : LMULReadAdvance<"ReadVSTOX64", 0>;1393 defm : LMULReadAdvance<"ReadVSTOXV", 0>;1394 defm : LMULReadAdvance<"ReadVSTOX8V", 0>;1395 defm : LMULReadAdvance<"ReadVSTOX16V", 0>;1396 defm : LMULReadAdvance<"ReadVSTOX32V", 0>;1397 defm : LMULReadAdvance<"ReadVSTOX64V", 0>;1398 // LMUL Aware1399 def : ReadAdvance<ReadVST1R, 0>;1400 def : ReadAdvance<ReadVST2R, 0>;1401 def : ReadAdvance<ReadVST4R, 0>;1402 def : ReadAdvance<ReadVST8R, 0>;1403 1404 // 11. Vector Integer Arithmetic Instructions1405 defm : LMULReadAdvance<"ReadVIALUV", 0>;1406 defm : LMULReadAdvance<"ReadVIALUX", 0>;1407 defm : LMULReadAdvanceW<"ReadVIWALUV", 0>;1408 defm : LMULReadAdvanceW<"ReadVIWALUX", 0>;1409 defm : LMULReadAdvance<"ReadVExtV", 0>;1410 defm : LMULReadAdvance<"ReadVICALUV", 0>;1411 defm : LMULReadAdvance<"ReadVICALUX", 0>;1412 defm : LMULReadAdvance<"ReadVShiftV", 0>;1413 defm : LMULReadAdvance<"ReadVShiftX", 0>;1414 defm : LMULReadAdvanceW<"ReadVNShiftV", 0>;1415 defm : LMULReadAdvanceW<"ReadVNShiftX", 0>;1416 defm : LMULReadAdvance<"ReadVICmpV", 0>;1417 defm : LMULReadAdvance<"ReadVICmpX", 0>;1418 defm : LMULReadAdvance<"ReadVIMinMaxV", 0>;1419 defm : LMULReadAdvance<"ReadVIMinMaxX", 0>;1420 defm : LMULReadAdvance<"ReadVIMulV", 0>;1421 defm : LMULReadAdvance<"ReadVIMulX", 0>;1422 defm : LMULSEWReadAdvance<"ReadVIDivV", 0>;1423 defm : LMULSEWReadAdvance<"ReadVIDivX", 0>;1424 defm : LMULReadAdvanceW<"ReadVIWMulV", 0>;1425 defm : LMULReadAdvanceW<"ReadVIWMulX", 0>;1426 defm : LMULReadAdvance<"ReadVIMulAddV", 0>;1427 defm : LMULReadAdvance<"ReadVIMulAddX", 0>;1428 defm : LMULReadAdvanceW<"ReadVIWMulAddV", 0>;1429 defm : LMULReadAdvanceW<"ReadVIWMulAddX", 0>;1430 defm : LMULReadAdvance<"ReadVIMergeV", 0>;1431 defm : LMULReadAdvance<"ReadVIMergeX", 0>;1432 defm : LMULReadAdvance<"ReadVIMovV", 0>;1433 defm : LMULReadAdvance<"ReadVIMovX", 0>;1434 1435 // 12. Vector Fixed-Point Arithmetic Instructions1436 defm : LMULReadAdvance<"ReadVSALUV", 0>;1437 defm : LMULReadAdvance<"ReadVSALUX", 0>;1438 defm : LMULReadAdvance<"ReadVAALUV", 0>;1439 defm : LMULReadAdvance<"ReadVAALUX", 0>;1440 defm : LMULReadAdvance<"ReadVSMulV", 0>;1441 defm : LMULReadAdvance<"ReadVSMulX", 0>;1442 defm : LMULReadAdvance<"ReadVSShiftV", 0>;1443 defm : LMULReadAdvance<"ReadVSShiftX", 0>;1444 defm : LMULReadAdvanceW<"ReadVNClipV", 0>;1445 defm : LMULReadAdvanceW<"ReadVNClipX", 0>;1446 1447 // 13. Vector Floating-Point Instructions1448 defm : LMULSEWReadAdvanceF<"ReadVFALUV", 0>;1449 defm : LMULSEWReadAdvanceF<"ReadVFALUF", 0>;1450 defm : LMULSEWReadAdvanceFW<"ReadVFWALUV", 0>;1451 defm : LMULSEWReadAdvanceFW<"ReadVFWALUF", 0>;1452 defm : LMULSEWReadAdvanceF<"ReadVFMulV", 0>;1453 defm : LMULSEWReadAdvanceF<"ReadVFMulF", 0>;1454 defm : LMULSEWReadAdvanceF<"ReadVFDivV", 0>;1455 defm : LMULSEWReadAdvanceF<"ReadVFDivF", 0>;1456 defm : LMULSEWReadAdvanceFW<"ReadVFWMulV", 0>;1457 defm : LMULSEWReadAdvanceFW<"ReadVFWMulF", 0>;1458 defm : LMULSEWReadAdvanceF<"ReadVFMulAddV", 0>;1459 defm : LMULSEWReadAdvanceF<"ReadVFMulAddF", 0>;1460 defm : LMULSEWReadAdvanceFW<"ReadVFWMulAddV", 0>;1461 defm : LMULSEWReadAdvanceFW<"ReadVFWMulAddF", 0>;1462 defm : LMULSEWReadAdvanceF<"ReadVFSqrtV", 0>;1463 defm : LMULSEWReadAdvanceF<"ReadVFRecpV", 0>;1464 defm : LMULSEWReadAdvanceF<"ReadVFMinMaxV", 0>;1465 defm : LMULSEWReadAdvanceF<"ReadVFMinMaxF", 0>;1466 defm : LMULSEWReadAdvanceF<"ReadVFSgnjV", 0>;1467 defm : LMULSEWReadAdvanceF<"ReadVFSgnjF", 0>;1468 defm : LMULReadAdvance<"ReadVFCmpV", 0>;1469 defm : LMULReadAdvance<"ReadVFCmpF", 0>;1470 defm : LMULReadAdvance<"ReadVFClassV", 0>;1471 defm : LMULReadAdvance<"ReadVFMergeV", 0>;1472 defm : LMULReadAdvance<"ReadVFMergeF", 0>;1473 defm : LMULReadAdvance<"ReadVFMovF", 0>;1474 defm : LMULSEWReadAdvanceF<"ReadVFCvtIToFV", 0>;1475 defm : LMULReadAdvance<"ReadVFCvtFToIV", 0>;1476 defm : LMULSEWReadAdvanceW<"ReadVFWCvtIToFV", 0>;1477 defm : LMULReadAdvanceFW<"ReadVFWCvtFToIV", 0>;1478 defm : LMULSEWReadAdvanceFW<"ReadVFWCvtFToFV", 0>;1479 defm : LMULSEWReadAdvanceFW<"ReadVFNCvtIToFV", 0>;1480 defm : LMULReadAdvanceW<"ReadVFNCvtFToIV", 0>;1481 defm : LMULSEWReadAdvanceFW<"ReadVFNCvtFToFV", 0>;1482 1483 // 14. Vector Reduction Operations1484 def : ReadAdvance<ReadVIRedV, 0>;1485 def : ReadAdvance<ReadVIRedV0, 0>;1486 def : ReadAdvance<ReadVIWRedV, 0>;1487 def : ReadAdvance<ReadVIWRedV0, 0>;1488 def : ReadAdvance<ReadVFRedV, 0>;1489 def : ReadAdvance<ReadVFRedV0, 0>;1490 def : ReadAdvance<ReadVFRedOV, 0>;1491 def : ReadAdvance<ReadVFRedOV0, 0>;1492 def : ReadAdvance<ReadVFWRedV, 0>;1493 def : ReadAdvance<ReadVFWRedV0, 0>;1494 def : ReadAdvance<ReadVFWRedOV, 0>;1495 def : ReadAdvance<ReadVFWRedOV0, 0>;1496 1497 // 15. Vector Mask Instructions1498 defm : LMULReadAdvance<"ReadVMALUV", 0>;1499 defm : LMULReadAdvance<"ReadVMPopV", 0>;1500 defm : LMULReadAdvance<"ReadVMFFSV", 0>;1501 defm : LMULReadAdvance<"ReadVMSFSV", 0>;1502 defm : LMULReadAdvance<"ReadVIotaV", 0>;1503 1504 // 16. Vector Permutation Instructions1505 def : ReadAdvance<ReadVMovXS, 0>;1506 def : ReadAdvance<ReadVMovSX_V, 0>;1507 def : ReadAdvance<ReadVMovSX_X, 0>;1508 def : ReadAdvance<ReadVMovFS, 0>;1509 def : ReadAdvance<ReadVMovSF_V, 0>;1510 def : ReadAdvance<ReadVMovSF_F, 0>;1511 defm : LMULReadAdvance<"ReadVISlideV", 0>;1512 defm : LMULReadAdvance<"ReadVISlideX", 0>;1513 defm : LMULReadAdvance<"ReadVFSlideV", 0>;1514 defm : LMULReadAdvance<"ReadVFSlideF", 0>;1515 defm : LMULSEWReadAdvance<"ReadVRGatherVV_data", 0>;1516 defm : LMULSEWReadAdvance<"ReadVRGatherVV_index", 0>;1517 defm : LMULSEWReadAdvance<"ReadVRGatherEI16VV_data", 0>;1518 defm : LMULSEWReadAdvance<"ReadVRGatherEI16VV_index", 0>;1519 defm : LMULReadAdvance<"ReadVRGatherVX_data", 0>;1520 defm : LMULReadAdvance<"ReadVRGatherVX_index", 0>;1521 defm : LMULReadAdvance<"ReadVRGatherVI_data", 0>;1522 defm : LMULSEWReadAdvance<"ReadVCompressV", 0>;1523 // LMUL Aware1524 def : ReadAdvance<ReadVMov1V, 0>;1525 def : ReadAdvance<ReadVMov2V, 0>;1526 def : ReadAdvance<ReadVMov4V, 0>;1527 def : ReadAdvance<ReadVMov8V, 0>;1528 1529 // XSfvfnrclipxfqf1530 defm : LMULReadAdvance<"ReadSF_VFNRClipV", 0>;1531 defm : LMULReadAdvance<"ReadSF_VFNRClipF", 0>;1532 1533 // SiFive VMACC1534 defm : LMULReadAdvance<"ReadSF_VQMACC_DOD", 0>;1535 defm : LMULReadAdvance<"ReadSF_VQMACC_QOQ", 0>;1536 defm : LMULReadAdvance<"ReadSF_VFWMACC_QQQ", 0>;1537 1538 // Others1539 def : ReadAdvance<ReadVMask, 0>;1540 def : ReadAdvance<ReadVPassthru_WorstCase, 0>;1541 foreach mx = SchedMxList in {1542 def : ReadAdvance<!cast<SchedRead>("ReadVPassthru_" # mx), 0>;1543 foreach sew = SchedSEWSet<mx>.val in1544 def : ReadAdvance<!cast<SchedRead>("ReadVPassthru_" # mx # "_E" # sew), 0>;1545 }1546}1547 1548//===----------------------------------------------------------------------===//1549 1550/// This multiclass is a "bundle" of (1) processor resources (i.e. pipes) and1551/// (2) WriteRes entries. It's parameterized by config values that will1552/// eventually be supplied by different SchedMachineModels.1553multiclass SiFive7SchedResources<int vlen, bit dualVALU,1554 SiFive7FPLatencies fpLatencies,1555 bit hasFastGather> {1556 defm SiFive7 : SiFive7ProcResources<dualVALU>;1557 1558 // Pull out defs from SiFive7ProcResources so we can refer to them by name.1559 defvar SiFive7PipeA = !cast<ProcResource>(NAME # SiFive7PipeA);1560 defvar SiFive7PipeB = !cast<ProcResource>(NAME # SiFive7PipeB);1561 defvar SiFive7PipeAB = !cast<ProcResGroup>(NAME # SiFive7PipeAB);1562 defvar SiFive7IDiv = !cast<ProcResource>(NAME # SiFive7IDiv);1563 defvar SiFive7FDiv = !cast<ProcResource>(NAME # SiFive7FDiv);1564 // Pass SiFive7VA for VA1 and VA1OrVA2 if there is only 1 VALU.1565 defvar SiFive7VA1 = !if (dualVALU,1566 !cast<ProcResource>(NAME # SiFive7VA1),1567 !cast<ProcResource>(NAME # SiFive7VA));1568 defvar SiFive7VA1OrVA2 = !if (dualVALU,1569 !cast<ProcResGroup>(NAME # SiFive7VA1OrVA2),1570 !cast<ProcResource>(NAME # SiFive7VA));1571 defvar SiFive7VA = !cast<ProcResource>(NAME # SiFive7VA);1572 defvar SiFive7VL = !cast<ProcResource>(NAME # SiFive7VL);1573 defvar SiFive7VS = !cast<ProcResource>(NAME # SiFive7VS);1574 defvar SiFive7VCQ = !cast<ProcResource>(NAME # SiFive7VCQ);1575 1576 // Define WriteRes records that are the same across all SiFive7 derived1577 // SchedModels.1578 defm SiFive71579 : SiFive7WriteResBase<vlen, SiFive7PipeA, SiFive7PipeB, SiFive7PipeAB,1580 SiFive7IDiv, SiFive7FDiv, SiFive7VA1,1581 SiFive7VA1OrVA2, SiFive7VL, SiFive7VS,1582 SiFive7VCQ, fpLatencies, hasFastGather>;1583 1584 //===----------------------------------------------------------------------===//1585 // Bypass and advance1586 1587 defm SiFive7 : SiFive7ReadAdvance;1588 //===----------------------------------------------------------------------===//1589 // Unsupported extensions1590 defm : UnsupportedSchedQ;1591 // TODO: scheduling info of XSfvfexp* and XSfvfexpa*1592 // for SiFive7 will be added in follow-up patches.1593 defm : UnsupportedSchedXSfvfexp;1594 defm : UnsupportedSchedXSfvfexpa;1595 defm : UnsupportedSchedZabha;1596 defm : UnsupportedSchedZbc;1597 defm : UnsupportedSchedZbkb;1598 defm : UnsupportedSchedZbkx;1599 defm : UnsupportedSchedZfa;1600 defm : UnsupportedSchedZvk;1601}1602 1603class SiFive7SchedMachineModel<int vlen> : SchedMachineModel {1604 let MicroOpBufferSize = 0; // Explicitly set to zero since SiFive7 is in-order.1605 let IssueWidth = 2; // 2 micro-ops are dispatched per cycle.1606 let LoadLatency = 3;1607 let MispredictPenalty = 3;1608 let CompleteModel = 0;1609 let EnableIntervals = true;1610 let UnsupportedFeatures = [HasStdExtZbkb, HasStdExtZbkc, HasStdExtZbkx,1611 HasStdExtZcmt, HasStdExtZknd, HasStdExtZkne,1612 HasStdExtZknh, HasStdExtZksed, HasStdExtZksh,1613 HasStdExtZkr];1614 int VLEN = vlen;1615 bit HasDualVALU = false;1616 1617 SiFive7FPLatencies FPLatencies;1618 bit HasFastGather = false;1619 1620 string Name = !subst("Model", "", !subst("SiFive7", "", NAME));1621}1622 1623/// Auxiliary config values.1624def SiFive7DefaultFPLatencies : SiFive7FPLatencies {1625 let BasicFP16ALU = 5;1626 let BasicFP32ALU = 5;1627 let BasicFP64ALU = 7;1628}1629 1630def SiFive7LowFPLatencies : SiFive7FPLatencies {1631 let BasicFP16ALU = 4;1632 let BasicFP32ALU = 4;1633 let BasicFP64ALU = 4;1634}1635 1636/// Models1637def SiFive7VLEN512Model : SiFive7SchedMachineModel<512> {1638 let FPLatencies = SiFive7DefaultFPLatencies;1639}1640 1641def SiFive7VLEN1024X300Model : SiFive7SchedMachineModel<1024> {1642 let HasDualVALU = true;1643 let FPLatencies = SiFive7LowFPLatencies;1644 let HasFastGather = true;1645}1646 1647/// Binding models to their scheduling resources.1648foreach model = [SiFive7VLEN512Model, SiFive7VLEN1024X300Model] in {1649 let SchedModel = model in1650 defm model.Name : SiFive7SchedResources<model.VLEN, model.HasDualVALU,1651 model.FPLatencies,1652 model.HasFastGather>;1653}1654 1655// Some model name aliases.1656defvar SiFive7Model = SiFive7VLEN512Model;1657defvar SiFiveX390Model = SiFive7VLEN1024X300Model;1658