1*e8d8bef9SDimitry Andric//==- RISCVSchedRocket.td - Rocket Scheduling Definitions ----*- tablegen -*-=// 2*e8d8bef9SDimitry Andric// 3*e8d8bef9SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*e8d8bef9SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 5*e8d8bef9SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*e8d8bef9SDimitry Andric// 7*e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 8*e8d8bef9SDimitry Andric 9*e8d8bef9SDimitry Andric// ===---------------------------------------------------------------------===// 10*e8d8bef9SDimitry Andric// The following definitions describe the simpler per-operand machine model. 11*e8d8bef9SDimitry Andric// This works with MachineScheduler. See MCSchedule.h for details. 12*e8d8bef9SDimitry Andric 13*e8d8bef9SDimitry Andric// Rocket machine model for scheduling and other instruction cost heuristics. 14*e8d8bef9SDimitry Andricdef RocketModel : SchedMachineModel { 15*e8d8bef9SDimitry Andric let MicroOpBufferSize = 0; // Rocket is in-order. 16*e8d8bef9SDimitry Andric let IssueWidth = 1; // 1 micro-op is dispatched per cycle. 17*e8d8bef9SDimitry Andric let LoadLatency = 3; 18*e8d8bef9SDimitry Andric let MispredictPenalty = 3; 19*e8d8bef9SDimitry Andric let UnsupportedFeatures = [HasStdExtV, HasStdExtZvamo, HasStdExtZvlsseg]; 20*e8d8bef9SDimitry Andric} 21*e8d8bef9SDimitry Andric 22*e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 23*e8d8bef9SDimitry Andric// Define each kind of processor resource and number available. 24*e8d8bef9SDimitry Andric 25*e8d8bef9SDimitry Andric// Modeling each pipeline as a ProcResource using the BufferSize = 0 since 26*e8d8bef9SDimitry Andric// Rocket is in-order. 27*e8d8bef9SDimitry Andric 28*e8d8bef9SDimitry Andriclet BufferSize = 0 in { 29*e8d8bef9SDimitry Andricdef RocketUnitALU : ProcResource<1>; // Int ALU 30*e8d8bef9SDimitry Andricdef RocketUnitIMul : ProcResource<1>; // Int Multiply 31*e8d8bef9SDimitry Andricdef RocketUnitMem : ProcResource<1>; // Load/Store 32*e8d8bef9SDimitry Andricdef RocketUnitB : ProcResource<1>; // Branch 33*e8d8bef9SDimitry Andric 34*e8d8bef9SDimitry Andricdef RocketUnitFPALU : ProcResource<1>; // FP ALU 35*e8d8bef9SDimitry Andric} 36*e8d8bef9SDimitry Andric 37*e8d8bef9SDimitry Andriclet BufferSize = 1 in { 38*e8d8bef9SDimitry Andricdef RocketUnitIDiv : ProcResource<1>; // Int Division 39*e8d8bef9SDimitry Andricdef RocketUnitFPDivSqrt : ProcResource<1>; // FP Divide/Sqrt 40*e8d8bef9SDimitry Andric} 41*e8d8bef9SDimitry Andric 42*e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 43*e8d8bef9SDimitry Andric 44*e8d8bef9SDimitry Andriclet SchedModel = RocketModel in { 45*e8d8bef9SDimitry Andric 46*e8d8bef9SDimitry Andric// Branching 47*e8d8bef9SDimitry Andricdef : WriteRes<WriteJmp, [RocketUnitB]>; 48*e8d8bef9SDimitry Andricdef : WriteRes<WriteJal, [RocketUnitB]>; 49*e8d8bef9SDimitry Andricdef : WriteRes<WriteJalr, [RocketUnitB]>; 50*e8d8bef9SDimitry Andricdef : WriteRes<WriteJmpReg, [RocketUnitB]>; 51*e8d8bef9SDimitry Andric 52*e8d8bef9SDimitry Andric// Integer arithmetic and logic 53*e8d8bef9SDimitry Andricdef : WriteRes<WriteIALU32, [RocketUnitALU]>; 54*e8d8bef9SDimitry Andricdef : WriteRes<WriteIALU, [RocketUnitALU]>; 55*e8d8bef9SDimitry Andricdef : WriteRes<WriteShift32, [RocketUnitALU]>; 56*e8d8bef9SDimitry Andricdef : WriteRes<WriteShift, [RocketUnitALU]>; 57*e8d8bef9SDimitry Andric 58*e8d8bef9SDimitry Andric// Integer multiplication 59*e8d8bef9SDimitry Andriclet Latency = 4 in { 60*e8d8bef9SDimitry Andricdef : WriteRes<WriteIMul, [RocketUnitIMul]>; 61*e8d8bef9SDimitry Andricdef : WriteRes<WriteIMul32, [RocketUnitIMul]>; 62*e8d8bef9SDimitry Andric} 63*e8d8bef9SDimitry Andric 64*e8d8bef9SDimitry Andric// Integer division 65*e8d8bef9SDimitry Andric// Worst case latency is used. 66*e8d8bef9SDimitry Andricdef : WriteRes<WriteIDiv32, [RocketUnitIDiv]> { 67*e8d8bef9SDimitry Andric let Latency = 34; 68*e8d8bef9SDimitry Andric let ResourceCycles = [34]; 69*e8d8bef9SDimitry Andric} 70*e8d8bef9SDimitry Andricdef : WriteRes<WriteIDiv, [RocketUnitIDiv]> { 71*e8d8bef9SDimitry Andric let Latency = 33; 72*e8d8bef9SDimitry Andric let ResourceCycles = [33]; 73*e8d8bef9SDimitry Andric} 74*e8d8bef9SDimitry Andric 75*e8d8bef9SDimitry Andric// Memory 76*e8d8bef9SDimitry Andricdef : WriteRes<WriteSTB, [RocketUnitMem]>; 77*e8d8bef9SDimitry Andricdef : WriteRes<WriteSTH, [RocketUnitMem]>; 78*e8d8bef9SDimitry Andricdef : WriteRes<WriteSTW, [RocketUnitMem]>; 79*e8d8bef9SDimitry Andricdef : WriteRes<WriteSTD, [RocketUnitMem]>; 80*e8d8bef9SDimitry Andricdef : WriteRes<WriteFST32, [RocketUnitMem]>; 81*e8d8bef9SDimitry Andricdef : WriteRes<WriteFST64, [RocketUnitMem]>; 82*e8d8bef9SDimitry Andric 83*e8d8bef9SDimitry Andriclet Latency = 3 in { 84*e8d8bef9SDimitry Andricdef : WriteRes<WriteLDB, [RocketUnitMem]>; 85*e8d8bef9SDimitry Andricdef : WriteRes<WriteLDH, [RocketUnitMem]>; 86*e8d8bef9SDimitry Andric} 87*e8d8bef9SDimitry Andric 88*e8d8bef9SDimitry Andriclet Latency = 2 in { 89*e8d8bef9SDimitry Andricdef : WriteRes<WriteLDW, [RocketUnitMem]>; 90*e8d8bef9SDimitry Andricdef : WriteRes<WriteLDWU, [RocketUnitMem]>; 91*e8d8bef9SDimitry Andricdef : WriteRes<WriteLDD, [RocketUnitMem]>; 92*e8d8bef9SDimitry Andricdef : WriteRes<WriteFLD32, [RocketUnitMem]>; 93*e8d8bef9SDimitry Andricdef : WriteRes<WriteFLD64, [RocketUnitMem]>; 94*e8d8bef9SDimitry Andric 95*e8d8bef9SDimitry Andric// Atomic memory 96*e8d8bef9SDimitry Andricdef : WriteRes<WriteAtomicW, [RocketUnitMem]>; 97*e8d8bef9SDimitry Andricdef : WriteRes<WriteAtomicD, [RocketUnitMem]>; 98*e8d8bef9SDimitry Andric 99*e8d8bef9SDimitry Andricdef : WriteRes<WriteAtomicLDW, [RocketUnitMem]>; 100*e8d8bef9SDimitry Andricdef : WriteRes<WriteAtomicLDD, [RocketUnitMem]>; 101*e8d8bef9SDimitry Andric} 102*e8d8bef9SDimitry Andric 103*e8d8bef9SDimitry Andricdef : WriteRes<WriteAtomicSTW, [RocketUnitMem]>; 104*e8d8bef9SDimitry Andricdef : WriteRes<WriteAtomicSTD, [RocketUnitMem]>; 105*e8d8bef9SDimitry Andric 106*e8d8bef9SDimitry Andric// Single precision. 107*e8d8bef9SDimitry Andriclet Latency = 4 in { 108*e8d8bef9SDimitry Andricdef : WriteRes<WriteFALU32, [RocketUnitFPALU]>; 109*e8d8bef9SDimitry Andricdef : WriteRes<WriteFSGNJ32, [RocketUnitFPALU]>; 110*e8d8bef9SDimitry Andricdef : WriteRes<WriteFMinMax32, [RocketUnitFPALU]>; 111*e8d8bef9SDimitry Andric} 112*e8d8bef9SDimitry Andric 113*e8d8bef9SDimitry Andric// Double precision 114*e8d8bef9SDimitry Andriclet Latency = 6 in { 115*e8d8bef9SDimitry Andricdef : WriteRes<WriteFALU64, [RocketUnitFPALU]>; 116*e8d8bef9SDimitry Andricdef : WriteRes<WriteFSGNJ64, [RocketUnitFPALU]>; 117*e8d8bef9SDimitry Andricdef : WriteRes<WriteFMinMax64, [RocketUnitFPALU]>; 118*e8d8bef9SDimitry Andric} 119*e8d8bef9SDimitry Andric 120*e8d8bef9SDimitry Andric// Conversions 121*e8d8bef9SDimitry Andriclet Latency = 2 in { 122*e8d8bef9SDimitry Andricdef : WriteRes<WriteFCvtI32ToF32, [RocketUnitFPALU]>; 123*e8d8bef9SDimitry Andricdef : WriteRes<WriteFCvtI32ToF64, [RocketUnitFPALU]>; 124*e8d8bef9SDimitry Andricdef : WriteRes<WriteFCvtI64ToF32, [RocketUnitFPALU]>; 125*e8d8bef9SDimitry Andricdef : WriteRes<WriteFCvtI64ToF64, [RocketUnitFPALU]>; 126*e8d8bef9SDimitry Andricdef : WriteRes<WriteFCvtF32ToI32, [RocketUnitFPALU]>; 127*e8d8bef9SDimitry Andricdef : WriteRes<WriteFCvtF32ToI64, [RocketUnitFPALU]>; 128*e8d8bef9SDimitry Andricdef : WriteRes<WriteFCvtF64ToI32, [RocketUnitFPALU]>; 129*e8d8bef9SDimitry Andricdef : WriteRes<WriteFCvtF64ToI64, [RocketUnitFPALU]>; 130*e8d8bef9SDimitry Andricdef : WriteRes<WriteFCvtF32ToF64, [RocketUnitFPALU]>; 131*e8d8bef9SDimitry Andricdef : WriteRes<WriteFCvtF64ToF32, [RocketUnitFPALU]>; 132*e8d8bef9SDimitry Andric 133*e8d8bef9SDimitry Andricdef : WriteRes<WriteFClass32, [RocketUnitFPALU]>; 134*e8d8bef9SDimitry Andricdef : WriteRes<WriteFClass64, [RocketUnitFPALU]>; 135*e8d8bef9SDimitry Andricdef : WriteRes<WriteFCmp32, [RocketUnitFPALU]>; 136*e8d8bef9SDimitry Andricdef : WriteRes<WriteFCmp64, [RocketUnitFPALU]>; 137*e8d8bef9SDimitry Andricdef : WriteRes<WriteFMovF32ToI32, [RocketUnitFPALU]>; 138*e8d8bef9SDimitry Andricdef : WriteRes<WriteFMovI32ToF32, [RocketUnitFPALU]>; 139*e8d8bef9SDimitry Andricdef : WriteRes<WriteFMovF64ToI64, [RocketUnitFPALU]>; 140*e8d8bef9SDimitry Andricdef : WriteRes<WriteFMovI64ToF64, [RocketUnitFPALU]>; 141*e8d8bef9SDimitry Andric} 142*e8d8bef9SDimitry Andric 143*e8d8bef9SDimitry Andric// FP multiplication 144*e8d8bef9SDimitry Andriclet Latency = 5 in { 145*e8d8bef9SDimitry Andricdef : WriteRes<WriteFMul32, [RocketUnitFPALU]>; 146*e8d8bef9SDimitry Andricdef : WriteRes<WriteFMulAdd32, [RocketUnitFPALU]>; 147*e8d8bef9SDimitry Andricdef : WriteRes<WriteFMulSub32, [RocketUnitFPALU]>; 148*e8d8bef9SDimitry Andric} 149*e8d8bef9SDimitry Andric 150*e8d8bef9SDimitry Andriclet Latency = 7 in { 151*e8d8bef9SDimitry Andricdef : WriteRes<WriteFMul64, [RocketUnitFPALU]>; 152*e8d8bef9SDimitry Andricdef : WriteRes<WriteFMulAdd64, [RocketUnitFPALU]>; 153*e8d8bef9SDimitry Andricdef : WriteRes<WriteFMulSub64, [RocketUnitFPALU]>; 154*e8d8bef9SDimitry Andric} 155*e8d8bef9SDimitry Andric 156*e8d8bef9SDimitry Andric// FP division 157*e8d8bef9SDimitry Andric// FP division unit on Rocket is not pipelined, so set resource cycles to latency. 158*e8d8bef9SDimitry Andriclet Latency = 20, ResourceCycles = [20] in { 159*e8d8bef9SDimitry Andricdef : WriteRes<WriteFDiv32, [RocketUnitFPDivSqrt]>; 160*e8d8bef9SDimitry Andricdef : WriteRes<WriteFDiv64, [RocketUnitFPDivSqrt]>; 161*e8d8bef9SDimitry Andric} 162*e8d8bef9SDimitry Andric 163*e8d8bef9SDimitry Andric// FP square root unit on Rocket is not pipelined, so set resource cycles to latency. 164*e8d8bef9SDimitry Andricdef : WriteRes<WriteFSqrt32, [RocketUnitFPDivSqrt]> { let Latency = 20; 165*e8d8bef9SDimitry Andric let ResourceCycles = [20]; } 166*e8d8bef9SDimitry Andricdef : WriteRes<WriteFSqrt64, [RocketUnitFPDivSqrt]> { let Latency = 25; 167*e8d8bef9SDimitry Andric let ResourceCycles = [25]; } 168*e8d8bef9SDimitry Andric 169*e8d8bef9SDimitry Andric// Others 170*e8d8bef9SDimitry Andricdef : WriteRes<WriteCSR, []>; 171*e8d8bef9SDimitry Andricdef : WriteRes<WriteNop, []>; 172*e8d8bef9SDimitry Andric 173*e8d8bef9SDimitry Andricdef : InstRW<[WriteIALU], (instrs COPY)>; 174*e8d8bef9SDimitry Andric 175*e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===// 176*e8d8bef9SDimitry Andric// Bypass and advance 177*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadJmp, 0>; 178*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadJalr, 0>; 179*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadCSR, 0>; 180*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadStoreData, 0>; 181*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadMemBase, 0>; 182*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadIALU, 0>; 183*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadIALU32, 0>; 184*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadShift, 0>; 185*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadShift32, 0>; 186*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadIDiv, 0>; 187*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadIDiv32, 0>; 188*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadIMul, 0>; 189*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadIMul32, 0>; 190*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadAtomicWA, 0>; 191*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadAtomicWD, 0>; 192*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadAtomicDA, 0>; 193*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadAtomicDD, 0>; 194*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadAtomicLDW, 0>; 195*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadAtomicLDD, 0>; 196*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadAtomicSTW, 0>; 197*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadAtomicSTD, 0>; 198*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFMemBase, 0>; 199*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFALU32, 0>; 200*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFALU64, 0>; 201*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFMul32, 0>; 202*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFMulAdd32, 0>; 203*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFMulSub32, 0>; 204*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFMul64, 0>; 205*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFMulAdd64, 0>; 206*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFMulSub64, 0>; 207*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFDiv32, 0>; 208*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFDiv64, 0>; 209*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFSqrt32, 0>; 210*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFSqrt64, 0>; 211*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFCmp32, 0>; 212*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFCmp64, 0>; 213*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFSGNJ32, 0>; 214*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFSGNJ64, 0>; 215*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFMinMax32, 0>; 216*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFMinMax64, 0>; 217*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFCvtF32ToI32, 0>; 218*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFCvtF32ToI64, 0>; 219*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFCvtF64ToI32, 0>; 220*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFCvtF64ToI64, 0>; 221*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFCvtI32ToF32, 0>; 222*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFCvtI32ToF64, 0>; 223*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFCvtI64ToF32, 0>; 224*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFCvtI64ToF64, 0>; 225*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFCvtF32ToF64, 0>; 226*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFCvtF64ToF32, 0>; 227*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFMovF32ToI32, 0>; 228*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFMovI32ToF32, 0>; 229*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFMovF64ToI64, 0>; 230*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFMovI64ToF64, 0>; 231*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFClass32, 0>; 232*e8d8bef9SDimitry Andricdef : ReadAdvance<ReadFClass64, 0>; 233*e8d8bef9SDimitry Andric} 234