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 for shifting in arithmetic and logic instructions.
35 foreach I = {0-4, 8} in {
36 let FunctionMapper = "AArch64_AM::getShiftValue" in
37 def CheckShiftBy#I : CheckImmOperand<3, I>;
40 // Check the extension type in the register offset addressing mode.
41 let FunctionMapper = "AArch64_AM::getMemExtendType" in {
42 def CheckMemExtUXTW : CheckImmOperand_s<3, "AArch64_AM::UXTW">;
43 def CheckMemExtLSL : CheckImmOperand_s<3, "AArch64_AM::UXTX">;
44 def CheckMemExtSXTW : CheckImmOperand_s<3, "AArch64_AM::SXTW">;
45 def CheckMemExtSXTX : CheckImmOperand_s<3, "AArch64_AM::SXTX">;
48 // Check for scaling in the register offset addressing mode.
49 let FunctionMapper = "AArch64_AM::getMemDoShift" in
50 def CheckMemScaled : CheckImmOperandSimple<4>;
52 // Check the shifting type in arithmetic and logic instructions.
53 let FunctionMapper = "AArch64_AM::getShiftType" in {
54 def CheckShiftLSL : CheckImmOperand_s<3, "AArch64_AM::LSL">;
55 def CheckShiftLSR : CheckImmOperand_s<3, "AArch64_AM::LSR">;
56 def CheckShiftASR : CheckImmOperand_s<3, "AArch64_AM::ASR">;
57 def CheckShiftROR : CheckImmOperand_s<3, "AArch64_AM::ROR">;
58 def CheckShiftMSL : CheckImmOperand_s<3, "AArch64_AM::MSL">;
61 // Generic predicates.
63 // Check for ZR in a register operand.
64 foreach I = {1-3} in {
65 def CheckIsReg#I#Zero : CheckAll<
66 [CheckIsRegOperand<I>,
68 [CheckRegOperand<I, WZR>,
69 CheckRegOperand<I, XZR>]>]>;
71 def IsReg1ZeroPred : MCSchedPredicate<CheckIsReg1Zero>;
72 def IsReg2ZeroPred : MCSchedPredicate<CheckIsReg2Zero>;
73 def IsReg3ZeroPred : MCSchedPredicate<CheckIsReg3Zero>;
75 // Identify whether an instruction is NEON or floating point
76 def CheckFpOrNEON : CheckFunctionPredicateWithTII<
77 "AArch64_MC::isFpOrNEON",
78 "AArch64InstrInfo::isFpOrNEON"
81 // Identify whether an instruction is the 16-bit NEON form based on its result.
82 def CheckHForm : CheckFunctionPredicateWithTII<
83 "AArch64_MC::isHForm",
84 "AArch64InstrInfo::isHForm"
87 // Identify whether an instruction is the 128-bit NEON form based on its result.
88 def CheckQForm : CheckFunctionPredicateWithTII<
89 "AArch64_MC::isQForm",
90 "AArch64InstrInfo::isQForm"
93 // Identify arithmetic instructions with extend.
94 def IsArithExtOp : CheckOpcode<[ADDWrx, ADDXrx, ADDSWrx, ADDSXrx,
95 SUBWrx, SUBXrx, SUBSWrx, SUBSXrx,
97 SUBXrx64, SUBSXrx64]>;
99 // Identify arithmetic immediate instructions.
100 def IsArithImmOp : CheckOpcode<[ADDWri, ADDXri, ADDSWri, ADDSXri,
101 SUBWri, SUBXri, SUBSWri, SUBSXri]>;
103 // Identify arithmetic instructions with shift.
104 def IsArithShiftOp : CheckOpcode<[ADDWrs, ADDXrs, ADDSWrs, ADDSXrs,
105 SUBWrs, SUBXrs, SUBSWrs, SUBSXrs]>;
107 // Identify arithmetic instructions without shift.
108 def IsArithUnshiftOp : CheckOpcode<[ADDWrr, ADDXrr, ADDSWrr, ADDSXrr,
109 SUBWrr, SUBXrr, SUBSWrr, SUBSXrr]>;
111 // Identify logic immediate instructions.
112 def IsLogicImmOp : CheckOpcode<[ANDWri, ANDXri,
116 // Identify logic instructions with shift.
117 def IsLogicShiftOp : CheckOpcode<[ANDWrs, ANDXrs, ANDSWrs, ANDSXrs,
118 BICWrs, BICXrs, BICSWrs, BICSXrs,
124 // Identify logic instructions without shift.
125 def IsLogicUnshiftOp : CheckOpcode<[ANDWrr, ANDXrr, ANDSWrr, ANDSXrr,
126 BICWrr, BICXrr, BICSWrr, BICSXrr,
132 // Identify arithmetic and logic immediate instructions.
133 def IsArithLogicImmOp : CheckOpcode<!listconcat(IsArithImmOp.ValidOpcodes,
134 IsLogicImmOp.ValidOpcodes)>;
136 // Identify arithmetic and logic instructions with shift.
137 def IsArithLogicShiftOp : CheckOpcode<!listconcat(IsArithShiftOp.ValidOpcodes,
138 IsLogicShiftOp.ValidOpcodes)>;
140 // Identify arithmetic and logic instructions without shift.
141 def IsArithLogicUnshiftOp : CheckOpcode<!listconcat(IsArithUnshiftOp.ValidOpcodes,
142 IsLogicUnshiftOp.ValidOpcodes)>;
144 // Identify whether an instruction is an ASIMD
145 // load using the post index addressing mode.
146 def IsLoadASIMDPostOp : CheckOpcode<[LD1Onev8b_POST, LD1Onev4h_POST, LD1Onev2s_POST, LD1Onev1d_POST,
147 LD1Onev16b_POST, LD1Onev8h_POST, LD1Onev4s_POST, LD1Onev2d_POST,
148 LD1Twov8b_POST, LD1Twov4h_POST, LD1Twov2s_POST, LD1Twov1d_POST,
149 LD1Twov16b_POST, LD1Twov8h_POST, LD1Twov4s_POST, LD1Twov2d_POST,
150 LD1Threev8b_POST, LD1Threev4h_POST, LD1Threev2s_POST, LD1Threev1d_POST,
151 LD1Threev16b_POST, LD1Threev8h_POST, LD1Threev4s_POST, LD1Threev2d_POST,
152 LD1Fourv8b_POST, LD1Fourv4h_POST, LD1Fourv2s_POST, LD1Fourv1d_POST,
153 LD1Fourv16b_POST, LD1Fourv8h_POST, LD1Fourv4s_POST, LD1Fourv2d_POST,
154 LD1i8_POST, LD1i16_POST, LD1i32_POST, LD1i64_POST,
155 LD1Rv8b_POST, LD1Rv4h_POST, LD1Rv2s_POST, LD1Rv1d_POST,
156 LD1Rv16b_POST, LD1Rv8h_POST, LD1Rv4s_POST, LD1Rv2d_POST,
157 LD2Twov8b_POST, LD2Twov4h_POST, LD2Twov2s_POST,
158 LD2Twov16b_POST, LD2Twov8h_POST, LD2Twov4s_POST, LD2Twov2d_POST,
159 LD2i8_POST, LD2i16_POST, LD2i32_POST, LD2i64_POST,
160 LD2Rv8b_POST, LD2Rv4h_POST, LD2Rv2s_POST, LD2Rv1d_POST,
161 LD2Rv16b_POST, LD2Rv8h_POST, LD2Rv4s_POST, LD2Rv2d_POST,
162 LD3Threev8b_POST, LD3Threev4h_POST, LD3Threev2s_POST,
163 LD3Threev16b_POST, LD3Threev8h_POST, LD3Threev4s_POST, LD3Threev2d_POST,
164 LD3i8_POST, LD3i16_POST, LD3i32_POST, LD3i64_POST,
165 LD3Rv8b_POST, LD3Rv4h_POST, LD3Rv2s_POST, LD3Rv1d_POST,
166 LD3Rv16b_POST, LD3Rv8h_POST, LD3Rv4s_POST, LD3Rv2d_POST,
167 LD4Fourv8b_POST, LD4Fourv4h_POST, LD4Fourv2s_POST,
168 LD4Fourv16b_POST, LD4Fourv8h_POST, LD4Fourv4s_POST, LD4Fourv2d_POST,
169 LD4i8_POST, LD4i16_POST, LD4i32_POST, LD4i64_POST,
170 LD4Rv8b_POST, LD4Rv4h_POST, LD4Rv2s_POST, LD4Rv1d_POST,
171 LD4Rv16b_POST, LD4Rv8h_POST, LD4Rv4s_POST, LD4Rv2d_POST]>;
173 // Identify whether an instruction is an ASIMD
174 // store using the post index addressing mode.
175 def IsStoreASIMDPostOp : CheckOpcode<[ST1Onev8b_POST, ST1Onev4h_POST, ST1Onev2s_POST, ST1Onev1d_POST,
176 ST1Onev16b_POST, ST1Onev8h_POST, ST1Onev4s_POST, ST1Onev2d_POST,
177 ST1Twov8b_POST, ST1Twov4h_POST, ST1Twov2s_POST, ST1Twov1d_POST,
178 ST1Twov16b_POST, ST1Twov8h_POST, ST1Twov4s_POST, ST1Twov2d_POST,
179 ST1Threev8b_POST, ST1Threev4h_POST, ST1Threev2s_POST, ST1Threev1d_POST,
180 ST1Threev16b_POST, ST1Threev8h_POST, ST1Threev4s_POST, ST1Threev2d_POST,
181 ST1Fourv8b_POST, ST1Fourv4h_POST, ST1Fourv2s_POST, ST1Fourv1d_POST,
182 ST1Fourv16b_POST, ST1Fourv8h_POST, ST1Fourv4s_POST, ST1Fourv2d_POST,
183 ST1i8_POST, ST1i16_POST, ST1i32_POST, ST1i64_POST,
184 ST2Twov8b_POST, ST2Twov4h_POST, ST2Twov2s_POST,
185 ST2Twov16b_POST, ST2Twov8h_POST, ST2Twov4s_POST, ST2Twov2d_POST,
186 ST2i8_POST, ST2i16_POST, ST2i32_POST, ST2i64_POST,
187 ST3Threev8b_POST, ST3Threev4h_POST, ST3Threev2s_POST,
188 ST3Threev16b_POST, ST3Threev8h_POST, ST3Threev4s_POST, ST3Threev2d_POST,
189 ST3i8_POST, ST3i16_POST, ST3i32_POST, ST3i64_POST,
190 ST4Fourv8b_POST, ST4Fourv4h_POST, ST4Fourv2s_POST,
191 ST4Fourv16b_POST, ST4Fourv8h_POST, ST4Fourv4s_POST, ST4Fourv2d_POST,
192 ST4i8_POST, ST4i16_POST, ST4i32_POST, ST4i64_POST]>;
194 // Identify whether an instruction is an ASIMD load
195 // or store using the post index addressing mode.
196 def IsLoadStoreASIMDPostOp : CheckOpcode<!listconcat(IsLoadASIMDPostOp.ValidOpcodes,
197 IsStoreASIMDPostOp.ValidOpcodes)>;
199 // Identify whether an instruction is a load
200 // using the register offset addressing mode.
201 def IsLoadRegOffsetOp : CheckOpcode<[PRFMroW, PRFMroX,
203 LDRSBWroW, LDRSBWroX, LDRSBXroW, LDRSBXroX,
205 LDRSHWroW, LDRSHWroX, LDRSHXroW, LDRSHXroX,
215 // Identify whether an instruction is a store
216 // using the register offset addressing mode.
217 def IsStoreRegOffsetOp : CheckOpcode<[STRBBroW, STRBBroX,
227 // Identify whether an instruction is a load or
228 // store using the register offset addressing mode.
229 def IsLoadStoreRegOffsetOp : CheckOpcode<!listconcat(IsLoadRegOffsetOp.ValidOpcodes,
230 IsStoreRegOffsetOp.ValidOpcodes)>;
232 // Target predicates.
234 // Identify arithmetic instructions with an extended register.
235 def RegExtendedFn : TIIPredicate<"hasExtendedReg",
236 MCOpcodeSwitchStatement<
238 IsArithExtOp.ValidOpcodes,
240 CheckNot<CheckZeroOperand<3>>>>],
241 MCReturnStatement<FalsePred>>>;
242 def RegExtendedPred : MCSchedPredicate<RegExtendedFn>;
244 // Identify arithmetic and logic instructions with a shifted register.
245 def RegShiftedFn : TIIPredicate<"hasShiftedReg",
246 MCOpcodeSwitchStatement<
248 IsArithLogicShiftOp.ValidOpcodes,
250 CheckNot<CheckZeroOperand<3>>>>],
251 MCReturnStatement<FalsePred>>>;
252 def RegShiftedPred : MCSchedPredicate<RegShiftedFn>;
254 // Identify a load or store using the register offset addressing mode
255 // with an extended or scaled register.
256 def ScaledIdxFn : TIIPredicate<"isScaledAddr",
257 MCOpcodeSwitchStatement<
259 IsLoadStoreRegOffsetOp.ValidOpcodes,
261 CheckAny<[CheckNot<CheckMemExtLSL>,
263 MCReturnStatement<FalsePred>>>;
264 def ScaledIdxPred : MCSchedPredicate<ScaledIdxFn>;
268 // Check for LSL shift <= 4
269 def IsCheapLSL : MCSchedPredicate<
281 // Identify an instruction that effectively transfers a register to another.
282 def IsCopyIdiomFn : TIIPredicate<"isCopyIdiom",
283 MCOpcodeSwitchStatement<
284 [// MOV {Rd, SP}, {SP, Rn} =>
285 // ADD {Rd, SP}, {SP, Rn}, #0
290 [CheckIsRegOperand<0>,
291 CheckIsRegOperand<1>,
293 [CheckRegOperand<0, WSP>,
294 CheckRegOperand<0, SP>,
295 CheckRegOperand<1, WSP>,
296 CheckRegOperand<1, SP>]>,
297 CheckZeroOperand<2>]>>>,
299 // ORR Rd, ZR, Rm, LSL #0
305 CheckIsRegOperand<2>,
307 MCReturnStatement<FalsePred>>>;
308 def IsCopyIdiomPred : MCSchedPredicate<IsCopyIdiomFn>;
310 // Identify an instruction that effectively resets a GP register to zero.
311 def IsZeroIdiomFn : TIIPredicate<"isZeroIdiom",
312 MCOpcodeSwitchStatement<
319 CheckZeroOperand<2>]>>>],
320 MCReturnStatement<FalsePred>>>;
321 def IsZeroIdiomPred : MCSchedPredicate<IsZeroIdiomFn>;
323 // Identify an instruction that effectively resets a FP register to zero.
324 def IsZeroFPIdiomFn : TIIPredicate<"isZeroFPIdiom",
325 MCOpcodeSwitchStatement<
328 [MOVIv8b_ns, MOVIv16b_ns,
330 MCReturnStatement<CheckZeroOperand<1>>>,
331 // MOVI Vd, #0, LSL #0
333 [MOVIv4i16, MOVIv8i16,
334 MOVIv2i32, MOVIv4i32],
337 [CheckZeroOperand<1>,
338 CheckZeroOperand<2>]>>>],
339 MCReturnStatement<FalsePred>>>;
340 def IsZeroFPIdiomPred : MCSchedPredicate<IsZeroFPIdiomFn>;
342 // Identify EXTR as the alias for ROR (immediate).
343 def IsRORImmIdiomPred : MCSchedPredicate< // EXTR Rd, Rs, Rs, #Imm
344 CheckAll<[CheckOpcode<[EXTRWrri, EXTRXrri]>,
345 CheckSameRegOperand<1, 2>]>>;