1 //===- AArch64SchedPredicates.td - AArch64 Sched Preds -----*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines scheduling predicate definitions that are used by the
11 // AArch64 subtargets.
13 //===----------------------------------------------------------------------===//
17 // Check the extension type in arithmetic instructions.
18 let FunctionMapper = "AArch64_AM::getArithExtendType" in {
19 def CheckExtUXTB : CheckImmOperand_s<3, "AArch64_AM::UXTB">;
20 def CheckExtUXTH : CheckImmOperand_s<3, "AArch64_AM::UXTH">;
21 def CheckExtUXTW : CheckImmOperand_s<3, "AArch64_AM::UXTW">;
22 def CheckExtUXTX : CheckImmOperand_s<3, "AArch64_AM::UXTX">;
23 def CheckExtSXTB : CheckImmOperand_s<3, "AArch64_AM::SXTB">;
24 def CheckExtSXTH : CheckImmOperand_s<3, "AArch64_AM::SXTH">;
25 def CheckExtSXTW : CheckImmOperand_s<3, "AArch64_AM::SXTW">;
26 def CheckExtSXTX : CheckImmOperand_s<3, "AArch64_AM::SXTX">;
29 // Check for shifting in extended arithmetic instructions.
30 foreach I = {0-3} in {
31 let FunctionMapper = "AArch64_AM::getArithShiftValue" in
32 def CheckExtBy#I : CheckImmOperand<3, I>;
35 // Check the extension type in the register offset addressing mode.
36 let FunctionMapper = "AArch64_AM::getMemExtendType" in {
37 def CheckMemExtUXTW : CheckImmOperand_s<3, "AArch64_AM::UXTW">;
38 def CheckMemExtLSL : CheckImmOperand_s<3, "AArch64_AM::UXTX">;
39 def CheckMemExtSXTW : CheckImmOperand_s<3, "AArch64_AM::SXTW">;
40 def CheckMemExtSXTX : CheckImmOperand_s<3, "AArch64_AM::SXTX">;
43 // Check for scaling in the register offset addressing mode.
44 let FunctionMapper = "AArch64_AM::getMemDoShift" in
45 def CheckMemScaled : CheckImmOperandSimple<3>;
47 // Check the shifting type in arithmetic and logic instructions.
48 let FunctionMapper = "AArch64_AM::getShiftType" in {
49 def CheckShiftLSL : CheckImmOperand_s<3, "AArch64_AM::LSL">;
50 def CheckShiftLSR : CheckImmOperand_s<3, "AArch64_AM::LSR">;
51 def CheckShiftASR : CheckImmOperand_s<3, "AArch64_AM::ASR">;
52 def CheckShiftROR : CheckImmOperand_s<3, "AArch64_AM::ROR">;
53 def CheckShiftMSL : CheckImmOperand_s<3, "AArch64_AM::MSL">;
56 // Check for shifting in arithmetic and logic instructions.
57 foreach I = {0-3, 8} in {
58 let FunctionMapper = "AArch64_AM::getShiftValue" in
59 def CheckShiftBy#I : CheckImmOperand<3, I>;
62 // Generic predicates.
64 // Identify whether an instruction is the 64-bit NEON form based on its result.
65 def CheckDForm : CheckAll<[CheckIsRegOperand<0>,
66 CheckAny<[CheckRegOperand<0, D0>,
67 CheckRegOperand<0, D1>,
68 CheckRegOperand<0, D2>,
69 CheckRegOperand<0, D3>,
70 CheckRegOperand<0, D4>,
71 CheckRegOperand<0, D5>,
72 CheckRegOperand<0, D6>,
73 CheckRegOperand<0, D7>,
74 CheckRegOperand<0, D8>,
75 CheckRegOperand<0, D9>,
76 CheckRegOperand<0, D10>,
77 CheckRegOperand<0, D11>,
78 CheckRegOperand<0, D12>,
79 CheckRegOperand<0, D13>,
80 CheckRegOperand<0, D14>,
81 CheckRegOperand<0, D15>,
82 CheckRegOperand<0, D16>,
83 CheckRegOperand<0, D17>,
84 CheckRegOperand<0, D18>,
85 CheckRegOperand<0, D19>,
86 CheckRegOperand<0, D20>,
87 CheckRegOperand<0, D21>,
88 CheckRegOperand<0, D22>,
89 CheckRegOperand<0, D23>,
90 CheckRegOperand<0, D24>,
91 CheckRegOperand<0, D25>,
92 CheckRegOperand<0, D26>,
93 CheckRegOperand<0, D27>,
94 CheckRegOperand<0, D28>,
95 CheckRegOperand<0, D29>,
96 CheckRegOperand<0, D30>,
97 CheckRegOperand<0, D31>]>]>;
99 // Identify whether an instruction is the 128-bit NEON form based on its result.
100 def CheckQForm : CheckAll<[CheckIsRegOperand<0>,
101 CheckAny<[CheckRegOperand<0, Q0>,
102 CheckRegOperand<0, Q1>,
103 CheckRegOperand<0, Q2>,
104 CheckRegOperand<0, Q3>,
105 CheckRegOperand<0, Q4>,
106 CheckRegOperand<0, Q5>,
107 CheckRegOperand<0, Q6>,
108 CheckRegOperand<0, Q7>,
109 CheckRegOperand<0, Q8>,
110 CheckRegOperand<0, Q9>,
111 CheckRegOperand<0, Q10>,
112 CheckRegOperand<0, Q11>,
113 CheckRegOperand<0, Q12>,
114 CheckRegOperand<0, Q13>,
115 CheckRegOperand<0, Q14>,
116 CheckRegOperand<0, Q15>,
117 CheckRegOperand<0, Q16>,
118 CheckRegOperand<0, Q17>,
119 CheckRegOperand<0, Q18>,
120 CheckRegOperand<0, Q19>,
121 CheckRegOperand<0, Q20>,
122 CheckRegOperand<0, Q21>,
123 CheckRegOperand<0, Q22>,
124 CheckRegOperand<0, Q23>,
125 CheckRegOperand<0, Q24>,
126 CheckRegOperand<0, Q25>,
127 CheckRegOperand<0, Q26>,
128 CheckRegOperand<0, Q27>,
129 CheckRegOperand<0, Q28>,
130 CheckRegOperand<0, Q29>,
131 CheckRegOperand<0, Q30>,
132 CheckRegOperand<0, Q31>]>]>;
134 // Identify arithmetic instructions with extend.
135 def IsArithExtOp : CheckOpcode<[ADDWrx, ADDXrx, ADDSWrx, ADDSXrx,
136 SUBWrx, SUBXrx, SUBSWrx, SUBSXrx,
138 SUBXrx64, SUBSXrx64]>;
140 // Identify arithmetic immediate instructions.
141 def IsArithImmOp : CheckOpcode<[ADDWri, ADDXri, ADDSWri, ADDSXri,
142 SUBWri, SUBXri, SUBSWri, SUBSXri]>;
144 // Identify arithmetic instructions with shift.
145 def IsArithShiftOp : CheckOpcode<[ADDWrs, ADDXrs, ADDSWrs, ADDSXrs,
146 SUBWrs, SUBXrs, SUBSWrs, SUBSXrs]>;
148 // Identify arithmetic instructions without shift.
149 def IsArithUnshiftOp : CheckOpcode<[ADDWrr, ADDXrr, ADDSWrr, ADDSXrr,
150 SUBWrr, SUBXrr, SUBSWrr, SUBSXrr]>;
152 // Identify logic immediate instructions.
153 def IsLogicImmOp : CheckOpcode<[ANDWri, ANDXri,
157 // Identify logic instructions with shift.
158 def IsLogicShiftOp : CheckOpcode<[ANDWrs, ANDXrs, ANDSWrs, ANDSXrs,
159 BICWrs, BICXrs, BICSWrs, BICSXrs,
165 // Identify logic instructions without shift.
166 def IsLogicUnshiftOp : CheckOpcode<[ANDWrr, ANDXrr, ANDSWrr, ANDSXrr,
167 BICWrr, BICXrr, BICSWrr, BICSXrr,
173 // Identify arithmetic and logic immediate instructions.
174 def IsArithLogicImmOp : CheckOpcode<!listconcat(IsArithImmOp.ValidOpcodes,
175 IsLogicImmOp.ValidOpcodes)>;
177 // Identify arithmetic and logic instructions with shift.
178 def IsArithLogicShiftOp : CheckOpcode<!listconcat(IsArithShiftOp.ValidOpcodes,
179 IsLogicShiftOp.ValidOpcodes)>;
181 // Identify arithmetic and logic instructions without shift.
182 def IsArithLogicUnshiftOp : CheckOpcode<!listconcat(IsArithUnshiftOp.ValidOpcodes,
183 IsLogicUnshiftOp.ValidOpcodes)>;
185 // Identify whether an instruction is an ASIMD
186 // load using the post index addressing mode.
187 def IsLoadASIMDPostOp : CheckOpcode<[LD1Onev8b_POST, LD1Onev4h_POST, LD1Onev2s_POST, LD1Onev1d_POST,
188 LD1Onev16b_POST, LD1Onev8h_POST, LD1Onev4s_POST, LD1Onev2d_POST,
189 LD1Twov8b_POST, LD1Twov4h_POST, LD1Twov2s_POST, LD1Twov1d_POST,
190 LD1Twov16b_POST, LD1Twov8h_POST, LD1Twov4s_POST, LD1Twov2d_POST,
191 LD1Threev8b_POST, LD1Threev4h_POST, LD1Threev2s_POST, LD1Threev1d_POST,
192 LD1Threev16b_POST, LD1Threev8h_POST, LD1Threev4s_POST, LD1Threev2d_POST,
193 LD1Fourv8b_POST, LD1Fourv4h_POST, LD1Fourv2s_POST, LD1Fourv1d_POST,
194 LD1Fourv16b_POST, LD1Fourv8h_POST, LD1Fourv4s_POST, LD1Fourv2d_POST,
195 LD1i8_POST, LD1i16_POST, LD1i32_POST, LD1i64_POST,
196 LD1Rv8b_POST, LD1Rv4h_POST, LD1Rv2s_POST, LD1Rv1d_POST,
197 LD1Rv16b_POST, LD1Rv8h_POST, LD1Rv4s_POST, LD1Rv2d_POST,
198 LD2Twov8b_POST, LD2Twov4h_POST, LD2Twov2s_POST,
199 LD2Twov16b_POST, LD2Twov8h_POST, LD2Twov4s_POST, LD2Twov2d_POST,
200 LD2i8_POST, LD2i16_POST, LD2i32_POST, LD2i64_POST,
201 LD2Rv8b_POST, LD2Rv4h_POST, LD2Rv2s_POST, LD2Rv1d_POST,
202 LD2Rv16b_POST, LD2Rv8h_POST, LD2Rv4s_POST, LD2Rv2d_POST,
203 LD3Threev8b_POST, LD3Threev4h_POST, LD3Threev2s_POST,
204 LD3Threev16b_POST, LD3Threev8h_POST, LD3Threev4s_POST, LD3Threev2d_POST,
205 LD3i8_POST, LD3i16_POST, LD3i32_POST, LD3i64_POST,
206 LD3Rv8b_POST, LD3Rv4h_POST, LD3Rv2s_POST, LD3Rv1d_POST,
207 LD3Rv16b_POST, LD3Rv8h_POST, LD3Rv4s_POST, LD3Rv2d_POST,
208 LD4Fourv8b_POST, LD4Fourv4h_POST, LD4Fourv2s_POST,
209 LD4Fourv16b_POST, LD4Fourv8h_POST, LD4Fourv4s_POST, LD4Fourv2d_POST,
210 LD4i8_POST, LD4i16_POST, LD4i32_POST, LD4i64_POST,
211 LD4Rv8b_POST, LD4Rv4h_POST, LD4Rv2s_POST, LD4Rv1d_POST,
212 LD4Rv16b_POST, LD4Rv8h_POST, LD4Rv4s_POST, LD4Rv2d_POST]>;
214 // Identify whether an instruction is an ASIMD
215 // store using the post index addressing mode.
216 def IsStoreASIMDPostOp : CheckOpcode<[ST1Onev8b_POST, ST1Onev4h_POST, ST1Onev2s_POST, ST1Onev1d_POST,
217 ST1Onev16b_POST, ST1Onev8h_POST, ST1Onev4s_POST, ST1Onev2d_POST,
218 ST1Twov8b_POST, ST1Twov4h_POST, ST1Twov2s_POST, ST1Twov1d_POST,
219 ST1Twov16b_POST, ST1Twov8h_POST, ST1Twov4s_POST, ST1Twov2d_POST,
220 ST1Threev8b_POST, ST1Threev4h_POST, ST1Threev2s_POST, ST1Threev1d_POST,
221 ST1Threev16b_POST, ST1Threev8h_POST, ST1Threev4s_POST, ST1Threev2d_POST,
222 ST1Fourv8b_POST, ST1Fourv4h_POST, ST1Fourv2s_POST, ST1Fourv1d_POST,
223 ST1Fourv16b_POST, ST1Fourv8h_POST, ST1Fourv4s_POST, ST1Fourv2d_POST,
224 ST1i8_POST, ST1i16_POST, ST1i32_POST, ST1i64_POST,
225 ST2Twov8b_POST, ST2Twov4h_POST, ST2Twov2s_POST,
226 ST2Twov16b_POST, ST2Twov8h_POST, ST2Twov4s_POST, ST2Twov2d_POST,
227 ST2i8_POST, ST2i16_POST, ST2i32_POST, ST2i64_POST,
228 ST3Threev8b_POST, ST3Threev4h_POST, ST3Threev2s_POST,
229 ST3Threev16b_POST, ST3Threev8h_POST, ST3Threev4s_POST, ST3Threev2d_POST,
230 ST3i8_POST, ST3i16_POST, ST3i32_POST, ST3i64_POST,
231 ST4Fourv8b_POST, ST4Fourv4h_POST, ST4Fourv2s_POST,
232 ST4Fourv16b_POST, ST4Fourv8h_POST, ST4Fourv4s_POST, ST4Fourv2d_POST,
233 ST4i8_POST, ST4i16_POST, ST4i32_POST, ST4i64_POST]>;
235 // Identify whether an instruction is an ASIMD load
236 // or store using the post index addressing mode.
237 def IsLoadStoreASIMDPostOp : CheckOpcode<!listconcat(IsLoadASIMDPostOp.ValidOpcodes,
238 IsStoreASIMDPostOp.ValidOpcodes)>;
240 // Identify whether an instruction is a load
241 // using the register offset addressing mode.
242 def IsLoadRegOffsetOp : CheckOpcode<[PRFMroW, PRFMroX,
244 LDRSBWroW, LDRSBWroX, LDRSBXroW, LDRSBXroX,
246 LDRSHWroW, LDRSHWroX, LDRSHXroW, LDRSHXroX,
255 // Identify whether an instruction is a load
256 // using the register offset addressing mode.
257 def IsStoreRegOffsetOp : CheckOpcode<[STRBBroW, STRBBroX,
266 // Identify whether an instruction is a load or
267 // store using the register offset addressing mode.
268 def IsLoadStoreRegOffsetOp : CheckOpcode<!listconcat(IsLoadRegOffsetOp.ValidOpcodes,
269 IsStoreRegOffsetOp.ValidOpcodes)>;
271 // Identify whether an instruction whose result is a long vector
272 // operates on the upper half of the input registers.
273 def IsLongVectorUpperOp : CheckOpcode<[FCVTLv8i16, FCVTLv4i32,
274 FCVTNv8i16, FCVTNv4i32,
276 PMULLv16i8, PMULLv2i64,
277 RADDHNv8i16_v16i8, RADDHNv4i32_v8i16, RADDHNv2i64_v4i32,
278 RSHRNv16i8_shift, RSHRNv8i16_shift, RSHRNv4i32_shift,
279 RSUBHNv8i16_v16i8, RSUBHNv4i32_v8i16, RSUBHNv2i64_v4i32,
280 SABALv16i8_v8i16, SABALv8i16_v4i32, SABALv4i32_v2i64,
281 SABDLv16i8_v8i16, SABDLv8i16_v4i32, SABDLv4i32_v2i64,
282 SADDLv16i8_v8i16, SADDLv8i16_v4i32, SADDLv4i32_v2i64,
283 SADDWv16i8_v8i16, SADDWv8i16_v4i32, SADDWv4i32_v2i64,
284 SHLLv16i8, SHLLv8i16, SHLLv4i32,
285 SHRNv16i8_shift, SHRNv8i16_shift, SHRNv4i32_shift,
286 SMLALv16i8_v8i16, SMLALv8i16_v4i32, SMLALv4i32_v2i64,
287 SMLALv8i16_indexed, SMLALv4i32_indexed,
288 SMLSLv16i8_v8i16, SMLSLv8i16_v4i32, SMLSLv4i32_v2i64,
289 SMLSLv8i16_indexed, SMLSLv4i32_indexed,
290 SMULLv16i8_v8i16, SMULLv8i16_v4i32, SMULLv4i32_v2i64,
291 SMULLv8i16_indexed, SMULLv4i32_indexed,
292 SQDMLALv8i16_v4i32, SQDMLALv4i32_v2i64,
293 SQDMLALv8i16_indexed, SQDMLALv4i32_indexed,
294 SQDMLSLv8i16_v4i32, SQDMLSLv4i32_v2i64,
295 SQDMLSLv8i16_indexed, SQDMLSLv4i32_indexed,
296 SQDMULLv8i16_v4i32, SQDMULLv4i32_v2i64,
297 SQDMULLv8i16_indexed, SQDMULLv4i32_indexed,
298 SQRSHRNv16i8_shift, SQRSHRNv8i16_shift, SQRSHRNv4i32_shift,
299 SQRSHRUNv16i8_shift, SQRSHRUNv8i16_shift, SQRSHRUNv4i32_shift,
300 SQSHRNv16i8_shift, SQSHRNv8i16_shift, SQSHRNv4i32_shift,
301 SQSHRUNv16i8_shift, SQSHRUNv8i16_shift, SQSHRUNv4i32_shift,
302 SQXTNv16i8, SQXTNv8i16, SQXTNv4i32,
303 SQXTUNv16i8, SQXTUNv8i16, SQXTUNv4i32,
304 SSHLLv16i8_shift, SSHLLv8i16_shift, SSHLLv4i32_shift,
305 SSUBLv16i8_v8i16, SSUBLv8i16_v4i32, SSUBLv4i32_v2i64,
306 SSUBWv16i8_v8i16, SSUBWv8i16_v4i32, SSUBWv4i32_v2i64,
307 UABALv16i8_v8i16, UABALv8i16_v4i32, UABALv4i32_v2i64,
308 UABDLv16i8_v8i16, UABDLv8i16_v4i32, UABDLv4i32_v2i64,
309 UADDLv16i8_v8i16, UADDLv8i16_v4i32, UADDLv4i32_v2i64,
310 UADDWv16i8_v8i16, UADDWv8i16_v4i32, UADDWv4i32_v2i64,
311 UMLALv16i8_v8i16, UMLALv8i16_v4i32, UMLALv4i32_v2i64,
312 UMLALv8i16_indexed, UMLALv4i32_indexed,
313 UMLSLv16i8_v8i16, UMLSLv8i16_v4i32, UMLSLv4i32_v2i64,
314 UMLSLv8i16_indexed, UMLSLv4i32_indexed,
315 UMULLv16i8_v8i16, UMULLv8i16_v4i32, UMULLv4i32_v2i64,
316 UMULLv8i16_indexed, UMULLv4i32_indexed,
317 UQSHRNv16i8_shift, UQSHRNv8i16_shift, UQSHRNv4i32_shift,
318 UQXTNv16i8, UQXTNv8i16, UQXTNv4i32,
319 USHLLv16i8_shift, USHLLv8i16_shift, USHLLv4i32_shift,
320 USUBLv16i8_v8i16, USUBLv8i16_v4i32, USUBLv4i32_v2i64,
321 USUBWv16i8_v8i16, USUBWv8i16_v4i32, USUBWv4i32_v2i64,
322 XTNv16i8, XTNv8i16, XTNv4i32]>;
324 // Target predicates.
326 // Identify an instruction that effectively transfers a register to another.
327 def IsCopyIdiomFn : TIIPredicate<"isCopyIdiom",
328 MCOpcodeSwitchStatement<
329 [// MOV {Rd, SP}, {SP, Rn} =>
330 // ADD {Rd, SP}, {SP, Rn}, #0
335 [CheckIsRegOperand<0>,
336 CheckIsRegOperand<1>,
338 [CheckRegOperand<0, WSP>,
339 CheckRegOperand<0, SP>,
340 CheckRegOperand<1, WSP>,
341 CheckRegOperand<1, SP>]>,
342 CheckZeroOperand<2>]>>>,
344 // ORR Rd, ZR, Rm, LSL #0
349 [CheckIsRegOperand<1>,
350 CheckIsRegOperand<2>,
352 [CheckRegOperand<1, WZR>,
353 CheckRegOperand<1, XZR>]>,
355 MCReturnStatement<FalsePred>>>;
356 def IsCopyIdiomPred : MCSchedPredicate<IsCopyIdiomFn>;
358 // Identify arithmetic instructions with an extended register.
359 def RegExtendedFn : TIIPredicate<"hasExtendedReg",
360 MCOpcodeSwitchStatement<
362 IsArithExtOp.ValidOpcodes,
364 CheckNot<CheckZeroOperand<3>>>>],
365 MCReturnStatement<FalsePred>>>;
366 def RegExtendedPred : MCSchedPredicate<RegExtendedFn>;
368 // Identify arithmetic and logic instructions with a shifted register.
369 def RegShiftedFn : TIIPredicate<"hasShiftedReg",
370 MCOpcodeSwitchStatement<
372 IsArithLogicShiftOp.ValidOpcodes,
374 CheckNot<CheckZeroOperand<3>>>>],
375 MCReturnStatement<FalsePred>>>;
376 def RegShiftedPred : MCSchedPredicate<RegShiftedFn>;
378 // Identify a load or store using the register offset addressing mode
379 // with an extended or scaled register.
380 def ScaledIdxFn : TIIPredicate<"isScaledAddr",
381 MCOpcodeSwitchStatement<
383 IsLoadStoreRegOffsetOp.ValidOpcodes,
385 CheckAny<[CheckNot<CheckMemExtLSL>,
387 MCReturnStatement<FalsePred>>>;
388 def ScaledIdxPred : MCSchedPredicate<ScaledIdxFn>;
390 // Identify an instruction that effectively resets a FP register to zero.
391 def IsZeroFPIdiomFn : TIIPredicate<"isZeroFPIdiom",
392 MCOpcodeSwitchStatement<
395 [MOVIv8b_ns, MOVIv16b_ns,
397 MCReturnStatement<CheckZeroOperand<1>>>,
398 // MOVI Vd, #0, LSL #0
400 [MOVIv4i16, MOVIv8i16,
401 MOVIv2i32, MOVIv4i32],
404 [CheckZeroOperand<1>,
405 CheckZeroOperand<2>]>>>],
406 MCReturnStatement<FalsePred>>>;
407 def IsZeroFPIdiomPred : MCSchedPredicate<IsZeroFPIdiomFn>;
409 // Identify an instruction that effectively resets a GP register to zero.
410 def IsZeroIdiomFn : TIIPredicate<"isZeroIdiom",
411 MCOpcodeSwitchStatement<
417 [CheckIsRegOperand<1>,
419 [CheckRegOperand<1, WZR>,
420 CheckRegOperand<1, XZR>]>,
421 CheckZeroOperand<2>]>>>],
422 MCReturnStatement<FalsePred>>>;
423 def IsZeroIdiomPred : MCSchedPredicate<IsZeroIdiomFn>;