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.
11//
12//===----------------------------------------------------------------------===//
13
14// Function mappers.
15
16// Check the extension type in arithmetic instructions.
17let 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">;
26}
27
28// Check for shifting in extended arithmetic instructions.
29foreach I = {0-3} in {
30  let FunctionMapper = "AArch64_AM::getArithShiftValue" in
31  def CheckExtBy#I                      : CheckImmOperand<3, I>;
32}
33
34// Check for shifting in arithmetic and logic instructions.
35foreach I = {0-4, 8} in {
36  let FunctionMapper = "AArch64_AM::getShiftValue" in
37  def CheckShiftBy#I                    : CheckImmOperand<3, I>;
38}
39
40// Check the extension type in the register offset addressing mode.
41let 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">;
46}
47
48// Check for scaling in the register offset addressing mode.
49let FunctionMapper = "AArch64_AM::getMemDoShift" in
50def CheckMemScaled                      : CheckImmOperandSimple<4>;
51
52// Check the shifting type in arithmetic and logic instructions.
53let 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">;
59}
60
61// Generic predicates.
62
63// Check for ZR in a register operand.
64foreach I = {1-3} in {
65  def CheckIsReg#I#Zero : CheckAll<
66                            [CheckIsRegOperand<I>,
67                             CheckAny<
68                               [CheckRegOperand<I, WZR>,
69                                CheckRegOperand<I, XZR>]>]>;
70}
71def IsReg1ZeroPred  : MCSchedPredicate<CheckIsReg1Zero>;
72def IsReg2ZeroPred  : MCSchedPredicate<CheckIsReg2Zero>;
73def IsReg3ZeroPred  : MCSchedPredicate<CheckIsReg3Zero>;
74
75// Identify whether an instruction is NEON or floating point
76def CheckFpOrNEON : CheckFunctionPredicateWithTII<
77  "AArch64_MC::isFpOrNEON",
78  "AArch64InstrInfo::isFpOrNEON"
79>;
80
81// Identify whether an instruction is the 16-bit NEON form based on its result.
82def CheckHForm : CheckFunctionPredicateWithTII<
83  "AArch64_MC::isHForm",
84  "AArch64InstrInfo::isHForm"
85>;
86
87// Identify whether an instruction is the 128-bit NEON form based on its result.
88def CheckQForm : CheckFunctionPredicateWithTII<
89  "AArch64_MC::isQForm",
90  "AArch64InstrInfo::isQForm"
91>;
92
93// Identify arithmetic instructions with extend.
94def IsArithExtOp           : CheckOpcode<[ADDWrx, ADDXrx, ADDSWrx, ADDSXrx,
95                                          SUBWrx, SUBXrx, SUBSWrx, SUBSXrx,
96                                          ADDXrx64, ADDSXrx64,
97                                          SUBXrx64, SUBSXrx64]>;
98
99// Identify arithmetic immediate instructions.
100def IsArithImmOp           : CheckOpcode<[ADDWri, ADDXri, ADDSWri, ADDSXri,
101                                          SUBWri, SUBXri, SUBSWri, SUBSXri]>;
102
103// Identify arithmetic instructions with shift.
104def IsArithShiftOp         : CheckOpcode<[ADDWrs, ADDXrs, ADDSWrs, ADDSXrs,
105                                          SUBWrs, SUBXrs, SUBSWrs, SUBSXrs]>;
106
107// Identify arithmetic instructions without shift.
108def IsArithUnshiftOp       : CheckOpcode<[ADDWrr, ADDXrr, ADDSWrr, ADDSXrr,
109                                          SUBWrr, SUBXrr, SUBSWrr, SUBSXrr]>;
110
111// Identify logic immediate instructions.
112def IsLogicImmOp           : CheckOpcode<[ANDWri, ANDXri,
113                                          EORWri, EORXri,
114                                          ORRWri, ORRXri]>;
115
116// Identify logic instructions with shift.
117def IsLogicShiftOp         : CheckOpcode<[ANDWrs, ANDXrs, ANDSWrs, ANDSXrs,
118                                          BICWrs, BICXrs, BICSWrs, BICSXrs,
119                                          EONWrs, EONXrs,
120                                          EORWrs, EORXrs,
121                                          ORNWrs, ORNXrs,
122                                          ORRWrs, ORRXrs]>;
123
124// Identify logic instructions without shift.
125def IsLogicUnshiftOp       : CheckOpcode<[ANDWrr, ANDXrr, ANDSWrr, ANDSXrr,
126                                          BICWrr, BICXrr, BICSWrr, BICSXrr,
127                                          EONWrr, EONXrr,
128                                          EORWrr, EORXrr,
129                                          ORNWrr, ORNXrr,
130                                          ORRWrr, ORRXrr]>;
131
132// Identify arithmetic and logic immediate instructions.
133def IsArithLogicImmOp      : CheckOpcode<!listconcat(IsArithImmOp.ValidOpcodes,
134                                                     IsLogicImmOp.ValidOpcodes)>;
135
136// Identify arithmetic and logic instructions with shift.
137def IsArithLogicShiftOp    : CheckOpcode<!listconcat(IsArithShiftOp.ValidOpcodes,
138                                                     IsLogicShiftOp.ValidOpcodes)>;
139
140// Identify arithmetic and logic instructions without shift.
141def IsArithLogicUnshiftOp  : CheckOpcode<!listconcat(IsArithUnshiftOp.ValidOpcodes,
142                                                     IsLogicUnshiftOp.ValidOpcodes)>;
143
144// Identify whether an instruction is an ASIMD
145// load using the post index addressing mode.
146def 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]>;
172
173// Identify whether an instruction is an ASIMD
174// store using the post index addressing mode.
175def 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]>;
193
194// Identify whether an instruction is an ASIMD load
195// or store using the post index addressing mode.
196def IsLoadStoreASIMDPostOp : CheckOpcode<!listconcat(IsLoadASIMDPostOp.ValidOpcodes,
197                                                     IsStoreASIMDPostOp.ValidOpcodes)>;
198
199// Identify whether an instruction is a load
200// using the register offset addressing mode.
201def 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]>;
214
215// Identify whether an instruction is a store
216// using the register offset addressing mode.
217def 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]>;
226
227// Identify whether an instruction is a load or
228// store using the register offset addressing mode.
229def IsLoadStoreRegOffsetOp : CheckOpcode<!listconcat(IsLoadRegOffsetOp.ValidOpcodes,
230                                                     IsStoreRegOffsetOp.ValidOpcodes)>;
231
232// Target predicates.
233
234// Identify arithmetic instructions with an extended register.
235def RegExtendedFn     : TIIPredicate<"hasExtendedReg",
236                                     MCOpcodeSwitchStatement<
237                                       [MCOpcodeSwitchCase<
238                                         IsArithExtOp.ValidOpcodes,
239                                         MCReturnStatement<
240                                           CheckNot<CheckZeroOperand<3>>>>],
241                                       MCReturnStatement<FalsePred>>>;
242def RegExtendedPred   : MCSchedPredicate<RegExtendedFn>;
243
244// Identify arithmetic and logic instructions with a shifted register.
245def RegShiftedFn      : TIIPredicate<"hasShiftedReg",
246                                     MCOpcodeSwitchStatement<
247                                       [MCOpcodeSwitchCase<
248                                          IsArithLogicShiftOp.ValidOpcodes,
249                                          MCReturnStatement<
250                                            CheckNot<CheckZeroOperand<3>>>>],
251                                       MCReturnStatement<FalsePred>>>;
252def RegShiftedPred    : MCSchedPredicate<RegShiftedFn>;
253
254// Identify a load or store using the register offset addressing mode
255// with an extended or scaled register.
256def ScaledIdxFn       : TIIPredicate<"isScaledAddr",
257                                     MCOpcodeSwitchStatement<
258                                       [MCOpcodeSwitchCase<
259                                          IsLoadStoreRegOffsetOp.ValidOpcodes,
260                                          MCReturnStatement<
261                                            CheckAny<[CheckNot<CheckMemExtLSL>,
262                                                      CheckMemScaled]>>>],
263                                       MCReturnStatement<FalsePred>>>;
264def ScaledIdxPred     : MCSchedPredicate<ScaledIdxFn>;
265
266// Special cases.
267
268// Check for LSL shift <= 4
269def IsCheapLSL        : MCSchedPredicate<
270                          CheckAll<
271                            [CheckShiftLSL,
272                             CheckAny<
273                               [CheckShiftBy0,
274                                CheckShiftBy1,
275                                CheckShiftBy2,
276                                CheckShiftBy3,
277                                CheckShiftBy4]>]>>;
278
279// Idioms.
280
281// Identify an instruction that effectively transfers a register to another.
282def 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>>>;
308def IsCopyIdiomPred   : MCSchedPredicate<IsCopyIdiomFn>;
309
310// Identify an instruction that effectively resets a GP register to zero.
311def 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>>>;
321def IsZeroIdiomPred   : MCSchedPredicate<IsZeroIdiomFn>;
322
323// Identify an instruction that effectively resets a FP register to zero.
324def 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>>>;
340def IsZeroFPIdiomPred : MCSchedPredicate<IsZeroFPIdiomFn>;
341
342// Identify EXTR as the alias for ROR (immediate).
343def IsRORImmIdiomPred : MCSchedPredicate< // EXTR Rd, Rs, Rs, #Imm
344                          CheckAll<[CheckOpcode<[EXTRWrri, EXTRXrri]>,
345                                    CheckSameRegOperand<1, 2>]>>;
346