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