1 //===-- RISCVSchedule.td - RISC-V 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 /// Define scheduler resources associated with def operands.
10 def WriteIALU : SchedWrite; // 32 or 64-bit integer ALU operations
11 def WriteIALU32 : SchedWrite; // 32-bit integer ALU operations on RV64I
12 def WriteShiftImm : SchedWrite; // 32 or 64-bit shift by immediate operations
13 def WriteShiftImm32 : SchedWrite; // 32-bit shift by immediate operations on RV64Ix
14 def WriteShiftReg : SchedWrite; // 32 or 64-bit shift by immediate operations
15 def WriteShiftReg32 : SchedWrite; // 32-bit shift by immediate operations on RV64Ix
16 def WriteIDiv : SchedWrite; // 32-bit or 64-bit divide
17 def WriteIDiv32 : SchedWrite; // 32-bit divide on RV64I
18 def WriteIRem : SchedWrite; // 32-bit or 64-bit remainder
19 def WriteIRem32 : SchedWrite; // 32-bit remainder on RV64I
20 def WriteIMul : SchedWrite; // 32-bit or 64-bit multiply
21 def WriteIMul32 : SchedWrite; // 32-bit multiply on RV64I
22 def WriteJmp : SchedWrite; // Jump
23 def WriteJal : SchedWrite; // Jump and link
24 def WriteJalr : SchedWrite; // Jump and link register
25 def WriteNop : SchedWrite;
26 def WriteLDB : SchedWrite; // Load byte
27 def WriteLDH : SchedWrite; // Load half-word
28 def WriteLDW : SchedWrite; // Load word
29 def WriteLDD : SchedWrite; // Load double-word
30 def WriteCSR : SchedWrite; // CSR instructions
31 def WriteSTB : SchedWrite; // Store byte
32 def WriteSTH : SchedWrite; // Store half-word
33 def WriteSTW : SchedWrite; // Store word
34 def WriteSTD : SchedWrite; // Store double-word
35 def WriteAtomicB : SchedWrite; //Atomic memory operation byte size
36 def WriteAtomicH : SchedWrite; //Atomic memory operation halfword size
37 def WriteAtomicW : SchedWrite; //Atomic memory operation word size
38 def WriteAtomicD : SchedWrite; //Atomic memory operation double word size
39 def WriteAtomicLDW : SchedWrite; // Atomic load word
40 def WriteAtomicLDD : SchedWrite; // Atomic load double word
41 def WriteAtomicSTW : SchedWrite; // Atomic store word
42 def WriteAtomicSTD : SchedWrite; // Atomic store double word
43 def WriteFAdd16 : SchedWrite; // 16-bit floating point addition/subtraction
44 def WriteFAdd32 : SchedWrite; // 32-bit floating point addition/subtraction
45 def WriteFAdd64 : SchedWrite; // 64-bit floating point addition/subtraction
46 def WriteFMul16 : SchedWrite; // 16-bit floating point multiply
47 def WriteFMul32 : SchedWrite; // 32-bit floating point multiply
48 def WriteFMul64 : SchedWrite; // 64-bit floating point multiply
49 def WriteFMA16 : SchedWrite; // 16-bit floating point fused multiply-add
50 def WriteFMA32 : SchedWrite; // 32-bit floating point fused multiply-add
51 def WriteFMA64 : SchedWrite; // 64-bit floating point fused multiply-add
52 def WriteFDiv16 : SchedWrite; // 16-bit floating point divide
53 def WriteFDiv32 : SchedWrite; // 32-bit floating point divide
54 def WriteFDiv64 : SchedWrite; // 64-bit floating point divide
55 def WriteFSqrt16 : SchedWrite; // 16-bit floating point sqrt
56 def WriteFSqrt32 : SchedWrite; // 32-bit floating point sqrt
57 def WriteFSqrt64 : SchedWrite; // 64-bit floating point sqrt
59 // Integer to float conversions
60 def WriteFCvtI32ToF16 : SchedWrite;
61 def WriteFCvtI32ToF32 : SchedWrite;
62 def WriteFCvtI32ToF64 : SchedWrite;
63 def WriteFCvtI64ToF16 : SchedWrite; // RV64I only
64 def WriteFCvtI64ToF32 : SchedWrite; // RV64I only
65 def WriteFCvtI64ToF64 : SchedWrite; // RV64I only
67 //Float to integer conversions
68 def WriteFCvtF16ToI32 : SchedWrite;
69 def WriteFCvtF16ToI64 : SchedWrite; // RV64I only
70 def WriteFCvtF32ToI32 : SchedWrite;
71 def WriteFCvtF32ToI64 : SchedWrite; // RV64I only
72 def WriteFCvtF64ToI32 : SchedWrite;
73 def WriteFCvtF64ToI64 : SchedWrite; // RV64I only
75 // Float to float conversions
76 def WriteFCvtF32ToF64 : SchedWrite;
77 def WriteFCvtF64ToF32 : SchedWrite;
78 def WriteFCvtF16ToF32 : SchedWrite;
79 def WriteFCvtF32ToF16 : SchedWrite;
80 def WriteFCvtF16ToF64 : SchedWrite;
81 def WriteFCvtF64ToF16 : SchedWrite;
83 // Zfa found instructions.
84 def WriteFRoundF32 : SchedWrite;
85 def WriteFRoundF64 : SchedWrite;
86 def WriteFRoundF16 : SchedWrite;
88 def WriteFClass16 : SchedWrite; // 16-bit floating point classify
89 def WriteFClass32 : SchedWrite; // 32-bit floating point classify
90 def WriteFClass64 : SchedWrite; // 64-bit floating point classify
91 def WriteFCmp16 : SchedWrite; // 16-bit floating point compare
92 def WriteFCmp32 : SchedWrite; // 32-bit floating point compare
93 def WriteFCmp64 : SchedWrite; // 64-bit floating point compare
94 def WriteFSGNJ16 : SchedWrite; // 16-bit floating point sign-injection
95 def WriteFSGNJ32 : SchedWrite; // 32-bit floating point sign-injection
96 def WriteFSGNJ64 : SchedWrite; // 64-bit floating point sign-injection
97 def WriteFMinMax16 : SchedWrite; // 16-bit floating point min or max
98 def WriteFMinMax32 : SchedWrite; // 32-bit floating point min or max
99 def WriteFMinMax64 : SchedWrite; // 64-bit floating point min or max
101 def WriteFMovF16ToI16 : SchedWrite;
102 def WriteFMovI16ToF16 : SchedWrite;
103 def WriteFMovF32ToI32 : SchedWrite;
104 def WriteFMovI32ToF32 : SchedWrite;
105 def WriteFMovF64ToI64 : SchedWrite; // RV64I only
106 def WriteFMovI64ToF64 : SchedWrite; // RV64I only
108 def WriteFLI16 : SchedWrite; // Floating point constant load
109 def WriteFLI32 : SchedWrite; // Floating point constant load
110 def WriteFLI64 : SchedWrite; // Floating point constant load
112 def WriteFLD16 : SchedWrite; // Floating point sp load
113 def WriteFLD32 : SchedWrite; // Floating point sp load
114 def WriteFLD64 : SchedWrite; // Floating point dp load
115 def WriteFST16 : SchedWrite; // Floating point sp store
116 def WriteFST32 : SchedWrite; // Floating point sp store
117 def WriteFST64 : SchedWrite; // Floating point dp store
119 // short forward branch for Bullet
120 def WriteSFB : SchedWrite;
121 def ReadSFBJmp : SchedRead;
122 def ReadSFBALU : SchedRead;
124 /// Define scheduler resources associated with use operands.
125 def ReadJmp : SchedRead;
126 def ReadJalr : SchedRead;
127 def ReadCSR : SchedRead;
128 def ReadMemBase : SchedRead;
129 def ReadFMemBase : SchedRead;
130 def ReadStoreData : SchedRead;
131 def ReadFStoreData : SchedRead;
132 def ReadIALU : SchedRead;
133 def ReadIALU32 : SchedRead; // 32-bit integer ALU operations on RV64I
134 def ReadShiftImm : SchedRead;
135 def ReadShiftImm32 : SchedRead; // 32-bit shift by immediate operations on RV64Ix
136 def ReadShiftReg : SchedRead;
137 def ReadShiftReg32 : SchedRead; // 32-bit shift by register operations on RV64Ix
138 def ReadIDiv : SchedRead;
139 def ReadIDiv32 : SchedRead;
140 def ReadIRem : SchedRead;
141 def ReadIRem32 : SchedRead;
142 def ReadIMul : SchedRead;
143 def ReadIMul32 : SchedRead;
144 def ReadAtomicBA : SchedRead;
145 def ReadAtomicBD : SchedRead;
146 def ReadAtomicHA : SchedRead;
147 def ReadAtomicHD : SchedRead;
148 def ReadAtomicWA : SchedRead;
149 def ReadAtomicWD : SchedRead;
150 def ReadAtomicDA : SchedRead;
151 def ReadAtomicDD : SchedRead;
152 def ReadAtomicLDW : SchedRead; // Atomic load word
153 def ReadAtomicLDD : SchedRead; // Atomic load double word
154 def ReadAtomicSTW : SchedRead; // Atomic store word
155 def ReadAtomicSTD : SchedRead; // Atomic store double word
156 def ReadFAdd16 : SchedRead; // 16-bit floating point addition/subtraction
157 def ReadFAdd32 : SchedRead; // 32-bit floating point addition/subtraction
158 def ReadFAdd64 : SchedRead; // 64-bit floating point addition/subtraction
159 def ReadFMul16 : SchedRead; // 16-bit floating point multiply
160 def ReadFMul32 : SchedRead; // 32-bit floating point multiply
161 def ReadFMul64 : SchedRead; // 64-bit floating point multiply
162 def ReadFMA16 : SchedRead; // 16-bit floating point fused multiply-add
163 def ReadFMA16Addend : SchedRead; // 16-bit floating point fused multiply-add (addend)
164 def ReadFMA32 : SchedRead; // 32-bit floating point fused multiply-add
165 def ReadFMA32Addend : SchedRead; // 32-bit floating point fused multiply-add (addend)
166 def ReadFMA64 : SchedRead; // 64-bit floating point fused multiply-add
167 def ReadFMA64Addend : SchedRead; // 64-bit floating point fused multiply-add (addend)
168 def ReadFDiv16 : SchedRead; // 16-bit floating point divide
169 def ReadFDiv32 : SchedRead; // 32-bit floating point divide
170 def ReadFDiv64 : SchedRead; // 64-bit floating point divide
171 def ReadFSqrt16 : SchedRead; // 16-bit floating point sqrt
172 def ReadFSqrt32 : SchedRead; // 32-bit floating point sqrt
173 def ReadFSqrt64 : SchedRead; // 64-bit floating point sqrt
174 def ReadFCmp16 : SchedRead;
175 def ReadFCmp32 : SchedRead;
176 def ReadFCmp64 : SchedRead;
177 def ReadFSGNJ16 : SchedRead;
178 def ReadFSGNJ32 : SchedRead;
179 def ReadFSGNJ64 : SchedRead;
180 def ReadFMinMax16 : SchedRead;
181 def ReadFMinMax32 : SchedRead;
182 def ReadFMinMax64 : SchedRead;
183 def ReadFCvtF16ToI32 : SchedRead;
184 def ReadFCvtF16ToI64 : SchedRead;
185 def ReadFCvtF32ToI32 : SchedRead;
186 def ReadFCvtF32ToI64 : SchedRead;
187 def ReadFCvtF64ToI32 : SchedRead;
188 def ReadFCvtF64ToI64 : SchedRead;
189 def ReadFCvtI32ToF16 : SchedRead;
190 def ReadFCvtI32ToF32 : SchedRead;
191 def ReadFCvtI32ToF64 : SchedRead;
192 def ReadFCvtI64ToF16 : SchedRead;
193 def ReadFCvtI64ToF32 : SchedRead;
194 def ReadFCvtI64ToF64 : SchedRead;
195 def ReadFMovF16ToI16 : SchedRead;
196 def ReadFMovI16ToF16 : SchedRead;
197 def ReadFMovF32ToI32 : SchedRead;
198 def ReadFMovI32ToF32 : SchedRead;
199 def ReadFMovF64ToI64 : SchedRead;
200 def ReadFMovI64ToF64 : SchedRead;
201 def ReadFCvtF32ToF64 : SchedRead;
202 def ReadFCvtF64ToF32 : SchedRead;
203 def ReadFCvtF16ToF32 : SchedRead;
204 def ReadFCvtF32ToF16 : SchedRead;
205 def ReadFCvtF16ToF64 : SchedRead;
206 def ReadFCvtF64ToF16 : SchedRead;
207 def ReadFRoundF16 : SchedRead;
208 def ReadFRoundF32 : SchedRead;
209 def ReadFRoundF64 : SchedRead;
210 def ReadFClass16 : SchedRead;
211 def ReadFClass32 : SchedRead;
212 def ReadFClass64 : SchedRead;
214 // For CPUs that support Zfhmin, but not Zfh.
215 multiclass UnsupportedSchedZfh {
216 let Unsupported = true in {
217 def : WriteRes<WriteFAdd16, []>;
218 def : WriteRes<WriteFClass16, []>;
219 def : WriteRes<WriteFCvtI64ToF16, []>;
220 def : WriteRes<WriteFCvtI32ToF16, []>;
221 def : WriteRes<WriteFCvtF16ToI64, []>;
222 def : WriteRes<WriteFCvtF16ToI32, []>;
223 def : WriteRes<WriteFDiv16, []>;
224 def : WriteRes<WriteFCmp16, []>;
225 def : WriteRes<WriteFMA16, []>;
226 def : WriteRes<WriteFMinMax16, []>;
227 def : WriteRes<WriteFMul16, []>;
228 def : WriteRes<WriteFSGNJ16, []>;
229 def : WriteRes<WriteFSqrt16, []>;
231 def : ReadAdvance<ReadFAdd16, 0>;
232 def : ReadAdvance<ReadFClass16, 0>;
233 def : ReadAdvance<ReadFCvtI64ToF16, 0>;
234 def : ReadAdvance<ReadFCvtI32ToF16, 0>;
235 def : ReadAdvance<ReadFCvtF16ToI64, 0>;
236 def : ReadAdvance<ReadFCvtF16ToI32, 0>;
237 def : ReadAdvance<ReadFDiv16, 0>;
238 def : ReadAdvance<ReadFCmp16, 0>;
239 def : ReadAdvance<ReadFMA16, 0>;
240 def : ReadAdvance<ReadFMA16Addend, 0>;
241 def : ReadAdvance<ReadFMinMax16, 0>;
242 def : ReadAdvance<ReadFMul16, 0>;
243 def : ReadAdvance<ReadFSGNJ16, 0>;
244 def : ReadAdvance<ReadFSqrt16, 0>;
245 } // Unsupported = true
248 // For CPUs that support neither Zfhmin or Zfh.
249 multiclass UnsupportedSchedZfhmin : UnsupportedSchedZfh {
250 let Unsupported = true in {
251 def : WriteRes<WriteFCvtF16ToF64, []>;
252 def : WriteRes<WriteFCvtF64ToF16, []>;
253 def : WriteRes<WriteFCvtF16ToF32, []>;
254 def : WriteRes<WriteFCvtF32ToF16, []>;
255 def : WriteRes<WriteFLD16, []>;
256 def : WriteRes<WriteFMovI16ToF16, []>;
257 def : WriteRes<WriteFMovF16ToI16, []>;
258 def : WriteRes<WriteFST16, []>;
260 def : ReadAdvance<ReadFCvtF16ToF64, 0>;
261 def : ReadAdvance<ReadFCvtF64ToF16, 0>;
262 def : ReadAdvance<ReadFCvtF16ToF32, 0>;
263 def : ReadAdvance<ReadFCvtF32ToF16, 0>;
264 def : ReadAdvance<ReadFMovI16ToF16, 0>;
265 def : ReadAdvance<ReadFMovF16ToI16, 0>;
266 } // Unsupported = true
269 multiclass UnsupportedSchedD {
270 let Unsupported = true in {
271 def : WriteRes<WriteFST64, []>;
272 def : WriteRes<WriteFLD64, []>;
273 def : WriteRes<WriteFAdd64, []>;
274 def : WriteRes<WriteFSGNJ64, []>;
275 def : WriteRes<WriteFMinMax64, []>;
276 def : WriteRes<WriteFCvtI32ToF64, []>;
277 def : WriteRes<WriteFCvtI64ToF64, []>;
278 def : WriteRes<WriteFCvtF64ToI32, []>;
279 def : WriteRes<WriteFCvtF64ToI64, []>;
280 def : WriteRes<WriteFCvtF32ToF64, []>;
281 def : WriteRes<WriteFCvtF64ToF32, []>;
282 def : WriteRes<WriteFClass64, []>;
283 def : WriteRes<WriteFCmp64, []>;
284 def : WriteRes<WriteFMovF64ToI64, []>;
285 def : WriteRes<WriteFMovI64ToF64, []>;
286 def : WriteRes<WriteFMul64, []>;
287 def : WriteRes<WriteFMA64, []>;
288 def : WriteRes<WriteFDiv64, []>;
289 def : WriteRes<WriteFSqrt64, []>;
291 def : ReadAdvance<ReadFAdd64, 0>;
292 def : ReadAdvance<ReadFMul64, 0>;
293 def : ReadAdvance<ReadFMA64, 0>;
294 def : ReadAdvance<ReadFMA64Addend, 0>;
295 def : ReadAdvance<ReadFDiv64, 0>;
296 def : ReadAdvance<ReadFSqrt64, 0>;
297 def : ReadAdvance<ReadFCmp64, 0>;
298 def : ReadAdvance<ReadFSGNJ64, 0>;
299 def : ReadAdvance<ReadFMinMax64, 0>;
300 def : ReadAdvance<ReadFCvtF64ToI32, 0>;
301 def : ReadAdvance<ReadFCvtF64ToI64, 0>;
302 def : ReadAdvance<ReadFCvtI32ToF64, 0>;
303 def : ReadAdvance<ReadFCvtI64ToF64, 0>;
304 def : ReadAdvance<ReadFCvtF32ToF64, 0>;
305 def : ReadAdvance<ReadFCvtF64ToF32, 0>;
306 def : ReadAdvance<ReadFMovF64ToI64, 0>;
307 def : ReadAdvance<ReadFMovI64ToF64, 0>;
308 def : ReadAdvance<ReadFClass64, 0>;
309 } // Unsupported = true
312 // For CPUs with no floating point.
313 multiclass UnsupportedSchedF : UnsupportedSchedD, UnsupportedSchedZfhmin {
314 let Unsupported = true in {
315 def : WriteRes<WriteFST32, []>;
316 def : WriteRes<WriteFLD32, []>;
317 def : WriteRes<WriteFAdd32, []>;
318 def : WriteRes<WriteFSGNJ32, []>;
319 def : WriteRes<WriteFMinMax32, []>;
320 def : WriteRes<WriteFCvtI32ToF32, []>;
321 def : WriteRes<WriteFCvtI64ToF32, []>;
322 def : WriteRes<WriteFCvtF32ToI32, []>;
323 def : WriteRes<WriteFCvtF32ToI64, []>;
324 def : WriteRes<WriteFClass32, []>;
325 def : WriteRes<WriteFCmp32, []>;
326 def : WriteRes<WriteFMovF32ToI32, []>;
327 def : WriteRes<WriteFMovI32ToF32, []>;
328 def : WriteRes<WriteFMul32, []>;
329 def : WriteRes<WriteFMA32, []>;
330 def : WriteRes<WriteFDiv32, []>;
331 def : WriteRes<WriteFSqrt32, []>;
333 def : ReadAdvance<ReadFAdd32, 0>;
334 def : ReadAdvance<ReadFMul32, 0>;
335 def : ReadAdvance<ReadFMA32, 0>;
336 def : ReadAdvance<ReadFMA32Addend, 0>;
337 def : ReadAdvance<ReadFDiv32, 0>;
338 def : ReadAdvance<ReadFSqrt32, 0>;
339 def : ReadAdvance<ReadFCmp32, 0>;
340 def : ReadAdvance<ReadFSGNJ32, 0>;
341 def : ReadAdvance<ReadFMinMax32, 0>;
342 def : ReadAdvance<ReadFCvtF32ToI32, 0>;
343 def : ReadAdvance<ReadFCvtF32ToI64, 0>;
344 def : ReadAdvance<ReadFCvtI32ToF32, 0>;
345 def : ReadAdvance<ReadFCvtI64ToF32, 0>;
346 def : ReadAdvance<ReadFMovF32ToI32, 0>;
347 def : ReadAdvance<ReadFMovI32ToF32, 0>;
348 def : ReadAdvance<ReadFClass32, 0>;
349 def : ReadAdvance<ReadFStoreData, 0>;
350 def : ReadAdvance<ReadFMemBase, 0>;
351 } // Unsupported = true
354 multiclass UnsupportedSchedSFB {
355 let Unsupported = true in {
356 def : WriteRes<WriteSFB, []>;
358 def : ReadAdvance<ReadSFBJmp, 0>;
359 def : ReadAdvance<ReadSFBALU, 0>;
360 } // Unsupported = true
363 multiclass UnsupportedSchedZfa {
364 let Unsupported = true in {
365 def : WriteRes<WriteFRoundF16, []>;
366 def : WriteRes<WriteFRoundF32, []>;
367 def : WriteRes<WriteFRoundF64, []>;
368 def : WriteRes<WriteFLI16, []>;
369 def : WriteRes<WriteFLI32, []>;
370 def : WriteRes<WriteFLI64, []>;
372 def : ReadAdvance<ReadFRoundF32, 0>;
373 def : ReadAdvance<ReadFRoundF64, 0>;
374 def : ReadAdvance<ReadFRoundF16, 0>;
375 } // Unsupported = true
378 multiclass UnsupportedSchedZabha {
379 let Unsupported = true in {
380 def : WriteRes<WriteAtomicB, []>;
381 def : WriteRes<WriteAtomicH, []>;
383 def : ReadAdvance<ReadAtomicBA, 0>;
384 def : ReadAdvance<ReadAtomicBD, 0>;
385 def : ReadAdvance<ReadAtomicHA, 0>;
386 def : ReadAdvance<ReadAtomicHD, 0>;
387 } // Unsupported = true
390 multiclass UnsupportedSchedA {
391 let Unsupported = true in {
392 def : WriteRes<WriteAtomicW, []>;
393 def : WriteRes<WriteAtomicD, []>;
394 def : WriteRes<WriteAtomicLDW, []>;
395 def : WriteRes<WriteAtomicLDD, []>;
396 def : WriteRes<WriteAtomicSTW, []>;
397 def : WriteRes<WriteAtomicSTD, []>;
399 def : ReadAdvance<ReadAtomicWA, 0>;
400 def : ReadAdvance<ReadAtomicWD, 0>;
401 def : ReadAdvance<ReadAtomicDA, 0>;
402 def : ReadAdvance<ReadAtomicDD, 0>;
403 def : ReadAdvance<ReadAtomicLDW, 0>;
404 def : ReadAdvance<ReadAtomicLDD, 0>;
405 def : ReadAdvance<ReadAtomicSTW, 0>;
406 def : ReadAdvance<ReadAtomicSTD, 0>;
407 } // Unsupported = true
410 // Include the scheduler resources for other instruction extensions.
411 include "RISCVScheduleZb.td"
412 include "RISCVScheduleV.td"
413 include "RISCVScheduleXSf.td"
414 include "RISCVScheduleZvk.td"