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_sub_sat_signed : 206 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 207 [LLVMMatchType<0>, LLVMMatchType<0>], 208 [IntrNoMem, IntrSpeculatable]>; 209def int_wasm_sub_sat_unsigned : 210 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 211 [LLVMMatchType<0>, LLVMMatchType<0>], 212 [IntrNoMem, IntrSpeculatable]>; 213def int_wasm_avgr_unsigned : 214 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 215 [LLVMMatchType<0>, LLVMMatchType<0>], 216 [IntrNoMem, IntrSpeculatable]>; 217def int_wasm_bitselect : 218 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 219 [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], 220 [IntrNoMem, IntrSpeculatable]>; 221def int_wasm_anytrue : 222 DefaultAttrsIntrinsic<[llvm_i32_ty], 223 [llvm_anyvector_ty], 224 [IntrNoMem, IntrSpeculatable]>; 225def int_wasm_alltrue : 226 DefaultAttrsIntrinsic<[llvm_i32_ty], 227 [llvm_anyvector_ty], 228 [IntrNoMem, IntrSpeculatable]>; 229def int_wasm_bitmask : 230 DefaultAttrsIntrinsic<[llvm_i32_ty], 231 [llvm_anyvector_ty], 232 [IntrNoMem, IntrSpeculatable]>; 233def int_wasm_dot : 234 DefaultAttrsIntrinsic<[llvm_v4i32_ty], 235 [llvm_v8i16_ty, llvm_v8i16_ty], 236 [IntrNoMem, IntrSpeculatable]>; 237 238def int_wasm_narrow_signed : 239 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 240 [llvm_anyvector_ty, LLVMMatchType<1>], 241 [IntrNoMem, IntrSpeculatable]>; 242def int_wasm_narrow_unsigned : 243 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 244 [llvm_anyvector_ty, LLVMMatchType<1>], 245 [IntrNoMem, IntrSpeculatable]>; 246 247def int_wasm_q15mulr_sat_signed : 248 DefaultAttrsIntrinsic<[llvm_v8i16_ty], 249 [llvm_v8i16_ty, llvm_v8i16_ty], 250 [IntrNoMem, IntrSpeculatable]>; 251 252def int_wasm_pmin : 253 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 254 [LLVMMatchType<0>, LLVMMatchType<0>], 255 [IntrNoMem, IntrSpeculatable]>; 256def int_wasm_pmax : 257 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 258 [LLVMMatchType<0>, LLVMMatchType<0>], 259 [IntrNoMem, IntrSpeculatable]>; 260 261def int_wasm_extadd_pairwise_signed : 262 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 263 [LLVMSubdivide2VectorType<0>], 264 [IntrNoMem, IntrSpeculatable]>; 265def int_wasm_extadd_pairwise_unsigned : 266 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 267 [LLVMSubdivide2VectorType<0>], 268 [IntrNoMem, IntrSpeculatable]>; 269 270//===----------------------------------------------------------------------===// 271// Relaxed SIMD intrinsics (experimental) 272//===----------------------------------------------------------------------===// 273 274def int_wasm_relaxed_madd : 275 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 276 [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], 277 [IntrNoMem, IntrSpeculatable]>; 278def int_wasm_relaxed_nmadd : 279 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 280 [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], 281 [IntrNoMem, IntrSpeculatable]>; 282 283def int_wasm_relaxed_laneselect : 284 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 285 [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], 286 [IntrNoMem, IntrSpeculatable]>; 287 288def int_wasm_relaxed_swizzle : 289 DefaultAttrsIntrinsic<[llvm_v16i8_ty], 290 [llvm_v16i8_ty, llvm_v16i8_ty], 291 [IntrNoMem, IntrSpeculatable]>; 292 293def int_wasm_relaxed_min : 294 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 295 [LLVMMatchType<0>, LLVMMatchType<0>], 296 [IntrNoMem, IntrSpeculatable]>; 297def int_wasm_relaxed_max : 298 DefaultAttrsIntrinsic<[llvm_anyvector_ty], 299 [LLVMMatchType<0>, LLVMMatchType<0>], 300 [IntrNoMem, IntrSpeculatable]>; 301 302def int_wasm_relaxed_trunc_signed: 303 DefaultAttrsIntrinsic<[llvm_v4i32_ty], 304 [llvm_v4f32_ty], 305 [IntrNoMem, IntrSpeculatable]>; 306 307def int_wasm_relaxed_trunc_unsigned: 308 DefaultAttrsIntrinsic<[llvm_v4i32_ty], 309 [llvm_v4f32_ty], 310 [IntrNoMem, IntrSpeculatable]>; 311 312def int_wasm_relaxed_trunc_signed_zero: 313 DefaultAttrsIntrinsic<[llvm_v4i32_ty], 314 [llvm_v2f64_ty], 315 [IntrNoMem, IntrSpeculatable]>; 316 317def int_wasm_relaxed_trunc_unsigned_zero: 318 DefaultAttrsIntrinsic<[llvm_v4i32_ty], 319 [llvm_v2f64_ty], 320 [IntrNoMem, IntrSpeculatable]>; 321 322def int_wasm_relaxed_q15mulr_signed: 323 DefaultAttrsIntrinsic<[llvm_v8i16_ty], 324 [llvm_v8i16_ty, llvm_v8i16_ty], 325 [IntrNoMem, IntrSpeculatable]>; 326 327def int_wasm_relaxed_dot_i8x16_i7x16_signed: 328 DefaultAttrsIntrinsic<[llvm_v8i16_ty], 329 [llvm_v16i8_ty, llvm_v16i8_ty], 330 [IntrNoMem, IntrSpeculatable]>; 331 332def int_wasm_relaxed_dot_i8x16_i7x16_add_signed: 333 DefaultAttrsIntrinsic<[llvm_v4i32_ty], 334 [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v4i32_ty], 335 [IntrNoMem, IntrSpeculatable]>; 336 337def int_wasm_relaxed_dot_bf16x8_add_f32: 338 DefaultAttrsIntrinsic<[llvm_v4f32_ty], 339 [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v4f32_ty], 340 [IntrNoMem, IntrSpeculatable]>; 341 342//===----------------------------------------------------------------------===// 343// Half-precision intrinsics (experimental) 344//===----------------------------------------------------------------------===// 345 346// TODO: Replace these intrinsic with normal ISel patterns once the XXX 347// instructions are merged to the proposal. 348def int_wasm_loadf16_f32: 349 Intrinsic<[llvm_float_ty], 350 [llvm_ptr_ty], 351 [IntrReadMem, IntrArgMemOnly], 352 "", [SDNPMemOperand]>; 353def int_wasm_storef16_f32: 354 Intrinsic<[], 355 [llvm_float_ty, llvm_ptr_ty], 356 [IntrWriteMem, IntrArgMemOnly], 357 "", [SDNPMemOperand]>; 358def int_wasm_splat_f16x8: 359 DefaultAttrsIntrinsic<[llvm_v8f16_ty], 360 [llvm_float_ty], 361 [IntrNoMem, IntrSpeculatable]>; 362def int_wasm_extract_lane_f16x8: 363 DefaultAttrsIntrinsic<[llvm_float_ty], 364 [llvm_v8f16_ty, llvm_i32_ty], 365 [IntrNoMem, IntrSpeculatable]>; 366 367 368//===----------------------------------------------------------------------===// 369// Thread-local storage intrinsics 370//===----------------------------------------------------------------------===// 371 372def int_wasm_tls_size : 373 DefaultAttrsIntrinsic<[llvm_anyint_ty], 374 [], 375 [IntrNoMem, IntrSpeculatable]>; 376 377def int_wasm_tls_align : 378 DefaultAttrsIntrinsic<[llvm_anyint_ty], 379 [], 380 [IntrNoMem, IntrSpeculatable]>; 381 382def int_wasm_tls_base : 383 DefaultAttrsIntrinsic<[llvm_ptr_ty], 384 [], 385 [IntrReadMem]>; 386 387} // TargetPrefix = "wasm" 388