IntrinsicsWebAssembly.td 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. //===- IntrinsicsWebAssembly.td - Defines wasm intrinsics --*- 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. /// \file
  10. /// This file defines all of the WebAssembly-specific intrinsics.
  11. ///
  12. //===----------------------------------------------------------------------===//
  13. let TargetPrefix = "wasm" in { // All intrinsics start with "llvm.wasm.".
  14. // Query the current memory size, and increase the current memory size.
  15. // Note that memory.size is not IntrNoMem because it must be sequenced with
  16. // respect to memory.grow calls.
  17. def int_wasm_memory_size : Intrinsic<[llvm_anyint_ty],
  18. [llvm_i32_ty],
  19. [IntrReadMem]>;
  20. def int_wasm_memory_grow : Intrinsic<[llvm_anyint_ty],
  21. [llvm_i32_ty, LLVMMatchType<0>],
  22. []>;
  23. //===----------------------------------------------------------------------===//
  24. // Trapping float-to-int conversions
  25. //===----------------------------------------------------------------------===//
  26. def int_wasm_trunc_signed : Intrinsic<[llvm_anyint_ty],
  27. [llvm_anyfloat_ty],
  28. [IntrNoMem]>;
  29. def int_wasm_trunc_unsigned : Intrinsic<[llvm_anyint_ty],
  30. [llvm_anyfloat_ty],
  31. [IntrNoMem]>;
  32. //===----------------------------------------------------------------------===//
  33. // Saturating float-to-int conversions
  34. //===----------------------------------------------------------------------===//
  35. def int_wasm_trunc_saturate_signed : Intrinsic<[llvm_anyint_ty],
  36. [llvm_anyfloat_ty],
  37. [IntrNoMem, IntrSpeculatable]>;
  38. def int_wasm_trunc_saturate_unsigned : Intrinsic<[llvm_anyint_ty],
  39. [llvm_anyfloat_ty],
  40. [IntrNoMem, IntrSpeculatable]>;
  41. //===----------------------------------------------------------------------===//
  42. // Exception handling intrinsics
  43. //===----------------------------------------------------------------------===//
  44. // throw / rethrow
  45. // The immediate argument is an index to a tag, which is 0 for C++.
  46. def int_wasm_throw : Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty],
  47. [Throws, IntrNoReturn, ImmArg<ArgIndex<0>>]>;
  48. def int_wasm_rethrow : Intrinsic<[], [], [Throws, IntrNoReturn]>;
  49. // Since wasm does not use landingpad instructions, these instructions return
  50. // exception pointer and selector values until we lower them in WasmEHPrepare.
  51. def int_wasm_get_exception : Intrinsic<[llvm_ptr_ty], [llvm_token_ty],
  52. [IntrHasSideEffects]>;
  53. def int_wasm_get_ehselector : Intrinsic<[llvm_i32_ty], [llvm_token_ty],
  54. [IntrHasSideEffects]>;
  55. // wasm.catch returns the pointer to the exception object caught by wasm 'catch'
  56. // instruction. This returns a single pointer, which is sufficient for C++
  57. // support. The immediate argument is an index to for a tag, which is 0 for C++.
  58. def int_wasm_catch : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty],
  59. [IntrHasSideEffects, ImmArg<ArgIndex<0>>]>;
  60. // WebAssembly EH must maintain the landingpads in the order assigned to them
  61. // by WasmEHPrepare pass to generate landingpad table in EHStreamer. This is
  62. // used in order to give them the indices in WasmEHPrepare.
  63. def int_wasm_landingpad_index: Intrinsic<[], [llvm_token_ty, llvm_i32_ty],
  64. [IntrNoMem, ImmArg<ArgIndex<1>>]>;
  65. // Returns LSDA address of the current function.
  66. def int_wasm_lsda : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
  67. //===----------------------------------------------------------------------===//
  68. // Atomic intrinsics
  69. //===----------------------------------------------------------------------===//
  70. // wait / notify
  71. def int_wasm_memory_atomic_wait32 :
  72. Intrinsic<[llvm_i32_ty],
  73. [LLVMPointerType<llvm_i32_ty>, llvm_i32_ty, llvm_i64_ty],
  74. [IntrInaccessibleMemOrArgMemOnly, ReadOnly<ArgIndex<0>>,
  75. NoCapture<ArgIndex<0>>, IntrHasSideEffects],
  76. "", [SDNPMemOperand]>;
  77. def int_wasm_memory_atomic_wait64 :
  78. Intrinsic<[llvm_i32_ty],
  79. [LLVMPointerType<llvm_i64_ty>, llvm_i64_ty, llvm_i64_ty],
  80. [IntrInaccessibleMemOrArgMemOnly, ReadOnly<ArgIndex<0>>,
  81. NoCapture<ArgIndex<0>>, IntrHasSideEffects],
  82. "", [SDNPMemOperand]>;
  83. def int_wasm_memory_atomic_notify:
  84. Intrinsic<[llvm_i32_ty], [LLVMPointerType<llvm_i32_ty>, llvm_i32_ty],
  85. [IntrInaccessibleMemOnly, NoCapture<ArgIndex<0>>,
  86. IntrHasSideEffects],
  87. "", [SDNPMemOperand]>;
  88. //===----------------------------------------------------------------------===//
  89. // SIMD intrinsics
  90. //===----------------------------------------------------------------------===//
  91. def int_wasm_swizzle :
  92. Intrinsic<[llvm_v16i8_ty],
  93. [llvm_v16i8_ty, llvm_v16i8_ty],
  94. [IntrNoMem, IntrSpeculatable]>;
  95. def int_wasm_shuffle :
  96. Intrinsic<[llvm_v16i8_ty],
  97. [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty, llvm_i32_ty,
  98. llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
  99. llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
  100. llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
  101. [IntrNoMem, IntrSpeculatable]>;
  102. def int_wasm_sub_saturate_signed :
  103. Intrinsic<[llvm_anyvector_ty],
  104. [LLVMMatchType<0>, LLVMMatchType<0>],
  105. [IntrNoMem, IntrSpeculatable]>;
  106. def int_wasm_sub_saturate_unsigned :
  107. Intrinsic<[llvm_anyvector_ty],
  108. [LLVMMatchType<0>, LLVMMatchType<0>],
  109. [IntrNoMem, IntrSpeculatable]>;
  110. def int_wasm_avgr_unsigned :
  111. Intrinsic<[llvm_anyvector_ty],
  112. [LLVMMatchType<0>, LLVMMatchType<0>],
  113. [IntrNoMem, IntrSpeculatable]>;
  114. def int_wasm_bitselect :
  115. Intrinsic<[llvm_anyvector_ty],
  116. [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
  117. [IntrNoMem, IntrSpeculatable]>;
  118. def int_wasm_anytrue :
  119. Intrinsic<[llvm_i32_ty],
  120. [llvm_anyvector_ty],
  121. [IntrNoMem, IntrSpeculatable]>;
  122. def int_wasm_alltrue :
  123. Intrinsic<[llvm_i32_ty],
  124. [llvm_anyvector_ty],
  125. [IntrNoMem, IntrSpeculatable]>;
  126. def int_wasm_bitmask :
  127. Intrinsic<[llvm_i32_ty],
  128. [llvm_anyvector_ty],
  129. [IntrNoMem, IntrSpeculatable]>;
  130. def int_wasm_qfma :
  131. Intrinsic<[llvm_anyvector_ty],
  132. [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
  133. [IntrNoMem, IntrSpeculatable]>;
  134. def int_wasm_qfms :
  135. Intrinsic<[llvm_anyvector_ty],
  136. [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
  137. [IntrNoMem, IntrSpeculatable]>;
  138. def int_wasm_dot :
  139. Intrinsic<[llvm_v4i32_ty],
  140. [llvm_v8i16_ty, llvm_v8i16_ty],
  141. [IntrNoMem, IntrSpeculatable]>;
  142. def int_wasm_narrow_signed :
  143. Intrinsic<[llvm_anyvector_ty],
  144. [llvm_anyvector_ty, LLVMMatchType<1>],
  145. [IntrNoMem, IntrSpeculatable]>;
  146. def int_wasm_narrow_unsigned :
  147. Intrinsic<[llvm_anyvector_ty],
  148. [llvm_anyvector_ty, LLVMMatchType<1>],
  149. [IntrNoMem, IntrSpeculatable]>;
  150. // TODO: Replace these intrinsics with normal ISel patterns once i32x4 to i64x2
  151. // widening is merged to the proposal.
  152. def int_wasm_widen_low_signed :
  153. Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem, IntrSpeculatable]>;
  154. def int_wasm_widen_high_signed :
  155. Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem, IntrSpeculatable]>;
  156. def int_wasm_widen_low_unsigned :
  157. Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem, IntrSpeculatable]>;
  158. def int_wasm_widen_high_unsigned :
  159. Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem, IntrSpeculatable]>;
  160. def int_wasm_q15mulr_saturate_signed :
  161. Intrinsic<[llvm_v8i16_ty],
  162. [llvm_v8i16_ty, llvm_v8i16_ty],
  163. [IntrNoMem, IntrSpeculatable]>;
  164. // TODO: Replace these intrinsics with normal ISel patterns
  165. def int_wasm_pmin :
  166. Intrinsic<[llvm_anyvector_ty],
  167. [LLVMMatchType<0>, LLVMMatchType<0>],
  168. [IntrNoMem, IntrSpeculatable]>;
  169. def int_wasm_pmax :
  170. Intrinsic<[llvm_anyvector_ty],
  171. [LLVMMatchType<0>, LLVMMatchType<0>],
  172. [IntrNoMem, IntrSpeculatable]>;
  173. // TODO: Replace these instrinsics with normal ISel patterns once the
  174. // rounding instructions are merged to the proposal
  175. // (https://github.com/WebAssembly/simd/pull/232).
  176. def int_wasm_ceil :
  177. Intrinsic<[llvm_anyvector_ty],
  178. [LLVMMatchType<0>],
  179. [IntrNoMem, IntrSpeculatable]>;
  180. def int_wasm_floor :
  181. Intrinsic<[llvm_anyvector_ty],
  182. [LLVMMatchType<0>],
  183. [IntrNoMem, IntrSpeculatable]>;
  184. def int_wasm_trunc :
  185. Intrinsic<[llvm_anyvector_ty],
  186. [LLVMMatchType<0>],
  187. [IntrNoMem, IntrSpeculatable]>;
  188. def int_wasm_nearest :
  189. Intrinsic<[llvm_anyvector_ty],
  190. [LLVMMatchType<0>],
  191. [IntrNoMem, IntrSpeculatable]>;
  192. // TODO: Replace these intrinsic with normal ISel patterns once the
  193. // load_zero instructions are merged to the proposal.
  194. def int_wasm_load32_zero :
  195. Intrinsic<[llvm_v4i32_ty],
  196. [LLVMPointerType<llvm_i32_ty>],
  197. [IntrReadMem, IntrArgMemOnly],
  198. "", [SDNPMemOperand]>;
  199. def int_wasm_load64_zero :
  200. Intrinsic<[llvm_v2i64_ty],
  201. [LLVMPointerType<llvm_i64_ty>],
  202. [IntrReadMem, IntrArgMemOnly],
  203. "", [SDNPMemOperand]>;
  204. // These intrinsics do not mark their lane index arguments as immediate because
  205. // that changes the corresponding SDNode from ISD::Constant to
  206. // ISD::TargetConstant, which would require extra complications in the ISel
  207. // tablegen patterns. TODO: Replace these intrinsic with normal ISel patterns
  208. // once the load_lane instructions are merged to the proposal.
  209. def int_wasm_load8_lane :
  210. Intrinsic<[llvm_v16i8_ty],
  211. [LLVMPointerType<llvm_i8_ty>, llvm_v16i8_ty, llvm_i32_ty],
  212. [IntrReadMem, IntrArgMemOnly],
  213. "", [SDNPMemOperand]>;
  214. def int_wasm_load16_lane :
  215. Intrinsic<[llvm_v8i16_ty],
  216. [LLVMPointerType<llvm_i16_ty>, llvm_v8i16_ty, llvm_i32_ty],
  217. [IntrReadMem, IntrArgMemOnly],
  218. "", [SDNPMemOperand]>;
  219. def int_wasm_load32_lane :
  220. Intrinsic<[llvm_v4i32_ty],
  221. [LLVMPointerType<llvm_i32_ty>, llvm_v4i32_ty, llvm_i32_ty],
  222. [IntrReadMem, IntrArgMemOnly],
  223. "", [SDNPMemOperand]>;
  224. def int_wasm_load64_lane :
  225. Intrinsic<[llvm_v2i64_ty],
  226. [LLVMPointerType<llvm_i64_ty>, llvm_v2i64_ty, llvm_i32_ty],
  227. [IntrReadMem, IntrArgMemOnly],
  228. "", [SDNPMemOperand]>;
  229. def int_wasm_store8_lane :
  230. Intrinsic<[],
  231. [LLVMPointerType<llvm_i8_ty>, llvm_v16i8_ty, llvm_i32_ty],
  232. [IntrWriteMem, IntrArgMemOnly],
  233. "", [SDNPMemOperand]>;
  234. def int_wasm_store16_lane :
  235. Intrinsic<[],
  236. [LLVMPointerType<llvm_i16_ty>, llvm_v8i16_ty, llvm_i32_ty],
  237. [IntrWriteMem, IntrArgMemOnly],
  238. "", [SDNPMemOperand]>;
  239. def int_wasm_store32_lane :
  240. Intrinsic<[],
  241. [LLVMPointerType<llvm_i32_ty>, llvm_v4i32_ty, llvm_i32_ty],
  242. [IntrWriteMem, IntrArgMemOnly],
  243. "", [SDNPMemOperand]>;
  244. def int_wasm_store64_lane :
  245. Intrinsic<[],
  246. [LLVMPointerType<llvm_i64_ty>, llvm_v2i64_ty, llvm_i32_ty],
  247. [IntrWriteMem, IntrArgMemOnly],
  248. "", [SDNPMemOperand]>;
  249. // TODO: Replace this intrinsic with normal ISel patterns once popcnt is merged
  250. // to the proposal.
  251. def int_wasm_popcnt :
  252. Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem, IntrSpeculatable]>;
  253. def int_wasm_extmul_low_signed :
  254. Intrinsic<[llvm_anyvector_ty],
  255. [LLVMSubdivide2VectorType<0>, LLVMSubdivide2VectorType<0>],
  256. [IntrNoMem, IntrSpeculatable]>;
  257. def int_wasm_extmul_high_signed :
  258. Intrinsic<[llvm_anyvector_ty],
  259. [LLVMSubdivide2VectorType<0>, LLVMSubdivide2VectorType<0>],
  260. [IntrNoMem, IntrSpeculatable]>;
  261. def int_wasm_extmul_low_unsigned :
  262. Intrinsic<[llvm_anyvector_ty],
  263. [LLVMSubdivide2VectorType<0>, LLVMSubdivide2VectorType<0>],
  264. [IntrNoMem, IntrSpeculatable]>;
  265. def int_wasm_extmul_high_unsigned :
  266. Intrinsic<[llvm_anyvector_ty],
  267. [LLVMSubdivide2VectorType<0>, LLVMSubdivide2VectorType<0>],
  268. [IntrNoMem, IntrSpeculatable]>;
  269. def int_wasm_extadd_pairwise_signed :
  270. Intrinsic<[llvm_anyvector_ty],
  271. [LLVMSubdivide2VectorType<0>],
  272. [IntrNoMem, IntrSpeculatable]>;
  273. def int_wasm_extadd_pairwise_unsigned :
  274. Intrinsic<[llvm_anyvector_ty],
  275. [LLVMSubdivide2VectorType<0>],
  276. [IntrNoMem, IntrSpeculatable]>;
  277. def int_wasm_signselect :
  278. Intrinsic<[llvm_anyvector_ty],
  279. [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
  280. [IntrNoMem, IntrSpeculatable]>;
  281. // TODO: Remove this intrinsic and the associated builtin if i64x2.eq gets
  282. // merged to the proposal.
  283. def int_wasm_eq :
  284. Intrinsic<[llvm_v2i64_ty],
  285. [llvm_v2i64_ty, llvm_v2i64_ty],
  286. [IntrNoMem, IntrSpeculatable]>;
  287. // TODO: Remove this after experiments have been run. Use the target-agnostic
  288. // int_prefetch if this becomes specified at some point.
  289. def int_wasm_prefetch_t :
  290. Intrinsic<[], [llvm_ptr_ty],
  291. [IntrInaccessibleMemOrArgMemOnly, IntrWillReturn,
  292. ReadOnly<ArgIndex<0>>, NoCapture<ArgIndex<0>>],
  293. "", [SDNPMemOperand]>;
  294. def int_wasm_prefetch_nt :
  295. Intrinsic<[], [llvm_ptr_ty],
  296. [IntrInaccessibleMemOrArgMemOnly, IntrWillReturn,
  297. ReadOnly<ArgIndex<0>>, NoCapture<ArgIndex<0>>],
  298. "", [SDNPMemOperand]>;
  299. // TODO: Remove these if possible if they are merged to the spec.
  300. def int_wasm_convert_low_signed :
  301. Intrinsic<[llvm_v2f64_ty], [llvm_v4i32_ty],
  302. [IntrNoMem, IntrSpeculatable]>;
  303. def int_wasm_convert_low_unsigned :
  304. Intrinsic<[llvm_v2f64_ty], [llvm_v4i32_ty],
  305. [IntrNoMem, IntrSpeculatable]>;
  306. def int_wasm_trunc_saturate_zero_signed :
  307. Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty],
  308. [IntrNoMem, IntrSpeculatable]>;
  309. def int_wasm_trunc_saturate_zero_unsigned :
  310. Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty],
  311. [IntrNoMem, IntrSpeculatable]>;
  312. def int_wasm_demote_zero :
  313. Intrinsic<[llvm_v4f32_ty], [llvm_v2f64_ty],
  314. [IntrNoMem, IntrSpeculatable]>;
  315. def int_wasm_promote_low :
  316. Intrinsic<[llvm_v2f64_ty], [llvm_v4f32_ty],
  317. [IntrNoMem, IntrSpeculatable]>;
  318. //===----------------------------------------------------------------------===//
  319. // Thread-local storage intrinsics
  320. //===----------------------------------------------------------------------===//
  321. def int_wasm_tls_size :
  322. Intrinsic<[llvm_anyint_ty],
  323. [],
  324. [IntrNoMem, IntrSpeculatable]>;
  325. def int_wasm_tls_align :
  326. Intrinsic<[llvm_anyint_ty],
  327. [],
  328. [IntrNoMem, IntrSpeculatable]>;
  329. def int_wasm_tls_base :
  330. Intrinsic<[llvm_ptr_ty],
  331. [],
  332. [IntrReadMem]>;
  333. } // TargetPrefix = "wasm"