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