1//===- AArch64SchedPredicates.td - AArch64 Sched Preds -----*- tablegen -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines scheduling predicate definitions that are used by the
11// AArch64 subtargets.
12//
13//===----------------------------------------------------------------------===//
14
15// Function mappers.
16
17// Check the extension type in arithmetic instructions.
18let FunctionMapper = "AArch64_AM::getArithExtendType" in {
19  def CheckExtUXTB                      : CheckImmOperand_s<3, "AArch64_AM::UXTB">;
20  def CheckExtUXTH                      : CheckImmOperand_s<3, "AArch64_AM::UXTH">;
21  def CheckExtUXTW                      : CheckImmOperand_s<3, "AArch64_AM::UXTW">;
22  def CheckExtUXTX                      : CheckImmOperand_s<3, "AArch64_AM::UXTX">;
23  def CheckExtSXTB                      : CheckImmOperand_s<3, "AArch64_AM::SXTB">;
24  def CheckExtSXTH                      : CheckImmOperand_s<3, "AArch64_AM::SXTH">;
25  def CheckExtSXTW                      : CheckImmOperand_s<3, "AArch64_AM::SXTW">;
26  def CheckExtSXTX                      : CheckImmOperand_s<3, "AArch64_AM::SXTX">;
27}
28
29// Check for shifting in extended arithmetic instructions.
30foreach I = {0-3} in {
31  let FunctionMapper = "AArch64_AM::getArithShiftValue" in
32  def CheckExtBy#I                      : CheckImmOperand<3, I>;
33}
34
35// Check the extension type in the register offset addressing mode.
36let FunctionMapper = "AArch64_AM::getMemExtendType" in {
37  def CheckMemExtUXTW                   : CheckImmOperand_s<3, "AArch64_AM::UXTW">;
38  def CheckMemExtLSL                    : CheckImmOperand_s<3, "AArch64_AM::UXTX">;
39  def CheckMemExtSXTW                   : CheckImmOperand_s<3, "AArch64_AM::SXTW">;
40  def CheckMemExtSXTX                   : CheckImmOperand_s<3, "AArch64_AM::SXTX">;
41}
42
43// Check for scaling in the register offset addressing mode.
44let FunctionMapper = "AArch64_AM::getMemDoShift" in
45def CheckMemScaled                      : CheckImmOperandSimple<3>;
46
47// Check the shifting type in arithmetic and logic instructions.
48let FunctionMapper = "AArch64_AM::getShiftType" in {
49  def CheckShiftLSL                : CheckImmOperand_s<3, "AArch64_AM::LSL">;
50  def CheckShiftLSR                : CheckImmOperand_s<3, "AArch64_AM::LSR">;
51  def CheckShiftASR                : CheckImmOperand_s<3, "AArch64_AM::ASR">;
52  def CheckShiftROR                : CheckImmOperand_s<3, "AArch64_AM::ROR">;
53  def CheckShiftMSL                : CheckImmOperand_s<3, "AArch64_AM::MSL">;
54}
55
56// Check for shifting in arithmetic and logic instructions.
57foreach I = {0-3, 8} in {
58  let FunctionMapper = "AArch64_AM::getShiftValue" in
59  def CheckShiftBy#I        : CheckImmOperand<3, I>;
60}
61
62// Generic predicates.
63
64// Identify whether an instruction is the 64-bit NEON form based on its result.
65def CheckDForm             : CheckAll<[CheckIsRegOperand<0>,
66                                       CheckAny<[CheckRegOperand<0, D0>,
67                                                 CheckRegOperand<0, D1>,
68                                                 CheckRegOperand<0, D2>,
69                                                 CheckRegOperand<0, D3>,
70                                                 CheckRegOperand<0, D4>,
71                                                 CheckRegOperand<0, D5>,
72                                                 CheckRegOperand<0, D6>,
73                                                 CheckRegOperand<0, D7>,
74                                                 CheckRegOperand<0, D8>,
75                                                 CheckRegOperand<0, D9>,
76                                                 CheckRegOperand<0, D10>,
77                                                 CheckRegOperand<0, D11>,
78                                                 CheckRegOperand<0, D12>,
79                                                 CheckRegOperand<0, D13>,
80                                                 CheckRegOperand<0, D14>,
81                                                 CheckRegOperand<0, D15>,
82                                                 CheckRegOperand<0, D16>,
83                                                 CheckRegOperand<0, D17>,
84                                                 CheckRegOperand<0, D18>,
85                                                 CheckRegOperand<0, D19>,
86                                                 CheckRegOperand<0, D20>,
87                                                 CheckRegOperand<0, D21>,
88                                                 CheckRegOperand<0, D22>,
89                                                 CheckRegOperand<0, D23>,
90                                                 CheckRegOperand<0, D24>,
91                                                 CheckRegOperand<0, D25>,
92                                                 CheckRegOperand<0, D26>,
93                                                 CheckRegOperand<0, D27>,
94                                                 CheckRegOperand<0, D28>,
95                                                 CheckRegOperand<0, D29>,
96                                                 CheckRegOperand<0, D30>,
97                                                 CheckRegOperand<0, D31>]>]>;
98
99// Identify whether an instruction is the 128-bit NEON form based on its result.
100def CheckQForm             : CheckAll<[CheckIsRegOperand<0>,
101                                       CheckAny<[CheckRegOperand<0, Q0>,
102                                                 CheckRegOperand<0, Q1>,
103                                                 CheckRegOperand<0, Q2>,
104                                                 CheckRegOperand<0, Q3>,
105                                                 CheckRegOperand<0, Q4>,
106                                                 CheckRegOperand<0, Q5>,
107                                                 CheckRegOperand<0, Q6>,
108                                                 CheckRegOperand<0, Q7>,
109                                                 CheckRegOperand<0, Q8>,
110                                                 CheckRegOperand<0, Q9>,
111                                                 CheckRegOperand<0, Q10>,
112                                                 CheckRegOperand<0, Q11>,
113                                                 CheckRegOperand<0, Q12>,
114                                                 CheckRegOperand<0, Q13>,
115                                                 CheckRegOperand<0, Q14>,
116                                                 CheckRegOperand<0, Q15>,
117                                                 CheckRegOperand<0, Q16>,
118                                                 CheckRegOperand<0, Q17>,
119                                                 CheckRegOperand<0, Q18>,
120                                                 CheckRegOperand<0, Q19>,
121                                                 CheckRegOperand<0, Q20>,
122                                                 CheckRegOperand<0, Q21>,
123                                                 CheckRegOperand<0, Q22>,
124                                                 CheckRegOperand<0, Q23>,
125                                                 CheckRegOperand<0, Q24>,
126                                                 CheckRegOperand<0, Q25>,
127                                                 CheckRegOperand<0, Q26>,
128                                                 CheckRegOperand<0, Q27>,
129                                                 CheckRegOperand<0, Q28>,
130                                                 CheckRegOperand<0, Q29>,
131                                                 CheckRegOperand<0, Q30>,
132                                                 CheckRegOperand<0, Q31>]>]>;
133
134// Identify arithmetic instructions with extend.
135def IsArithExtOp           : CheckOpcode<[ADDWrx, ADDXrx, ADDSWrx, ADDSXrx,
136                                          SUBWrx, SUBXrx, SUBSWrx, SUBSXrx,
137                                          ADDXrx64, ADDSXrx64,
138                                          SUBXrx64, SUBSXrx64]>;
139
140// Identify arithmetic immediate instructions.
141def IsArithImmOp           : CheckOpcode<[ADDWri, ADDXri, ADDSWri, ADDSXri,
142                                          SUBWri, SUBXri, SUBSWri, SUBSXri]>;
143
144// Identify arithmetic instructions with shift.
145def IsArithShiftOp         : CheckOpcode<[ADDWrs, ADDXrs, ADDSWrs, ADDSXrs,
146                                          SUBWrs, SUBXrs, SUBSWrs, SUBSXrs]>;
147
148// Identify arithmetic instructions without shift.
149def IsArithUnshiftOp       : CheckOpcode<[ADDWrr, ADDXrr, ADDSWrr, ADDSXrr,
150                                          SUBWrr, SUBXrr, SUBSWrr, SUBSXrr]>;
151
152// Identify logic immediate instructions.
153def IsLogicImmOp           : CheckOpcode<[ANDWri, ANDXri,
154                                          EORWri, EORXri,
155                                          ORRWri, ORRXri]>;
156
157// Identify logic instructions with shift.
158def IsLogicShiftOp         : CheckOpcode<[ANDWrs, ANDXrs, ANDSWrs, ANDSXrs,
159                                          BICWrs, BICXrs, BICSWrs, BICSXrs,
160                                          EONWrs, EONXrs,
161                                          EORWrs, EORXrs,
162                                          ORNWrs, ORNXrs,
163                                          ORRWrs, ORRXrs]>;
164
165// Identify logic instructions without shift.
166def IsLogicUnshiftOp       : CheckOpcode<[ANDWrr, ANDXrr, ANDSWrr, ANDSXrr,
167                                          BICWrr, BICXrr, BICSWrr, BICSXrr,
168                                          EONWrr, EONXrr,
169                                          EORWrr, EORXrr,
170                                          ORNWrr, ORNXrr,
171                                          ORRWrr, ORRXrr]>;
172
173// Identify arithmetic and logic immediate instructions.
174def IsArithLogicImmOp      : CheckOpcode<!listconcat(IsArithImmOp.ValidOpcodes,
175                                                     IsLogicImmOp.ValidOpcodes)>;
176
177// Identify arithmetic and logic instructions with shift.
178def IsArithLogicShiftOp    : CheckOpcode<!listconcat(IsArithShiftOp.ValidOpcodes,
179                                                     IsLogicShiftOp.ValidOpcodes)>;
180
181// Identify arithmetic and logic instructions without shift.
182def IsArithLogicUnshiftOp  : CheckOpcode<!listconcat(IsArithUnshiftOp.ValidOpcodes,
183                                                     IsLogicUnshiftOp.ValidOpcodes)>;
184
185// Identify whether an instruction is an ASIMD
186// load using the post index addressing mode.
187def IsLoadASIMDPostOp      : CheckOpcode<[LD1Onev8b_POST, LD1Onev4h_POST, LD1Onev2s_POST, LD1Onev1d_POST,
188                                          LD1Onev16b_POST, LD1Onev8h_POST, LD1Onev4s_POST, LD1Onev2d_POST,
189                                          LD1Twov8b_POST, LD1Twov4h_POST, LD1Twov2s_POST, LD1Twov1d_POST,
190                                          LD1Twov16b_POST, LD1Twov8h_POST, LD1Twov4s_POST, LD1Twov2d_POST,
191                                          LD1Threev8b_POST, LD1Threev4h_POST, LD1Threev2s_POST, LD1Threev1d_POST,
192                                          LD1Threev16b_POST, LD1Threev8h_POST, LD1Threev4s_POST, LD1Threev2d_POST,
193                                          LD1Fourv8b_POST, LD1Fourv4h_POST, LD1Fourv2s_POST, LD1Fourv1d_POST,
194                                          LD1Fourv16b_POST, LD1Fourv8h_POST, LD1Fourv4s_POST, LD1Fourv2d_POST,
195                                          LD1i8_POST, LD1i16_POST, LD1i32_POST, LD1i64_POST,
196                                          LD1Rv8b_POST, LD1Rv4h_POST, LD1Rv2s_POST, LD1Rv1d_POST,
197                                          LD1Rv16b_POST, LD1Rv8h_POST, LD1Rv4s_POST, LD1Rv2d_POST,
198                                          LD2Twov8b_POST, LD2Twov4h_POST, LD2Twov2s_POST,
199                                          LD2Twov16b_POST, LD2Twov8h_POST, LD2Twov4s_POST, LD2Twov2d_POST,
200                                          LD2i8_POST, LD2i16_POST, LD2i32_POST, LD2i64_POST,
201                                          LD2Rv8b_POST, LD2Rv4h_POST, LD2Rv2s_POST, LD2Rv1d_POST,
202                                          LD2Rv16b_POST, LD2Rv8h_POST, LD2Rv4s_POST, LD2Rv2d_POST,
203                                          LD3Threev8b_POST, LD3Threev4h_POST, LD3Threev2s_POST,
204                                          LD3Threev16b_POST, LD3Threev8h_POST, LD3Threev4s_POST, LD3Threev2d_POST,
205                                          LD3i8_POST, LD3i16_POST, LD3i32_POST, LD3i64_POST,
206                                          LD3Rv8b_POST, LD3Rv4h_POST, LD3Rv2s_POST, LD3Rv1d_POST,
207                                          LD3Rv16b_POST, LD3Rv8h_POST, LD3Rv4s_POST, LD3Rv2d_POST,
208                                          LD4Fourv8b_POST, LD4Fourv4h_POST, LD4Fourv2s_POST,
209                                          LD4Fourv16b_POST, LD4Fourv8h_POST, LD4Fourv4s_POST, LD4Fourv2d_POST,
210                                          LD4i8_POST, LD4i16_POST, LD4i32_POST, LD4i64_POST,
211                                          LD4Rv8b_POST, LD4Rv4h_POST, LD4Rv2s_POST, LD4Rv1d_POST,
212                                          LD4Rv16b_POST, LD4Rv8h_POST, LD4Rv4s_POST, LD4Rv2d_POST]>;
213
214// Identify whether an instruction is an ASIMD
215// store using the post index addressing mode.
216def IsStoreASIMDPostOp     : CheckOpcode<[ST1Onev8b_POST, ST1Onev4h_POST, ST1Onev2s_POST, ST1Onev1d_POST,
217                                          ST1Onev16b_POST, ST1Onev8h_POST, ST1Onev4s_POST, ST1Onev2d_POST,
218                                          ST1Twov8b_POST, ST1Twov4h_POST, ST1Twov2s_POST, ST1Twov1d_POST,
219                                          ST1Twov16b_POST, ST1Twov8h_POST, ST1Twov4s_POST, ST1Twov2d_POST,
220                                          ST1Threev8b_POST, ST1Threev4h_POST, ST1Threev2s_POST, ST1Threev1d_POST,
221                                          ST1Threev16b_POST, ST1Threev8h_POST, ST1Threev4s_POST, ST1Threev2d_POST,
222                                          ST1Fourv8b_POST, ST1Fourv4h_POST, ST1Fourv2s_POST, ST1Fourv1d_POST,
223                                          ST1Fourv16b_POST, ST1Fourv8h_POST, ST1Fourv4s_POST, ST1Fourv2d_POST,
224                                          ST1i8_POST, ST1i16_POST, ST1i32_POST, ST1i64_POST,
225                                          ST2Twov8b_POST, ST2Twov4h_POST, ST2Twov2s_POST,
226                                          ST2Twov16b_POST, ST2Twov8h_POST, ST2Twov4s_POST, ST2Twov2d_POST,
227                                          ST2i8_POST, ST2i16_POST, ST2i32_POST, ST2i64_POST,
228                                          ST3Threev8b_POST, ST3Threev4h_POST, ST3Threev2s_POST,
229                                          ST3Threev16b_POST, ST3Threev8h_POST, ST3Threev4s_POST, ST3Threev2d_POST,
230                                          ST3i8_POST, ST3i16_POST, ST3i32_POST, ST3i64_POST,
231                                          ST4Fourv8b_POST, ST4Fourv4h_POST, ST4Fourv2s_POST,
232                                          ST4Fourv16b_POST, ST4Fourv8h_POST, ST4Fourv4s_POST, ST4Fourv2d_POST,
233                                          ST4i8_POST, ST4i16_POST, ST4i32_POST, ST4i64_POST]>;
234
235// Identify whether an instruction is an ASIMD load
236// or store using the post index addressing mode.
237def IsLoadStoreASIMDPostOp : CheckOpcode<!listconcat(IsLoadASIMDPostOp.ValidOpcodes,
238                                                     IsStoreASIMDPostOp.ValidOpcodes)>;
239
240// Identify whether an instruction is a load
241// using the register offset addressing mode.
242def IsLoadRegOffsetOp      : CheckOpcode<[PRFMroW, PRFMroX,
243                                          LDRBBroW, LDRBBroX,
244                                          LDRSBWroW, LDRSBWroX, LDRSBXroW, LDRSBXroX,
245                                          LDRHHroW, LDRHHroX,
246                                          LDRSHWroW, LDRSHWroX, LDRSHXroW, LDRSHXroX,
247                                          LDRWroW, LDRWroX,
248                                          LDRSWroW, LDRSWroX,
249                                          LDRXroW, LDRXroX,
250                                          LDRBroW, LDRBroX,
251                                          LDRHroW, LDRHroX,
252                                          LDRSroW, LDRSroX,
253                                          LDRDroW, LDRDroX]>;
254
255// Identify whether an instruction is a load
256// using the register offset addressing mode.
257def IsStoreRegOffsetOp     : CheckOpcode<[STRBBroW, STRBBroX,
258                                          STRHHroW, STRHHroX,
259                                          STRWroW, STRWroX,
260                                          STRXroW, STRXroX,
261                                          STRBroW, STRBroX,
262                                          STRHroW, STRHroX,
263                                          STRSroW, STRSroX,
264                                          STRDroW, STRDroX]>;
265
266// Identify whether an instruction is a load or
267// store using the register offset addressing mode.
268def IsLoadStoreRegOffsetOp : CheckOpcode<!listconcat(IsLoadRegOffsetOp.ValidOpcodes,
269                                                     IsStoreRegOffsetOp.ValidOpcodes)>;
270
271// Target predicates.
272
273// Identify an instruction that effectively transfers a register to another.
274def IsCopyIdiomFn     : TIIPredicate<"isCopyIdiom",
275                                     MCOpcodeSwitchStatement<
276                                       [// MOV {Rd, SP}, {SP, Rn} =>
277                                        // ADD {Rd, SP}, {SP, Rn}, #0
278                                        MCOpcodeSwitchCase<
279                                          [ADDWri, ADDXri],
280                                          MCReturnStatement<
281                                            CheckAll<
282                                              [CheckIsRegOperand<0>,
283                                               CheckIsRegOperand<1>,
284                                               CheckAny<
285                                                 [CheckRegOperand<0, WSP>,
286                                                  CheckRegOperand<0, SP>,
287                                                  CheckRegOperand<1, WSP>,
288                                                  CheckRegOperand<1, SP>]>,
289                                               CheckZeroOperand<2>]>>>,
290                                        // MOV Rd, Rm =>
291                                        // ORR Rd, ZR, Rm, LSL #0
292                                        MCOpcodeSwitchCase<
293                                          [ORRWrs, ORRXrs],
294                                          MCReturnStatement<
295                                            CheckAll<
296                                              [CheckIsRegOperand<1>,
297                                               CheckIsRegOperand<2>,
298                                               CheckAny<
299                                                 [CheckRegOperand<1, WZR>,
300                                                  CheckRegOperand<1, XZR>]>,
301                                               CheckShiftBy0]>>>],
302                                       MCReturnStatement<FalsePred>>>;
303def IsCopyIdiomPred   : MCSchedPredicate<IsCopyIdiomFn>;
304
305// Identify arithmetic instructions with an extended register.
306def RegExtendedFn     : TIIPredicate<"hasExtendedReg",
307                                     MCOpcodeSwitchStatement<
308                                       [MCOpcodeSwitchCase<
309                                         IsArithExtOp.ValidOpcodes,
310                                         MCReturnStatement<
311                                           CheckNot<CheckZeroOperand<3>>>>],
312                                       MCReturnStatement<FalsePred>>>;
313def RegExtendedPred   : MCSchedPredicate<RegExtendedFn>;
314
315// Identify arithmetic and logic instructions with a shifted register.
316def RegShiftedFn      : TIIPredicate<"hasShiftedReg",
317                                     MCOpcodeSwitchStatement<
318                                       [MCOpcodeSwitchCase<
319                                          IsArithLogicShiftOp.ValidOpcodes,
320                                          MCReturnStatement<
321                                            CheckNot<CheckZeroOperand<3>>>>],
322                                       MCReturnStatement<FalsePred>>>;
323def RegShiftedPred    : MCSchedPredicate<RegShiftedFn>;
324
325// Identify a load or store using the register offset addressing mode
326// with an extended or scaled register.
327def ScaledIdxFn       : TIIPredicate<"isScaledAddr",
328                                     MCOpcodeSwitchStatement<
329                                       [MCOpcodeSwitchCase<
330                                          IsLoadStoreRegOffsetOp.ValidOpcodes,
331                                          MCReturnStatement<
332                                            CheckAny<[CheckNot<CheckMemExtLSL>,
333                                                      CheckMemScaled]>>>],
334                                       MCReturnStatement<FalsePred>>>;
335def ScaledIdxPred     : MCSchedPredicate<ScaledIdxFn>;
336
337// Identify an instruction that effectively resets a FP register to zero.
338def IsZeroFPIdiomFn   : TIIPredicate<"isZeroFPIdiom",
339                                     MCOpcodeSwitchStatement<
340                                       [// MOVI Vd, #0
341                                        MCOpcodeSwitchCase<
342                                          [MOVIv8b_ns, MOVIv16b_ns,
343                                           MOVID, MOVIv2d_ns],
344                                          MCReturnStatement<CheckZeroOperand<1>>>,
345                                        // MOVI Vd, #0, LSL #0
346                                        MCOpcodeSwitchCase<
347                                          [MOVIv4i16, MOVIv8i16,
348                                           MOVIv2i32, MOVIv4i32],
349                                          MCReturnStatement<
350                                            CheckAll<
351                                              [CheckZeroOperand<1>,
352                                               CheckZeroOperand<2>]>>>],
353                                       MCReturnStatement<FalsePred>>>;
354def IsZeroFPIdiomPred : MCSchedPredicate<IsZeroFPIdiomFn>;
355
356// Identify an instruction that effectively resets a GP register to zero.
357def IsZeroIdiomFn     : TIIPredicate<"isZeroIdiom",
358                                    MCOpcodeSwitchStatement<
359                                      [// ORR Rd, ZR, #0
360                                       MCOpcodeSwitchCase<
361                                         [ORRWri, ORRXri],
362                                         MCReturnStatement<
363                                           CheckAll<
364                                             [CheckIsRegOperand<1>,
365                                              CheckAny<
366                                                [CheckRegOperand<1, WZR>,
367                                                 CheckRegOperand<1, XZR>]>,
368                                              CheckZeroOperand<2>]>>>],
369                                      MCReturnStatement<FalsePred>>>;
370def IsZeroIdiomPred   : MCSchedPredicate<IsZeroIdiomFn>;
371