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<llvm_i8_ty, 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 : Intrinsic<[llvm_anyint_ty],
23                                     [llvm_i32_ty],
24                                     [IntrReadMem]>;
25def int_wasm_memory_grow : Intrinsic<[llvm_anyint_ty],
26                                     [llvm_i32_ty, LLVMMatchType<0>],
27                                     []>;
28
29//===----------------------------------------------------------------------===//
30// ref.null intrinsics
31//===----------------------------------------------------------------------===//
32def int_wasm_ref_null_extern : Intrinsic<[llvm_externref_ty], [], [IntrNoMem]>;
33def int_wasm_ref_null_func : Intrinsic<[llvm_funcref_ty], [], [IntrNoMem]>;
34def int_wasm_ref_is_null_extern : Intrinsic<[llvm_i32_ty], [llvm_externref_ty],
35                                            [IntrNoMem], "llvm.wasm.ref.is_null.extern">;
36def int_wasm_ref_is_null_func : Intrinsic<[llvm_i32_ty], [llvm_funcref_ty],
37                                          [IntrNoMem], "llvm.wasm.ref.is_null.func">;
38
39//===----------------------------------------------------------------------===//
40// Table intrinsics
41//===----------------------------------------------------------------------===//
42// Query the current table size, and increase the current table size.
43def int_wasm_table_size : Intrinsic<[llvm_i32_ty],
44                                    [llvm_table_ty],
45                                    [IntrReadMem]>;
46def int_wasm_table_copy : Intrinsic<[],
47                                    [llvm_table_ty, llvm_table_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
48                                    []>;
49def int_wasm_table_grow_externref : Intrinsic<[llvm_i32_ty],
50                                              [llvm_table_ty, llvm_externref_ty, llvm_i32_ty],
51                                              []>;
52def int_wasm_table_grow_funcref : Intrinsic<[llvm_i32_ty],
53                                            [llvm_table_ty, llvm_funcref_ty, llvm_i32_ty],
54                                            []>;
55def int_wasm_table_fill_externref : Intrinsic<[],
56                                              [llvm_table_ty, llvm_i32_ty, llvm_externref_ty, llvm_i32_ty],
57                                              []>;
58def int_wasm_table_fill_funcref : Intrinsic<[],
59                                            [llvm_table_ty, llvm_i32_ty, llvm_funcref_ty, llvm_i32_ty],
60                                            []>;
61
62//===----------------------------------------------------------------------===//
63// Trapping float-to-int conversions
64//===----------------------------------------------------------------------===//
65
66def int_wasm_trunc_signed : Intrinsic<[llvm_anyint_ty],
67                                      [llvm_anyfloat_ty],
68                                      [IntrNoMem]>;
69def int_wasm_trunc_unsigned : Intrinsic<[llvm_anyint_ty],
70                                        [llvm_anyfloat_ty],
71                                        [IntrNoMem]>;
72
73//===----------------------------------------------------------------------===//
74// Saturating float-to-int conversions
75//===----------------------------------------------------------------------===//
76
77def int_wasm_trunc_saturate_signed : Intrinsic<[llvm_anyint_ty],
78                                               [llvm_anyfloat_ty],
79                                               [IntrNoMem, IntrSpeculatable]>;
80def int_wasm_trunc_saturate_unsigned : Intrinsic<[llvm_anyint_ty],
81                                                 [llvm_anyfloat_ty],
82                                                 [IntrNoMem, IntrSpeculatable]>;
83
84//===----------------------------------------------------------------------===//
85// Exception handling intrinsics
86//===----------------------------------------------------------------------===//
87
88// throw / rethrow
89// The first immediate argument is an index to a tag, which is 0 for C++
90// exception. The second argument is the thrown exception pointer.
91def int_wasm_throw : Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty],
92                               [Throws, IntrNoReturn, ImmArg<ArgIndex<0>>]>;
93def int_wasm_rethrow : Intrinsic<[], [], [Throws, IntrNoReturn]>;
94
95// Since wasm does not use landingpad instructions, these instructions return
96// exception pointer and selector values until we lower them in WasmEHPrepare.
97def int_wasm_get_exception : Intrinsic<[llvm_ptr_ty], [llvm_token_ty],
98                                       [IntrHasSideEffects]>;
99def int_wasm_get_ehselector : Intrinsic<[llvm_i32_ty], [llvm_token_ty],
100                                        [IntrHasSideEffects]>;
101
102// wasm.catch returns the pointer to the exception object caught by wasm 'catch'
103// instruction. This returns a single pointer, which is the case for C++
104// exceptions. The immediate argument is an index to for a tag, which is 0 for
105// C++ exceptions.
106def int_wasm_catch : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty],
107                               [IntrHasSideEffects, ImmArg<ArgIndex<0>>]>;
108
109// WebAssembly EH must maintain the landingpads in the order assigned to them
110// by WasmEHPrepare pass to generate landingpad table in EHStreamer. This is
111// used in order to give them the indices in WasmEHPrepare.
112def int_wasm_landingpad_index: Intrinsic<[], [llvm_token_ty, llvm_i32_ty],
113                                         [IntrNoMem, ImmArg<ArgIndex<1>>]>;
114
115// Returns LSDA address of the current function.
116def int_wasm_lsda : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
117
118//===----------------------------------------------------------------------===//
119// Atomic intrinsics
120//===----------------------------------------------------------------------===//
121
122// wait / notify
123def int_wasm_memory_atomic_wait32 :
124  Intrinsic<[llvm_i32_ty],
125            [LLVMPointerType<llvm_i32_ty>, llvm_i32_ty, llvm_i64_ty],
126            [IntrInaccessibleMemOrArgMemOnly, ReadOnly<ArgIndex<0>>,
127             NoCapture<ArgIndex<0>>, IntrHasSideEffects],
128            "", [SDNPMemOperand]>;
129def int_wasm_memory_atomic_wait64 :
130  Intrinsic<[llvm_i32_ty],
131            [LLVMPointerType<llvm_i64_ty>, llvm_i64_ty, llvm_i64_ty],
132            [IntrInaccessibleMemOrArgMemOnly, ReadOnly<ArgIndex<0>>,
133             NoCapture<ArgIndex<0>>, IntrHasSideEffects],
134            "", [SDNPMemOperand]>;
135def int_wasm_memory_atomic_notify:
136  Intrinsic<[llvm_i32_ty], [LLVMPointerType<llvm_i32_ty>, llvm_i32_ty],
137            [IntrInaccessibleMemOnly, NoCapture<ArgIndex<0>>,
138             IntrHasSideEffects],
139            "", [SDNPMemOperand]>;
140
141//===----------------------------------------------------------------------===//
142// SIMD intrinsics
143//===----------------------------------------------------------------------===//
144
145def int_wasm_swizzle :
146  Intrinsic<[llvm_v16i8_ty],
147            [llvm_v16i8_ty, llvm_v16i8_ty],
148            [IntrNoMem, IntrSpeculatable]>;
149def int_wasm_shuffle :
150  Intrinsic<[llvm_v16i8_ty],
151            [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty, llvm_i32_ty,
152             llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
153             llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
154             llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
155            [IntrNoMem, IntrSpeculatable]>;
156def int_wasm_sub_sat_signed :
157  Intrinsic<[llvm_anyvector_ty],
158            [LLVMMatchType<0>, LLVMMatchType<0>],
159            [IntrNoMem, IntrSpeculatable]>;
160def int_wasm_sub_sat_unsigned :
161  Intrinsic<[llvm_anyvector_ty],
162            [LLVMMatchType<0>, LLVMMatchType<0>],
163            [IntrNoMem, IntrSpeculatable]>;
164def int_wasm_avgr_unsigned :
165  Intrinsic<[llvm_anyvector_ty],
166            [LLVMMatchType<0>, LLVMMatchType<0>],
167            [IntrNoMem, IntrSpeculatable]>;
168def int_wasm_bitselect :
169  Intrinsic<[llvm_anyvector_ty],
170            [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
171            [IntrNoMem, IntrSpeculatable]>;
172def int_wasm_anytrue :
173  Intrinsic<[llvm_i32_ty],
174            [llvm_anyvector_ty],
175            [IntrNoMem, IntrSpeculatable]>;
176def int_wasm_alltrue :
177  Intrinsic<[llvm_i32_ty],
178            [llvm_anyvector_ty],
179            [IntrNoMem, IntrSpeculatable]>;
180def int_wasm_bitmask :
181  Intrinsic<[llvm_i32_ty],
182            [llvm_anyvector_ty],
183            [IntrNoMem, IntrSpeculatable]>;
184def int_wasm_dot :
185  Intrinsic<[llvm_v4i32_ty],
186            [llvm_v8i16_ty, llvm_v8i16_ty],
187            [IntrNoMem, IntrSpeculatable]>;
188
189def int_wasm_narrow_signed :
190  Intrinsic<[llvm_anyvector_ty],
191            [llvm_anyvector_ty, LLVMMatchType<1>],
192            [IntrNoMem, IntrSpeculatable]>;
193def int_wasm_narrow_unsigned :
194  Intrinsic<[llvm_anyvector_ty],
195            [llvm_anyvector_ty, LLVMMatchType<1>],
196            [IntrNoMem, IntrSpeculatable]>;
197
198def int_wasm_q15mulr_sat_signed :
199  Intrinsic<[llvm_v8i16_ty],
200            [llvm_v8i16_ty, llvm_v8i16_ty],
201            [IntrNoMem, IntrSpeculatable]>;
202
203def int_wasm_pmin :
204  Intrinsic<[llvm_anyvector_ty],
205            [LLVMMatchType<0>, LLVMMatchType<0>],
206            [IntrNoMem, IntrSpeculatable]>;
207def int_wasm_pmax :
208  Intrinsic<[llvm_anyvector_ty],
209            [LLVMMatchType<0>, LLVMMatchType<0>],
210            [IntrNoMem, IntrSpeculatable]>;
211
212def int_wasm_extadd_pairwise_signed :
213  Intrinsic<[llvm_anyvector_ty],
214            [LLVMSubdivide2VectorType<0>],
215            [IntrNoMem, IntrSpeculatable]>;
216def int_wasm_extadd_pairwise_unsigned :
217  Intrinsic<[llvm_anyvector_ty],
218            [LLVMSubdivide2VectorType<0>],
219            [IntrNoMem, IntrSpeculatable]>;
220
221//===----------------------------------------------------------------------===//
222// Relaxed SIMD intrinsics (experimental)
223//===----------------------------------------------------------------------===//
224
225def int_wasm_fma :
226  Intrinsic<[llvm_anyvector_ty],
227            [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
228            [IntrNoMem, IntrSpeculatable]>;
229def int_wasm_fms :
230  Intrinsic<[llvm_anyvector_ty],
231            [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
232            [IntrNoMem, IntrSpeculatable]>;
233
234def int_wasm_laneselect :
235  Intrinsic<[llvm_anyvector_ty],
236            [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
237            [IntrNoMem, IntrSpeculatable]>;
238
239def int_wasm_relaxed_swizzle :
240  Intrinsic<[llvm_v16i8_ty],
241            [llvm_v16i8_ty, llvm_v16i8_ty],
242            [IntrNoMem, IntrSpeculatable]>;
243
244def int_wasm_relaxed_min :
245  Intrinsic<[llvm_anyvector_ty],
246            [LLVMMatchType<0>, LLVMMatchType<0>],
247            [IntrNoMem, IntrSpeculatable]>;
248def int_wasm_relaxed_max :
249  Intrinsic<[llvm_anyvector_ty],
250            [LLVMMatchType<0>, LLVMMatchType<0>],
251            [IntrNoMem, IntrSpeculatable]>;
252
253def int_wasm_relaxed_trunc_signed:
254  Intrinsic<[llvm_v4i32_ty],
255            [llvm_v4f32_ty],
256            [IntrNoMem, IntrSpeculatable]>;
257
258def int_wasm_relaxed_trunc_unsigned:
259  Intrinsic<[llvm_v4i32_ty],
260            [llvm_v4f32_ty],
261            [IntrNoMem, IntrSpeculatable]>;
262
263def int_wasm_relaxed_trunc_signed_zero:
264  Intrinsic<[llvm_v4i32_ty],
265            [llvm_v2f64_ty],
266            [IntrNoMem, IntrSpeculatable]>;
267
268def int_wasm_relaxed_trunc_unsigned_zero:
269  Intrinsic<[llvm_v4i32_ty],
270            [llvm_v2f64_ty],
271            [IntrNoMem, IntrSpeculatable]>;
272
273def int_wasm_relaxed_q15mulr_signed:
274  Intrinsic<[llvm_v8i16_ty],
275            [llvm_v8i16_ty, llvm_v8i16_ty],
276            [IntrNoMem, IntrSpeculatable]>;
277
278def int_wasm_dot_i8x16_i7x16_signed:
279  Intrinsic<[llvm_v8i16_ty],
280            [llvm_v16i8_ty, llvm_v16i8_ty],
281            [IntrNoMem, IntrSpeculatable]>;
282
283def int_wasm_dot_i8x16_i7x16_add_signed:
284  Intrinsic<[llvm_v4i32_ty],
285            [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v4i32_ty],
286            [IntrNoMem, IntrSpeculatable]>;
287
288//===----------------------------------------------------------------------===//
289// Thread-local storage intrinsics
290//===----------------------------------------------------------------------===//
291
292def int_wasm_tls_size :
293  Intrinsic<[llvm_anyint_ty],
294            [],
295            [IntrNoMem, IntrSpeculatable]>;
296
297def int_wasm_tls_align :
298  Intrinsic<[llvm_anyint_ty],
299            [],
300            [IntrNoMem, IntrSpeculatable]>;
301
302def int_wasm_tls_base :
303  Intrinsic<[llvm_ptr_ty],
304            [],
305            [IntrReadMem]>;
306
307} // TargetPrefix = "wasm"
308