RISCVSchedRocket.td 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. //==- RISCVSchedRocket.td - Rocket Scheduling Definitions ----*- tablegen -*-=//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. // ===---------------------------------------------------------------------===//
  9. // The following definitions describe the simpler per-operand machine model.
  10. // This works with MachineScheduler. See MCSchedule.h for details.
  11. // Rocket machine model for scheduling and other instruction cost heuristics.
  12. def RocketModel : SchedMachineModel {
  13. let MicroOpBufferSize = 0; // Rocket is in-order.
  14. let IssueWidth = 1; // 1 micro-op is dispatched per cycle.
  15. let LoadLatency = 3;
  16. let MispredictPenalty = 3;
  17. let CompleteModel = false;
  18. let UnsupportedFeatures = [HasStdExtZbkb, HasStdExtZbkc, HasStdExtZbkx,
  19. HasStdExtZknd, HasStdExtZkne, HasStdExtZknh,
  20. HasStdExtZksed, HasStdExtZksh, HasStdExtZkr,
  21. HasVInstructions, HasVInstructionsI64];
  22. }
  23. //===----------------------------------------------------------------------===//
  24. // Define each kind of processor resource and number available.
  25. // Modeling each pipeline as a ProcResource using the BufferSize = 0 since
  26. // Rocket is in-order.
  27. let BufferSize = 0 in {
  28. def RocketUnitALU : ProcResource<1>; // Int ALU
  29. def RocketUnitIMul : ProcResource<1>; // Int Multiply
  30. def RocketUnitMem : ProcResource<1>; // Load/Store
  31. def RocketUnitB : ProcResource<1>; // Branch
  32. def RocketUnitFPALU : ProcResource<1>; // FP ALU
  33. }
  34. let BufferSize = 1 in {
  35. def RocketUnitIDiv : ProcResource<1>; // Int Division
  36. def RocketUnitFPDivSqrt : ProcResource<1>; // FP Divide/Sqrt
  37. }
  38. //===----------------------------------------------------------------------===//
  39. let SchedModel = RocketModel in {
  40. // Branching
  41. def : WriteRes<WriteJmp, [RocketUnitB]>;
  42. def : WriteRes<WriteJal, [RocketUnitB]>;
  43. def : WriteRes<WriteJalr, [RocketUnitB]>;
  44. def : WriteRes<WriteJmpReg, [RocketUnitB]>;
  45. // Integer arithmetic and logic
  46. def : WriteRes<WriteIALU32, [RocketUnitALU]>;
  47. def : WriteRes<WriteIALU, [RocketUnitALU]>;
  48. def : WriteRes<WriteShiftImm32, [RocketUnitALU]>;
  49. def : WriteRes<WriteShiftImm, [RocketUnitALU]>;
  50. def : WriteRes<WriteShiftReg32, [RocketUnitALU]>;
  51. def : WriteRes<WriteShiftReg, [RocketUnitALU]>;
  52. // Integer multiplication
  53. let Latency = 4 in {
  54. def : WriteRes<WriteIMul, [RocketUnitIMul]>;
  55. def : WriteRes<WriteIMul32, [RocketUnitIMul]>;
  56. }
  57. // Integer division
  58. // Worst case latency is used.
  59. def : WriteRes<WriteIDiv32, [RocketUnitIDiv]> {
  60. let Latency = 34;
  61. let ResourceCycles = [34];
  62. }
  63. def : WriteRes<WriteIDiv, [RocketUnitIDiv]> {
  64. let Latency = 33;
  65. let ResourceCycles = [33];
  66. }
  67. // Memory
  68. def : WriteRes<WriteSTB, [RocketUnitMem]>;
  69. def : WriteRes<WriteSTH, [RocketUnitMem]>;
  70. def : WriteRes<WriteSTW, [RocketUnitMem]>;
  71. def : WriteRes<WriteSTD, [RocketUnitMem]>;
  72. def : WriteRes<WriteFST32, [RocketUnitMem]>;
  73. def : WriteRes<WriteFST64, [RocketUnitMem]>;
  74. let Latency = 3 in {
  75. def : WriteRes<WriteLDB, [RocketUnitMem]>;
  76. def : WriteRes<WriteLDH, [RocketUnitMem]>;
  77. }
  78. let Latency = 2 in {
  79. def : WriteRes<WriteLDW, [RocketUnitMem]>;
  80. def : WriteRes<WriteLDD, [RocketUnitMem]>;
  81. def : WriteRes<WriteFLD32, [RocketUnitMem]>;
  82. def : WriteRes<WriteFLD64, [RocketUnitMem]>;
  83. // Atomic memory
  84. def : WriteRes<WriteAtomicW, [RocketUnitMem]>;
  85. def : WriteRes<WriteAtomicD, [RocketUnitMem]>;
  86. def : WriteRes<WriteAtomicLDW, [RocketUnitMem]>;
  87. def : WriteRes<WriteAtomicLDD, [RocketUnitMem]>;
  88. }
  89. def : WriteRes<WriteAtomicSTW, [RocketUnitMem]>;
  90. def : WriteRes<WriteAtomicSTD, [RocketUnitMem]>;
  91. // Single precision.
  92. let Latency = 4 in {
  93. def : WriteRes<WriteFAdd32, [RocketUnitFPALU]>;
  94. def : WriteRes<WriteFSGNJ32, [RocketUnitFPALU]>;
  95. def : WriteRes<WriteFMinMax32, [RocketUnitFPALU]>;
  96. }
  97. // Double precision
  98. let Latency = 6 in {
  99. def : WriteRes<WriteFAdd64, [RocketUnitFPALU]>;
  100. def : WriteRes<WriteFSGNJ64, [RocketUnitFPALU]>;
  101. def : WriteRes<WriteFMinMax64, [RocketUnitFPALU]>;
  102. }
  103. // Conversions
  104. let Latency = 2 in {
  105. def : WriteRes<WriteFCvtI32ToF32, [RocketUnitFPALU]>;
  106. def : WriteRes<WriteFCvtI32ToF64, [RocketUnitFPALU]>;
  107. def : WriteRes<WriteFCvtI64ToF32, [RocketUnitFPALU]>;
  108. def : WriteRes<WriteFCvtI64ToF64, [RocketUnitFPALU]>;
  109. def : WriteRes<WriteFCvtF32ToI32, [RocketUnitFPALU]>;
  110. def : WriteRes<WriteFCvtF32ToI64, [RocketUnitFPALU]>;
  111. def : WriteRes<WriteFCvtF64ToI32, [RocketUnitFPALU]>;
  112. def : WriteRes<WriteFCvtF64ToI64, [RocketUnitFPALU]>;
  113. def : WriteRes<WriteFCvtF32ToF64, [RocketUnitFPALU]>;
  114. def : WriteRes<WriteFCvtF64ToF32, [RocketUnitFPALU]>;
  115. def : WriteRes<WriteFClass32, [RocketUnitFPALU]>;
  116. def : WriteRes<WriteFClass64, [RocketUnitFPALU]>;
  117. def : WriteRes<WriteFCmp32, [RocketUnitFPALU]>;
  118. def : WriteRes<WriteFCmp64, [RocketUnitFPALU]>;
  119. def : WriteRes<WriteFMovF32ToI32, [RocketUnitFPALU]>;
  120. def : WriteRes<WriteFMovI32ToF32, [RocketUnitFPALU]>;
  121. def : WriteRes<WriteFMovF64ToI64, [RocketUnitFPALU]>;
  122. def : WriteRes<WriteFMovI64ToF64, [RocketUnitFPALU]>;
  123. }
  124. // FP multiplication
  125. let Latency = 5 in {
  126. def : WriteRes<WriteFMul32, [RocketUnitFPALU]>;
  127. def : WriteRes<WriteFMA32, [RocketUnitFPALU]>;
  128. }
  129. let Latency = 7 in {
  130. def : WriteRes<WriteFMul64, [RocketUnitFPALU]>;
  131. def : WriteRes<WriteFMA64, [RocketUnitFPALU]>;
  132. }
  133. // FP division
  134. // FP division unit on Rocket is not pipelined, so set resource cycles to latency.
  135. let Latency = 20, ResourceCycles = [20] in {
  136. def : WriteRes<WriteFDiv32, [RocketUnitFPDivSqrt]>;
  137. def : WriteRes<WriteFDiv64, [RocketUnitFPDivSqrt]>;
  138. }
  139. // FP square root unit on Rocket is not pipelined, so set resource cycles to latency.
  140. def : WriteRes<WriteFSqrt32, [RocketUnitFPDivSqrt]> { let Latency = 20;
  141. let ResourceCycles = [20]; }
  142. def : WriteRes<WriteFSqrt64, [RocketUnitFPDivSqrt]> { let Latency = 25;
  143. let ResourceCycles = [25]; }
  144. // Others
  145. def : WriteRes<WriteCSR, []>;
  146. def : WriteRes<WriteNop, []>;
  147. def : InstRW<[WriteIALU], (instrs COPY)>;
  148. //===----------------------------------------------------------------------===//
  149. // Bypass and advance
  150. def : ReadAdvance<ReadJmp, 0>;
  151. def : ReadAdvance<ReadJalr, 0>;
  152. def : ReadAdvance<ReadCSR, 0>;
  153. def : ReadAdvance<ReadStoreData, 0>;
  154. def : ReadAdvance<ReadMemBase, 0>;
  155. def : ReadAdvance<ReadIALU, 0>;
  156. def : ReadAdvance<ReadIALU32, 0>;
  157. def : ReadAdvance<ReadShiftImm, 0>;
  158. def : ReadAdvance<ReadShiftImm32, 0>;
  159. def : ReadAdvance<ReadShiftReg, 0>;
  160. def : ReadAdvance<ReadShiftReg32, 0>;
  161. def : ReadAdvance<ReadIDiv, 0>;
  162. def : ReadAdvance<ReadIDiv32, 0>;
  163. def : ReadAdvance<ReadIMul, 0>;
  164. def : ReadAdvance<ReadIMul32, 0>;
  165. def : ReadAdvance<ReadAtomicWA, 0>;
  166. def : ReadAdvance<ReadAtomicWD, 0>;
  167. def : ReadAdvance<ReadAtomicDA, 0>;
  168. def : ReadAdvance<ReadAtomicDD, 0>;
  169. def : ReadAdvance<ReadAtomicLDW, 0>;
  170. def : ReadAdvance<ReadAtomicLDD, 0>;
  171. def : ReadAdvance<ReadAtomicSTW, 0>;
  172. def : ReadAdvance<ReadAtomicSTD, 0>;
  173. def : ReadAdvance<ReadFStoreData, 0>;
  174. def : ReadAdvance<ReadFMemBase, 0>;
  175. def : ReadAdvance<ReadFAdd32, 0>;
  176. def : ReadAdvance<ReadFAdd64, 0>;
  177. def : ReadAdvance<ReadFMul32, 0>;
  178. def : ReadAdvance<ReadFMul64, 0>;
  179. def : ReadAdvance<ReadFMA32, 0>;
  180. def : ReadAdvance<ReadFMA64, 0>;
  181. def : ReadAdvance<ReadFDiv32, 0>;
  182. def : ReadAdvance<ReadFDiv64, 0>;
  183. def : ReadAdvance<ReadFSqrt32, 0>;
  184. def : ReadAdvance<ReadFSqrt64, 0>;
  185. def : ReadAdvance<ReadFCmp32, 0>;
  186. def : ReadAdvance<ReadFCmp64, 0>;
  187. def : ReadAdvance<ReadFSGNJ32, 0>;
  188. def : ReadAdvance<ReadFSGNJ64, 0>;
  189. def : ReadAdvance<ReadFMinMax32, 0>;
  190. def : ReadAdvance<ReadFMinMax64, 0>;
  191. def : ReadAdvance<ReadFCvtF32ToI32, 0>;
  192. def : ReadAdvance<ReadFCvtF32ToI64, 0>;
  193. def : ReadAdvance<ReadFCvtF64ToI32, 0>;
  194. def : ReadAdvance<ReadFCvtF64ToI64, 0>;
  195. def : ReadAdvance<ReadFCvtI32ToF32, 0>;
  196. def : ReadAdvance<ReadFCvtI32ToF64, 0>;
  197. def : ReadAdvance<ReadFCvtI64ToF32, 0>;
  198. def : ReadAdvance<ReadFCvtI64ToF64, 0>;
  199. def : ReadAdvance<ReadFCvtF32ToF64, 0>;
  200. def : ReadAdvance<ReadFCvtF64ToF32, 0>;
  201. def : ReadAdvance<ReadFMovF32ToI32, 0>;
  202. def : ReadAdvance<ReadFMovI32ToF32, 0>;
  203. def : ReadAdvance<ReadFMovF64ToI64, 0>;
  204. def : ReadAdvance<ReadFMovI64ToF64, 0>;
  205. def : ReadAdvance<ReadFClass32, 0>;
  206. def : ReadAdvance<ReadFClass64, 0>;
  207. //===----------------------------------------------------------------------===//
  208. // Unsupported extensions
  209. defm : UnsupportedSchedV;
  210. defm : UnsupportedSchedZba;
  211. defm : UnsupportedSchedZbb;
  212. defm : UnsupportedSchedZbc;
  213. defm : UnsupportedSchedZbs;
  214. defm : UnsupportedSchedZbkb;
  215. defm : UnsupportedSchedZbkx;
  216. defm : UnsupportedSchedZfh;
  217. defm : UnsupportedSchedSFB;
  218. }