AArch64SchedPredicates.td 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  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. // Function mappers.
  14. // Check the extension type in arithmetic instructions.
  15. let FunctionMapper = "AArch64_AM::getArithExtendType" in {
  16. def CheckExtUXTB : CheckImmOperand_s<3, "AArch64_AM::UXTB">;
  17. def CheckExtUXTH : CheckImmOperand_s<3, "AArch64_AM::UXTH">;
  18. def CheckExtUXTW : CheckImmOperand_s<3, "AArch64_AM::UXTW">;
  19. def CheckExtUXTX : CheckImmOperand_s<3, "AArch64_AM::UXTX">;
  20. def CheckExtSXTB : CheckImmOperand_s<3, "AArch64_AM::SXTB">;
  21. def CheckExtSXTH : CheckImmOperand_s<3, "AArch64_AM::SXTH">;
  22. def CheckExtSXTW : CheckImmOperand_s<3, "AArch64_AM::SXTW">;
  23. def CheckExtSXTX : CheckImmOperand_s<3, "AArch64_AM::SXTX">;
  24. }
  25. // Check for shifting in extended arithmetic instructions.
  26. foreach I = {0-3} in {
  27. let FunctionMapper = "AArch64_AM::getArithShiftValue" in
  28. def CheckExtBy#I : CheckImmOperand<3, I>;
  29. }
  30. // Check the extension type in the register offset addressing mode.
  31. let FunctionMapper = "AArch64_AM::getMemExtendType" in {
  32. def CheckMemExtUXTW : CheckImmOperand_s<3, "AArch64_AM::UXTW">;
  33. def CheckMemExtLSL : CheckImmOperand_s<3, "AArch64_AM::UXTX">;
  34. def CheckMemExtSXTW : CheckImmOperand_s<3, "AArch64_AM::SXTW">;
  35. def CheckMemExtSXTX : CheckImmOperand_s<3, "AArch64_AM::SXTX">;
  36. }
  37. // Check for scaling in the register offset addressing mode.
  38. let FunctionMapper = "AArch64_AM::getMemDoShift" in
  39. def CheckMemScaled : CheckImmOperandSimple<4>;
  40. // Check the shifting type in arithmetic and logic instructions.
  41. let FunctionMapper = "AArch64_AM::getShiftType" in {
  42. def CheckShiftLSL : CheckImmOperand_s<3, "AArch64_AM::LSL">;
  43. def CheckShiftLSR : CheckImmOperand_s<3, "AArch64_AM::LSR">;
  44. def CheckShiftASR : CheckImmOperand_s<3, "AArch64_AM::ASR">;
  45. def CheckShiftROR : CheckImmOperand_s<3, "AArch64_AM::ROR">;
  46. def CheckShiftMSL : CheckImmOperand_s<3, "AArch64_AM::MSL">;
  47. }
  48. // Check for shifting in arithmetic and logic instructions.
  49. foreach I = {0-4, 8} in {
  50. let FunctionMapper = "AArch64_AM::getShiftValue" in
  51. def CheckShiftBy#I : CheckImmOperand<3, I>;
  52. }
  53. // Generic predicates.
  54. // Identify whether an instruction is NEON or floating point
  55. def CheckFpOrNEON : CheckFunctionPredicateWithTII<
  56. "AArch64_MC::isFpOrNEON",
  57. "AArch64InstrInfo::isFpOrNEON"
  58. >;
  59. // Identify whether an instruction is the 128-bit NEON form based on its result.
  60. def CheckQForm : CheckFunctionPredicateWithTII<
  61. "AArch64_MC::isQForm",
  62. "AArch64InstrInfo::isQForm"
  63. >;
  64. // Identify arithmetic instructions with extend.
  65. def IsArithExtOp : CheckOpcode<[ADDWrx, ADDXrx, ADDSWrx, ADDSXrx,
  66. SUBWrx, SUBXrx, SUBSWrx, SUBSXrx,
  67. ADDXrx64, ADDSXrx64,
  68. SUBXrx64, SUBSXrx64]>;
  69. // Identify arithmetic immediate instructions.
  70. def IsArithImmOp : CheckOpcode<[ADDWri, ADDXri, ADDSWri, ADDSXri,
  71. SUBWri, SUBXri, SUBSWri, SUBSXri]>;
  72. // Identify arithmetic instructions with shift.
  73. def IsArithShiftOp : CheckOpcode<[ADDWrs, ADDXrs, ADDSWrs, ADDSXrs,
  74. SUBWrs, SUBXrs, SUBSWrs, SUBSXrs]>;
  75. // Identify arithmetic instructions without shift.
  76. def IsArithUnshiftOp : CheckOpcode<[ADDWrr, ADDXrr, ADDSWrr, ADDSXrr,
  77. SUBWrr, SUBXrr, SUBSWrr, SUBSXrr]>;
  78. // Identify logic immediate instructions.
  79. def IsLogicImmOp : CheckOpcode<[ANDWri, ANDXri,
  80. EORWri, EORXri,
  81. ORRWri, ORRXri]>;
  82. // Identify logic instructions with shift.
  83. def IsLogicShiftOp : CheckOpcode<[ANDWrs, ANDXrs, ANDSWrs, ANDSXrs,
  84. BICWrs, BICXrs, BICSWrs, BICSXrs,
  85. EONWrs, EONXrs,
  86. EORWrs, EORXrs,
  87. ORNWrs, ORNXrs,
  88. ORRWrs, ORRXrs]>;
  89. // Identify logic instructions without shift.
  90. def IsLogicUnshiftOp : CheckOpcode<[ANDWrr, ANDXrr, ANDSWrr, ANDSXrr,
  91. BICWrr, BICXrr, BICSWrr, BICSXrr,
  92. EONWrr, EONXrr,
  93. EORWrr, EORXrr,
  94. ORNWrr, ORNXrr,
  95. ORRWrr, ORRXrr]>;
  96. // Identify arithmetic and logic immediate instructions.
  97. def IsArithLogicImmOp : CheckOpcode<!listconcat(IsArithImmOp.ValidOpcodes,
  98. IsLogicImmOp.ValidOpcodes)>;
  99. // Identify arithmetic and logic instructions with shift.
  100. def IsArithLogicShiftOp : CheckOpcode<!listconcat(IsArithShiftOp.ValidOpcodes,
  101. IsLogicShiftOp.ValidOpcodes)>;
  102. // Identify arithmetic and logic instructions without shift.
  103. def IsArithLogicUnshiftOp : CheckOpcode<!listconcat(IsArithUnshiftOp.ValidOpcodes,
  104. IsLogicUnshiftOp.ValidOpcodes)>;
  105. // Identify whether an instruction is an ASIMD
  106. // load using the post index addressing mode.
  107. def IsLoadASIMDPostOp : CheckOpcode<[LD1Onev8b_POST, LD1Onev4h_POST, LD1Onev2s_POST, LD1Onev1d_POST,
  108. LD1Onev16b_POST, LD1Onev8h_POST, LD1Onev4s_POST, LD1Onev2d_POST,
  109. LD1Twov8b_POST, LD1Twov4h_POST, LD1Twov2s_POST, LD1Twov1d_POST,
  110. LD1Twov16b_POST, LD1Twov8h_POST, LD1Twov4s_POST, LD1Twov2d_POST,
  111. LD1Threev8b_POST, LD1Threev4h_POST, LD1Threev2s_POST, LD1Threev1d_POST,
  112. LD1Threev16b_POST, LD1Threev8h_POST, LD1Threev4s_POST, LD1Threev2d_POST,
  113. LD1Fourv8b_POST, LD1Fourv4h_POST, LD1Fourv2s_POST, LD1Fourv1d_POST,
  114. LD1Fourv16b_POST, LD1Fourv8h_POST, LD1Fourv4s_POST, LD1Fourv2d_POST,
  115. LD1i8_POST, LD1i16_POST, LD1i32_POST, LD1i64_POST,
  116. LD1Rv8b_POST, LD1Rv4h_POST, LD1Rv2s_POST, LD1Rv1d_POST,
  117. LD1Rv16b_POST, LD1Rv8h_POST, LD1Rv4s_POST, LD1Rv2d_POST,
  118. LD2Twov8b_POST, LD2Twov4h_POST, LD2Twov2s_POST,
  119. LD2Twov16b_POST, LD2Twov8h_POST, LD2Twov4s_POST, LD2Twov2d_POST,
  120. LD2i8_POST, LD2i16_POST, LD2i32_POST, LD2i64_POST,
  121. LD2Rv8b_POST, LD2Rv4h_POST, LD2Rv2s_POST, LD2Rv1d_POST,
  122. LD2Rv16b_POST, LD2Rv8h_POST, LD2Rv4s_POST, LD2Rv2d_POST,
  123. LD3Threev8b_POST, LD3Threev4h_POST, LD3Threev2s_POST,
  124. LD3Threev16b_POST, LD3Threev8h_POST, LD3Threev4s_POST, LD3Threev2d_POST,
  125. LD3i8_POST, LD3i16_POST, LD3i32_POST, LD3i64_POST,
  126. LD3Rv8b_POST, LD3Rv4h_POST, LD3Rv2s_POST, LD3Rv1d_POST,
  127. LD3Rv16b_POST, LD3Rv8h_POST, LD3Rv4s_POST, LD3Rv2d_POST,
  128. LD4Fourv8b_POST, LD4Fourv4h_POST, LD4Fourv2s_POST,
  129. LD4Fourv16b_POST, LD4Fourv8h_POST, LD4Fourv4s_POST, LD4Fourv2d_POST,
  130. LD4i8_POST, LD4i16_POST, LD4i32_POST, LD4i64_POST,
  131. LD4Rv8b_POST, LD4Rv4h_POST, LD4Rv2s_POST, LD4Rv1d_POST,
  132. LD4Rv16b_POST, LD4Rv8h_POST, LD4Rv4s_POST, LD4Rv2d_POST]>;
  133. // Identify whether an instruction is an ASIMD
  134. // store using the post index addressing mode.
  135. def IsStoreASIMDPostOp : CheckOpcode<[ST1Onev8b_POST, ST1Onev4h_POST, ST1Onev2s_POST, ST1Onev1d_POST,
  136. ST1Onev16b_POST, ST1Onev8h_POST, ST1Onev4s_POST, ST1Onev2d_POST,
  137. ST1Twov8b_POST, ST1Twov4h_POST, ST1Twov2s_POST, ST1Twov1d_POST,
  138. ST1Twov16b_POST, ST1Twov8h_POST, ST1Twov4s_POST, ST1Twov2d_POST,
  139. ST1Threev8b_POST, ST1Threev4h_POST, ST1Threev2s_POST, ST1Threev1d_POST,
  140. ST1Threev16b_POST, ST1Threev8h_POST, ST1Threev4s_POST, ST1Threev2d_POST,
  141. ST1Fourv8b_POST, ST1Fourv4h_POST, ST1Fourv2s_POST, ST1Fourv1d_POST,
  142. ST1Fourv16b_POST, ST1Fourv8h_POST, ST1Fourv4s_POST, ST1Fourv2d_POST,
  143. ST1i8_POST, ST1i16_POST, ST1i32_POST, ST1i64_POST,
  144. ST2Twov8b_POST, ST2Twov4h_POST, ST2Twov2s_POST,
  145. ST2Twov16b_POST, ST2Twov8h_POST, ST2Twov4s_POST, ST2Twov2d_POST,
  146. ST2i8_POST, ST2i16_POST, ST2i32_POST, ST2i64_POST,
  147. ST3Threev8b_POST, ST3Threev4h_POST, ST3Threev2s_POST,
  148. ST3Threev16b_POST, ST3Threev8h_POST, ST3Threev4s_POST, ST3Threev2d_POST,
  149. ST3i8_POST, ST3i16_POST, ST3i32_POST, ST3i64_POST,
  150. ST4Fourv8b_POST, ST4Fourv4h_POST, ST4Fourv2s_POST,
  151. ST4Fourv16b_POST, ST4Fourv8h_POST, ST4Fourv4s_POST, ST4Fourv2d_POST,
  152. ST4i8_POST, ST4i16_POST, ST4i32_POST, ST4i64_POST]>;
  153. // Identify whether an instruction is an ASIMD load
  154. // or store using the post index addressing mode.
  155. def IsLoadStoreASIMDPostOp : CheckOpcode<!listconcat(IsLoadASIMDPostOp.ValidOpcodes,
  156. IsStoreASIMDPostOp.ValidOpcodes)>;
  157. // Identify whether an instruction is a load
  158. // using the register offset addressing mode.
  159. def IsLoadRegOffsetOp : CheckOpcode<[PRFMroW, PRFMroX,
  160. LDRBBroW, LDRBBroX,
  161. LDRSBWroW, LDRSBWroX, LDRSBXroW, LDRSBXroX,
  162. LDRHHroW, LDRHHroX,
  163. LDRSHWroW, LDRSHWroX, LDRSHXroW, LDRSHXroX,
  164. LDRWroW, LDRWroX,
  165. LDRSWroW, LDRSWroX,
  166. LDRXroW, LDRXroX,
  167. LDRBroW, LDRBroX,
  168. LDRHroW, LDRHroX,
  169. LDRSroW, LDRSroX,
  170. LDRDroW, LDRDroX,
  171. LDRQroW, LDRQroX]>;
  172. // Identify whether an instruction is a store
  173. // using the register offset addressing mode.
  174. def IsStoreRegOffsetOp : CheckOpcode<[STRBBroW, STRBBroX,
  175. STRHHroW, STRHHroX,
  176. STRWroW, STRWroX,
  177. STRXroW, STRXroX,
  178. STRBroW, STRBroX,
  179. STRHroW, STRHroX,
  180. STRSroW, STRSroX,
  181. STRDroW, STRDroX,
  182. STRQroW, STRQroX]>;
  183. // Identify whether an instruction is a load or
  184. // store using the register offset addressing mode.
  185. def IsLoadStoreRegOffsetOp : CheckOpcode<!listconcat(IsLoadRegOffsetOp.ValidOpcodes,
  186. IsStoreRegOffsetOp.ValidOpcodes)>;
  187. // Target predicates.
  188. // Identify an instruction that effectively transfers a register to another.
  189. def IsCopyIdiomFn : TIIPredicate<"isCopyIdiom",
  190. MCOpcodeSwitchStatement<
  191. [// MOV {Rd, SP}, {SP, Rn} =>
  192. // ADD {Rd, SP}, {SP, Rn}, #0
  193. MCOpcodeSwitchCase<
  194. [ADDWri, ADDXri],
  195. MCReturnStatement<
  196. CheckAll<
  197. [CheckIsRegOperand<0>,
  198. CheckIsRegOperand<1>,
  199. CheckAny<
  200. [CheckRegOperand<0, WSP>,
  201. CheckRegOperand<0, SP>,
  202. CheckRegOperand<1, WSP>,
  203. CheckRegOperand<1, SP>]>,
  204. CheckZeroOperand<2>]>>>,
  205. // MOV Rd, Rm =>
  206. // ORR Rd, ZR, Rm, LSL #0
  207. MCOpcodeSwitchCase<
  208. [ORRWrs, ORRXrs],
  209. MCReturnStatement<
  210. CheckAll<
  211. [CheckIsRegOperand<1>,
  212. CheckIsRegOperand<2>,
  213. CheckAny<
  214. [CheckRegOperand<1, WZR>,
  215. CheckRegOperand<1, XZR>]>,
  216. CheckShiftBy0]>>>],
  217. MCReturnStatement<FalsePred>>>;
  218. def IsCopyIdiomPred : MCSchedPredicate<IsCopyIdiomFn>;
  219. // Identify arithmetic instructions with an extended register.
  220. def RegExtendedFn : TIIPredicate<"hasExtendedReg",
  221. MCOpcodeSwitchStatement<
  222. [MCOpcodeSwitchCase<
  223. IsArithExtOp.ValidOpcodes,
  224. MCReturnStatement<
  225. CheckNot<CheckZeroOperand<3>>>>],
  226. MCReturnStatement<FalsePred>>>;
  227. def RegExtendedPred : MCSchedPredicate<RegExtendedFn>;
  228. // Identify arithmetic and logic instructions with a shifted register.
  229. def RegShiftedFn : TIIPredicate<"hasShiftedReg",
  230. MCOpcodeSwitchStatement<
  231. [MCOpcodeSwitchCase<
  232. IsArithLogicShiftOp.ValidOpcodes,
  233. MCReturnStatement<
  234. CheckNot<CheckZeroOperand<3>>>>],
  235. MCReturnStatement<FalsePred>>>;
  236. def RegShiftedPred : MCSchedPredicate<RegShiftedFn>;
  237. // Identify a load or store using the register offset addressing mode
  238. // with an extended or scaled register.
  239. def ScaledIdxFn : TIIPredicate<"isScaledAddr",
  240. MCOpcodeSwitchStatement<
  241. [MCOpcodeSwitchCase<
  242. IsLoadStoreRegOffsetOp.ValidOpcodes,
  243. MCReturnStatement<
  244. CheckAny<[CheckNot<CheckMemExtLSL>,
  245. CheckMemScaled]>>>],
  246. MCReturnStatement<FalsePred>>>;
  247. def ScaledIdxPred : MCSchedPredicate<ScaledIdxFn>;
  248. // Identify an instruction that effectively resets a FP register to zero.
  249. def IsZeroFPIdiomFn : TIIPredicate<"isZeroFPIdiom",
  250. MCOpcodeSwitchStatement<
  251. [// MOVI Vd, #0
  252. MCOpcodeSwitchCase<
  253. [MOVIv8b_ns, MOVIv16b_ns,
  254. MOVID, MOVIv2d_ns],
  255. MCReturnStatement<CheckZeroOperand<1>>>,
  256. // MOVI Vd, #0, LSL #0
  257. MCOpcodeSwitchCase<
  258. [MOVIv4i16, MOVIv8i16,
  259. MOVIv2i32, MOVIv4i32],
  260. MCReturnStatement<
  261. CheckAll<
  262. [CheckZeroOperand<1>,
  263. CheckZeroOperand<2>]>>>],
  264. MCReturnStatement<FalsePred>>>;
  265. def IsZeroFPIdiomPred : MCSchedPredicate<IsZeroFPIdiomFn>;
  266. // Identify an instruction that effectively resets a GP register to zero.
  267. def IsZeroIdiomFn : TIIPredicate<"isZeroIdiom",
  268. MCOpcodeSwitchStatement<
  269. [// ORR Rd, ZR, #0
  270. MCOpcodeSwitchCase<
  271. [ORRWri, ORRXri],
  272. MCReturnStatement<
  273. CheckAll<
  274. [CheckIsRegOperand<1>,
  275. CheckAny<
  276. [CheckRegOperand<1, WZR>,
  277. CheckRegOperand<1, XZR>]>,
  278. CheckZeroOperand<2>]>>>],
  279. MCReturnStatement<FalsePred>>>;
  280. def IsZeroIdiomPred : MCSchedPredicate<IsZeroIdiomFn>;