s/requires/REQUIRES to fix the test on release build
[llvm-project.git] / llvm / lib / Target / AArch64 / AArch64SchedPredicates.td
blob854d3ce564831dba20c6a75c008bd1b26785e2e9
1 //===- AArch64SchedPredicates.td - AArch64 Sched Preds -----*- tablegen -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines scheduling predicate definitions that are used by the
10 // AArch64 subtargets.
12 //===----------------------------------------------------------------------===//
14 // Function mappers.
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>,
67                              CheckAny<
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,
96                                           ADDXrx64, ADDSXrx64,
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,
113                                           EORWri, EORXri,
114                                           ORRWri, ORRXri]>;
116 // Identify logic instructions with shift.
117 def IsLogicShiftOp         : CheckOpcode<[ANDWrs, ANDXrs, ANDSWrs, ANDSXrs,
118                                           BICWrs, BICXrs, BICSWrs, BICSXrs,
119                                           EONWrs, EONXrs,
120                                           EORWrs, EORXrs,
121                                           ORNWrs, ORNXrs,
122                                           ORRWrs, ORRXrs]>;
124 // Identify logic instructions without shift.
125 def IsLogicUnshiftOp       : CheckOpcode<[ANDWrr, ANDXrr, ANDSWrr, ANDSXrr,
126                                           BICWrr, BICXrr, BICSWrr, BICSXrr,
127                                           EONWrr, EONXrr,
128                                           EORWrr, EORXrr,
129                                           ORNWrr, ORNXrr,
130                                           ORRWrr, ORRXrr]>;
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,
202                                           LDRBBroW, LDRBBroX,
203                                           LDRSBWroW, LDRSBWroX, LDRSBXroW, LDRSBXroX,
204                                           LDRHHroW, LDRHHroX,
205                                           LDRSHWroW, LDRSHWroX, LDRSHXroW, LDRSHXroX,
206                                           LDRWroW, LDRWroX,
207                                           LDRSWroW, LDRSWroX,
208                                           LDRXroW, LDRXroX,
209                                           LDRBroW, LDRBroX,
210                                           LDRHroW, LDRHroX,
211                                           LDRSroW, LDRSroX,
212                                           LDRDroW, LDRDroX,
213                                           LDRQroW, LDRQroX]>;
215 // Identify whether an instruction is a store
216 // using the register offset addressing mode.
217 def IsStoreRegOffsetOp     : CheckOpcode<[STRBBroW, STRBBroX,
218                                           STRHHroW, STRHHroX,
219                                           STRWroW, STRWroX,
220                                           STRXroW, STRXroX,
221                                           STRBroW, STRBroX,
222                                           STRHroW, STRHroX,
223                                           STRSroW, STRSroX,
224                                           STRDroW, STRDroX,
225                                           STRQroW, STRQroX]>;
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<
237                                        [MCOpcodeSwitchCase<
238                                          IsArithExtOp.ValidOpcodes,
239                                          MCReturnStatement<
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<
247                                        [MCOpcodeSwitchCase<
248                                           IsArithLogicShiftOp.ValidOpcodes,
249                                           MCReturnStatement<
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<
258                                        [MCOpcodeSwitchCase<
259                                           IsLoadStoreRegOffsetOp.ValidOpcodes,
260                                           MCReturnStatement<
261                                             CheckAny<[CheckNot<CheckMemExtLSL>,
262                                                       CheckMemScaled]>>>],
263                                        MCReturnStatement<FalsePred>>>;
264 def ScaledIdxPred     : MCSchedPredicate<ScaledIdxFn>;
266 // Special cases.
268 // Check for LSL shift <= 4
269 def IsCheapLSL        : MCSchedPredicate<
270                           CheckAll<
271                             [CheckShiftLSL,
272                              CheckAny<
273                                [CheckShiftBy0,
274                                 CheckShiftBy1,
275                                 CheckShiftBy2,
276                                 CheckShiftBy3,
277                                 CheckShiftBy4]>]>>;
279 // Idioms.
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
286                                         MCOpcodeSwitchCase<
287                                           [ADDWri, ADDXri],
288                                           MCReturnStatement<
289                                             CheckAll<
290                                               [CheckIsRegOperand<0>,
291                                                CheckIsRegOperand<1>,
292                                                CheckAny<
293                                                  [CheckRegOperand<0, WSP>,
294                                                   CheckRegOperand<0, SP>,
295                                                   CheckRegOperand<1, WSP>,
296                                                   CheckRegOperand<1, SP>]>,
297                                                CheckZeroOperand<2>]>>>,
298                                         // MOV Rd, Rm =>
299                                         // ORR Rd, ZR, Rm, LSL #0
300                                         MCOpcodeSwitchCase<
301                                           [ORRWrs, ORRXrs],
302                                           MCReturnStatement<
303                                             CheckAll<
304                                               [CheckIsReg1Zero,
305                                                CheckIsRegOperand<2>,
306                                                CheckShiftBy0]>>>],
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<
313                                       [// ORR Rd, ZR, #0
314                                        MCOpcodeSwitchCase<
315                                          [ORRWri, ORRXri],
316                                          MCReturnStatement<
317                                            CheckAll<
318                                              [CheckIsReg1Zero,
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<
326                                        [// MOVI Vd, #0
327                                         MCOpcodeSwitchCase<
328                                           [MOVIv8b_ns, MOVIv16b_ns,
329                                            MOVID, MOVIv2d_ns],
330                                           MCReturnStatement<CheckZeroOperand<1>>>,
331                                         // MOVI Vd, #0, LSL #0
332                                         MCOpcodeSwitchCase<
333                                           [MOVIv4i16, MOVIv8i16,
334                                            MOVIv2i32, MOVIv4i32],
335                                           MCReturnStatement<
336                                             CheckAll<
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>]>>;