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 // Target predicates.
272 // Identify an instruction that effectively transfers a register to another.
273 def IsCopyIdiomFn : TIIPredicate<"isCopyIdiom",
274 MCOpcodeSwitchStatement<
275 [// MOV {Rd, SP}, {SP, Rn} =>
276 // ADD {Rd, SP}, {SP, Rn}, #0
281 [CheckIsRegOperand<0>,
282 CheckIsRegOperand<1>,
284 [CheckRegOperand<0, WSP>,
285 CheckRegOperand<0, SP>,
286 CheckRegOperand<1, WSP>,
287 CheckRegOperand<1, SP>]>,
288 CheckZeroOperand<2>]>>>,
290 // ORR Rd, ZR, Rm, LSL #0
295 [CheckIsRegOperand<1>,
296 CheckIsRegOperand<2>,
298 [CheckRegOperand<1, WZR>,
299 CheckRegOperand<1, XZR>]>,
301 MCReturnStatement<FalsePred>>>;
302 def IsCopyIdiomPred : MCSchedPredicate<IsCopyIdiomFn>;
304 // Identify arithmetic instructions with an extended register.
305 def RegExtendedFn : TIIPredicate<"hasExtendedReg",
306 MCOpcodeSwitchStatement<
308 IsArithExtOp.ValidOpcodes,
310 CheckNot<CheckZeroOperand<3>>>>],
311 MCReturnStatement<FalsePred>>>;
312 def RegExtendedPred : MCSchedPredicate<RegExtendedFn>;
314 // Identify arithmetic and logic instructions with a shifted register.
315 def RegShiftedFn : TIIPredicate<"hasShiftedReg",
316 MCOpcodeSwitchStatement<
318 IsArithLogicShiftOp.ValidOpcodes,
320 CheckNot<CheckZeroOperand<3>>>>],
321 MCReturnStatement<FalsePred>>>;
322 def RegShiftedPred : MCSchedPredicate<RegShiftedFn>;
324 // Identify a load or store using the register offset addressing mode
325 // with an extended or scaled register.
326 def ScaledIdxFn : TIIPredicate<"isScaledAddr",
327 MCOpcodeSwitchStatement<
329 IsLoadStoreRegOffsetOp.ValidOpcodes,
331 CheckAny<[CheckNot<CheckMemExtLSL>,
333 MCReturnStatement<FalsePred>>>;
334 def ScaledIdxPred : MCSchedPredicate<ScaledIdxFn>;
336 // Identify an instruction that effectively resets a FP register to zero.
337 def IsZeroFPIdiomFn : TIIPredicate<"isZeroFPIdiom",
338 MCOpcodeSwitchStatement<
341 [MOVIv8b_ns, MOVIv16b_ns,
343 MCReturnStatement<CheckZeroOperand<1>>>,
344 // MOVI Vd, #0, LSL #0
346 [MOVIv4i16, MOVIv8i16,
347 MOVIv2i32, MOVIv4i32],
350 [CheckZeroOperand<1>,
351 CheckZeroOperand<2>]>>>],
352 MCReturnStatement<FalsePred>>>;
353 def IsZeroFPIdiomPred : MCSchedPredicate<IsZeroFPIdiomFn>;
355 // Identify an instruction that effectively resets a GP register to zero.
356 def IsZeroIdiomFn : TIIPredicate<"isZeroIdiom",
357 MCOpcodeSwitchStatement<
363 [CheckIsRegOperand<1>,
365 [CheckRegOperand<1, WZR>,
366 CheckRegOperand<1, XZR>]>,
367 CheckZeroOperand<2>]>>>],
368 MCReturnStatement<FalsePred>>>;
369 def IsZeroIdiomPred : MCSchedPredicate<IsZeroIdiomFn>;