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