xref: /llvm-project/llvm/include/llvm/IR/IntrinsicsWebAssembly.td (revision f8f0a266e0c26cd940ccba9542aec4b5efed9821)
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