[llvm] [RISCV] Add scheduler definitions for XiangShan-KunMingHu (PR #148581)
Lin Wang via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 3 02:54:36 PDT 2026
================
@@ -0,0 +1,357 @@
+//==- RISCVSchedXiangShanKunMingHu.td - XiangShanKunMingHu 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
+//
+//===----------------------------------------------------------------------===//
+
+// The XiangShan is a high-performance open-source RISC-V processor project
+// initiated by the Institute of Computing Technology(ICT), Chinese Academy of Sciences(CAS).
+// The KunMingHu architecture is its third-generation derivative,
+// developed by the Institute of Computing Technology, Chinese Academy of Sciences
+// and the Beijing Institute of Open Source Chip (BOSC),
+// with a focus on achieving higher performance.
+// Source: https://github.com/OpenXiangShan/XiangShan
+// Documentation: https://docs.xiangshan.cc/projects/design/en/latest/
+// User Guide: https://docs.xiangshan.cc/projects/user-guide/en/latest/
+
+def XiangShanKunMingHuModel : SchedMachineModel {
+ let IssueWidth = 6; // 6-way decode and dispatch
+ let MicroOpBufferSize = 256;
+ let LoopMicroOpBufferSize = 48; // Instruction queue size
+ let LoadLatency = 6;
+ let MispredictPenalty = 13; // Based on estimate of pipeline depth.
+ let CompleteModel = 0;
+ let UnsupportedFeatures = [HasStdExtZcmt, HasStdExtZkr, HasVInstructions,
+ HasVInstructionsI64];
+}
+
+let SchedModel = XiangShanKunMingHuModel in {
+// Define each kind of processor resource and number available.
+/// Pipline
+let BufferSize = 24 in {
+ // Integer
+ def XSPipeALU0 : ProcResource<1>; // ALU, MUL, BKU
+ def XSPipeALU1 : ProcResource<1>; // ALU, MUL, BKU
+ def XSPipeALU2 : ProcResource<1>; // ALU
+ def XSPipeALU3 : ProcResource<1>; // ALU
+
+ def XSPipeBJU0 : ProcResource<1>; // BRU, JMP
+ def XSPipeBJU1 : ProcResource<1>; // BRU, JMP
+ def XSPipeBJU2 : ProcResource<1>; // BRU, JMP, I2F, I2V, VSet
+ def XSPipeBJU3 : ProcResource<1>; // CSR, Fence, DIV
+}
+
+let BufferSize = 18 in {
+ // Floating-point
+ def XSPipeFEX0 : ProcResource<1>; // FALU, FMA, FCVT, F2V
+ def XSPipeFEX1 : ProcResource<1>; // FDIV
+ def XSPipeFEX2 : ProcResource<1>; // FALU, FMA
+ def XSPipeFEX3 : ProcResource<1>; // FDIV
+ def XSPipeFEX4 : ProcResource<1>; // FALU, FMA
+}
+
+let BufferSize = 16 in {
+ // Load and store
+ def XSPipeLDU : ProcResource<3>; // LDU
+
+ def XSPipeSTA : ProcResource<2>; // STA
+ def XSPipeSTD : ProcResource<2>; // STD
+}
+
+def XSPipeGroupALU : ProcResGroup<[XSPipeALU0, XSPipeALU1, XSPipeALU2, XSPipeALU3]>;
+def XSPipeGroupMUL : ProcResGroup<[XSPipeALU0, XSPipeALU1]>;
+def XSPipeGroupBKU : ProcResGroup<[XSPipeALU0, XSPipeALU1]>;
+def XSPipeGroupBRU : ProcResGroup<[XSPipeBJU0, XSPipeBJU1, XSPipeBJU2]>;
+
+def XSPipeGroupFALU : ProcResGroup<[XSPipeFEX0, XSPipeFEX2, XSPipeFEX4]>;
+def XSPipeGroupFMA : ProcResGroup<[XSPipeFEX0, XSPipeFEX2, XSPipeFEX4]>;
+def XSPipeGroupFDIV : ProcResGroup<[XSPipeFEX1, XSPipeFEX3]>;
+
+def XSPipeGroupSTU : ProcResGroup<[XSPipeSTA, XSPipeSTD]>;
+
+//===----------------------------------------------------------------------===//
+
+
+// Jump
+def : WriteRes<WriteJmp, [XSPipeGroupBRU]>;
+def : WriteRes<WriteJal, [XSPipeGroupBRU]>;
+def : WriteRes<WriteJalr, [XSPipeGroupBRU]>;
+
+// Integer arithmetic and logic
+def : WriteRes<WriteIALU32, [XSPipeGroupALU]>;
+def : WriteRes<WriteIALU, [XSPipeGroupALU]>;
+def : WriteRes<WriteShiftImm32, [XSPipeGroupALU]>;
+def : WriteRes<WriteShiftImm, [XSPipeGroupALU]>;
+def : WriteRes<WriteShiftReg32, [XSPipeGroupALU]>;
+def : WriteRes<WriteShiftReg, [XSPipeGroupALU]>;
+
+// Integer multiplication
+let Latency = 2 in {
+ def : WriteRes<WriteIMul, [XSPipeGroupMUL]>;
+ def : WriteRes<WriteIMul32, [XSPipeGroupMUL]>;
+}
+
+// Integer division
+// Worst case latency is used.
+// The latency of integer division ranges from 4 to 20.
+let Latency = 20, ReleaseAtCycles = [20] in {
+ def : WriteRes<WriteIDiv32, [XSPipeBJU3]>;
+ def : WriteRes<WriteIDiv, [XSPipeBJU3]>;
+ def : WriteRes<WriteIRem32, [XSPipeBJU3]>;
+ def : WriteRes<WriteIRem, [XSPipeBJU3]>;
+}
+
+// Memory
+let Latency = 4 in {
+ def : WriteRes<WriteSTB, [XSPipeGroupSTU]>;
+ def : WriteRes<WriteSTH, [XSPipeGroupSTU]>;
+ def : WriteRes<WriteSTW, [XSPipeGroupSTU]>;
+ def : WriteRes<WriteSTD, [XSPipeGroupSTU]>;
+ def : WriteRes<WriteFST32, [XSPipeGroupSTU]>;
+ def : WriteRes<WriteFST64, [XSPipeGroupSTU]>;
+ def : WriteRes<WriteAtomicSTW, [XSPipeGroupSTU]>;
+ def : WriteRes<WriteAtomicSTD, [XSPipeGroupSTU]>;
+}
+
+let Latency = 6 in {
+ def : WriteRes<WriteLDB, [XSPipeLDU]>;
+ def : WriteRes<WriteLDH, [XSPipeLDU]>;
+ def : WriteRes<WriteLDW, [XSPipeLDU]>;
+ def : WriteRes<WriteLDD, [XSPipeLDU]>;
+
+ def : WriteRes<WriteFLD32, [XSPipeLDU]>;
+ def : WriteRes<WriteFLD64, [XSPipeLDU]>;
+
+ def : WriteRes<WriteAtomicW, [XSPipeLDU]>;
+ def : WriteRes<WriteAtomicD, [XSPipeLDU]>;
+ def : WriteRes<WriteAtomicLDW, [XSPipeLDU]>;
+ def : WriteRes<WriteAtomicLDD, [XSPipeLDU]>;
+}
+
+let Latency = 1 in {
+ def : WriteRes<WriteFAdd32, [XSPipeGroupFALU]>;
+ def : WriteRes<WriteFAdd64, [XSPipeGroupFALU]>;
+}
+
+let Latency = 2 in {
+ def : WriteRes<WriteFCmp32, [XSPipeGroupFALU]>;
+ def : WriteRes<WriteFCmp64, [XSPipeGroupFALU]>;
+ def : WriteRes<WriteFMinMax32, [XSPipeGroupFALU]>;
+ def : WriteRes<WriteFMinMax64, [XSPipeGroupFALU]>;
+ def : WriteRes<WriteFClass32, [XSPipeGroupFALU]>;
+ def : WriteRes<WriteFClass64, [XSPipeGroupFALU]>;
+ def : WriteRes<WriteFSGNJ32, [XSPipeGroupFALU]>;
+ def : WriteRes<WriteFSGNJ64, [XSPipeGroupFALU]>;
+}
+
+let Latency = 3 in {
+ def : WriteRes<WriteFMul32, [XSPipeGroupFMA]>;
+ def : WriteRes<WriteFMul64, [XSPipeGroupFMA]>;
+ def : WriteRes<WriteFMA32, [XSPipeGroupFMA]>;
+ def : WriteRes<WriteFMA64, [XSPipeGroupFMA]>;
+}
+
+// FDIV
+let Latency = 10 in {
+ def : WriteRes<WriteFDiv32, [XSPipeGroupFDIV]>;
+ def : WriteRes<WriteFSqrt32, [XSPipeGroupFDIV]>;
+}
+let Latency = 15 in {
+ def : WriteRes<WriteFDiv64, [XSPipeGroupFDIV]>;
+ def : WriteRes<WriteFSqrt64, [XSPipeGroupFDIV]>;
+}
+
+// FCVT
+let Latency = 2 in {
+ def : WriteRes<WriteFCvtF32ToI32, [XSPipeFEX0]>;
+ def : WriteRes<WriteFCvtF32ToI64, [XSPipeFEX0]>;
+ def : WriteRes<WriteFCvtF64ToI32, [XSPipeFEX0]>;
+ def : WriteRes<WriteFCvtF64ToI64, [XSPipeFEX0]>;
+ def : WriteRes<WriteFCvtF64ToF32, [XSPipeFEX0]>;
+ def : WriteRes<WriteFCvtF32ToF64, [XSPipeFEX0]>;
+ def : WriteRes<WriteFMovF64ToI64, [XSPipeFEX0]>;
+ def : WriteRes<WriteFMovF32ToI32, [XSPipeFEX0]>;
+}
+
+// I2V
+let Latency = 0 in {
----------------
MrLinWang wrote:
Thank you! The reason I used "I2V" is that, in the [Kunminghu Source Code in DecodeUnit](https://github.com/OpenXiangShan/XiangShan/blob/kunminghu-v2/src/main/scala/xiangshan/backend/decode/DecodeUnit.scala#L404)
, these instructions are defined as "I2V". However, I understand this could be misleading, as "I2V" is commonly associated with "integer to vector" conversions. To avoid confusion, I’ll update them to "I2F" as you suggested.
As for the zero latency, it’s defined in the [Kunminghu Source Code in I2vCfg Unit](https://github.com/OpenXiangShan/XiangShan/blob/kunminghu-v2/src/main/scala/xiangshan/backend/fu/FuConfig.scala#L273)
. I’ll check with the hardware team to confirm whether this value is appropriate.
Thanks again for your valuable input!
https://github.com/llvm/llvm-project/pull/148581
More information about the llvm-commits
mailing list