brintos

brintos / llvm-project-archived public Read only

0
0
Text · 72.1 KiB · 36a2f46 Raw
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