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