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_sat_signed : 119 Intrinsic<[llvm_anyvector_ty], 120 [LLVMMatchType<0>, LLVMMatchType<0>], 121 [IntrNoMem, IntrSpeculatable]>; 122def int_wasm_sub_sat_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_dot : 147 Intrinsic<[llvm_v4i32_ty], 148 [llvm_v8i16_ty, llvm_v8i16_ty], 149 [IntrNoMem, IntrSpeculatable]>; 150 151def int_wasm_narrow_signed : 152 Intrinsic<[llvm_anyvector_ty], 153 [llvm_anyvector_ty, LLVMMatchType<1>], 154 [IntrNoMem, IntrSpeculatable]>; 155def int_wasm_narrow_unsigned : 156 Intrinsic<[llvm_anyvector_ty], 157 [llvm_anyvector_ty, LLVMMatchType<1>], 158 [IntrNoMem, IntrSpeculatable]>; 159 160def int_wasm_q15mulr_sat_signed : 161 Intrinsic<[llvm_v8i16_ty], 162 [llvm_v8i16_ty, llvm_v8i16_ty], 163 [IntrNoMem, IntrSpeculatable]>; 164 165// TODO: Replace these intrinsics with normal ISel patterns 166def int_wasm_pmin : 167 Intrinsic<[llvm_anyvector_ty], 168 [LLVMMatchType<0>, LLVMMatchType<0>], 169 [IntrNoMem, IntrSpeculatable]>; 170def int_wasm_pmax : 171 Intrinsic<[llvm_anyvector_ty], 172 [LLVMMatchType<0>, LLVMMatchType<0>], 173 [IntrNoMem, IntrSpeculatable]>; 174 175// TODO: Replace these intrinsic with normal ISel patterns once the 176// load_zero instructions are merged to the proposal. 177def int_wasm_load32_zero : 178 Intrinsic<[llvm_v4i32_ty], 179 [LLVMPointerType<llvm_i32_ty>], 180 [IntrReadMem, IntrArgMemOnly], 181 "", [SDNPMemOperand]>; 182 183def int_wasm_load64_zero : 184 Intrinsic<[llvm_v2i64_ty], 185 [LLVMPointerType<llvm_i64_ty>], 186 [IntrReadMem, IntrArgMemOnly], 187 "", [SDNPMemOperand]>; 188 189// These intrinsics do not mark their lane index arguments as immediate because 190// that changes the corresponding SDNode from ISD::Constant to 191// ISD::TargetConstant, which would require extra complications in the ISel 192// tablegen patterns. TODO: Replace these intrinsic with normal ISel patterns 193// once the load_lane instructions are merged to the proposal. 194def int_wasm_load8_lane : 195 Intrinsic<[llvm_v16i8_ty], 196 [LLVMPointerType<llvm_i8_ty>, llvm_v16i8_ty, llvm_i32_ty], 197 [IntrReadMem, IntrArgMemOnly], 198 "", [SDNPMemOperand]>; 199def int_wasm_load16_lane : 200 Intrinsic<[llvm_v8i16_ty], 201 [LLVMPointerType<llvm_i16_ty>, llvm_v8i16_ty, llvm_i32_ty], 202 [IntrReadMem, IntrArgMemOnly], 203 "", [SDNPMemOperand]>; 204def int_wasm_load32_lane : 205 Intrinsic<[llvm_v4i32_ty], 206 [LLVMPointerType<llvm_i32_ty>, llvm_v4i32_ty, llvm_i32_ty], 207 [IntrReadMem, IntrArgMemOnly], 208 "", [SDNPMemOperand]>; 209def int_wasm_load64_lane : 210 Intrinsic<[llvm_v2i64_ty], 211 [LLVMPointerType<llvm_i64_ty>, llvm_v2i64_ty, llvm_i32_ty], 212 [IntrReadMem, IntrArgMemOnly], 213 "", [SDNPMemOperand]>; 214def int_wasm_store8_lane : 215 Intrinsic<[], 216 [LLVMPointerType<llvm_i8_ty>, llvm_v16i8_ty, llvm_i32_ty], 217 [IntrWriteMem, IntrArgMemOnly], 218 "", [SDNPMemOperand]>; 219def int_wasm_store16_lane : 220 Intrinsic<[], 221 [LLVMPointerType<llvm_i16_ty>, llvm_v8i16_ty, llvm_i32_ty], 222 [IntrWriteMem, IntrArgMemOnly], 223 "", [SDNPMemOperand]>; 224def int_wasm_store32_lane : 225 Intrinsic<[], 226 [LLVMPointerType<llvm_i32_ty>, llvm_v4i32_ty, llvm_i32_ty], 227 [IntrWriteMem, IntrArgMemOnly], 228 "", [SDNPMemOperand]>; 229def int_wasm_store64_lane : 230 Intrinsic<[], 231 [LLVMPointerType<llvm_i64_ty>, llvm_v2i64_ty, llvm_i32_ty], 232 [IntrWriteMem, IntrArgMemOnly], 233 "", [SDNPMemOperand]>; 234 235// TODO: Replace this intrinsic with normal ISel patterns once popcnt is merged 236// to the proposal. 237def int_wasm_popcnt : 238 Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem, IntrSpeculatable]>; 239 240def int_wasm_extmul_low_signed : 241 Intrinsic<[llvm_anyvector_ty], 242 [LLVMSubdivide2VectorType<0>, LLVMSubdivide2VectorType<0>], 243 [IntrNoMem, IntrSpeculatable]>; 244def int_wasm_extmul_high_signed : 245 Intrinsic<[llvm_anyvector_ty], 246 [LLVMSubdivide2VectorType<0>, LLVMSubdivide2VectorType<0>], 247 [IntrNoMem, IntrSpeculatable]>; 248def int_wasm_extmul_low_unsigned : 249 Intrinsic<[llvm_anyvector_ty], 250 [LLVMSubdivide2VectorType<0>, LLVMSubdivide2VectorType<0>], 251 [IntrNoMem, IntrSpeculatable]>; 252def int_wasm_extmul_high_unsigned : 253 Intrinsic<[llvm_anyvector_ty], 254 [LLVMSubdivide2VectorType<0>, LLVMSubdivide2VectorType<0>], 255 [IntrNoMem, IntrSpeculatable]>; 256 257def int_wasm_extadd_pairwise_signed : 258 Intrinsic<[llvm_anyvector_ty], 259 [LLVMSubdivide2VectorType<0>], 260 [IntrNoMem, IntrSpeculatable]>; 261def int_wasm_extadd_pairwise_unsigned : 262 Intrinsic<[llvm_anyvector_ty], 263 [LLVMSubdivide2VectorType<0>], 264 [IntrNoMem, IntrSpeculatable]>; 265 266// TODO: Remove these if possible if they are merged to the spec. 267def int_wasm_demote_zero : 268 Intrinsic<[llvm_v4f32_ty], [llvm_v2f64_ty], 269 [IntrNoMem, IntrSpeculatable]>; 270def int_wasm_promote_low : 271 Intrinsic<[llvm_v2f64_ty], [llvm_v4f32_ty], 272 [IntrNoMem, IntrSpeculatable]>; 273 274//===----------------------------------------------------------------------===// 275// Thread-local storage intrinsics 276//===----------------------------------------------------------------------===// 277 278def int_wasm_tls_size : 279 Intrinsic<[llvm_anyint_ty], 280 [], 281 [IntrNoMem, IntrSpeculatable]>; 282 283def int_wasm_tls_align : 284 Intrinsic<[llvm_anyint_ty], 285 [], 286 [IntrNoMem, IntrSpeculatable]>; 287 288def int_wasm_tls_base : 289 Intrinsic<[llvm_ptr_ty], 290 [], 291 [IntrReadMem]>; 292 293} // TargetPrefix = "wasm" 294