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 the extension type in the register offset addressing mode.
35let 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">;
40}
41
42// Check for scaling in the register offset addressing mode.
43let FunctionMapper = "AArch64_AM::getMemDoShift" in
44def CheckMemScaled                      : CheckImmOperandSimple<4>;
45
46// Check the shifting type in arithmetic and logic instructions.
47let 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">;
53}
54
55// Check for shifting in arithmetic and logic instructions.
56foreach I = {0-4, 8} in {
57  let FunctionMapper = "AArch64_AM::getShiftValue" in
58  def CheckShiftBy#I        : CheckImmOperand<3, I>;
59}
60
61// Generic predicates.
62// Identify whether an instruction is NEON or floating point
63def CheckFpOrNEON : CheckFunctionPredicateWithTII<
64  "AArch64_MC::isFpOrNEON",
65  "AArch64InstrInfo::isFpOrNEON"
66>;
67
68// Identify whether an instruction is the 128-bit NEON form based on its result.
69def CheckQForm : CheckFunctionPredicateWithTII<
70  "AArch64_MC::isQForm",
71  "AArch64InstrInfo::isQForm"
72>;
73
74// Identify arithmetic instructions with extend.
75def IsArithExtOp           : CheckOpcode<[ADDWrx, ADDXrx, ADDSWrx, ADDSXrx,
76                                          SUBWrx, SUBXrx, SUBSWrx, SUBSXrx,
77                                          ADDXrx64, ADDSXrx64,
78                                          SUBXrx64, SUBSXrx64]>;
79
80// Identify arithmetic immediate instructions.
81def IsArithImmOp           : CheckOpcode<[ADDWri, ADDXri, ADDSWri, ADDSXri,
82                                          SUBWri, SUBXri, SUBSWri, SUBSXri]>;
83
84// Identify arithmetic instructions with shift.
85def IsArithShiftOp         : CheckOpcode<[ADDWrs, ADDXrs, ADDSWrs, ADDSXrs,
86                                          SUBWrs, SUBXrs, SUBSWrs, SUBSXrs]>;
87
88// Identify arithmetic instructions without shift.
89def IsArithUnshiftOp       : CheckOpcode<[ADDWrr, ADDXrr, ADDSWrr, ADDSXrr,
90                                          SUBWrr, SUBXrr, SUBSWrr, SUBSXrr]>;
91
92// Identify logic immediate instructions.
93def IsLogicImmOp           : CheckOpcode<[ANDWri, ANDXri,
94                                          EORWri, EORXri,
95                                          ORRWri, ORRXri]>;
96
97// Identify logic instructions with shift.
98def IsLogicShiftOp         : CheckOpcode<[ANDWrs, ANDXrs, ANDSWrs, ANDSXrs,
99                                          BICWrs, BICXrs, BICSWrs, BICSXrs,
100                                          EONWrs, EONXrs,
101                                          EORWrs, EORXrs,
102                                          ORNWrs, ORNXrs,
103                                          ORRWrs, ORRXrs]>;
104
105// Identify logic instructions without shift.
106def IsLogicUnshiftOp       : CheckOpcode<[ANDWrr, ANDXrr, ANDSWrr, ANDSXrr,
107                                          BICWrr, BICXrr, BICSWrr, BICSXrr,
108                                          EONWrr, EONXrr,
109                                          EORWrr, EORXrr,
110                                          ORNWrr, ORNXrr,
111                                          ORRWrr, ORRXrr]>;
112
113// Identify arithmetic and logic immediate instructions.
114def IsArithLogicImmOp      : CheckOpcode<!listconcat(IsArithImmOp.ValidOpcodes,
115                                                     IsLogicImmOp.ValidOpcodes)>;
116
117// Identify arithmetic and logic instructions with shift.
118def IsArithLogicShiftOp    : CheckOpcode<!listconcat(IsArithShiftOp.ValidOpcodes,
119                                                     IsLogicShiftOp.ValidOpcodes)>;
120
121// Identify arithmetic and logic instructions without shift.
122def IsArithLogicUnshiftOp  : CheckOpcode<!listconcat(IsArithUnshiftOp.ValidOpcodes,
123                                                     IsLogicUnshiftOp.ValidOpcodes)>;
124
125// Identify whether an instruction is an ASIMD
126// load using the post index addressing mode.
127def IsLoadASIMDPostOp      : CheckOpcode<[LD1Onev8b_POST, LD1Onev4h_POST, LD1Onev2s_POST, LD1Onev1d_POST,
128                                          LD1Onev16b_POST, LD1Onev8h_POST, LD1Onev4s_POST, LD1Onev2d_POST,
129                                          LD1Twov8b_POST, LD1Twov4h_POST, LD1Twov2s_POST, LD1Twov1d_POST,
130                                          LD1Twov16b_POST, LD1Twov8h_POST, LD1Twov4s_POST, LD1Twov2d_POST,
131                                          LD1Threev8b_POST, LD1Threev4h_POST, LD1Threev2s_POST, LD1Threev1d_POST,
132                                          LD1Threev16b_POST, LD1Threev8h_POST, LD1Threev4s_POST, LD1Threev2d_POST,
133                                          LD1Fourv8b_POST, LD1Fourv4h_POST, LD1Fourv2s_POST, LD1Fourv1d_POST,
134                                          LD1Fourv16b_POST, LD1Fourv8h_POST, LD1Fourv4s_POST, LD1Fourv2d_POST,
135                                          LD1i8_POST, LD1i16_POST, LD1i32_POST, LD1i64_POST,
136                                          LD1Rv8b_POST, LD1Rv4h_POST, LD1Rv2s_POST, LD1Rv1d_POST,
137                                          LD1Rv16b_POST, LD1Rv8h_POST, LD1Rv4s_POST, LD1Rv2d_POST,
138                                          LD2Twov8b_POST, LD2Twov4h_POST, LD2Twov2s_POST,
139                                          LD2Twov16b_POST, LD2Twov8h_POST, LD2Twov4s_POST, LD2Twov2d_POST,
140                                          LD2i8_POST, LD2i16_POST, LD2i32_POST, LD2i64_POST,
141                                          LD2Rv8b_POST, LD2Rv4h_POST, LD2Rv2s_POST, LD2Rv1d_POST,
142                                          LD2Rv16b_POST, LD2Rv8h_POST, LD2Rv4s_POST, LD2Rv2d_POST,
143                                          LD3Threev8b_POST, LD3Threev4h_POST, LD3Threev2s_POST,
144                                          LD3Threev16b_POST, LD3Threev8h_POST, LD3Threev4s_POST, LD3Threev2d_POST,
145                                          LD3i8_POST, LD3i16_POST, LD3i32_POST, LD3i64_POST,
146                                          LD3Rv8b_POST, LD3Rv4h_POST, LD3Rv2s_POST, LD3Rv1d_POST,
147                                          LD3Rv16b_POST, LD3Rv8h_POST, LD3Rv4s_POST, LD3Rv2d_POST,
148                                          LD4Fourv8b_POST, LD4Fourv4h_POST, LD4Fourv2s_POST,
149                                          LD4Fourv16b_POST, LD4Fourv8h_POST, LD4Fourv4s_POST, LD4Fourv2d_POST,
150                                          LD4i8_POST, LD4i16_POST, LD4i32_POST, LD4i64_POST,
151                                          LD4Rv8b_POST, LD4Rv4h_POST, LD4Rv2s_POST, LD4Rv1d_POST,
152                                          LD4Rv16b_POST, LD4Rv8h_POST, LD4Rv4s_POST, LD4Rv2d_POST]>;
153
154// Identify whether an instruction is an ASIMD
155// store using the post index addressing mode.
156def IsStoreASIMDPostOp     : CheckOpcode<[ST1Onev8b_POST, ST1Onev4h_POST, ST1Onev2s_POST, ST1Onev1d_POST,
157                                          ST1Onev16b_POST, ST1Onev8h_POST, ST1Onev4s_POST, ST1Onev2d_POST,
158                                          ST1Twov8b_POST, ST1Twov4h_POST, ST1Twov2s_POST, ST1Twov1d_POST,
159                                          ST1Twov16b_POST, ST1Twov8h_POST, ST1Twov4s_POST, ST1Twov2d_POST,
160                                          ST1Threev8b_POST, ST1Threev4h_POST, ST1Threev2s_POST, ST1Threev1d_POST,
161                                          ST1Threev16b_POST, ST1Threev8h_POST, ST1Threev4s_POST, ST1Threev2d_POST,
162                                          ST1Fourv8b_POST, ST1Fourv4h_POST, ST1Fourv2s_POST, ST1Fourv1d_POST,
163                                          ST1Fourv16b_POST, ST1Fourv8h_POST, ST1Fourv4s_POST, ST1Fourv2d_POST,
164                                          ST1i8_POST, ST1i16_POST, ST1i32_POST, ST1i64_POST,
165                                          ST2Twov8b_POST, ST2Twov4h_POST, ST2Twov2s_POST,
166                                          ST2Twov16b_POST, ST2Twov8h_POST, ST2Twov4s_POST, ST2Twov2d_POST,
167                                          ST2i8_POST, ST2i16_POST, ST2i32_POST, ST2i64_POST,
168                                          ST3Threev8b_POST, ST3Threev4h_POST, ST3Threev2s_POST,
169                                          ST3Threev16b_POST, ST3Threev8h_POST, ST3Threev4s_POST, ST3Threev2d_POST,
170                                          ST3i8_POST, ST3i16_POST, ST3i32_POST, ST3i64_POST,
171                                          ST4Fourv8b_POST, ST4Fourv4h_POST, ST4Fourv2s_POST,
172                                          ST4Fourv16b_POST, ST4Fourv8h_POST, ST4Fourv4s_POST, ST4Fourv2d_POST,
173                                          ST4i8_POST, ST4i16_POST, ST4i32_POST, ST4i64_POST]>;
174
175// Identify whether an instruction is an ASIMD load
176// or store using the post index addressing mode.
177def IsLoadStoreASIMDPostOp : CheckOpcode<!listconcat(IsLoadASIMDPostOp.ValidOpcodes,
178                                                     IsStoreASIMDPostOp.ValidOpcodes)>;
179
180// Identify whether an instruction is a load
181// using the register offset addressing mode.
182def IsLoadRegOffsetOp      : CheckOpcode<[PRFMroW, PRFMroX,
183                                          LDRBBroW, LDRBBroX,
184                                          LDRSBWroW, LDRSBWroX, LDRSBXroW, LDRSBXroX,
185                                          LDRHHroW, LDRHHroX,
186                                          LDRSHWroW, LDRSHWroX, LDRSHXroW, LDRSHXroX,
187                                          LDRWroW, LDRWroX,
188                                          LDRSWroW, LDRSWroX,
189                                          LDRXroW, LDRXroX,
190                                          LDRBroW, LDRBroX,
191                                          LDRHroW, LDRHroX,
192                                          LDRSroW, LDRSroX,
193                                          LDRDroW, LDRDroX,
194                                          LDRQroW, LDRQroX]>;
195
196// Identify whether an instruction is a store
197// using the register offset addressing mode.
198def IsStoreRegOffsetOp     : CheckOpcode<[STRBBroW, STRBBroX,
199                                          STRHHroW, STRHHroX,
200                                          STRWroW, STRWroX,
201                                          STRXroW, STRXroX,
202                                          STRBroW, STRBroX,
203                                          STRHroW, STRHroX,
204                                          STRSroW, STRSroX,
205                                          STRDroW, STRDroX,
206                                          STRQroW, STRQroX]>;
207
208// Identify whether an instruction is a load or
209// store using the register offset addressing mode.
210def IsLoadStoreRegOffsetOp : CheckOpcode<!listconcat(IsLoadRegOffsetOp.ValidOpcodes,
211                                                     IsStoreRegOffsetOp.ValidOpcodes)>;
212
213// Target predicates.
214
215// Identify an instruction that effectively transfers a register to another.
216def IsCopyIdiomFn     : TIIPredicate<"isCopyIdiom",
217                                     MCOpcodeSwitchStatement<
218                                       [// MOV {Rd, SP}, {SP, Rn} =>
219                                        // ADD {Rd, SP}, {SP, Rn}, #0
220                                        MCOpcodeSwitchCase<
221                                          [ADDWri, ADDXri],
222                                          MCReturnStatement<
223                                            CheckAll<
224                                              [CheckIsRegOperand<0>,
225                                               CheckIsRegOperand<1>,
226                                               CheckAny<
227                                                 [CheckRegOperand<0, WSP>,
228                                                  CheckRegOperand<0, SP>,
229                                                  CheckRegOperand<1, WSP>,
230                                                  CheckRegOperand<1, SP>]>,
231                                               CheckZeroOperand<2>]>>>,
232                                        // MOV Rd, Rm =>
233                                        // ORR Rd, ZR, Rm, LSL #0
234                                        MCOpcodeSwitchCase<
235                                          [ORRWrs, ORRXrs],
236                                          MCReturnStatement<
237                                            CheckAll<
238                                              [CheckIsRegOperand<1>,
239                                               CheckIsRegOperand<2>,
240                                               CheckAny<
241                                                 [CheckRegOperand<1, WZR>,
242                                                  CheckRegOperand<1, XZR>]>,
243                                               CheckShiftBy0]>>>],
244                                       MCReturnStatement<FalsePred>>>;
245def IsCopyIdiomPred   : MCSchedPredicate<IsCopyIdiomFn>;
246
247// Identify arithmetic instructions with an extended register.
248def RegExtendedFn     : TIIPredicate<"hasExtendedReg",
249                                     MCOpcodeSwitchStatement<
250                                       [MCOpcodeSwitchCase<
251                                         IsArithExtOp.ValidOpcodes,
252                                         MCReturnStatement<
253                                           CheckNot<CheckZeroOperand<3>>>>],
254                                       MCReturnStatement<FalsePred>>>;
255def RegExtendedPred   : MCSchedPredicate<RegExtendedFn>;
256
257// Identify arithmetic and logic instructions with a shifted register.
258def RegShiftedFn      : TIIPredicate<"hasShiftedReg",
259                                     MCOpcodeSwitchStatement<
260                                       [MCOpcodeSwitchCase<
261                                          IsArithLogicShiftOp.ValidOpcodes,
262                                          MCReturnStatement<
263                                            CheckNot<CheckZeroOperand<3>>>>],
264                                       MCReturnStatement<FalsePred>>>;
265def RegShiftedPred    : MCSchedPredicate<RegShiftedFn>;
266
267// Identify a load or store using the register offset addressing mode
268// with an extended or scaled register.
269def ScaledIdxFn       : TIIPredicate<"isScaledAddr",
270                                     MCOpcodeSwitchStatement<
271                                       [MCOpcodeSwitchCase<
272                                          IsLoadStoreRegOffsetOp.ValidOpcodes,
273                                          MCReturnStatement<
274                                            CheckAny<[CheckNot<CheckMemExtLSL>,
275                                                      CheckMemScaled]>>>],
276                                       MCReturnStatement<FalsePred>>>;
277def ScaledIdxPred     : MCSchedPredicate<ScaledIdxFn>;
278
279// Identify an instruction that effectively resets a FP register to zero.
280def IsZeroFPIdiomFn   : TIIPredicate<"isZeroFPIdiom",
281                                     MCOpcodeSwitchStatement<
282                                       [// MOVI Vd, #0
283                                        MCOpcodeSwitchCase<
284                                          [MOVIv8b_ns, MOVIv16b_ns,
285                                           MOVID, MOVIv2d_ns],
286                                          MCReturnStatement<CheckZeroOperand<1>>>,
287                                        // MOVI Vd, #0, LSL #0
288                                        MCOpcodeSwitchCase<
289                                          [MOVIv4i16, MOVIv8i16,
290                                           MOVIv2i32, MOVIv4i32],
291                                          MCReturnStatement<
292                                            CheckAll<
293                                              [CheckZeroOperand<1>,
294                                               CheckZeroOperand<2>]>>>],
295                                       MCReturnStatement<FalsePred>>>;
296def IsZeroFPIdiomPred : MCSchedPredicate<IsZeroFPIdiomFn>;
297
298// Identify an instruction that effectively resets a GP register to zero.
299def IsZeroIdiomFn     : TIIPredicate<"isZeroIdiom",
300                                    MCOpcodeSwitchStatement<
301                                      [// ORR Rd, ZR, #0
302                                       MCOpcodeSwitchCase<
303                                         [ORRWri, ORRXri],
304                                         MCReturnStatement<
305                                           CheckAll<
306                                             [CheckIsRegOperand<1>,
307                                              CheckAny<
308                                                [CheckRegOperand<1, WZR>,
309                                                 CheckRegOperand<1, XZR>]>,
310                                              CheckZeroOperand<2>]>>>],
311                                      MCReturnStatement<FalsePred>>>;
312def IsZeroIdiomPred   : MCSchedPredicate<IsZeroIdiomFn>;
313