AArch64InstrGISel.td 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. //=----- AArch64InstrGISel.td - AArch64 GISel target pseudos -*- 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. // AArch64 GlobalISel target pseudo instruction definitions. This is kept
  10. // separately from the other tablegen files for organizational purposes, but
  11. // share the same infrastructure.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. class AArch64GenericInstruction : GenericInstruction {
  15. let Namespace = "AArch64";
  16. }
  17. // A pseudo to represent a relocatable add instruction as part of address
  18. // computation.
  19. def G_ADD_LOW : AArch64GenericInstruction {
  20. let OutOperandList = (outs type0:$dst);
  21. let InOperandList = (ins type1:$src, type2:$imm);
  22. let hasSideEffects = 0;
  23. }
  24. // Pseudo for a rev16 instruction. Produced post-legalization from
  25. // G_SHUFFLE_VECTORs with appropriate masks.
  26. def G_REV16 : AArch64GenericInstruction {
  27. let OutOperandList = (outs type0:$dst);
  28. let InOperandList = (ins type0:$src);
  29. let hasSideEffects = 0;
  30. }
  31. // Pseudo for a rev32 instruction. Produced post-legalization from
  32. // G_SHUFFLE_VECTORs with appropriate masks.
  33. def G_REV32 : AArch64GenericInstruction {
  34. let OutOperandList = (outs type0:$dst);
  35. let InOperandList = (ins type0:$src);
  36. let hasSideEffects = 0;
  37. }
  38. // Pseudo for a rev64 instruction. Produced post-legalization from
  39. // G_SHUFFLE_VECTORs with appropriate masks.
  40. def G_REV64 : AArch64GenericInstruction {
  41. let OutOperandList = (outs type0:$dst);
  42. let InOperandList = (ins type0:$src);
  43. let hasSideEffects = 0;
  44. }
  45. // Represents an uzp1 instruction. Produced post-legalization from
  46. // G_SHUFFLE_VECTORs with appropriate masks.
  47. def G_UZP1 : AArch64GenericInstruction {
  48. let OutOperandList = (outs type0:$dst);
  49. let InOperandList = (ins type0:$v1, type0:$v2);
  50. let hasSideEffects = 0;
  51. }
  52. // Represents an uzp2 instruction. Produced post-legalization from
  53. // G_SHUFFLE_VECTORs with appropriate masks.
  54. def G_UZP2 : AArch64GenericInstruction {
  55. let OutOperandList = (outs type0:$dst);
  56. let InOperandList = (ins type0:$v1, type0:$v2);
  57. let hasSideEffects = 0;
  58. }
  59. // Represents a zip1 instruction. Produced post-legalization from
  60. // G_SHUFFLE_VECTORs with appropriate masks.
  61. def G_ZIP1 : AArch64GenericInstruction {
  62. let OutOperandList = (outs type0:$dst);
  63. let InOperandList = (ins type0:$v1, type0:$v2);
  64. let hasSideEffects = 0;
  65. }
  66. // Represents a zip2 instruction. Produced post-legalization from
  67. // G_SHUFFLE_VECTORs with appropriate masks.
  68. def G_ZIP2 : AArch64GenericInstruction {
  69. let OutOperandList = (outs type0:$dst);
  70. let InOperandList = (ins type0:$v1, type0:$v2);
  71. let hasSideEffects = 0;
  72. }
  73. // Represents a dup instruction. Produced post-legalization from
  74. // G_SHUFFLE_VECTORs with appropriate masks.
  75. def G_DUP: AArch64GenericInstruction {
  76. let OutOperandList = (outs type0:$dst);
  77. let InOperandList = (ins type1:$lane);
  78. let hasSideEffects = 0;
  79. }
  80. // Represents a lane duplicate operation.
  81. def G_DUPLANE8 : AArch64GenericInstruction {
  82. let OutOperandList = (outs type0:$dst);
  83. let InOperandList = (ins type0:$src, type1:$lane);
  84. let hasSideEffects = 0;
  85. }
  86. def G_DUPLANE16 : AArch64GenericInstruction {
  87. let OutOperandList = (outs type0:$dst);
  88. let InOperandList = (ins type0:$src, type1:$lane);
  89. let hasSideEffects = 0;
  90. }
  91. def G_DUPLANE32 : AArch64GenericInstruction {
  92. let OutOperandList = (outs type0:$dst);
  93. let InOperandList = (ins type0:$src, type1:$lane);
  94. let hasSideEffects = 0;
  95. }
  96. def G_DUPLANE64 : AArch64GenericInstruction {
  97. let OutOperandList = (outs type0:$dst);
  98. let InOperandList = (ins type0:$src, type1:$lane);
  99. let hasSideEffects = 0;
  100. }
  101. // Represents a trn1 instruction. Produced post-legalization from
  102. // G_SHUFFLE_VECTORs with appropriate masks.
  103. def G_TRN1 : AArch64GenericInstruction {
  104. let OutOperandList = (outs type0:$dst);
  105. let InOperandList = (ins type0:$v1, type0:$v2);
  106. let hasSideEffects = 0;
  107. }
  108. // Represents a trn2 instruction. Produced post-legalization from
  109. // G_SHUFFLE_VECTORs with appropriate masks.
  110. def G_TRN2 : AArch64GenericInstruction {
  111. let OutOperandList = (outs type0:$dst);
  112. let InOperandList = (ins type0:$v1, type0:$v2);
  113. let hasSideEffects = 0;
  114. }
  115. // Represents an ext instruction. Produced post-legalization from
  116. // G_SHUFFLE_VECTORs with appropriate masks.
  117. def G_EXT: AArch64GenericInstruction {
  118. let OutOperandList = (outs type0:$dst);
  119. let InOperandList = (ins type0:$v1, type0:$v2, untyped_imm_0:$imm);
  120. let hasSideEffects = 0;
  121. }
  122. // Represents a vector G_ASHR with an immediate.
  123. def G_VASHR : AArch64GenericInstruction {
  124. let OutOperandList = (outs type0:$dst);
  125. let InOperandList = (ins type0:$src1, untyped_imm_0:$imm);
  126. let hasSideEffects = 0;
  127. }
  128. // Represents a vector G_LSHR with an immediate.
  129. def G_VLSHR : AArch64GenericInstruction {
  130. let OutOperandList = (outs type0:$dst);
  131. let InOperandList = (ins type0:$src1, untyped_imm_0:$imm);
  132. let hasSideEffects = 0;
  133. }
  134. // Represents an integer to FP conversion on the FPR bank.
  135. def G_SITOF : AArch64GenericInstruction {
  136. let OutOperandList = (outs type0:$dst);
  137. let InOperandList = (ins type0:$src);
  138. let hasSideEffects = 0;
  139. }
  140. def G_UITOF : AArch64GenericInstruction {
  141. let OutOperandList = (outs type0:$dst);
  142. let InOperandList = (ins type0:$src);
  143. let hasSideEffects = 0;
  144. }
  145. def G_FCMEQ : AArch64GenericInstruction {
  146. let OutOperandList = (outs type0:$dst);
  147. let InOperandList = (ins type0:$src1, type1:$src2);
  148. let hasSideEffects = 0;
  149. }
  150. def G_FCMGE : AArch64GenericInstruction {
  151. let OutOperandList = (outs type0:$dst);
  152. let InOperandList = (ins type0:$src1, type1:$src2);
  153. let hasSideEffects = 0;
  154. }
  155. def G_FCMGT : AArch64GenericInstruction {
  156. let OutOperandList = (outs type0:$dst);
  157. let InOperandList = (ins type0:$src1, type1:$src2);
  158. let hasSideEffects = 0;
  159. }
  160. def G_FCMEQZ : AArch64GenericInstruction {
  161. let OutOperandList = (outs type0:$dst);
  162. let InOperandList = (ins type0:$src);
  163. let hasSideEffects = 0;
  164. }
  165. def G_FCMGEZ : AArch64GenericInstruction {
  166. let OutOperandList = (outs type0:$dst);
  167. let InOperandList = (ins type0:$src);
  168. let hasSideEffects = 0;
  169. }
  170. def G_FCMGTZ : AArch64GenericInstruction {
  171. let OutOperandList = (outs type0:$dst);
  172. let InOperandList = (ins type0:$src);
  173. let hasSideEffects = 0;
  174. }
  175. def G_FCMLEZ : AArch64GenericInstruction {
  176. let OutOperandList = (outs type0:$dst);
  177. let InOperandList = (ins type0:$src);
  178. let hasSideEffects = 0;
  179. }
  180. def G_FCMLTZ : AArch64GenericInstruction {
  181. let OutOperandList = (outs type0:$dst);
  182. let InOperandList = (ins type0:$src);
  183. let hasSideEffects = 0;
  184. }
  185. def G_PREFETCH : AArch64GenericInstruction {
  186. let OutOperandList = (outs);
  187. let InOperandList = (ins type0:$imm, ptype0:$src1);
  188. let hasSideEffects = 1;
  189. }
  190. // Generic bitwise insert if true.
  191. def G_BIT : AArch64GenericInstruction {
  192. let OutOperandList = (outs type0:$dst);
  193. let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
  194. let hasSideEffects = 0;
  195. }
  196. def : GINodeEquiv<G_REV16, AArch64rev16>;
  197. def : GINodeEquiv<G_REV32, AArch64rev32>;
  198. def : GINodeEquiv<G_REV64, AArch64rev64>;
  199. def : GINodeEquiv<G_UZP1, AArch64uzp1>;
  200. def : GINodeEquiv<G_UZP2, AArch64uzp2>;
  201. def : GINodeEquiv<G_ZIP1, AArch64zip1>;
  202. def : GINodeEquiv<G_ZIP2, AArch64zip2>;
  203. def : GINodeEquiv<G_DUP, AArch64dup>;
  204. def : GINodeEquiv<G_DUPLANE8, AArch64duplane8>;
  205. def : GINodeEquiv<G_DUPLANE16, AArch64duplane16>;
  206. def : GINodeEquiv<G_DUPLANE32, AArch64duplane32>;
  207. def : GINodeEquiv<G_DUPLANE64, AArch64duplane64>;
  208. def : GINodeEquiv<G_TRN1, AArch64trn1>;
  209. def : GINodeEquiv<G_TRN2, AArch64trn2>;
  210. def : GINodeEquiv<G_EXT, AArch64ext>;
  211. def : GINodeEquiv<G_VASHR, AArch64vashr>;
  212. def : GINodeEquiv<G_VLSHR, AArch64vlshr>;
  213. def : GINodeEquiv<G_SITOF, AArch64sitof>;
  214. def : GINodeEquiv<G_UITOF, AArch64uitof>;
  215. def : GINodeEquiv<G_FCMEQ, AArch64fcmeq>;
  216. def : GINodeEquiv<G_FCMGE, AArch64fcmge>;
  217. def : GINodeEquiv<G_FCMGT, AArch64fcmgt>;
  218. def : GINodeEquiv<G_FCMEQZ, AArch64fcmeqz>;
  219. def : GINodeEquiv<G_FCMGEZ, AArch64fcmgez>;
  220. def : GINodeEquiv<G_FCMGTZ, AArch64fcmgtz>;
  221. def : GINodeEquiv<G_FCMLEZ, AArch64fcmlez>;
  222. def : GINodeEquiv<G_FCMLTZ, AArch64fcmltz>;
  223. def : GINodeEquiv<G_BIT, AArch64bit>;
  224. def : GINodeEquiv<G_EXTRACT_VECTOR_ELT, vector_extract>;
  225. def : GINodeEquiv<G_PREFETCH, AArch64Prefetch>;
  226. // These are patterns that we only use for GlobalISel via the importer.
  227. def : Pat<(f32 (fadd (vector_extract (v2f32 FPR64:$Rn), (i64 0)),
  228. (vector_extract (v2f32 FPR64:$Rn), (i64 1)))),
  229. (f32 (FADDPv2i32p (v2f32 FPR64:$Rn)))>;
  230. let Predicates = [HasNEON] in {
  231. def : Pat<(v2f64 (sint_to_fp v2i32:$src)),
  232. (SCVTFv2f64 (SSHLLv2i32_shift V64:$src, 0))>;
  233. def : Pat<(v2f64 (uint_to_fp v2i32:$src)),
  234. (UCVTFv2f64 (USHLLv2i32_shift V64:$src, 0))>;
  235. def : Pat<(v2f32 (sint_to_fp v2i64:$src)),
  236. (FCVTNv2i32 (SCVTFv2f64 V128:$src))>;
  237. def : Pat<(v2f32 (uint_to_fp v2i64:$src)),
  238. (FCVTNv2i32 (UCVTFv2f64 V128:$src))>;
  239. def : Pat<(v2i64 (fp_to_sint v2f32:$src)),
  240. (FCVTZSv2f64 (FCVTLv2i32 V64:$src))>;
  241. def : Pat<(v2i64 (fp_to_uint v2f32:$src)),
  242. (FCVTZUv2f64 (FCVTLv2i32 V64:$src))>;
  243. def : Pat<(v2i32 (fp_to_sint v2f64:$src)),
  244. (XTNv2i32 (FCVTZSv2f64 V128:$src))>;
  245. def : Pat<(v2i32 (fp_to_uint v2f64:$src)),
  246. (XTNv2i32 (FCVTZUv2f64 V128:$src))>;
  247. }
  248. let Predicates = [HasNoLSE] in {
  249. def : Pat<(atomic_cmp_swap_8 GPR64:$addr, GPR32:$desired, GPR32:$new),
  250. (CMP_SWAP_8 GPR64:$addr, GPR32:$desired, GPR32:$new)>;
  251. def : Pat<(atomic_cmp_swap_16 GPR64:$addr, GPR32:$desired, GPR32:$new),
  252. (CMP_SWAP_16 GPR64:$addr, GPR32:$desired, GPR32:$new)>;
  253. def : Pat<(atomic_cmp_swap_32 GPR64:$addr, GPR32:$desired, GPR32:$new),
  254. (CMP_SWAP_32 GPR64:$addr, GPR32:$desired, GPR32:$new)>;
  255. def : Pat<(atomic_cmp_swap_64 GPR64:$addr, GPR64:$desired, GPR64:$new),
  256. (CMP_SWAP_64 GPR64:$addr, GPR64:$desired, GPR64:$new)>;
  257. }
  258. def : Pat<(int_aarch64_stlxp GPR64:$lo, GPR64:$hi, GPR64:$addr),
  259. (STLXPX GPR64:$lo, GPR64:$hi, GPR64:$addr)>;
  260. def : Pat<(int_aarch64_stxp GPR64:$lo, GPR64:$hi, GPR64:$addr),
  261. (STXPX GPR64:$lo, GPR64:$hi, GPR64:$addr)>;