diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td --- a/llvm/lib/Target/RISCV/RISCV.td +++ b/llvm/lib/Target/RISCV/RISCV.td @@ -194,6 +194,7 @@ include "RISCVRegisterBanks.td" include "RISCVSchedRocket32.td" include "RISCVSchedRocket64.td" +include "RISCVSchedRISCBoy.td" //===----------------------------------------------------------------------===// // RISC-V processors supported. @@ -209,6 +210,8 @@ def : ProcessorModel<"rocket-rv64", Rocket64Model, [Feature64Bit, FeatureRVCHints]>; +// https://github.com/Wren6991/RISCBoy +def : ProcessorModel<"riscboy", RISCBoyModel, [FeatureStdExtM, FeatureStdExtC]>; //===----------------------------------------------------------------------===// // Define the RISC-V target. diff --git a/llvm/lib/Target/RISCV/RISCVSchedRISCBoy.td b/llvm/lib/Target/RISCV/RISCVSchedRISCBoy.td new file mode 100644 --- /dev/null +++ b/llvm/lib/Target/RISCV/RISCVSchedRISCBoy.td @@ -0,0 +1,243 @@ +//==- RISCVSchedRISCBoy.td - RISCBoy Scheduling Definitions -*- 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 +// +//===----------------------------------------------------------------------===// + +// ===---------------------------------------------------------------------===// +// The following is a scheduling model for RISCBoy, a very well-documented open- +// source RISC-V chip. It implements the RV32IMC instruction set, using a +// conventional 5-stage in-order pipeline. +// +// There are lots of documents about the core in the following document: +// https://github.com/Wren6991/RISCBoy/blob/master/doc/riscboy_doc.pdf +// Section references in comments below are to this document. +// + +// ===---------------------------------------------------------------------===// +// The following definitions describe the simpler per-operand machine model. +// This works with MachineScheduler. See MCSchedule.h for details. + +def RISCBoyModel : SchedMachineModel { + // RISCBoy is in-order + let MicroOpBufferSize = 0; + + // RISCBoy is single-issue + let IssueWidth = 1; + + // RISCBoy has some funky instruction fetch fun + let LoopMicroOpBufferSize = 2; + + // I'm entirely not sure about this. + // let LoadLatency = 2; + + + // From Table in §2.1.4 + let MispredictPenalty = 2; + + // RISCBoy has plugins (§2.6) so we won't claim to be complete. + let CompleteModel = 0; + + let UnsupportedFeatures = [ + IsRV64, // 64-bit + HasStdExtA, // Atomics + HasStdExtF, // Floats + HasStdExtD, // Doubles + // Bitwise Manipulation + HasStdExtB, + HasStdExtZbb, + HasStdExtZbc, + HasStdExtZbe, + HasStdExtZbf, + HasStdExtZbm, + HasStdExtZbp, + HasStdExtZbr, + HasStdExtZbs, + HasStdExtZbt, + HasStdExtZbproposedc, + ]; +} // RISCBoyModel + +//===----------------------------------------------------------------------===// +// Define each kind of processor resource and number available. +// +// Modeling each pipeline as a ProcResource using the BufferSize = 0 since +// RISCBoy is in-order. + +let BufferSize = 0 in { + +def RISCBoyUnitALU : ProcResource<1>; // ALU +def RISCBoyUnitMemory : ProcResource<1>; // Load/Store +def RISCBoyUnitBranch : ProcResource<1>; // Branch +def RISCBoyUnitMPlugin : ProcResource<1>; // Multiply Plugin (§2.6.1, §2.6.2) + +} // BufferSize = 0 + + +let SchedModel = RISCBoyModel in { + +// Branches +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; + +// ALU +def : WriteRes; +def : WriteRes; + +// Use worst-case §2.6.1 M-small plugin: 1 cycle per bit, 32 bits. +let Latency = 32, ResourceCycles = [32] in { + def : WriteRes; + def : WriteRes; +} // Latency = 32, ResourceCycles = [32] + +// Memory +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; + +// CSRs +def : WriteRes; + +// Nop +def : WriteRes; + +//===----------------------------------------------------------------------===// +// RISCBoy supports forwarding (operand bypass) §2.2.1 + +// def : ReadAdvance< +def : ReadAdvance; +def : ReadAdvance; +def : ReadAdvance; +def : ReadAdvance; +def : ReadAdvance; +def : ReadAdvance; +def : ReadAdvance; +def : ReadAdvance; +def : ReadAdvance; + +let Unsupported = 1 in { + +// FP Load/Store +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; + +// Atomic Arithmetic/Load/Store +def : WriteRes; +def : WriteRes; +def : WriteRes; + +// FP ALU +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; + +// FP Convert/Move +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; + +// 64-bit ALU +def : WriteRes; +def : WriteRes; +def : WriteRes; +def : WriteRes; + +// 64-bit Load/Store +def : WriteRes; +def : WriteRes; +def : WriteRes; + +// 64-bit Atomic Arithmetic/Load/Store +def : WriteRes; +def : WriteRes; +def : WriteRes; + +// Reads +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; + +} // Unsupported = 1 + +} // SchedModel = RISCBoyModel \ No newline at end of file