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//===----------------------------------------------------------------------===//
326// Thread-local storage intrinsics
327//===----------------------------------------------------------------------===//
328
329def int_wasm_tls_size :
330  DefaultAttrsIntrinsic<[llvm_anyint_ty],
331                        [],
332                        [IntrNoMem, IntrSpeculatable]>;
333
334def int_wasm_tls_align :
335  DefaultAttrsIntrinsic<[llvm_anyint_ty],
336                        [],
337                        [IntrNoMem, IntrSpeculatable]>;
338
339def int_wasm_tls_base :
340  DefaultAttrsIntrinsic<[llvm_ptr_ty],
341                        [],
342                        [IntrReadMem]>;
343
344} // TargetPrefix = "wasm"
345