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<3>;
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-3, 8} in {
57  let FunctionMapper = "AArch64_AM::getShiftValue" in
58  def CheckShiftBy#I        : CheckImmOperand<3, I>;
59}
60
61// Generic predicates.
62
63// Identify whether an instruction is the 64-bit NEON form based on its result.
64def 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>]>]>;
97
98// Identify whether an instruction is the 128-bit NEON form based on its result.
99def 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>]>]>;
132
133// Identify arithmetic instructions with extend.
134def IsArithExtOp           : CheckOpcode<[ADDWrx, ADDXrx, ADDSWrx, ADDSXrx,
135                                          SUBWrx, SUBXrx, SUBSWrx, SUBSXrx,
136                                          ADDXrx64, ADDSXrx64,
137                                          SUBXrx64, SUBSXrx64]>;
138
139// Identify arithmetic immediate instructions.
140def IsArithImmOp           : CheckOpcode<[ADDWri, ADDXri, ADDSWri, ADDSXri,
141                                          SUBWri, SUBXri, SUBSWri, SUBSXri]>;
142
143// Identify arithmetic instructions with shift.
144def IsArithShiftOp         : CheckOpcode<[ADDWrs, ADDXrs, ADDSWrs, ADDSXrs,
145                                          SUBWrs, SUBXrs, SUBSWrs, SUBSXrs]>;
146
147// Identify arithmetic instructions without shift.
148def IsArithUnshiftOp       : CheckOpcode<[ADDWrr, ADDXrr, ADDSWrr, ADDSXrr,
149                                          SUBWrr, SUBXrr, SUBSWrr, SUBSXrr]>;
150
151// Identify logic immediate instructions.
152def IsLogicImmOp           : CheckOpcode<[ANDWri, ANDXri,
153                                          EORWri, EORXri,
154                                          ORRWri, ORRXri]>;
155
156// Identify logic instructions with shift.
157def IsLogicShiftOp         : CheckOpcode<[ANDWrs, ANDXrs, ANDSWrs, ANDSXrs,
158                                          BICWrs, BICXrs, BICSWrs, BICSXrs,
159                                          EONWrs, EONXrs,
160                                          EORWrs, EORXrs,
161                                          ORNWrs, ORNXrs,
162                                          ORRWrs, ORRXrs]>;
163
164// Identify logic instructions without shift.
165def IsLogicUnshiftOp       : CheckOpcode<[ANDWrr, ANDXrr, ANDSWrr, ANDSXrr,
166                                          BICWrr, BICXrr, BICSWrr, BICSXrr,
167                                          EONWrr, EONXrr,
168                                          EORWrr, EORXrr,
169                                          ORNWrr, ORNXrr,
170                                          ORRWrr, ORRXrr]>;
171
172// Identify arithmetic and logic immediate instructions.
173def IsArithLogicImmOp      : CheckOpcode<!listconcat(IsArithImmOp.ValidOpcodes,
174                                                     IsLogicImmOp.ValidOpcodes)>;
175
176// Identify arithmetic and logic instructions with shift.
177def IsArithLogicShiftOp    : CheckOpcode<!listconcat(IsArithShiftOp.ValidOpcodes,
178                                                     IsLogicShiftOp.ValidOpcodes)>;
179
180// Identify arithmetic and logic instructions without shift.
181def IsArithLogicUnshiftOp  : CheckOpcode<!listconcat(IsArithUnshiftOp.ValidOpcodes,
182                                                     IsLogicUnshiftOp.ValidOpcodes)>;
183
184// Identify whether an instruction is an ASIMD
185// load using the post index addressing mode.
186def 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]>;
212
213// Identify whether an instruction is an ASIMD
214// store using the post index addressing mode.
215def 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]>;
233
234// Identify whether an instruction is an ASIMD load
235// or store using the post index addressing mode.
236def IsLoadStoreASIMDPostOp : CheckOpcode<!listconcat(IsLoadASIMDPostOp.ValidOpcodes,
237                                                     IsStoreASIMDPostOp.ValidOpcodes)>;
238
239// Identify whether an instruction is a load
240// using the register offset addressing mode.
241def IsLoadRegOffsetOp      : CheckOpcode<[PRFMroW, PRFMroX,
242                                          LDRBBroW, LDRBBroX,
243                                          LDRSBWroW, LDRSBWroX, LDRSBXroW, LDRSBXroX,
244                                          LDRHHroW, LDRHHroX,
245                                          LDRSHWroW, LDRSHWroX, LDRSHXroW, LDRSHXroX,
246                                          LDRWroW, LDRWroX,
247                                          LDRSWroW, LDRSWroX,
248                                          LDRXroW, LDRXroX,
249                                          LDRBroW, LDRBroX,
250                                          LDRHroW, LDRHroX,
251                                          LDRSroW, LDRSroX,
252                                          LDRDroW, LDRDroX]>;
253
254// Identify whether an instruction is a load
255// using the register offset addressing mode.
256def IsStoreRegOffsetOp     : CheckOpcode<[STRBBroW, STRBBroX,
257                                          STRHHroW, STRHHroX,
258                                          STRWroW, STRWroX,
259                                          STRXroW, STRXroX,
260                                          STRBroW, STRBroX,
261                                          STRHroW, STRHroX,
262                                          STRSroW, STRSroX,
263                                          STRDroW, STRDroX]>;
264
265// Identify whether an instruction is a load or
266// store using the register offset addressing mode.
267def IsLoadStoreRegOffsetOp : CheckOpcode<!listconcat(IsLoadRegOffsetOp.ValidOpcodes,
268                                                     IsStoreRegOffsetOp.ValidOpcodes)>;
269
270// Target predicates.
271
272// Identify an instruction that effectively transfers a register to another.
273def IsCopyIdiomFn     : TIIPredicate<"isCopyIdiom",
274                                     MCOpcodeSwitchStatement<
275                                       [// MOV {Rd, SP}, {SP, Rn} =>
276                                        // ADD {Rd, SP}, {SP, Rn}, #0
277                                        MCOpcodeSwitchCase<
278                                          [ADDWri, ADDXri],
279                                          MCReturnStatement<
280                                            CheckAll<
281                                              [CheckIsRegOperand<0>,
282                                               CheckIsRegOperand<1>,
283                                               CheckAny<
284                                                 [CheckRegOperand<0, WSP>,
285                                                  CheckRegOperand<0, SP>,
286                                                  CheckRegOperand<1, WSP>,
287                                                  CheckRegOperand<1, SP>]>,
288                                               CheckZeroOperand<2>]>>>,
289                                        // MOV Rd, Rm =>
290                                        // ORR Rd, ZR, Rm, LSL #0
291                                        MCOpcodeSwitchCase<
292                                          [ORRWrs, ORRXrs],
293                                          MCReturnStatement<
294                                            CheckAll<
295                                              [CheckIsRegOperand<1>,
296                                               CheckIsRegOperand<2>,
297                                               CheckAny<
298                                                 [CheckRegOperand<1, WZR>,
299                                                  CheckRegOperand<1, XZR>]>,
300                                               CheckShiftBy0]>>>],
301                                       MCReturnStatement<FalsePred>>>;
302def IsCopyIdiomPred   : MCSchedPredicate<IsCopyIdiomFn>;
303
304// Identify arithmetic instructions with an extended register.
305def RegExtendedFn     : TIIPredicate<"hasExtendedReg",
306                                     MCOpcodeSwitchStatement<
307                                       [MCOpcodeSwitchCase<
308                                         IsArithExtOp.ValidOpcodes,
309                                         MCReturnStatement<
310                                           CheckNot<CheckZeroOperand<3>>>>],
311                                       MCReturnStatement<FalsePred>>>;
312def RegExtendedPred   : MCSchedPredicate<RegExtendedFn>;
313
314// Identify arithmetic and logic instructions with a shifted register.
315def RegShiftedFn      : TIIPredicate<"hasShiftedReg",
316                                     MCOpcodeSwitchStatement<
317                                       [MCOpcodeSwitchCase<
318                                          IsArithLogicShiftOp.ValidOpcodes,
319                                          MCReturnStatement<
320                                            CheckNot<CheckZeroOperand<3>>>>],
321                                       MCReturnStatement<FalsePred>>>;
322def RegShiftedPred    : MCSchedPredicate<RegShiftedFn>;
323
324// Identify a load or store using the register offset addressing mode
325// with an extended or scaled register.
326def ScaledIdxFn       : TIIPredicate<"isScaledAddr",
327                                     MCOpcodeSwitchStatement<
328                                       [MCOpcodeSwitchCase<
329                                          IsLoadStoreRegOffsetOp.ValidOpcodes,
330                                          MCReturnStatement<
331                                            CheckAny<[CheckNot<CheckMemExtLSL>,
332                                                      CheckMemScaled]>>>],
333                                       MCReturnStatement<FalsePred>>>;
334def ScaledIdxPred     : MCSchedPredicate<ScaledIdxFn>;
335
336// Identify an instruction that effectively resets a FP register to zero.
337def IsZeroFPIdiomFn   : TIIPredicate<"isZeroFPIdiom",
338                                     MCOpcodeSwitchStatement<
339                                       [// MOVI Vd, #0
340                                        MCOpcodeSwitchCase<
341                                          [MOVIv8b_ns, MOVIv16b_ns,
342                                           MOVID, MOVIv2d_ns],
343                                          MCReturnStatement<CheckZeroOperand<1>>>,
344                                        // MOVI Vd, #0, LSL #0
345                                        MCOpcodeSwitchCase<
346                                          [MOVIv4i16, MOVIv8i16,
347                                           MOVIv2i32, MOVIv4i32],
348                                          MCReturnStatement<
349                                            CheckAll<
350                                              [CheckZeroOperand<1>,
351                                               CheckZeroOperand<2>]>>>],
352                                       MCReturnStatement<FalsePred>>>;
353def IsZeroFPIdiomPred : MCSchedPredicate<IsZeroFPIdiomFn>;
354
355// Identify an instruction that effectively resets a GP register to zero.
356def IsZeroIdiomFn     : TIIPredicate<"isZeroIdiom",
357                                    MCOpcodeSwitchStatement<
358                                      [// ORR Rd, ZR, #0
359                                       MCOpcodeSwitchCase<
360                                         [ORRWri, ORRXri],
361                                         MCReturnStatement<
362                                           CheckAll<
363                                             [CheckIsRegOperand<1>,
364                                              CheckAny<
365                                                [CheckRegOperand<1, WZR>,
366                                                 CheckRegOperand<1, XZR>]>,
367                                              CheckZeroOperand<2>]>>>],
368                                      MCReturnStatement<FalsePred>>>;
369def IsZeroIdiomPred   : MCSchedPredicate<IsZeroIdiomFn>;
370