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