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<3>;
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 64-bit NEON form based on its result.
64 def CheckDForm : CheckAll<[CheckIsRegOperand<0>,
65 CheckAny<[CheckRegOperand<0, D0>,
66 CheckRegOperand<0, D1>,
67 CheckRegOperand<0, D2>,
68 CheckRegOperand<0, D3>,
69 CheckRegOperand<0, D4>,
70 CheckRegOperand<0, D5>,
71 CheckRegOperand<0, D6>,
72 CheckRegOperand<0, D7>,
73 CheckRegOperand<0, D8>,
74 CheckRegOperand<0, D9>,
75 CheckRegOperand<0, D10>,
76 CheckRegOperand<0, D11>,
77 CheckRegOperand<0, D12>,
78 CheckRegOperand<0, D13>,
79 CheckRegOperand<0, D14>,
80 CheckRegOperand<0, D15>,
81 CheckRegOperand<0, D16>,
82 CheckRegOperand<0, D17>,
83 CheckRegOperand<0, D18>,
84 CheckRegOperand<0, D19>,
85 CheckRegOperand<0, D20>,
86 CheckRegOperand<0, D21>,
87 CheckRegOperand<0, D22>,
88 CheckRegOperand<0, D23>,
89 CheckRegOperand<0, D24>,
90 CheckRegOperand<0, D25>,
91 CheckRegOperand<0, D26>,
92 CheckRegOperand<0, D27>,
93 CheckRegOperand<0, D28>,
94 CheckRegOperand<0, D29>,
95 CheckRegOperand<0, D30>,
96 CheckRegOperand<0, D31>]>]>;
98 // Identify whether an instruction is the 128-bit NEON form based on its result.
99 def CheckQForm : CheckAll<[CheckIsRegOperand<0>,
100 CheckAny<[CheckRegOperand<0, Q0>,
101 CheckRegOperand<0, Q1>,
102 CheckRegOperand<0, Q2>,
103 CheckRegOperand<0, Q3>,
104 CheckRegOperand<0, Q4>,
105 CheckRegOperand<0, Q5>,
106 CheckRegOperand<0, Q6>,
107 CheckRegOperand<0, Q7>,
108 CheckRegOperand<0, Q8>,
109 CheckRegOperand<0, Q9>,
110 CheckRegOperand<0, Q10>,
111 CheckRegOperand<0, Q11>,
112 CheckRegOperand<0, Q12>,
113 CheckRegOperand<0, Q13>,
114 CheckRegOperand<0, Q14>,
115 CheckRegOperand<0, Q15>,
116 CheckRegOperand<0, Q16>,
117 CheckRegOperand<0, Q17>,
118 CheckRegOperand<0, Q18>,
119 CheckRegOperand<0, Q19>,
120 CheckRegOperand<0, Q20>,
121 CheckRegOperand<0, Q21>,
122 CheckRegOperand<0, Q22>,
123 CheckRegOperand<0, Q23>,
124 CheckRegOperand<0, Q24>,
125 CheckRegOperand<0, Q25>,
126 CheckRegOperand<0, Q26>,
127 CheckRegOperand<0, Q27>,
128 CheckRegOperand<0, Q28>,
129 CheckRegOperand<0, Q29>,
130 CheckRegOperand<0, Q30>,
131 CheckRegOperand<0, Q31>]>]>;
133 // Identify arithmetic instructions with extend.
134 def IsArithExtOp : CheckOpcode<[ADDWrx, ADDXrx, ADDSWrx, ADDSXrx,
135 SUBWrx, SUBXrx, SUBSWrx, SUBSXrx,
137 SUBXrx64, SUBSXrx64]>;
139 // Identify arithmetic immediate instructions.
140 def IsArithImmOp : CheckOpcode<[ADDWri, ADDXri, ADDSWri, ADDSXri,
141 SUBWri, SUBXri, SUBSWri, SUBSXri]>;
143 // Identify arithmetic instructions with shift.
144 def IsArithShiftOp : CheckOpcode<[ADDWrs, ADDXrs, ADDSWrs, ADDSXrs,
145 SUBWrs, SUBXrs, SUBSWrs, SUBSXrs]>;
147 // Identify arithmetic instructions without shift.
148 def IsArithUnshiftOp : CheckOpcode<[ADDWrr, ADDXrr, ADDSWrr, ADDSXrr,
149 SUBWrr, SUBXrr, SUBSWrr, SUBSXrr]>;
151 // Identify logic immediate instructions.
152 def IsLogicImmOp : CheckOpcode<[ANDWri, ANDXri,
156 // Identify logic instructions with shift.
157 def IsLogicShiftOp : CheckOpcode<[ANDWrs, ANDXrs, ANDSWrs, ANDSXrs,
158 BICWrs, BICXrs, BICSWrs, BICSXrs,
164 // Identify logic instructions without shift.
165 def IsLogicUnshiftOp : CheckOpcode<[ANDWrr, ANDXrr, ANDSWrr, ANDSXrr,
166 BICWrr, BICXrr, BICSWrr, BICSXrr,
172 // Identify arithmetic and logic immediate instructions.
173 def IsArithLogicImmOp : CheckOpcode<!listconcat(IsArithImmOp.ValidOpcodes,
174 IsLogicImmOp.ValidOpcodes)>;
176 // Identify arithmetic and logic instructions with shift.
177 def IsArithLogicShiftOp : CheckOpcode<!listconcat(IsArithShiftOp.ValidOpcodes,
178 IsLogicShiftOp.ValidOpcodes)>;
180 // Identify arithmetic and logic instructions without shift.
181 def IsArithLogicUnshiftOp : CheckOpcode<!listconcat(IsArithUnshiftOp.ValidOpcodes,
182 IsLogicUnshiftOp.ValidOpcodes)>;
184 // Identify whether an instruction is an ASIMD
185 // load using the post index addressing mode.
186 def IsLoadASIMDPostOp : CheckOpcode<[LD1Onev8b_POST, LD1Onev4h_POST, LD1Onev2s_POST, LD1Onev1d_POST,
187 LD1Onev16b_POST, LD1Onev8h_POST, LD1Onev4s_POST, LD1Onev2d_POST,
188 LD1Twov8b_POST, LD1Twov4h_POST, LD1Twov2s_POST, LD1Twov1d_POST,
189 LD1Twov16b_POST, LD1Twov8h_POST, LD1Twov4s_POST, LD1Twov2d_POST,
190 LD1Threev8b_POST, LD1Threev4h_POST, LD1Threev2s_POST, LD1Threev1d_POST,
191 LD1Threev16b_POST, LD1Threev8h_POST, LD1Threev4s_POST, LD1Threev2d_POST,
192 LD1Fourv8b_POST, LD1Fourv4h_POST, LD1Fourv2s_POST, LD1Fourv1d_POST,
193 LD1Fourv16b_POST, LD1Fourv8h_POST, LD1Fourv4s_POST, LD1Fourv2d_POST,
194 LD1i8_POST, LD1i16_POST, LD1i32_POST, LD1i64_POST,
195 LD1Rv8b_POST, LD1Rv4h_POST, LD1Rv2s_POST, LD1Rv1d_POST,
196 LD1Rv16b_POST, LD1Rv8h_POST, LD1Rv4s_POST, LD1Rv2d_POST,
197 LD2Twov8b_POST, LD2Twov4h_POST, LD2Twov2s_POST,
198 LD2Twov16b_POST, LD2Twov8h_POST, LD2Twov4s_POST, LD2Twov2d_POST,
199 LD2i8_POST, LD2i16_POST, LD2i32_POST, LD2i64_POST,
200 LD2Rv8b_POST, LD2Rv4h_POST, LD2Rv2s_POST, LD2Rv1d_POST,
201 LD2Rv16b_POST, LD2Rv8h_POST, LD2Rv4s_POST, LD2Rv2d_POST,
202 LD3Threev8b_POST, LD3Threev4h_POST, LD3Threev2s_POST,
203 LD3Threev16b_POST, LD3Threev8h_POST, LD3Threev4s_POST, LD3Threev2d_POST,
204 LD3i8_POST, LD3i16_POST, LD3i32_POST, LD3i64_POST,
205 LD3Rv8b_POST, LD3Rv4h_POST, LD3Rv2s_POST, LD3Rv1d_POST,
206 LD3Rv16b_POST, LD3Rv8h_POST, LD3Rv4s_POST, LD3Rv2d_POST,
207 LD4Fourv8b_POST, LD4Fourv4h_POST, LD4Fourv2s_POST,
208 LD4Fourv16b_POST, LD4Fourv8h_POST, LD4Fourv4s_POST, LD4Fourv2d_POST,
209 LD4i8_POST, LD4i16_POST, LD4i32_POST, LD4i64_POST,
210 LD4Rv8b_POST, LD4Rv4h_POST, LD4Rv2s_POST, LD4Rv1d_POST,
211 LD4Rv16b_POST, LD4Rv8h_POST, LD4Rv4s_POST, LD4Rv2d_POST]>;
213 // Identify whether an instruction is an ASIMD
214 // store using the post index addressing mode.
215 def IsStoreASIMDPostOp : CheckOpcode<[ST1Onev8b_POST, ST1Onev4h_POST, ST1Onev2s_POST, ST1Onev1d_POST,
216 ST1Onev16b_POST, ST1Onev8h_POST, ST1Onev4s_POST, ST1Onev2d_POST,
217 ST1Twov8b_POST, ST1Twov4h_POST, ST1Twov2s_POST, ST1Twov1d_POST,
218 ST1Twov16b_POST, ST1Twov8h_POST, ST1Twov4s_POST, ST1Twov2d_POST,
219 ST1Threev8b_POST, ST1Threev4h_POST, ST1Threev2s_POST, ST1Threev1d_POST,
220 ST1Threev16b_POST, ST1Threev8h_POST, ST1Threev4s_POST, ST1Threev2d_POST,
221 ST1Fourv8b_POST, ST1Fourv4h_POST, ST1Fourv2s_POST, ST1Fourv1d_POST,
222 ST1Fourv16b_POST, ST1Fourv8h_POST, ST1Fourv4s_POST, ST1Fourv2d_POST,
223 ST1i8_POST, ST1i16_POST, ST1i32_POST, ST1i64_POST,
224 ST2Twov8b_POST, ST2Twov4h_POST, ST2Twov2s_POST,
225 ST2Twov16b_POST, ST2Twov8h_POST, ST2Twov4s_POST, ST2Twov2d_POST,
226 ST2i8_POST, ST2i16_POST, ST2i32_POST, ST2i64_POST,
227 ST3Threev8b_POST, ST3Threev4h_POST, ST3Threev2s_POST,
228 ST3Threev16b_POST, ST3Threev8h_POST, ST3Threev4s_POST, ST3Threev2d_POST,
229 ST3i8_POST, ST3i16_POST, ST3i32_POST, ST3i64_POST,
230 ST4Fourv8b_POST, ST4Fourv4h_POST, ST4Fourv2s_POST,
231 ST4Fourv16b_POST, ST4Fourv8h_POST, ST4Fourv4s_POST, ST4Fourv2d_POST,
232 ST4i8_POST, ST4i16_POST, ST4i32_POST, ST4i64_POST]>;
234 // Identify whether an instruction is an ASIMD load
235 // or store using the post index addressing mode.
236 def IsLoadStoreASIMDPostOp : CheckOpcode<!listconcat(IsLoadASIMDPostOp.ValidOpcodes,
237 IsStoreASIMDPostOp.ValidOpcodes)>;
239 // Identify whether an instruction is a load
240 // using the register offset addressing mode.
241 def IsLoadRegOffsetOp : CheckOpcode<[PRFMroW, PRFMroX,
243 LDRSBWroW, LDRSBWroX, LDRSBXroW, LDRSBXroX,
245 LDRSHWroW, LDRSHWroX, LDRSHXroW, LDRSHXroX,
254 // Identify whether an instruction is a load
255 // using the register offset addressing mode.
256 def IsStoreRegOffsetOp : CheckOpcode<[STRBBroW, STRBBroX,
265 // Identify whether an instruction is a load or
266 // store using the register offset addressing mode.
267 def IsLoadStoreRegOffsetOp : CheckOpcode<!listconcat(IsLoadRegOffsetOp.ValidOpcodes,
268 IsStoreRegOffsetOp.ValidOpcodes)>;
270 // Identify whether an instruction whose result is a long vector
271 // operates on the upper half of the input registers.
272 def IsLongVectorUpperOp : CheckOpcode<[FCVTLv8i16, FCVTLv4i32,
273 FCVTNv8i16, FCVTNv4i32,
275 PMULLv16i8, PMULLv2i64,
276 RADDHNv8i16_v16i8, RADDHNv4i32_v8i16, RADDHNv2i64_v4i32,
277 RSHRNv16i8_shift, RSHRNv8i16_shift, RSHRNv4i32_shift,
278 RSUBHNv8i16_v16i8, RSUBHNv4i32_v8i16, RSUBHNv2i64_v4i32,
279 SABALv16i8_v8i16, SABALv8i16_v4i32, SABALv4i32_v2i64,
280 SABDLv16i8_v8i16, SABDLv8i16_v4i32, SABDLv4i32_v2i64,
281 SADDLv16i8_v8i16, SADDLv8i16_v4i32, SADDLv4i32_v2i64,
282 SADDWv16i8_v8i16, SADDWv8i16_v4i32, SADDWv4i32_v2i64,
283 SHLLv16i8, SHLLv8i16, SHLLv4i32,
284 SHRNv16i8_shift, SHRNv8i16_shift, SHRNv4i32_shift,
285 SMLALv16i8_v8i16, SMLALv8i16_v4i32, SMLALv4i32_v2i64,
286 SMLALv8i16_indexed, SMLALv4i32_indexed,
287 SMLSLv16i8_v8i16, SMLSLv8i16_v4i32, SMLSLv4i32_v2i64,
288 SMLSLv8i16_indexed, SMLSLv4i32_indexed,
289 SMULLv16i8_v8i16, SMULLv8i16_v4i32, SMULLv4i32_v2i64,
290 SMULLv8i16_indexed, SMULLv4i32_indexed,
291 SQDMLALv8i16_v4i32, SQDMLALv4i32_v2i64,
292 SQDMLALv8i16_indexed, SQDMLALv4i32_indexed,
293 SQDMLSLv8i16_v4i32, SQDMLSLv4i32_v2i64,
294 SQDMLSLv8i16_indexed, SQDMLSLv4i32_indexed,
295 SQDMULLv8i16_v4i32, SQDMULLv4i32_v2i64,
296 SQDMULLv8i16_indexed, SQDMULLv4i32_indexed,
297 SQRSHRNv16i8_shift, SQRSHRNv8i16_shift, SQRSHRNv4i32_shift,
298 SQRSHRUNv16i8_shift, SQRSHRUNv8i16_shift, SQRSHRUNv4i32_shift,
299 SQSHRNv16i8_shift, SQSHRNv8i16_shift, SQSHRNv4i32_shift,
300 SQSHRUNv16i8_shift, SQSHRUNv8i16_shift, SQSHRUNv4i32_shift,
301 SQXTNv16i8, SQXTNv8i16, SQXTNv4i32,
302 SQXTUNv16i8, SQXTUNv8i16, SQXTUNv4i32,
303 SSHLLv16i8_shift, SSHLLv8i16_shift, SSHLLv4i32_shift,
304 SSUBLv16i8_v8i16, SSUBLv8i16_v4i32, SSUBLv4i32_v2i64,
305 SSUBWv16i8_v8i16, SSUBWv8i16_v4i32, SSUBWv4i32_v2i64,
306 UABALv16i8_v8i16, UABALv8i16_v4i32, UABALv4i32_v2i64,
307 UABDLv16i8_v8i16, UABDLv8i16_v4i32, UABDLv4i32_v2i64,
308 UADDLv16i8_v8i16, UADDLv8i16_v4i32, UADDLv4i32_v2i64,
309 UADDWv16i8_v8i16, UADDWv8i16_v4i32, UADDWv4i32_v2i64,
310 UMLALv16i8_v8i16, UMLALv8i16_v4i32, UMLALv4i32_v2i64,
311 UMLALv8i16_indexed, UMLALv4i32_indexed,
312 UMLSLv16i8_v8i16, UMLSLv8i16_v4i32, UMLSLv4i32_v2i64,
313 UMLSLv8i16_indexed, UMLSLv4i32_indexed,
314 UMULLv16i8_v8i16, UMULLv8i16_v4i32, UMULLv4i32_v2i64,
315 UMULLv8i16_indexed, UMULLv4i32_indexed,
316 UQSHRNv16i8_shift, UQSHRNv8i16_shift, UQSHRNv4i32_shift,
317 UQXTNv16i8, UQXTNv8i16, UQXTNv4i32,
318 USHLLv16i8_shift, USHLLv8i16_shift, USHLLv4i32_shift,
319 USUBLv16i8_v8i16, USUBLv8i16_v4i32, USUBLv4i32_v2i64,
320 USUBWv16i8_v8i16, USUBWv8i16_v4i32, USUBWv4i32_v2i64,
321 XTNv16i8, XTNv8i16, XTNv4i32]>;
323 // Target predicates.
325 // Identify an instruction that effectively transfers a register to another.
326 def IsCopyIdiomFn : TIIPredicate<"isCopyIdiom",
327 MCOpcodeSwitchStatement<
328 [// MOV {Rd, SP}, {SP, Rn} =>
329 // ADD {Rd, SP}, {SP, Rn}, #0
334 [CheckIsRegOperand<0>,
335 CheckIsRegOperand<1>,
337 [CheckRegOperand<0, WSP>,
338 CheckRegOperand<0, SP>,
339 CheckRegOperand<1, WSP>,
340 CheckRegOperand<1, SP>]>,
341 CheckZeroOperand<2>]>>>,
343 // ORR Rd, ZR, Rm, LSL #0
348 [CheckIsRegOperand<1>,
349 CheckIsRegOperand<2>,
351 [CheckRegOperand<1, WZR>,
352 CheckRegOperand<1, XZR>]>,
354 MCReturnStatement<FalsePred>>>;
355 def IsCopyIdiomPred : MCSchedPredicate<IsCopyIdiomFn>;
357 // Identify arithmetic instructions with an extended register.
358 def RegExtendedFn : TIIPredicate<"hasExtendedReg",
359 MCOpcodeSwitchStatement<
361 IsArithExtOp.ValidOpcodes,
363 CheckNot<CheckZeroOperand<3>>>>],
364 MCReturnStatement<FalsePred>>>;
365 def RegExtendedPred : MCSchedPredicate<RegExtendedFn>;
367 // Identify arithmetic and logic instructions with a shifted register.
368 def RegShiftedFn : TIIPredicate<"hasShiftedReg",
369 MCOpcodeSwitchStatement<
371 IsArithLogicShiftOp.ValidOpcodes,
373 CheckNot<CheckZeroOperand<3>>>>],
374 MCReturnStatement<FalsePred>>>;
375 def RegShiftedPred : MCSchedPredicate<RegShiftedFn>;
377 // Identify a load or store using the register offset addressing mode
378 // with an extended or scaled register.
379 def ScaledIdxFn : TIIPredicate<"isScaledAddr",
380 MCOpcodeSwitchStatement<
382 IsLoadStoreRegOffsetOp.ValidOpcodes,
384 CheckAny<[CheckNot<CheckMemExtLSL>,
386 MCReturnStatement<FalsePred>>>;
387 def ScaledIdxPred : MCSchedPredicate<ScaledIdxFn>;
389 // Identify an instruction that effectively resets a FP register to zero.
390 def IsZeroFPIdiomFn : TIIPredicate<"isZeroFPIdiom",
391 MCOpcodeSwitchStatement<
394 [MOVIv8b_ns, MOVIv16b_ns,
396 MCReturnStatement<CheckZeroOperand<1>>>,
397 // MOVI Vd, #0, LSL #0
399 [MOVIv4i16, MOVIv8i16,
400 MOVIv2i32, MOVIv4i32],
403 [CheckZeroOperand<1>,
404 CheckZeroOperand<2>]>>>],
405 MCReturnStatement<FalsePred>>>;
406 def IsZeroFPIdiomPred : MCSchedPredicate<IsZeroFPIdiomFn>;
408 // Identify an instruction that effectively resets a GP register to zero.
409 def IsZeroIdiomFn : TIIPredicate<"isZeroIdiom",
410 MCOpcodeSwitchStatement<
416 [CheckIsRegOperand<1>,
418 [CheckRegOperand<1, WZR>,
419 CheckRegOperand<1, XZR>]>,
420 CheckZeroOperand<2>]>>>],
421 MCReturnStatement<FalsePred>>>;
422 def IsZeroIdiomPred : MCSchedPredicate<IsZeroIdiomFn>;