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