//=- RISCVSchedSpacemitX60.td - Spacemit X60 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 // //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// // // Scheduler model for the SpacemiT-X60 processor based on documentation of the // C908 and experiments on real hardware (bpi-f3). // //===----------------------------------------------------------------------===// def SpacemitX60Model : SchedMachineModel { let IssueWidth = 2; // dual-issue let MicroOpBufferSize = 0; // in-order let LoadLatency = 3; // worse case: >= 3 let MispredictPenalty = 9; // nine-stage let CompleteModel = 0; let UnsupportedFeatures = [HasStdExtZknd, HasStdExtZkne, HasStdExtZknh, HasStdExtZksed, HasStdExtZksh, HasStdExtZkr]; } let SchedModel = SpacemitX60Model in { //===----------------------------------------------------------------------===// // Define processor resources for Spacemit-X60 // Information gathered from the C908 user manual: let BufferSize = 0 in { // The LSU supports dual issue for scalar store/load instructions def SMX60_LS : ProcResource<2>; // An IEU can decode and issue two instructions at the same time def SMX60_IEUA : ProcResource<1>; def SMX60_IEUB : ProcResource<1>; def SMX60_IEU : ProcResGroup<[SMX60_IEUA, SMX60_IEUB]>; // Although the X60 does appear to support multiple issue for at least some // floating point instructions, this model assumes single issue as // increasing it reduces the gains we saw in performance def SMX60_FP : ProcResource<1>; } //===----------------------------------------------------------------------===// // Branching def : WriteRes; def : WriteRes; def : WriteRes; // Integer arithmetic and logic // Latency of ALU instructions is 1, but add.uw is 2 def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; // Integer multiplication def : WriteRes { let Latency = 3; } // The latency of mul is 5, while in mulh, mulhsu, mulhu is 6 // Worst case latency is used def : WriteRes { let Latency = 6; } // Integer division/remainder // TODO: Latency set based on C908 datasheet and hasn't been // confirmed experimentally. let Latency = 12, ReleaseAtCycles = [12] in { def : WriteRes; def : WriteRes; } let Latency = 20, ReleaseAtCycles = [20] in { def : WriteRes; def : WriteRes; } // Bitmanip 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; let Latency = 2 in { def : WriteRes; def : WriteRes; def : WriteRes; } // Single-bit instructions def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; // Memory/Atomic memory let Latency = 4 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; } // Atomics let Latency = 8 in { def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; } let Latency = 12 in { def : WriteRes; def : WriteRes; } // Floating point units Half precision let Latency = 4 in { def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; } def : WriteRes { let Latency = 5; } let Latency = 12, ReleaseAtCycles = [12] in { def : WriteRes; def : WriteRes; } // Single precision let Latency = 4 in { def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; } def : WriteRes { let Latency = 5; } let Latency = 15, ReleaseAtCycles = [15] in { def : WriteRes; def : WriteRes; } // Double precision let Latency = 5 in { def : WriteRes; def : WriteRes; def : WriteRes; } def : WriteRes { let Latency = 4; } def : WriteRes { let Latency = 6; } let Latency = 22, ReleaseAtCycles = [22] in { def : WriteRes; def : WriteRes; } // Conversions let Latency = 6 in { def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; } let Latency = 4 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; } let Latency = 6 in { def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; } let Latency = 4 in { def : WriteRes; def : WriteRes; def : WriteRes; def : WriteRes; } // Others def : WriteRes; def : WriteRes; //===----------------------------------------------------------------------===// // 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; // Single-bit instructions def : ReadAdvance; def : ReadAdvance; //===----------------------------------------------------------------------===// // Unsupported extensions defm : UnsupportedSchedQ; defm : UnsupportedSchedV; defm : UnsupportedSchedZabha; defm : UnsupportedSchedZbkb; defm : UnsupportedSchedZbkx; defm : UnsupportedSchedZfa; defm : UnsupportedSchedZvk; defm : UnsupportedSchedSFB; defm : UnsupportedSchedXsf; }