1 //==- RISCVSchedSiFive7.td - SiFive7 Scheduling Definitions --*- tablegen -*-=//
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
7 //===----------------------------------------------------------------------===//
9 //===----------------------------------------------------------------------===//
11 // SiFive7 machine model for scheduling and other instruction cost heuristics.
12 def SiFive7Model : SchedMachineModel {
13 let MicroOpBufferSize = 0; // Explicitly set to zero since SiFive7 is in-order.
14 let IssueWidth = 2; // 2 micro-ops are dispatched per cycle.
16 let MispredictPenalty = 3;
17 let CompleteModel = 0;
18 let UnsupportedFeatures = [HasStdExtV, HasStdExtZvamo, HasStdExtZvlsseg];
21 // The SiFive7 microarchitecure 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>;
31 let BufferSize = 1 in {
32 def SiFive7IDiv : ProcResource<1> { let Super = SiFive7PipeB; } // Int Division
33 def SiFive7FDiv : ProcResource<1> { let Super = SiFive7PipeB; } // FP Division/Sqrt
36 def SiFive7PipeAB : ProcResGroup<[SiFive7PipeA, SiFive7PipeB]>;
39 def : WriteRes<WriteJmp, [SiFive7PipeB]>;
40 def : WriteRes<WriteJal, [SiFive7PipeB]>;
41 def : WriteRes<WriteJalr, [SiFive7PipeB]>;
42 def : WriteRes<WriteJmpReg, [SiFive7PipeB]>;
44 // Integer arithmetic and logic
46 def : WriteRes<WriteIALU, [SiFive7PipeAB]>;
47 def : WriteRes<WriteIALU32, [SiFive7PipeAB]>;
48 def : WriteRes<WriteShiftImm, [SiFive7PipeAB]>;
49 def : WriteRes<WriteShiftImm32, [SiFive7PipeAB]>;
50 def : WriteRes<WriteShiftReg, [SiFive7PipeAB]>;
51 def : WriteRes<WriteShiftReg32, [SiFive7PipeAB]>;
54 // Integer multiplication
56 def : WriteRes<WriteIMul, [SiFive7PipeB]>;
57 def : WriteRes<WriteIMul32, [SiFive7PipeB]>;
61 def : WriteRes<WriteIDiv, [SiFive7PipeB, SiFive7IDiv]> {
63 let ResourceCycles = [1, 15];
65 def : WriteRes<WriteIDiv32, [SiFive7PipeB, SiFive7IDiv]> {
67 let ResourceCycles = [1, 15];
71 def : WriteRes<WriteSTB, [SiFive7PipeA]>;
72 def : WriteRes<WriteSTH, [SiFive7PipeA]>;
73 def : WriteRes<WriteSTW, [SiFive7PipeA]>;
74 def : WriteRes<WriteSTD, [SiFive7PipeA]>;
75 def : WriteRes<WriteFST32, [SiFive7PipeA]>;
76 def : WriteRes<WriteFST64, [SiFive7PipeA]>;
79 def : WriteRes<WriteLDB, [SiFive7PipeA]>;
80 def : WriteRes<WriteLDH, [SiFive7PipeA]>;
81 def : WriteRes<WriteLDW, [SiFive7PipeA]>;
82 def : WriteRes<WriteLDWU, [SiFive7PipeA]>;
83 def : WriteRes<WriteLDD, [SiFive7PipeA]>;
87 def : WriteRes<WriteFLD32, [SiFive7PipeA]>;
88 def : WriteRes<WriteFLD64, [SiFive7PipeA]>;
92 def : WriteRes<WriteAtomicSTW, [SiFive7PipeA]>;
93 def : WriteRes<WriteAtomicSTD, [SiFive7PipeA]>;
96 def : WriteRes<WriteAtomicW, [SiFive7PipeA]>;
97 def : WriteRes<WriteAtomicD, [SiFive7PipeA]>;
98 def : WriteRes<WriteAtomicLDW, [SiFive7PipeA]>;
99 def : WriteRes<WriteAtomicLDD, [SiFive7PipeA]>;
104 def : WriteRes<WriteFALU32, [SiFive7PipeB]>;
105 def : WriteRes<WriteFMul32, [SiFive7PipeB]>;
106 def : WriteRes<WriteFMA32, [SiFive7PipeB]>;
109 def : WriteRes<WriteFSGNJ32, [SiFive7PipeB]>;
110 def : WriteRes<WriteFMinMax32, [SiFive7PipeB]>;
113 def : WriteRes<WriteFDiv32, [SiFive7PipeB, SiFive7FDiv]> { let Latency = 27;
114 let ResourceCycles = [1, 26]; }
115 def : WriteRes<WriteFSqrt32, [SiFive7PipeB, SiFive7FDiv]> { let Latency = 27;
116 let ResourceCycles = [1, 26]; }
120 def : WriteRes<WriteFALU64, [SiFive7PipeB]>;
121 def : WriteRes<WriteFMul64, [SiFive7PipeB]>;
122 def : WriteRes<WriteFMA64, [SiFive7PipeB]>;
125 def : WriteRes<WriteFSGNJ64, [SiFive7PipeB]>;
126 def : WriteRes<WriteFMinMax64, [SiFive7PipeB]>;
129 def : WriteRes<WriteFDiv64, [SiFive7PipeB, SiFive7FDiv]> { let Latency = 56;
130 let ResourceCycles = [1, 55]; }
131 def : WriteRes<WriteFSqrt64, [SiFive7PipeB, SiFive7FDiv]> { let Latency = 56;
132 let ResourceCycles = [1, 55]; }
136 def : WriteRes<WriteFCvtI32ToF32, [SiFive7PipeB]>;
137 def : WriteRes<WriteFCvtI32ToF64, [SiFive7PipeB]>;
138 def : WriteRes<WriteFCvtI64ToF32, [SiFive7PipeB]>;
139 def : WriteRes<WriteFCvtI64ToF64, [SiFive7PipeB]>;
140 def : WriteRes<WriteFCvtF32ToI32, [SiFive7PipeB]>;
141 def : WriteRes<WriteFCvtF32ToI64, [SiFive7PipeB]>;
142 def : WriteRes<WriteFCvtF32ToF64, [SiFive7PipeB]>;
143 def : WriteRes<WriteFCvtF64ToI32, [SiFive7PipeB]>;
144 def : WriteRes<WriteFCvtF64ToI64, [SiFive7PipeB]>;
145 def : WriteRes<WriteFCvtF64ToF32, [SiFive7PipeB]>;
147 def : WriteRes<WriteFClass32, [SiFive7PipeB]>;
148 def : WriteRes<WriteFClass64, [SiFive7PipeB]>;
149 def : WriteRes<WriteFCmp32, [SiFive7PipeB]>;
150 def : WriteRes<WriteFCmp64, [SiFive7PipeB]>;
151 def : WriteRes<WriteFMovI32ToF32, [SiFive7PipeB]>;
152 def : WriteRes<WriteFMovF32ToI32, [SiFive7PipeB]>;
153 def : WriteRes<WriteFMovI64ToF64, [SiFive7PipeB]>;
154 def : WriteRes<WriteFMovF64ToI64, [SiFive7PipeB]>;
158 def : WriteRes<WriteCSR, [SiFive7PipeB]>;
159 def : WriteRes<WriteNop, []>;
161 def : InstRW<[WriteIALU], (instrs COPY)>;
163 //===----------------------------------------------------------------------===//
164 // Bypass and advance
165 def : ReadAdvance<ReadJmp, 0>;
166 def : ReadAdvance<ReadJalr, 0>;
167 def : ReadAdvance<ReadCSR, 0>;
168 def : ReadAdvance<ReadStoreData, 0>;
169 def : ReadAdvance<ReadMemBase, 0>;
170 def : ReadAdvance<ReadIALU, 0>;
171 def : ReadAdvance<ReadIALU32, 0>;
172 def : ReadAdvance<ReadShiftImm, 0>;
173 def : ReadAdvance<ReadShiftImm32, 0>;
174 def : ReadAdvance<ReadShiftReg, 0>;
175 def : ReadAdvance<ReadShiftReg32, 0>;
176 def : ReadAdvance<ReadIDiv, 0>;
177 def : ReadAdvance<ReadIDiv32, 0>;
178 def : ReadAdvance<ReadIMul, 0>;
179 def : ReadAdvance<ReadIMul32, 0>;
180 def : ReadAdvance<ReadAtomicWA, 0>;
181 def : ReadAdvance<ReadAtomicWD, 0>;
182 def : ReadAdvance<ReadAtomicDA, 0>;
183 def : ReadAdvance<ReadAtomicDD, 0>;
184 def : ReadAdvance<ReadAtomicLDW, 0>;
185 def : ReadAdvance<ReadAtomicLDD, 0>;
186 def : ReadAdvance<ReadAtomicSTW, 0>;
187 def : ReadAdvance<ReadAtomicSTD, 0>;
188 def : ReadAdvance<ReadFMemBase, 0>;
189 def : ReadAdvance<ReadFALU32, 0>;
190 def : ReadAdvance<ReadFALU64, 0>;
191 def : ReadAdvance<ReadFMul32, 0>;
192 def : ReadAdvance<ReadFMA32, 0>;
193 def : ReadAdvance<ReadFMul64, 0>;
194 def : ReadAdvance<ReadFMA64, 0>;
195 def : ReadAdvance<ReadFDiv32, 0>;
196 def : ReadAdvance<ReadFDiv64, 0>;
197 def : ReadAdvance<ReadFSqrt32, 0>;
198 def : ReadAdvance<ReadFSqrt64, 0>;
199 def : ReadAdvance<ReadFCmp32, 0>;
200 def : ReadAdvance<ReadFCmp64, 0>;
201 def : ReadAdvance<ReadFSGNJ32, 0>;
202 def : ReadAdvance<ReadFSGNJ64, 0>;
203 def : ReadAdvance<ReadFMinMax32, 0>;
204 def : ReadAdvance<ReadFMinMax64, 0>;
205 def : ReadAdvance<ReadFCvtF32ToI32, 0>;
206 def : ReadAdvance<ReadFCvtF32ToI64, 0>;
207 def : ReadAdvance<ReadFCvtF64ToI32, 0>;
208 def : ReadAdvance<ReadFCvtF64ToI64, 0>;
209 def : ReadAdvance<ReadFCvtI32ToF32, 0>;
210 def : ReadAdvance<ReadFCvtI32ToF64, 0>;
211 def : ReadAdvance<ReadFCvtI64ToF32, 0>;
212 def : ReadAdvance<ReadFCvtI64ToF64, 0>;
213 def : ReadAdvance<ReadFCvtF32ToF64, 0>;
214 def : ReadAdvance<ReadFCvtF64ToF32, 0>;
215 def : ReadAdvance<ReadFMovF32ToI32, 0>;
216 def : ReadAdvance<ReadFMovI32ToF32, 0>;
217 def : ReadAdvance<ReadFMovF64ToI64, 0>;
218 def : ReadAdvance<ReadFMovI64ToF64, 0>;
219 def : ReadAdvance<ReadFClass32, 0>;
220 def : ReadAdvance<ReadFClass64, 0>;
222 //===----------------------------------------------------------------------===//
223 // Unsupported extensions
224 defm : UnsupportedSchedV;
225 defm : UnsupportedSchedZba;
226 defm : UnsupportedSchedZbb;
227 defm : UnsupportedSchedZfh;