Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 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 |
||
15 | def llvm_table_ty : LLVMQualPointerType<llvm_i8_ty, 1>; |
||
16 | |||
17 | let 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. |
||
22 | def int_wasm_memory_size : |
||
23 | DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_i32_ty], [IntrReadMem]>; |
||
24 | def int_wasm_memory_grow : |
||
25 | DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_i32_ty, LLVMMatchType<0>], []>; |
||
26 | |||
27 | //===----------------------------------------------------------------------===// |
||
28 | // ref.null intrinsics |
||
29 | //===----------------------------------------------------------------------===// |
||
30 | def int_wasm_ref_null_extern : |
||
31 | DefaultAttrsIntrinsic<[llvm_externref_ty], [], [IntrNoMem]>; |
||
32 | def int_wasm_ref_null_func : |
||
33 | DefaultAttrsIntrinsic<[llvm_funcref_ty], [], [IntrNoMem]>; |
||
34 | def int_wasm_ref_is_null_extern : |
||
35 | DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_externref_ty], [IntrNoMem], |
||
36 | "llvm.wasm.ref.is_null.extern">; |
||
37 | def 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 | //===----------------------------------------------------------------------===// |
||
44 | def int_wasm_table_set_externref : |
||
45 | DefaultAttrsIntrinsic<[], [llvm_table_ty, llvm_i32_ty, llvm_externref_ty], |
||
46 | [IntrWriteMem]>; |
||
47 | def int_wasm_table_set_funcref : |
||
48 | DefaultAttrsIntrinsic<[], [llvm_table_ty, llvm_i32_ty, llvm_funcref_ty], |
||
49 | [IntrWriteMem]>; |
||
50 | |||
51 | def int_wasm_table_get_externref : |
||
52 | DefaultAttrsIntrinsic<[llvm_externref_ty], [llvm_table_ty, llvm_i32_ty], |
||
53 | [IntrReadMem]>; |
||
54 | def 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. |
||
59 | def int_wasm_table_size : |
||
60 | DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_table_ty], [IntrReadMem]>; |
||
61 | def int_wasm_table_copy : |
||
62 | DefaultAttrsIntrinsic<[], |
||
63 | [llvm_table_ty, llvm_table_ty, llvm_i32_ty, llvm_i32_ty, |
||
64 | llvm_i32_ty], []>; |
||
65 | def int_wasm_table_grow_externref : |
||
66 | DefaultAttrsIntrinsic<[llvm_i32_ty], |
||
67 | [llvm_table_ty, llvm_externref_ty, llvm_i32_ty], []>; |
||
68 | def int_wasm_table_grow_funcref : |
||
69 | DefaultAttrsIntrinsic<[llvm_i32_ty], |
||
70 | [llvm_table_ty, llvm_funcref_ty, llvm_i32_ty], []>; |
||
71 | def int_wasm_table_fill_externref : |
||
72 | DefaultAttrsIntrinsic<[], |
||
73 | [llvm_table_ty, llvm_i32_ty, llvm_externref_ty, |
||
74 | llvm_i32_ty], []>; |
||
75 | def 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. |
||
85 | def int_wasm_trunc_signed : Intrinsic<[llvm_anyint_ty], |
||
86 | [llvm_anyfloat_ty], |
||
87 | [IntrNoMem]>; |
||
88 | def int_wasm_trunc_unsigned : Intrinsic<[llvm_anyint_ty], |
||
89 | [llvm_anyfloat_ty], |
||
90 | [IntrNoMem]>; |
||
91 | |||
92 | //===----------------------------------------------------------------------===// |
||
93 | // Saturating float-to-int conversions |
||
94 | //===----------------------------------------------------------------------===// |
||
95 | |||
96 | def int_wasm_trunc_saturate_signed : |
||
97 | DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty], |
||
98 | [IntrNoMem, IntrSpeculatable]>; |
||
99 | def 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. |
||
110 | def int_wasm_throw : Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty], |
||
111 | [Throws, IntrNoReturn, ImmArg<ArgIndex<0>>]>; |
||
112 | def 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. |
||
116 | def int_wasm_get_exception : |
||
117 | DefaultAttrsIntrinsic<[llvm_ptr_ty], [llvm_token_ty], [IntrHasSideEffects]>; |
||
118 | def 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. |
||
125 | def 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. |
||
132 | def 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. |
||
137 | def 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. |
||
145 | def int_wasm_memory_atomic_wait32 : |
||
146 | Intrinsic<[llvm_i32_ty], |
||
147 | [LLVMPointerType<llvm_i32_ty>, llvm_i32_ty, llvm_i64_ty], |
||
148 | [IntrInaccessibleMemOrArgMemOnly, ReadOnly<ArgIndex<0>>, |
||
149 | NoCapture<ArgIndex<0>>, IntrHasSideEffects], |
||
150 | "", [SDNPMemOperand]>; |
||
151 | def int_wasm_memory_atomic_wait64 : |
||
152 | Intrinsic<[llvm_i32_ty], |
||
153 | [LLVMPointerType<llvm_i64_ty>, llvm_i64_ty, llvm_i64_ty], |
||
154 | [IntrInaccessibleMemOrArgMemOnly, ReadOnly<ArgIndex<0>>, |
||
155 | NoCapture<ArgIndex<0>>, IntrHasSideEffects], |
||
156 | "", [SDNPMemOperand]>; |
||
157 | def int_wasm_memory_atomic_notify: |
||
158 | Intrinsic<[llvm_i32_ty], [LLVMPointerType<llvm_i32_ty>, llvm_i32_ty], |
||
159 | [IntrInaccessibleMemOnly, NoCapture<ArgIndex<0>>, |
||
160 | IntrHasSideEffects], |
||
161 | "", [SDNPMemOperand]>; |
||
162 | |||
163 | //===----------------------------------------------------------------------===// |
||
164 | // SIMD intrinsics |
||
165 | //===----------------------------------------------------------------------===// |
||
166 | |||
167 | def int_wasm_swizzle : |
||
168 | DefaultAttrsIntrinsic<[llvm_v16i8_ty], |
||
169 | [llvm_v16i8_ty, llvm_v16i8_ty], |
||
170 | [IntrNoMem, IntrSpeculatable]>; |
||
171 | def 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 | def int_wasm_sub_sat_signed : |
||
180 | DefaultAttrsIntrinsic<[llvm_anyvector_ty], |
||
181 | [LLVMMatchType<0>, LLVMMatchType<0>], |
||
182 | [IntrNoMem, IntrSpeculatable]>; |
||
183 | def int_wasm_sub_sat_unsigned : |
||
184 | DefaultAttrsIntrinsic<[llvm_anyvector_ty], |
||
185 | [LLVMMatchType<0>, LLVMMatchType<0>], |
||
186 | [IntrNoMem, IntrSpeculatable]>; |
||
187 | def int_wasm_avgr_unsigned : |
||
188 | DefaultAttrsIntrinsic<[llvm_anyvector_ty], |
||
189 | [LLVMMatchType<0>, LLVMMatchType<0>], |
||
190 | [IntrNoMem, IntrSpeculatable]>; |
||
191 | def int_wasm_bitselect : |
||
192 | DefaultAttrsIntrinsic<[llvm_anyvector_ty], |
||
193 | [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], |
||
194 | [IntrNoMem, IntrSpeculatable]>; |
||
195 | def int_wasm_anytrue : |
||
196 | DefaultAttrsIntrinsic<[llvm_i32_ty], |
||
197 | [llvm_anyvector_ty], |
||
198 | [IntrNoMem, IntrSpeculatable]>; |
||
199 | def int_wasm_alltrue : |
||
200 | DefaultAttrsIntrinsic<[llvm_i32_ty], |
||
201 | [llvm_anyvector_ty], |
||
202 | [IntrNoMem, IntrSpeculatable]>; |
||
203 | def int_wasm_bitmask : |
||
204 | DefaultAttrsIntrinsic<[llvm_i32_ty], |
||
205 | [llvm_anyvector_ty], |
||
206 | [IntrNoMem, IntrSpeculatable]>; |
||
207 | def int_wasm_dot : |
||
208 | DefaultAttrsIntrinsic<[llvm_v4i32_ty], |
||
209 | [llvm_v8i16_ty, llvm_v8i16_ty], |
||
210 | [IntrNoMem, IntrSpeculatable]>; |
||
211 | |||
212 | def int_wasm_narrow_signed : |
||
213 | DefaultAttrsIntrinsic<[llvm_anyvector_ty], |
||
214 | [llvm_anyvector_ty, LLVMMatchType<1>], |
||
215 | [IntrNoMem, IntrSpeculatable]>; |
||
216 | def int_wasm_narrow_unsigned : |
||
217 | DefaultAttrsIntrinsic<[llvm_anyvector_ty], |
||
218 | [llvm_anyvector_ty, LLVMMatchType<1>], |
||
219 | [IntrNoMem, IntrSpeculatable]>; |
||
220 | |||
221 | def int_wasm_q15mulr_sat_signed : |
||
222 | DefaultAttrsIntrinsic<[llvm_v8i16_ty], |
||
223 | [llvm_v8i16_ty, llvm_v8i16_ty], |
||
224 | [IntrNoMem, IntrSpeculatable]>; |
||
225 | |||
226 | def int_wasm_pmin : |
||
227 | DefaultAttrsIntrinsic<[llvm_anyvector_ty], |
||
228 | [LLVMMatchType<0>, LLVMMatchType<0>], |
||
229 | [IntrNoMem, IntrSpeculatable]>; |
||
230 | def int_wasm_pmax : |
||
231 | DefaultAttrsIntrinsic<[llvm_anyvector_ty], |
||
232 | [LLVMMatchType<0>, LLVMMatchType<0>], |
||
233 | [IntrNoMem, IntrSpeculatable]>; |
||
234 | |||
235 | def int_wasm_extadd_pairwise_signed : |
||
236 | DefaultAttrsIntrinsic<[llvm_anyvector_ty], |
||
237 | [LLVMSubdivide2VectorType<0>], |
||
238 | [IntrNoMem, IntrSpeculatable]>; |
||
239 | def int_wasm_extadd_pairwise_unsigned : |
||
240 | DefaultAttrsIntrinsic<[llvm_anyvector_ty], |
||
241 | [LLVMSubdivide2VectorType<0>], |
||
242 | [IntrNoMem, IntrSpeculatable]>; |
||
243 | |||
244 | //===----------------------------------------------------------------------===// |
||
245 | // Relaxed SIMD intrinsics (experimental) |
||
246 | //===----------------------------------------------------------------------===// |
||
247 | |||
248 | def int_wasm_relaxed_madd : |
||
249 | DefaultAttrsIntrinsic<[llvm_anyvector_ty], |
||
250 | [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], |
||
251 | [IntrNoMem, IntrSpeculatable]>; |
||
252 | def int_wasm_relaxed_nmadd : |
||
253 | DefaultAttrsIntrinsic<[llvm_anyvector_ty], |
||
254 | [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], |
||
255 | [IntrNoMem, IntrSpeculatable]>; |
||
256 | |||
257 | def int_wasm_relaxed_laneselect : |
||
258 | DefaultAttrsIntrinsic<[llvm_anyvector_ty], |
||
259 | [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], |
||
260 | [IntrNoMem, IntrSpeculatable]>; |
||
261 | |||
262 | def int_wasm_relaxed_swizzle : |
||
263 | DefaultAttrsIntrinsic<[llvm_v16i8_ty], |
||
264 | [llvm_v16i8_ty, llvm_v16i8_ty], |
||
265 | [IntrNoMem, IntrSpeculatable]>; |
||
266 | |||
267 | def int_wasm_relaxed_min : |
||
268 | DefaultAttrsIntrinsic<[llvm_anyvector_ty], |
||
269 | [LLVMMatchType<0>, LLVMMatchType<0>], |
||
270 | [IntrNoMem, IntrSpeculatable]>; |
||
271 | def int_wasm_relaxed_max : |
||
272 | DefaultAttrsIntrinsic<[llvm_anyvector_ty], |
||
273 | [LLVMMatchType<0>, LLVMMatchType<0>], |
||
274 | [IntrNoMem, IntrSpeculatable]>; |
||
275 | |||
276 | def int_wasm_relaxed_trunc_signed: |
||
277 | DefaultAttrsIntrinsic<[llvm_v4i32_ty], |
||
278 | [llvm_v4f32_ty], |
||
279 | [IntrNoMem, IntrSpeculatable]>; |
||
280 | |||
281 | def int_wasm_relaxed_trunc_unsigned: |
||
282 | DefaultAttrsIntrinsic<[llvm_v4i32_ty], |
||
283 | [llvm_v4f32_ty], |
||
284 | [IntrNoMem, IntrSpeculatable]>; |
||
285 | |||
286 | def int_wasm_relaxed_trunc_signed_zero: |
||
287 | DefaultAttrsIntrinsic<[llvm_v4i32_ty], |
||
288 | [llvm_v2f64_ty], |
||
289 | [IntrNoMem, IntrSpeculatable]>; |
||
290 | |||
291 | def int_wasm_relaxed_trunc_unsigned_zero: |
||
292 | DefaultAttrsIntrinsic<[llvm_v4i32_ty], |
||
293 | [llvm_v2f64_ty], |
||
294 | [IntrNoMem, IntrSpeculatable]>; |
||
295 | |||
296 | def int_wasm_relaxed_q15mulr_signed: |
||
297 | DefaultAttrsIntrinsic<[llvm_v8i16_ty], |
||
298 | [llvm_v8i16_ty, llvm_v8i16_ty], |
||
299 | [IntrNoMem, IntrSpeculatable]>; |
||
300 | |||
301 | def int_wasm_relaxed_dot_i8x16_i7x16_signed: |
||
302 | DefaultAttrsIntrinsic<[llvm_v8i16_ty], |
||
303 | [llvm_v16i8_ty, llvm_v16i8_ty], |
||
304 | [IntrNoMem, IntrSpeculatable]>; |
||
305 | |||
306 | def int_wasm_relaxed_dot_i8x16_i7x16_add_signed: |
||
307 | DefaultAttrsIntrinsic<[llvm_v4i32_ty], |
||
308 | [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v4i32_ty], |
||
309 | [IntrNoMem, IntrSpeculatable]>; |
||
310 | |||
311 | def int_wasm_relaxed_dot_bf16x8_add_f32: |
||
312 | DefaultAttrsIntrinsic<[llvm_v4f32_ty], |
||
313 | [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v4f32_ty], |
||
314 | [IntrNoMem, IntrSpeculatable]>; |
||
315 | |||
316 | |||
317 | //===----------------------------------------------------------------------===// |
||
318 | // Thread-local storage intrinsics |
||
319 | //===----------------------------------------------------------------------===// |
||
320 | |||
321 | def int_wasm_tls_size : |
||
322 | DefaultAttrsIntrinsic<[llvm_anyint_ty], |
||
323 | [], |
||
324 | [IntrNoMem, IntrSpeculatable]>; |
||
325 | |||
326 | def int_wasm_tls_align : |
||
327 | DefaultAttrsIntrinsic<[llvm_anyint_ty], |
||
328 | [], |
||
329 | [IntrNoMem, IntrSpeculatable]>; |
||
330 | |||
331 | def int_wasm_tls_base : |
||
332 | DefaultAttrsIntrinsic<[llvm_ptr_ty], |
||
333 | [], |
||
334 | [IntrReadMem]>; |
||
335 | |||
336 | } // TargetPrefix = "wasm" |