1 //===- AArch64SchedPredicates.td - AArch64 Sched Preds -----*- 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 // This file defines scheduling predicate definitions that are used by the
10 // AArch64 subtargets.
12 //===----------------------------------------------------------------------===//
16 // Check the extension type in arithmetic instructions.
17 let FunctionMapper = "AArch64_AM::getArithExtendType" in {
18 def CheckExtUXTB : CheckImmOperand_s<3, "AArch64_AM::UXTB">;
19 def CheckExtUXTH : CheckImmOperand_s<3, "AArch64_AM::UXTH">;
20 def CheckExtUXTW : CheckImmOperand_s<3, "AArch64_AM::UXTW">;
21 def CheckExtUXTX : CheckImmOperand_s<3, "AArch64_AM::UXTX">;
22 def CheckExtSXTB : CheckImmOperand_s<3, "AArch64_AM::SXTB">;
23 def CheckExtSXTH : CheckImmOperand_s<3, "AArch64_AM::SXTH">;
24 def CheckExtSXTW : CheckImmOperand_s<3, "AArch64_AM::SXTW">;
25 def CheckExtSXTX : CheckImmOperand_s<3, "AArch64_AM::SXTX">;
28 // Check for shifting in extended arithmetic instructions.
29 foreach I = {0-3} in {
30 let FunctionMapper = "AArch64_AM::getArithShiftValue" in
31 def CheckExtBy#I : CheckImmOperand<3, I>;
34 // Check the extension type in the register offset addressing mode.
35 let FunctionMapper = "AArch64_AM::getMemExtendType" in {
36 def CheckMemExtUXTW : CheckImmOperand_s<3, "AArch64_AM::UXTW">;
37 def CheckMemExtLSL : CheckImmOperand_s<3, "AArch64_AM::UXTX">;
38 def CheckMemExtSXTW : CheckImmOperand_s<3, "AArch64_AM::SXTW">;
39 def CheckMemExtSXTX : CheckImmOperand_s<3, "AArch64_AM::SXTX">;
42 // Check for scaling in the register offset addressing mode.
43 let FunctionMapper = "AArch64_AM::getMemDoShift" in
44 def CheckMemScaled : CheckImmOperandSimple<4>;
46 // Check the shifting type in arithmetic and logic instructions.
47 let FunctionMapper = "AArch64_AM::getShiftType" in {
48 def CheckShiftLSL : CheckImmOperand_s<3, "AArch64_AM::LSL">;
49 def CheckShiftLSR : CheckImmOperand_s<3, "AArch64_AM::LSR">;
50 def CheckShiftASR : CheckImmOperand_s<3, "AArch64_AM::ASR">;
51 def CheckShiftROR : CheckImmOperand_s<3, "AArch64_AM::ROR">;
52 def CheckShiftMSL : CheckImmOperand_s<3, "AArch64_AM::MSL">;
55 // Check for shifting in arithmetic and logic instructions.
56 foreach I = {0-3, 8} in {
57 let FunctionMapper = "AArch64_AM::getShiftValue" in
58 def CheckShiftBy#I : CheckImmOperand<3, I>;
61 // Generic predicates.
63 // Identify whether an instruction is the 16-bit NEON form based on its result.
64 def CheckHForm : CheckAll<[CheckIsRegOperand<0>,
65 CheckAny<[CheckRegOperand<0, H0>,
66 CheckRegOperand<0, H1>,
67 CheckRegOperand<0, H2>,
68 CheckRegOperand<0, H3>,
69 CheckRegOperand<0, H4>,
70 CheckRegOperand<0, H5>,
71 CheckRegOperand<0, H6>,
72 CheckRegOperand<0, H7>,
73 CheckRegOperand<0, H8>,
74 CheckRegOperand<0, H9>,
75 CheckRegOperand<0, H10>,
76 CheckRegOperand<0, H11>,
77 CheckRegOperand<0, H12>,
78 CheckRegOperand<0, H13>,
79 CheckRegOperand<0, H14>,
80 CheckRegOperand<0, H15>,
81 CheckRegOperand<0, H16>,
82 CheckRegOperand<0, H17>,
83 CheckRegOperand<0, H18>,
84 CheckRegOperand<0, H19>,
85 CheckRegOperand<0, H20>,
86 CheckRegOperand<0, H21>,
87 CheckRegOperand<0, H22>,
88 CheckRegOperand<0, H23>,
89 CheckRegOperand<0, H24>,
90 CheckRegOperand<0, H25>,
91 CheckRegOperand<0, H26>,
92 CheckRegOperand<0, H27>,
93 CheckRegOperand<0, H28>,
94 CheckRegOperand<0, H29>,
95 CheckRegOperand<0, H30>,
96 CheckRegOperand<0, H31>]>]>;
98 // Identify whether an instruction is the 32-bit NEON form based on its result.
99 def CheckSForm : CheckAll<[CheckIsRegOperand<0>,
100 CheckAny<[CheckRegOperand<0, S0>,
101 CheckRegOperand<0, S1>,
102 CheckRegOperand<0, S2>,
103 CheckRegOperand<0, S3>,
104 CheckRegOperand<0, S4>,
105 CheckRegOperand<0, S5>,
106 CheckRegOperand<0, S6>,
107 CheckRegOperand<0, S7>,
108 CheckRegOperand<0, S8>,
109 CheckRegOperand<0, S9>,
110 CheckRegOperand<0, S10>,
111 CheckRegOperand<0, S11>,
112 CheckRegOperand<0, S12>,
113 CheckRegOperand<0, S13>,
114 CheckRegOperand<0, S14>,
115 CheckRegOperand<0, S15>,
116 CheckRegOperand<0, S16>,
117 CheckRegOperand<0, S17>,
118 CheckRegOperand<0, S18>,
119 CheckRegOperand<0, S19>,
120 CheckRegOperand<0, S20>,
121 CheckRegOperand<0, S21>,
122 CheckRegOperand<0, S22>,
123 CheckRegOperand<0, S23>,
124 CheckRegOperand<0, S24>,
125 CheckRegOperand<0, S25>,
126 CheckRegOperand<0, S26>,
127 CheckRegOperand<0, S27>,
128 CheckRegOperand<0, S28>,
129 CheckRegOperand<0, S29>,
130 CheckRegOperand<0, S30>,
131 CheckRegOperand<0, S31>]>]>;
133 // Identify whether an instruction is the 64-bit NEON form based on its result.
134 def CheckDForm : CheckAll<[CheckIsRegOperand<0>,
135 CheckAny<[CheckRegOperand<0, D0>,
136 CheckRegOperand<0, D1>,
137 CheckRegOperand<0, D2>,
138 CheckRegOperand<0, D3>,
139 CheckRegOperand<0, D4>,
140 CheckRegOperand<0, D5>,
141 CheckRegOperand<0, D6>,
142 CheckRegOperand<0, D7>,
143 CheckRegOperand<0, D8>,
144 CheckRegOperand<0, D9>,
145 CheckRegOperand<0, D10>,
146 CheckRegOperand<0, D11>,
147 CheckRegOperand<0, D12>,
148 CheckRegOperand<0, D13>,
149 CheckRegOperand<0, D14>,
150 CheckRegOperand<0, D15>,
151 CheckRegOperand<0, D16>,
152 CheckRegOperand<0, D17>,
153 CheckRegOperand<0, D18>,
154 CheckRegOperand<0, D19>,
155 CheckRegOperand<0, D20>,
156 CheckRegOperand<0, D21>,
157 CheckRegOperand<0, D22>,
158 CheckRegOperand<0, D23>,
159 CheckRegOperand<0, D24>,
160 CheckRegOperand<0, D25>,
161 CheckRegOperand<0, D26>,
162 CheckRegOperand<0, D27>,
163 CheckRegOperand<0, D28>,
164 CheckRegOperand<0, D29>,
165 CheckRegOperand<0, D30>,
166 CheckRegOperand<0, D31>]>]>;
168 // Identify whether an instruction is the 128-bit NEON form based on its result.
169 def CheckQForm : CheckAll<[CheckIsRegOperand<0>,
170 CheckAny<[CheckRegOperand<0, Q0>,
171 CheckRegOperand<0, Q1>,
172 CheckRegOperand<0, Q2>,
173 CheckRegOperand<0, Q3>,
174 CheckRegOperand<0, Q4>,
175 CheckRegOperand<0, Q5>,
176 CheckRegOperand<0, Q6>,
177 CheckRegOperand<0, Q7>,
178 CheckRegOperand<0, Q8>,
179 CheckRegOperand<0, Q9>,
180 CheckRegOperand<0, Q10>,
181 CheckRegOperand<0, Q11>,
182 CheckRegOperand<0, Q12>,
183 CheckRegOperand<0, Q13>,
184 CheckRegOperand<0, Q14>,
185 CheckRegOperand<0, Q15>,
186 CheckRegOperand<0, Q16>,
187 CheckRegOperand<0, Q17>,
188 CheckRegOperand<0, Q18>,
189 CheckRegOperand<0, Q19>,
190 CheckRegOperand<0, Q20>,
191 CheckRegOperand<0, Q21>,
192 CheckRegOperand<0, Q22>,
193 CheckRegOperand<0, Q23>,
194 CheckRegOperand<0, Q24>,
195 CheckRegOperand<0, Q25>,
196 CheckRegOperand<0, Q26>,
197 CheckRegOperand<0, Q27>,
198 CheckRegOperand<0, Q28>,
199 CheckRegOperand<0, Q29>,
200 CheckRegOperand<0, Q30>,
201 CheckRegOperand<0, Q31>]>]>;
203 // Identify arithmetic instructions with extend.
204 def IsArithExtOp : CheckOpcode<[ADDWrx, ADDXrx, ADDSWrx, ADDSXrx,
205 SUBWrx, SUBXrx, SUBSWrx, SUBSXrx,
207 SUBXrx64, SUBSXrx64]>;
209 // Identify arithmetic immediate instructions.
210 def IsArithImmOp : CheckOpcode<[ADDWri, ADDXri, ADDSWri, ADDSXri,
211 SUBWri, SUBXri, SUBSWri, SUBSXri]>;
213 // Identify arithmetic instructions with shift.
214 def IsArithShiftOp : CheckOpcode<[ADDWrs, ADDXrs, ADDSWrs, ADDSXrs,
215 SUBWrs, SUBXrs, SUBSWrs, SUBSXrs]>;
217 // Identify arithmetic instructions without shift.
218 def IsArithUnshiftOp : CheckOpcode<[ADDWrr, ADDXrr, ADDSWrr, ADDSXrr,
219 SUBWrr, SUBXrr, SUBSWrr, SUBSXrr]>;
221 // Identify logic immediate instructions.
222 def IsLogicImmOp : CheckOpcode<[ANDWri, ANDXri,
226 // Identify logic instructions with shift.
227 def IsLogicShiftOp : CheckOpcode<[ANDWrs, ANDXrs, ANDSWrs, ANDSXrs,
228 BICWrs, BICXrs, BICSWrs, BICSXrs,
234 // Identify logic instructions without shift.
235 def IsLogicUnshiftOp : CheckOpcode<[ANDWrr, ANDXrr, ANDSWrr, ANDSXrr,
236 BICWrr, BICXrr, BICSWrr, BICSXrr,
242 // Identify arithmetic and logic immediate instructions.
243 def IsArithLogicImmOp : CheckOpcode<!listconcat(IsArithImmOp.ValidOpcodes,
244 IsLogicImmOp.ValidOpcodes)>;
246 // Identify arithmetic and logic instructions with shift.
247 def IsArithLogicShiftOp : CheckOpcode<!listconcat(IsArithShiftOp.ValidOpcodes,
248 IsLogicShiftOp.ValidOpcodes)>;
250 // Identify arithmetic and logic instructions without shift.
251 def IsArithLogicUnshiftOp : CheckOpcode<!listconcat(IsArithUnshiftOp.ValidOpcodes,
252 IsLogicUnshiftOp.ValidOpcodes)>;
254 // Identify whether an instruction is an ASIMD
255 // load using the post index addressing mode.
256 def IsLoadASIMDPostOp : CheckOpcode<[LD1Onev8b_POST, LD1Onev4h_POST, LD1Onev2s_POST, LD1Onev1d_POST,
257 LD1Onev16b_POST, LD1Onev8h_POST, LD1Onev4s_POST, LD1Onev2d_POST,
258 LD1Twov8b_POST, LD1Twov4h_POST, LD1Twov2s_POST, LD1Twov1d_POST,
259 LD1Twov16b_POST, LD1Twov8h_POST, LD1Twov4s_POST, LD1Twov2d_POST,
260 LD1Threev8b_POST, LD1Threev4h_POST, LD1Threev2s_POST, LD1Threev1d_POST,
261 LD1Threev16b_POST, LD1Threev8h_POST, LD1Threev4s_POST, LD1Threev2d_POST,
262 LD1Fourv8b_POST, LD1Fourv4h_POST, LD1Fourv2s_POST, LD1Fourv1d_POST,
263 LD1Fourv16b_POST, LD1Fourv8h_POST, LD1Fourv4s_POST, LD1Fourv2d_POST,
264 LD1i8_POST, LD1i16_POST, LD1i32_POST, LD1i64_POST,
265 LD1Rv8b_POST, LD1Rv4h_POST, LD1Rv2s_POST, LD1Rv1d_POST,
266 LD1Rv16b_POST, LD1Rv8h_POST, LD1Rv4s_POST, LD1Rv2d_POST,
267 LD2Twov8b_POST, LD2Twov4h_POST, LD2Twov2s_POST,
268 LD2Twov16b_POST, LD2Twov8h_POST, LD2Twov4s_POST, LD2Twov2d_POST,
269 LD2i8_POST, LD2i16_POST, LD2i32_POST, LD2i64_POST,
270 LD2Rv8b_POST, LD2Rv4h_POST, LD2Rv2s_POST, LD2Rv1d_POST,
271 LD2Rv16b_POST, LD2Rv8h_POST, LD2Rv4s_POST, LD2Rv2d_POST,
272 LD3Threev8b_POST, LD3Threev4h_POST, LD3Threev2s_POST,
273 LD3Threev16b_POST, LD3Threev8h_POST, LD3Threev4s_POST, LD3Threev2d_POST,
274 LD3i8_POST, LD3i16_POST, LD3i32_POST, LD3i64_POST,
275 LD3Rv8b_POST, LD3Rv4h_POST, LD3Rv2s_POST, LD3Rv1d_POST,
276 LD3Rv16b_POST, LD3Rv8h_POST, LD3Rv4s_POST, LD3Rv2d_POST,
277 LD4Fourv8b_POST, LD4Fourv4h_POST, LD4Fourv2s_POST,
278 LD4Fourv16b_POST, LD4Fourv8h_POST, LD4Fourv4s_POST, LD4Fourv2d_POST,
279 LD4i8_POST, LD4i16_POST, LD4i32_POST, LD4i64_POST,
280 LD4Rv8b_POST, LD4Rv4h_POST, LD4Rv2s_POST, LD4Rv1d_POST,
281 LD4Rv16b_POST, LD4Rv8h_POST, LD4Rv4s_POST, LD4Rv2d_POST]>;
283 // Identify whether an instruction is an ASIMD
284 // store using the post index addressing mode.
285 def IsStoreASIMDPostOp : CheckOpcode<[ST1Onev8b_POST, ST1Onev4h_POST, ST1Onev2s_POST, ST1Onev1d_POST,
286 ST1Onev16b_POST, ST1Onev8h_POST, ST1Onev4s_POST, ST1Onev2d_POST,
287 ST1Twov8b_POST, ST1Twov4h_POST, ST1Twov2s_POST, ST1Twov1d_POST,
288 ST1Twov16b_POST, ST1Twov8h_POST, ST1Twov4s_POST, ST1Twov2d_POST,
289 ST1Threev8b_POST, ST1Threev4h_POST, ST1Threev2s_POST, ST1Threev1d_POST,
290 ST1Threev16b_POST, ST1Threev8h_POST, ST1Threev4s_POST, ST1Threev2d_POST,
291 ST1Fourv8b_POST, ST1Fourv4h_POST, ST1Fourv2s_POST, ST1Fourv1d_POST,
292 ST1Fourv16b_POST, ST1Fourv8h_POST, ST1Fourv4s_POST, ST1Fourv2d_POST,
293 ST1i8_POST, ST1i16_POST, ST1i32_POST, ST1i64_POST,
294 ST2Twov8b_POST, ST2Twov4h_POST, ST2Twov2s_POST,
295 ST2Twov16b_POST, ST2Twov8h_POST, ST2Twov4s_POST, ST2Twov2d_POST,
296 ST2i8_POST, ST2i16_POST, ST2i32_POST, ST2i64_POST,
297 ST3Threev8b_POST, ST3Threev4h_POST, ST3Threev2s_POST,
298 ST3Threev16b_POST, ST3Threev8h_POST, ST3Threev4s_POST, ST3Threev2d_POST,
299 ST3i8_POST, ST3i16_POST, ST3i32_POST, ST3i64_POST,
300 ST4Fourv8b_POST, ST4Fourv4h_POST, ST4Fourv2s_POST,
301 ST4Fourv16b_POST, ST4Fourv8h_POST, ST4Fourv4s_POST, ST4Fourv2d_POST,
302 ST4i8_POST, ST4i16_POST, ST4i32_POST, ST4i64_POST]>;
304 // Identify whether an instruction is an ASIMD load
305 // or store using the post index addressing mode.
306 def IsLoadStoreASIMDPostOp : CheckOpcode<!listconcat(IsLoadASIMDPostOp.ValidOpcodes,
307 IsStoreASIMDPostOp.ValidOpcodes)>;
309 // Identify whether an instruction is a load
310 // using the register offset addressing mode.
311 def IsLoadRegOffsetOp : CheckOpcode<[PRFMroW, PRFMroX,
313 LDRSBWroW, LDRSBWroX, LDRSBXroW, LDRSBXroX,
315 LDRSHWroW, LDRSHWroX, LDRSHXroW, LDRSHXroX,
325 // Identify whether an instruction is a store
326 // using the register offset addressing mode.
327 def IsStoreRegOffsetOp : CheckOpcode<[STRBBroW, STRBBroX,
337 // Identify whether an instruction is a load or
338 // store using the register offset addressing mode.
339 def IsLoadStoreRegOffsetOp : CheckOpcode<!listconcat(IsLoadRegOffsetOp.ValidOpcodes,
340 IsStoreRegOffsetOp.ValidOpcodes)>;
342 // Target predicates.
344 // Identify an instruction that effectively transfers a register to another.
345 def IsCopyIdiomFn : TIIPredicate<"isCopyIdiom",
346 MCOpcodeSwitchStatement<
347 [// MOV {Rd, SP}, {SP, Rn} =>
348 // ADD {Rd, SP}, {SP, Rn}, #0
353 [CheckIsRegOperand<0>,
354 CheckIsRegOperand<1>,
356 [CheckRegOperand<0, WSP>,
357 CheckRegOperand<0, SP>,
358 CheckRegOperand<1, WSP>,
359 CheckRegOperand<1, SP>]>,
360 CheckZeroOperand<2>]>>>,
362 // ORR Rd, ZR, Rm, LSL #0
367 [CheckIsRegOperand<1>,
368 CheckIsRegOperand<2>,
370 [CheckRegOperand<1, WZR>,
371 CheckRegOperand<1, XZR>]>,
373 MCReturnStatement<FalsePred>>>;
374 def IsCopyIdiomPred : MCSchedPredicate<IsCopyIdiomFn>;
376 // Identify arithmetic instructions with an extended register.
377 def RegExtendedFn : TIIPredicate<"hasExtendedReg",
378 MCOpcodeSwitchStatement<
380 IsArithExtOp.ValidOpcodes,
382 CheckNot<CheckZeroOperand<3>>>>],
383 MCReturnStatement<FalsePred>>>;
384 def RegExtendedPred : MCSchedPredicate<RegExtendedFn>;
386 // Identify arithmetic and logic instructions with a shifted register.
387 def RegShiftedFn : TIIPredicate<"hasShiftedReg",
388 MCOpcodeSwitchStatement<
390 IsArithLogicShiftOp.ValidOpcodes,
392 CheckNot<CheckZeroOperand<3>>>>],
393 MCReturnStatement<FalsePred>>>;
394 def RegShiftedPred : MCSchedPredicate<RegShiftedFn>;
396 // Identify a load or store using the register offset addressing mode
397 // with an extended or scaled register.
398 def ScaledIdxFn : TIIPredicate<"isScaledAddr",
399 MCOpcodeSwitchStatement<
401 IsLoadStoreRegOffsetOp.ValidOpcodes,
403 CheckAny<[CheckNot<CheckMemExtLSL>,
405 MCReturnStatement<FalsePred>>>;
406 def ScaledIdxPred : MCSchedPredicate<ScaledIdxFn>;
408 // Identify an instruction that effectively resets a FP register to zero.
409 def IsZeroFPIdiomFn : TIIPredicate<"isZeroFPIdiom",
410 MCOpcodeSwitchStatement<
413 [MOVIv8b_ns, MOVIv16b_ns,
415 MCReturnStatement<CheckZeroOperand<1>>>,
416 // MOVI Vd, #0, LSL #0
418 [MOVIv4i16, MOVIv8i16,
419 MOVIv2i32, MOVIv4i32],
422 [CheckZeroOperand<1>,
423 CheckZeroOperand<2>]>>>],
424 MCReturnStatement<FalsePred>>>;
425 def IsZeroFPIdiomPred : MCSchedPredicate<IsZeroFPIdiomFn>;
427 // Identify an instruction that effectively resets a GP register to zero.
428 def IsZeroIdiomFn : TIIPredicate<"isZeroIdiom",
429 MCOpcodeSwitchStatement<
435 [CheckIsRegOperand<1>,
437 [CheckRegOperand<1, WZR>,
438 CheckRegOperand<1, XZR>]>,
439 CheckZeroOperand<2>]>>>],
440 MCReturnStatement<FalsePred>>>;
441 def IsZeroIdiomPred : MCSchedPredicate<IsZeroIdiomFn>;