//==- RISCVSchedSiFiveP400.td - SiFiveP400 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 SiFiveP400Model : SchedMachineModel { let IssueWidth = 3; // 3 micro-ops are dispatched per cycle. let MicroOpBufferSize = 56; // 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 UnsupportedFeatures = [HasStdExtZbkb, HasStdExtZbkc, HasStdExtZbkx, HasStdExtZcmt, HasStdExtZknd, HasStdExtZkne, HasStdExtZknh, HasStdExtZksed, HasStdExtZksh, HasStdExtZkr]; let CompleteModel = false; } // The SiFiveP400 microarchitecure has 6 pipelines: // Three pipelines for integer operations. // One pipeline for FPU operations. // One pipeline for Load operations. // One pipeline for Store operations. let SchedModel = SiFiveP400Model in { def SiFiveP400IEXQ0 : ProcResource<1>; def SiFiveP400IEXQ1 : ProcResource<1>; def SiFiveP400IEXQ2 : ProcResource<1>; def SiFiveP400FEXQ0 : ProcResource<1>; def SiFiveP400Load : ProcResource<1>; def SiFiveP400Store : ProcResource<1>; def SiFiveP400IntArith : ProcResGroup<[SiFiveP400IEXQ0, SiFiveP400IEXQ1, SiFiveP400IEXQ2]>; defvar SiFiveP400Branch = SiFiveP400IEXQ0; defvar SiFiveP400SYS = SiFiveP400IEXQ1; defvar SiFiveP400MulDiv = SiFiveP400IEXQ2; defvar SiFiveP400I2F = SiFiveP400IEXQ2; def SiFiveP400Div : ProcResource<1>; defvar SiFiveP400FloatArith = SiFiveP400FEXQ0; defvar SiFiveP400F2I = SiFiveP400FEXQ0; def SiFiveP400FloatDiv : 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 P400WriteCMOV : SchedWriteRes<[SiFiveP400Branch, SiFiveP400IEXQ1]> { let Latency = 2; let NumMicroOps = 2; } def : InstRW<[P400WriteCMOV], (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; 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; def : ReadAdvance; def : ReadAdvance; //===----------------------------------------------------------------------===// // Unsupported extensions defm : UnsupportedSchedZabha; defm : UnsupportedSchedZbc; defm : UnsupportedSchedZbkb; defm : UnsupportedSchedZbkx; defm : UnsupportedSchedSFB; defm : UnsupportedSchedZfa; defm : UnsupportedSchedV; defm : UnsupportedSchedXsfvcp; defm : UnsupportedSchedZvk; }