RISCVSchedSiFive7.td 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. //==- RISCVSchedSiFive7.td - SiFive7 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. // SiFive7 machine model for scheduling and other instruction cost heuristics.
  10. def SiFive7Model : SchedMachineModel {
  11. let MicroOpBufferSize = 0; // Explicitly set to zero since SiFive7 is in-order.
  12. let IssueWidth = 2; // 2 micro-ops are dispatched per cycle.
  13. let LoadLatency = 3;
  14. let MispredictPenalty = 3;
  15. let CompleteModel = 0;
  16. let UnsupportedFeatures = [HasStdExtZbkb, HasStdExtZbkc, HasStdExtZbkx,
  17. HasStdExtZknd, HasStdExtZkne, HasStdExtZknh,
  18. HasStdExtZksed, HasStdExtZksh, HasStdExtZkr,
  19. HasVInstructions];
  20. }
  21. // The SiFive7 microarchitecture has two pipelines: A and B.
  22. // Pipe A can handle memory, integer alu and vector operations.
  23. // Pipe B can handle integer alu, control flow, integer multiply and divide,
  24. // and floating point computation.
  25. let SchedModel = SiFive7Model in {
  26. let BufferSize = 0 in {
  27. def SiFive7PipeA : ProcResource<1>;
  28. def SiFive7PipeB : ProcResource<1>;
  29. }
  30. let BufferSize = 1 in {
  31. def SiFive7IDiv : ProcResource<1> { let Super = SiFive7PipeB; } // Int Division
  32. def SiFive7FDiv : ProcResource<1> { let Super = SiFive7PipeB; } // FP Division/Sqrt
  33. }
  34. def SiFive7PipeAB : ProcResGroup<[SiFive7PipeA, SiFive7PipeB]>;
  35. // Branching
  36. def : WriteRes<WriteJmp, [SiFive7PipeB]>;
  37. def : WriteRes<WriteJal, [SiFive7PipeB]>;
  38. def : WriteRes<WriteJalr, [SiFive7PipeB]>;
  39. def : WriteRes<WriteJmpReg, [SiFive7PipeB]>;
  40. //Short forward branch
  41. def : WriteRes<WriteSFB, [SiFive7PipeA, SiFive7PipeB]> {
  42. let Latency = 3;
  43. let NumMicroOps = 2;
  44. }
  45. // Integer arithmetic and logic
  46. let Latency = 3 in {
  47. def : WriteRes<WriteIALU, [SiFive7PipeAB]>;
  48. def : WriteRes<WriteIALU32, [SiFive7PipeAB]>;
  49. def : WriteRes<WriteShiftImm, [SiFive7PipeAB]>;
  50. def : WriteRes<WriteShiftImm32, [SiFive7PipeAB]>;
  51. def : WriteRes<WriteShiftReg, [SiFive7PipeAB]>;
  52. def : WriteRes<WriteShiftReg32, [SiFive7PipeAB]>;
  53. }
  54. // Integer multiplication
  55. let Latency = 3 in {
  56. def : WriteRes<WriteIMul, [SiFive7PipeB]>;
  57. def : WriteRes<WriteIMul32, [SiFive7PipeB]>;
  58. }
  59. // Integer division
  60. def : WriteRes<WriteIDiv, [SiFive7PipeB, SiFive7IDiv]> {
  61. let Latency = 16;
  62. let ResourceCycles = [1, 15];
  63. }
  64. def : WriteRes<WriteIDiv32, [SiFive7PipeB, SiFive7IDiv]> {
  65. let Latency = 16;
  66. let ResourceCycles = [1, 15];
  67. }
  68. // Memory
  69. def : WriteRes<WriteSTB, [SiFive7PipeA]>;
  70. def : WriteRes<WriteSTH, [SiFive7PipeA]>;
  71. def : WriteRes<WriteSTW, [SiFive7PipeA]>;
  72. def : WriteRes<WriteSTD, [SiFive7PipeA]>;
  73. def : WriteRes<WriteFST32, [SiFive7PipeA]>;
  74. def : WriteRes<WriteFST64, [SiFive7PipeA]>;
  75. let Latency = 3 in {
  76. def : WriteRes<WriteLDB, [SiFive7PipeA]>;
  77. def : WriteRes<WriteLDH, [SiFive7PipeA]>;
  78. def : WriteRes<WriteLDW, [SiFive7PipeA]>;
  79. def : WriteRes<WriteLDD, [SiFive7PipeA]>;
  80. }
  81. let Latency = 2 in {
  82. def : WriteRes<WriteFLD32, [SiFive7PipeA]>;
  83. def : WriteRes<WriteFLD64, [SiFive7PipeA]>;
  84. }
  85. // Atomic memory
  86. def : WriteRes<WriteAtomicSTW, [SiFive7PipeA]>;
  87. def : WriteRes<WriteAtomicSTD, [SiFive7PipeA]>;
  88. let Latency = 3 in {
  89. def : WriteRes<WriteAtomicW, [SiFive7PipeA]>;
  90. def : WriteRes<WriteAtomicD, [SiFive7PipeA]>;
  91. def : WriteRes<WriteAtomicLDW, [SiFive7PipeA]>;
  92. def : WriteRes<WriteAtomicLDD, [SiFive7PipeA]>;
  93. }
  94. // Single precision.
  95. let Latency = 5 in {
  96. def : WriteRes<WriteFAdd32, [SiFive7PipeB]>;
  97. def : WriteRes<WriteFMul32, [SiFive7PipeB]>;
  98. def : WriteRes<WriteFMA32, [SiFive7PipeB]>;
  99. }
  100. let Latency = 3 in {
  101. def : WriteRes<WriteFSGNJ32, [SiFive7PipeB]>;
  102. def : WriteRes<WriteFMinMax32, [SiFive7PipeB]>;
  103. }
  104. def : WriteRes<WriteFDiv32, [SiFive7PipeB, SiFive7FDiv]> { let Latency = 27;
  105. let ResourceCycles = [1, 26]; }
  106. def : WriteRes<WriteFSqrt32, [SiFive7PipeB, SiFive7FDiv]> { let Latency = 27;
  107. let ResourceCycles = [1, 26]; }
  108. // Double precision
  109. let Latency = 7 in {
  110. def : WriteRes<WriteFAdd64, [SiFive7PipeB]>;
  111. def : WriteRes<WriteFMul64, [SiFive7PipeB]>;
  112. def : WriteRes<WriteFMA64, [SiFive7PipeB]>;
  113. }
  114. let Latency = 3 in {
  115. def : WriteRes<WriteFSGNJ64, [SiFive7PipeB]>;
  116. def : WriteRes<WriteFMinMax64, [SiFive7PipeB]>;
  117. }
  118. def : WriteRes<WriteFDiv64, [SiFive7PipeB, SiFive7FDiv]> { let Latency = 56;
  119. let ResourceCycles = [1, 55]; }
  120. def : WriteRes<WriteFSqrt64, [SiFive7PipeB, SiFive7FDiv]> { let Latency = 56;
  121. let ResourceCycles = [1, 55]; }
  122. // Conversions
  123. let Latency = 3 in {
  124. def : WriteRes<WriteFCvtI32ToF32, [SiFive7PipeB]>;
  125. def : WriteRes<WriteFCvtI32ToF64, [SiFive7PipeB]>;
  126. def : WriteRes<WriteFCvtI64ToF32, [SiFive7PipeB]>;
  127. def : WriteRes<WriteFCvtI64ToF64, [SiFive7PipeB]>;
  128. def : WriteRes<WriteFCvtF32ToI32, [SiFive7PipeB]>;
  129. def : WriteRes<WriteFCvtF32ToI64, [SiFive7PipeB]>;
  130. def : WriteRes<WriteFCvtF32ToF64, [SiFive7PipeB]>;
  131. def : WriteRes<WriteFCvtF64ToI32, [SiFive7PipeB]>;
  132. def : WriteRes<WriteFCvtF64ToI64, [SiFive7PipeB]>;
  133. def : WriteRes<WriteFCvtF64ToF32, [SiFive7PipeB]>;
  134. def : WriteRes<WriteFClass32, [SiFive7PipeB]>;
  135. def : WriteRes<WriteFClass64, [SiFive7PipeB]>;
  136. def : WriteRes<WriteFCmp32, [SiFive7PipeB]>;
  137. def : WriteRes<WriteFCmp64, [SiFive7PipeB]>;
  138. def : WriteRes<WriteFMovI32ToF32, [SiFive7PipeB]>;
  139. def : WriteRes<WriteFMovF32ToI32, [SiFive7PipeB]>;
  140. def : WriteRes<WriteFMovI64ToF64, [SiFive7PipeB]>;
  141. def : WriteRes<WriteFMovF64ToI64, [SiFive7PipeB]>;
  142. }
  143. // Others
  144. def : WriteRes<WriteCSR, [SiFive7PipeB]>;
  145. def : WriteRes<WriteNop, []>;
  146. def : InstRW<[WriteIALU], (instrs COPY)>;
  147. //===----------------------------------------------------------------------===//
  148. // Bypass and advance
  149. def : ReadAdvance<ReadJmp, 0>;
  150. def : ReadAdvance<ReadJalr, 0>;
  151. def : ReadAdvance<ReadCSR, 0>;
  152. def : ReadAdvance<ReadStoreData, 0>;
  153. def : ReadAdvance<ReadMemBase, 0>;
  154. def : ReadAdvance<ReadIALU, 0>;
  155. def : ReadAdvance<ReadIALU32, 0>;
  156. def : ReadAdvance<ReadShiftImm, 0>;
  157. def : ReadAdvance<ReadShiftImm32, 0>;
  158. def : ReadAdvance<ReadShiftReg, 0>;
  159. def : ReadAdvance<ReadShiftReg32, 0>;
  160. def : ReadAdvance<ReadIDiv, 0>;
  161. def : ReadAdvance<ReadIDiv32, 0>;
  162. def : ReadAdvance<ReadIMul, 0>;
  163. def : ReadAdvance<ReadIMul32, 0>;
  164. def : ReadAdvance<ReadAtomicWA, 0>;
  165. def : ReadAdvance<ReadAtomicWD, 0>;
  166. def : ReadAdvance<ReadAtomicDA, 0>;
  167. def : ReadAdvance<ReadAtomicDD, 0>;
  168. def : ReadAdvance<ReadAtomicLDW, 0>;
  169. def : ReadAdvance<ReadAtomicLDD, 0>;
  170. def : ReadAdvance<ReadAtomicSTW, 0>;
  171. def : ReadAdvance<ReadAtomicSTD, 0>;
  172. def : ReadAdvance<ReadFStoreData, 0>;
  173. def : ReadAdvance<ReadFMemBase, 0>;
  174. def : ReadAdvance<ReadFAdd32, 0>;
  175. def : ReadAdvance<ReadFAdd64, 0>;
  176. def : ReadAdvance<ReadFMul32, 0>;
  177. def : ReadAdvance<ReadFMul64, 0>;
  178. def : ReadAdvance<ReadFMA32, 0>;
  179. def : ReadAdvance<ReadFMA64, 0>;
  180. def : ReadAdvance<ReadFDiv32, 0>;
  181. def : ReadAdvance<ReadFDiv64, 0>;
  182. def : ReadAdvance<ReadFSqrt32, 0>;
  183. def : ReadAdvance<ReadFSqrt64, 0>;
  184. def : ReadAdvance<ReadFCmp32, 0>;
  185. def : ReadAdvance<ReadFCmp64, 0>;
  186. def : ReadAdvance<ReadFSGNJ32, 0>;
  187. def : ReadAdvance<ReadFSGNJ64, 0>;
  188. def : ReadAdvance<ReadFMinMax32, 0>;
  189. def : ReadAdvance<ReadFMinMax64, 0>;
  190. def : ReadAdvance<ReadFCvtF32ToI32, 0>;
  191. def : ReadAdvance<ReadFCvtF32ToI64, 0>;
  192. def : ReadAdvance<ReadFCvtF64ToI32, 0>;
  193. def : ReadAdvance<ReadFCvtF64ToI64, 0>;
  194. def : ReadAdvance<ReadFCvtI32ToF32, 0>;
  195. def : ReadAdvance<ReadFCvtI32ToF64, 0>;
  196. def : ReadAdvance<ReadFCvtI64ToF32, 0>;
  197. def : ReadAdvance<ReadFCvtI64ToF64, 0>;
  198. def : ReadAdvance<ReadFCvtF32ToF64, 0>;
  199. def : ReadAdvance<ReadFCvtF64ToF32, 0>;
  200. def : ReadAdvance<ReadFMovF32ToI32, 0>;
  201. def : ReadAdvance<ReadFMovI32ToF32, 0>;
  202. def : ReadAdvance<ReadFMovF64ToI64, 0>;
  203. def : ReadAdvance<ReadFMovI64ToF64, 0>;
  204. def : ReadAdvance<ReadFClass32, 0>;
  205. def : ReadAdvance<ReadFClass64, 0>;
  206. def : ReadAdvance<ReadSFB, 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. }