[llvm] [RISCV] Add scheduler definitions for XiangShan-KunMingHu (PR #148581)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 2 09:39:19 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]>;
----------------
topperc wrote:

Is the FP divider pipelined? The Integer divide has `ReleaseAtCycles = [20]`. Can multiple FP divides be in flight at the same time in different stages?

https://github.com/llvm/llvm-project/pull/148581


More information about the llvm-commits mailing list