//==- RISCVSchedSiFiveP500.td - SiFiveP500 Scheduling Defs ---*- tablegen -*-=// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// def SiFiveP500Model : SchedMachineModel { let IssueWidth = 3; // 3 micro-ops are dispatched per cycle. let MicroOpBufferSize = 96; // Max micro-ops that can be buffered. let LoadLatency = 4; // Cycles for loads to access the cache. let MispredictPenalty = 9; // Extra cycles for a mispredicted branch. let CompleteModel = false; } // The SiFiveP500 microarchitecure has 7 pipelines: // Three pipelines for integer operations. // Two pipelines for FPU operations. // One pipeline for Load operations. // One pipeline for Store operations. let SchedModel = SiFiveP500Model in { def SiFiveP500IEXQ0 : ProcResource<1>; def SiFiveP500IEXQ1 : ProcResource<1>; def SiFiveP500IEXQ2 : ProcResource<1>; def SiFiveP500FEXQ0 : ProcResource<1>; def SiFiveP500FEXQ1 : ProcResource<1>; def SiFiveP500Load : ProcResource<1>; def SiFiveP500Store : ProcResource<1>; def SiFiveP500IntArith : ProcResGroup<[SiFiveP500IEXQ0, SiFiveP500IEXQ1, SiFiveP500IEXQ2]>; defvar SiFiveP500Branch = SiFiveP500IEXQ0; defvar SiFiveP500SYS = SiFiveP500IEXQ1; defvar SiFiveP500CMOV = SiFiveP500IEXQ1; defvar SiFiveP500MulI2F = SiFiveP500IEXQ2; def SiFiveP500Div : ProcResource<1>; def SiFiveP500FloatArith : ProcResGroup<[SiFiveP500FEXQ0, SiFiveP500FEXQ1]>; defvar SiFiveP500F2I = SiFiveP500FEXQ0; def SiFiveP500FloatDiv : ProcResource<1>; let Latency = 1 in { // Integer arithmetic and logic def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; // Branching def : WriteRes; def : WriteRes; def : WriteRes; } // CMOV def P500WriteCMOV : SchedWriteRes<[SiFiveP500Branch, SiFiveP500CMOV]> { let Latency = 2; let NumMicroOps = 2; } def : InstRW<[P500WriteCMOV], (instrs PseudoCCMOVGPRNoX0)>; let Latency = 3 in { // Integer multiplication def : WriteRes; def : WriteRes; // cpop[w] look exactly like multiply. def : WriteRes; def : WriteRes; } // Integer division def : WriteRes { let Latency = 35; let ReleaseAtCycles = [1, 34]; } def : WriteRes { let Latency = 20; let ReleaseAtCycles = [1, 19]; } // Integer remainder def : WriteRes { let Latency = 35; let ReleaseAtCycles = [1, 34]; } def : WriteRes { let Latency = 20; let ReleaseAtCycles = [1, 19]; } let Latency = 1 in { // Bitmanip def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; } // Memory let Latency = 1 in { def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; } let Latency = 4 in { def : WriteRes; def : WriteRes; } let Latency = 4 in { def : WriteRes; def : WriteRes; } let Latency = 5 in { def : WriteRes; def : WriteRes; def : WriteRes; } // Atomic memory let Latency = 3 in { def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; } // Floating point let Latency = 4 in { def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; } let Latency = 2 in { def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; } // Half precision. def : WriteRes { let Latency = 19; let ReleaseAtCycles = [1, 18]; } def : WriteRes { let Latency = 18; let ReleaseAtCycles = [1, 17]; } // Single precision. def : WriteRes { let Latency = 19; let ReleaseAtCycles = [1, 18]; } def : WriteRes { let Latency = 18; let ReleaseAtCycles = [1, 17]; } // Double precision def : WriteRes { let Latency = 33; let ReleaseAtCycles = [1, 32]; } def : WriteRes { let Latency = 33; let ReleaseAtCycles = [1, 32]; } // Conversions let Latency = 2 in { def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; } // Others def : WriteRes; def : WriteRes; // FIXME: This could be better modeled by looking at the regclasses of the operands. def : InstRW<[WriteIALU, ReadIALU], (instrs COPY)>; //===----------------------------------------------------------------------===// // Bypass and advance def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; // Bitmanip def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; def : ReadAdvance; //===----------------------------------------------------------------------===// // Unsupported extensions defm : UnsupportedSchedQ; defm : UnsupportedSchedV; defm : UnsupportedSchedZabha; defm : UnsupportedSchedZbc; defm : UnsupportedSchedZbs; defm : UnsupportedSchedZbkb; defm : UnsupportedSchedZbkx; defm : UnsupportedSchedSFB; defm : UnsupportedSchedZfa; defm : UnsupportedSchedZvk; defm : UnsupportedSchedXsf; }