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 14// Type definition for a table in an intrinsic 15def llvm_table_ty : LLVMQualPointerType<1>; 16 17let TargetPrefix = "wasm" in { // All intrinsics start with "llvm.wasm.". 18 19// Query the current memory size, and increase the current memory size. 20// Note that memory.size is not IntrNoMem because it must be sequenced with 21// respect to memory.grow calls. 22def int_wasm_memory_size : 23 DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_i32_ty], [IntrReadMem]>; 24def int_wasm_memory_grow : 25 DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_i32_ty, LLVMMatchType<0>], []>; 26 27//===----------------------------------------------------------------------===// 28// ref.null intrinsics 29//===----------------------------------------------------------------------===// 30def int_wasm_ref_null_extern : 31 DefaultAttrsIntrinsic<[llvm_externref_ty], [], [IntrNoMem]>; 32def int_wasm_ref_null_func : 33 DefaultAttrsIntrinsic<[llvm_funcref_ty], [], [IntrNoMem]>; 34def int_wasm_ref_null_exn: 35 DefaultAttrsIntrinsic<[llvm_exnref_ty], [], [IntrNoMem]>; 36def int_wasm_ref_is_null_extern : 37 DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_externref_ty], [IntrNoMem], 38 "llvm.wasm.ref.is_null.extern">; 39def int_wasm_ref_is_null_func : 40 DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_funcref_ty], 41 [IntrNoMem], "llvm.wasm.ref.is_null.func">; 42def int_wasm_ref_is_null_exn : 43 DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_exnref_ty], [IntrNoMem], 44 "llvm.wasm.ref.is_null.exn">; 45 46//===----------------------------------------------------------------------===// 47// Table intrinsics 48//===----------------------------------------------------------------------===// 49def int_wasm_table_set_externref : 50 DefaultAttrsIntrinsic<[], [llvm_table_ty, llvm_i32_ty, llvm_externref_ty], 51 [IntrWriteMem]>; 52def int_wasm_table_set_funcref : 53 DefaultAttrsIntrinsic<[], [llvm_table_ty, llvm_i32_ty, llvm_funcref_ty], 54 [IntrWriteMem]>; 55def int_wasm_table_set_exnref : 56 DefaultAttrsIntrinsic<[], [llvm_table_ty, llvm_i32_ty, llvm_exnref_ty], 57 [IntrWriteMem]>; 58 59def int_wasm_table_get_externref : 60 DefaultAttrsIntrinsic<[llvm_externref_ty], [llvm_table_ty, llvm_i32_ty], 61 [IntrReadMem]>; 62def int_wasm_table_get_funcref : 63 DefaultAttrsIntrinsic<[llvm_funcref_ty], [llvm_table_ty, llvm_i32_ty], 64 [IntrReadMem]>; 65def int_wasm_table_get_exnref : 66 DefaultAttrsIntrinsic<[llvm_exnref_ty], [llvm_table_ty, llvm_i32_ty], 67 [IntrReadMem]>; 68 69// Query the current table size, and increase the current table size. 70def int_wasm_table_size : 71 DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_table_ty], [IntrReadMem]>; 72def int_wasm_table_copy : 73 DefaultAttrsIntrinsic<[], 74 [llvm_table_ty, llvm_table_ty, llvm_i32_ty, llvm_i32_ty, 75 llvm_i32_ty], []>; 76def int_wasm_table_grow_externref : 77 DefaultAttrsIntrinsic<[llvm_i32_ty], 78 [llvm_table_ty, llvm_externref_ty, llvm_i32_ty], []>; 79def int_wasm_table_grow_funcref : 80 DefaultAttrsIntrinsic<[llvm_i32_ty], 81 [llvm_table_ty, llvm_funcref_ty, llvm_i32_ty], []>; 82def int_wasm_table_grow_exnref : 83 DefaultAttrsIntrinsic<[llvm_i32_ty], 84 [llvm_table_ty, llvm_exnref_ty, llvm_i32_ty], []>; 85def int_wasm_table_fill_externref : 86 DefaultAttrsIntrinsic<[], 87 [llvm_table_ty, llvm_i32_ty, llvm_externref_ty, 88 llvm_i32_ty], []>; 89def int_wasm_table_fill_funcref : 90 DefaultAttrsIntrinsic<[], 91 [llvm_table_ty, llvm_i32_ty, llvm_funcref_ty, 92 llvm_i32_ty], []>; 93def int_wasm_table_fill_exnref : 94 DefaultAttrsIntrinsic<[], 95 [llvm_table_ty, llvm_i32_ty, llvm_exnref_ty, 96 llvm_i32_ty], []>; 97 98//===----------------------------------------------------------------------===// 99// Trapping float-to-int conversions 100//===----------------------------------------------------------------------===// 101 102// These don't use default attributes, because they are not willreturn. 103def int_wasm_trunc_signed : Intrinsic<[llvm_anyint_ty], 104 [llvm_anyfloat_ty], 105 [IntrNoMem]>; 106def int_wasm_trunc_unsigned : Intrinsic<[llvm_anyint_ty], 107 [llvm_anyfloat_ty], 108 [IntrNoMem]>; 109 110//===----------------------------------------------------------------------===// 111// Saturating float-to-int conversions 112//===----------------------------------------------------------------------===// 113 114def int_wasm_trunc_saturate_signed : 115 DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty], 116 [IntrNoMem, IntrSpeculatable]>; 117def int_wasm_trunc_saturate_unsigned : 118 DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty], 119 [IntrNoMem, IntrSpeculatable]>; 120 121//===----------------------------------------------------------------------===// 122// Exception handling intrinsics 123//===----------------------------------------------------------------------===// 124 125// throw / rethrow 126// The first immediate argument is an index to a tag, which is 0 for C++ 127// exception. The second argument is the thrown exception pointer. 128def int_wasm_throw : Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty], 129 [Throws, IntrNoReturn, ImmArg<ArgIndex<0>>]>; 130def int_wasm_rethrow : Intrinsic<[], [], [Throws, IntrNoReturn]>; 131 132// Since wasm does not use landingpad instructions, these instructions return 133// exception pointer and selector values until we lower them in WasmEHPrepare. 134def int_wasm_get_exception : 135 DefaultAttrsIntrinsic<[llvm_ptr_ty], [llvm_token_ty], [IntrHasSideEffects]>; 136def int_wasm_get_ehselector : 137 DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_token_ty], [IntrHasSideEffects]>; 138 139// wasm.catch returns the pointer to the exception object caught by wasm 'catch' 140// instruction. This returns a single pointer, which is the case for C++ 141// exceptions. The immediate argument is an index to for a tag, which is 0 for 142// C++ exceptions. 143def int_wasm_catch : 144 DefaultAttrsIntrinsic<[llvm_ptr_ty], [llvm_i32_ty], 145 [IntrHasSideEffects, ImmArg<ArgIndex<0>>]>; 146 147// WebAssembly EH must maintain the landingpads in the order assigned to them 148// by WasmEHPrepare pass to generate landingpad table in EHStreamer. This is 149// used in order to give them the indices in WasmEHPrepare. 150def int_wasm_landingpad_index : 151 DefaultAttrsIntrinsic<[], [llvm_token_ty, llvm_i32_ty], 152 [IntrNoMem, ImmArg<ArgIndex<1>>]>; 153 154// Returns LSDA address of the current function. 155def int_wasm_lsda : DefaultAttrsIntrinsic<[llvm_ptr_ty], [], [IntrNoMem]>; 156 157//===----------------------------------------------------------------------===// 158// Atomic intrinsics 159//===----------------------------------------------------------------------===// 160 161// wait / notify 162// These don't use default attributes, because they are not nosync. 163def int_wasm_memory_atomic_wait32 : 164 Intrinsic<[llvm_i32_ty], 165 [llvm_ptr_ty, llvm_i32_ty, llvm_i64_ty], 166 [IntrInaccessibleMemOrArgMemOnly, ReadOnly<ArgIndex<0>>, 167 NoCapture<ArgIndex<0>>, IntrHasSideEffects], 168 "", [SDNPMemOperand]>; 169def int_wasm_memory_atomic_wait64 : 170 Intrinsic<[llvm_i32_ty], 171 [llvm_ptr_ty, llvm_i64_ty, llvm_i64_ty], 172 [IntrInaccessibleMemOrArgMemOnly, ReadOnly<ArgIndex<0>>, 173 NoCapture<ArgIndex<0>>, IntrHasSideEffects], 174 "", [SDNPMemOperand]>; 175def int_wasm_memory_atomic_notify: 176 Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty], 177 [IntrInaccessibleMemOnly, NoCapture<ArgIndex<0>>, 178 IntrHasSideEffects], 179 "", [SDNPMemOperand]>; 180 181//===----------------------------------------------------------------------===// 182// SIMD intrinsics 183//===----------------------------------------------------------------------===// 184 185def int_wasm_swizzle : 186 DefaultAttrsIntrinsic<[llvm_v16i8_ty], 187 [llvm_v16i8_ty, llvm_v16i8_ty], 188 [IntrNoMem, IntrSpeculatable]>; 189def int_wasm_shuffle : 190 DefaultAttrsIntrinsic<[llvm_v16i8_ty], 191 [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty, 192 llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, 193 llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, 194 llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, 195 llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], 196 [IntrNoMem, IntrSpeculatable, 197 ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>, 198 ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>, 199 ImmArg<ArgIndex<6>>, ImmArg<ArgIndex<7>>, 200 ImmArg<ArgIndex<8>>, ImmArg<ArgIndex<9>>, 201 ImmArg<ArgIndex<10>>, ImmArg<ArgIndex<11>>, 202 ImmArg<ArgIndex<12>>, ImmArg<ArgIndex<13>>, 203 ImmArg<ArgIndex<14>>, ImmArg<ArgIndex<15>>, 204 ImmArg<ArgIndex<16>>, ImmArg<ArgIndex<17>>]>; 205def int_wasm_avgr_unsigned : 206 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 207 [LLVMMatchType<0>, LLVMMatchType<0>], 208 [IntrNoMem, IntrSpeculatable]>; 209def int_wasm_bitselect : 210 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 211 [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], 212 [IntrNoMem, IntrSpeculatable]>; 213def int_wasm_anytrue : 214 DefaultAttrsIntrinsic<[llvm_i32_ty], 215 [llvm_anyvector_ty], 216 [IntrNoMem, IntrSpeculatable]>; 217def int_wasm_alltrue : 218 DefaultAttrsIntrinsic<[llvm_i32_ty], 219 [llvm_anyvector_ty], 220 [IntrNoMem, IntrSpeculatable]>; 221def int_wasm_bitmask : 222 DefaultAttrsIntrinsic<[llvm_i32_ty], 223 [llvm_anyvector_ty], 224 [IntrNoMem, IntrSpeculatable]>; 225def int_wasm_dot : 226 DefaultAttrsIntrinsic<[llvm_v4i32_ty], 227 [llvm_v8i16_ty, llvm_v8i16_ty], 228 [IntrNoMem, IntrSpeculatable]>; 229 230def int_wasm_narrow_signed : 231 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 232 [llvm_anyvector_ty, LLVMMatchType<1>], 233 [IntrNoMem, IntrSpeculatable]>; 234def int_wasm_narrow_unsigned : 235 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 236 [llvm_anyvector_ty, LLVMMatchType<1>], 237 [IntrNoMem, IntrSpeculatable]>; 238 239def int_wasm_q15mulr_sat_signed : 240 DefaultAttrsIntrinsic<[llvm_v8i16_ty], 241 [llvm_v8i16_ty, llvm_v8i16_ty], 242 [IntrNoMem, IntrSpeculatable]>; 243 244def int_wasm_pmin : 245 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 246 [LLVMMatchType<0>, LLVMMatchType<0>], 247 [IntrNoMem, IntrSpeculatable]>; 248def int_wasm_pmax : 249 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 250 [LLVMMatchType<0>, LLVMMatchType<0>], 251 [IntrNoMem, IntrSpeculatable]>; 252 253def int_wasm_extadd_pairwise_signed : 254 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 255 [LLVMSubdivide2VectorType<0>], 256 [IntrNoMem, IntrSpeculatable]>; 257def int_wasm_extadd_pairwise_unsigned : 258 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 259 [LLVMSubdivide2VectorType<0>], 260 [IntrNoMem, IntrSpeculatable]>; 261 262//===----------------------------------------------------------------------===// 263// Relaxed SIMD intrinsics (experimental) 264//===----------------------------------------------------------------------===// 265 266def int_wasm_relaxed_madd : 267 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 268 [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], 269 [IntrNoMem, IntrSpeculatable]>; 270def int_wasm_relaxed_nmadd : 271 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 272 [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], 273 [IntrNoMem, IntrSpeculatable]>; 274 275def int_wasm_relaxed_laneselect : 276 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 277 [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], 278 [IntrNoMem, IntrSpeculatable]>; 279 280def int_wasm_relaxed_swizzle : 281 DefaultAttrsIntrinsic<[llvm_v16i8_ty], 282 [llvm_v16i8_ty, llvm_v16i8_ty], 283 [IntrNoMem, IntrSpeculatable]>; 284 285def int_wasm_relaxed_min : 286 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 287 [LLVMMatchType<0>, LLVMMatchType<0>], 288 [IntrNoMem, IntrSpeculatable]>; 289def int_wasm_relaxed_max : 290 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 291 [LLVMMatchType<0>, LLVMMatchType<0>], 292 [IntrNoMem, IntrSpeculatable]>; 293 294def int_wasm_relaxed_trunc_signed: 295 DefaultAttrsIntrinsic<[llvm_v4i32_ty], 296 [llvm_v4f32_ty], 297 [IntrNoMem, IntrSpeculatable]>; 298 299def int_wasm_relaxed_trunc_unsigned: 300 DefaultAttrsIntrinsic<[llvm_v4i32_ty], 301 [llvm_v4f32_ty], 302 [IntrNoMem, IntrSpeculatable]>; 303 304def int_wasm_relaxed_trunc_signed_zero: 305 DefaultAttrsIntrinsic<[llvm_v4i32_ty], 306 [llvm_v2f64_ty], 307 [IntrNoMem, IntrSpeculatable]>; 308 309def int_wasm_relaxed_trunc_unsigned_zero: 310 DefaultAttrsIntrinsic<[llvm_v4i32_ty], 311 [llvm_v2f64_ty], 312 [IntrNoMem, IntrSpeculatable]>; 313 314def int_wasm_relaxed_q15mulr_signed: 315 DefaultAttrsIntrinsic<[llvm_v8i16_ty], 316 [llvm_v8i16_ty, llvm_v8i16_ty], 317 [IntrNoMem, IntrSpeculatable]>; 318 319def int_wasm_relaxed_dot_i8x16_i7x16_signed: 320 DefaultAttrsIntrinsic<[llvm_v8i16_ty], 321 [llvm_v16i8_ty, llvm_v16i8_ty], 322 [IntrNoMem, IntrSpeculatable]>; 323 324def int_wasm_relaxed_dot_i8x16_i7x16_add_signed: 325 DefaultAttrsIntrinsic<[llvm_v4i32_ty], 326 [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v4i32_ty], 327 [IntrNoMem, IntrSpeculatable]>; 328 329def int_wasm_relaxed_dot_bf16x8_add_f32: 330 DefaultAttrsIntrinsic<[llvm_v4f32_ty], 331 [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v4f32_ty], 332 [IntrNoMem, IntrSpeculatable]>; 333 334//===----------------------------------------------------------------------===// 335// Half-precision intrinsics (experimental) 336//===----------------------------------------------------------------------===// 337 338// TODO: Replace these intrinsic with normal ISel patterns once the XXX 339// instructions are merged to the proposal. 340def int_wasm_loadf16_f32: 341 DefaultAttrsIntrinsic<[llvm_float_ty], 342 [llvm_ptr_ty], 343 [IntrReadMem, IntrArgMemOnly], 344 "", [SDNPMemOperand]>; 345def int_wasm_storef16_f32: 346 Intrinsic<[], 347 [llvm_float_ty, llvm_ptr_ty], 348 [IntrWriteMem, IntrArgMemOnly], 349 "", [SDNPMemOperand]>; 350def int_wasm_splat_f16x8: 351 DefaultAttrsIntrinsic<[llvm_v8f16_ty], 352 [llvm_float_ty], 353 [IntrNoMem, IntrSpeculatable]>; 354def int_wasm_extract_lane_f16x8: 355 DefaultAttrsIntrinsic<[llvm_float_ty], 356 [llvm_v8f16_ty, llvm_i32_ty], 357 [IntrNoMem, IntrSpeculatable]>; 358def int_wasm_replace_lane_f16x8: 359 DefaultAttrsIntrinsic<[llvm_v8f16_ty], 360 [llvm_v8f16_ty, llvm_i32_ty, llvm_float_ty], 361 [IntrNoMem, IntrSpeculatable]>; 362 363 364//===----------------------------------------------------------------------===// 365// Thread-local storage intrinsics 366//===----------------------------------------------------------------------===// 367 368def int_wasm_tls_size : 369 DefaultAttrsIntrinsic<[llvm_anyint_ty], 370 [], 371 [IntrNoMem, IntrSpeculatable]>; 372 373def int_wasm_tls_align : 374 DefaultAttrsIntrinsic<[llvm_anyint_ty], 375 [], 376 [IntrNoMem, IntrSpeculatable]>; 377 378def int_wasm_tls_base : 379 DefaultAttrsIntrinsic<[llvm_ptr_ty], 380 [], 381 [IntrReadMem]>; 382 383} // TargetPrefix = "wasm" 384