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
14let TargetPrefix = "wasm" in {  // All intrinsics start with "llvm.wasm.".
15
16// Query the current memory size, and increase the current memory size.
17// Note that memory.size is not IntrNoMem because it must be sequenced with
18// respect to memory.grow calls.
19def int_wasm_memory_size : Intrinsic<[llvm_anyint_ty],
20                                     [llvm_i32_ty],
21                                     [IntrReadMem]>;
22def int_wasm_memory_grow : Intrinsic<[llvm_anyint_ty],
23                                     [llvm_i32_ty, LLVMMatchType<0>],
24                                     []>;
25
26//===----------------------------------------------------------------------===//
27// Trapping float-to-int conversions
28//===----------------------------------------------------------------------===//
29
30def int_wasm_trunc_signed : Intrinsic<[llvm_anyint_ty],
31                                      [llvm_anyfloat_ty],
32                                      [IntrNoMem]>;
33def int_wasm_trunc_unsigned : Intrinsic<[llvm_anyint_ty],
34                                        [llvm_anyfloat_ty],
35                                        [IntrNoMem]>;
36
37//===----------------------------------------------------------------------===//
38// Saturating float-to-int conversions
39//===----------------------------------------------------------------------===//
40
41def int_wasm_trunc_saturate_signed : Intrinsic<[llvm_anyint_ty],
42                                               [llvm_anyfloat_ty],
43                                               [IntrNoMem, IntrSpeculatable]>;
44def int_wasm_trunc_saturate_unsigned : Intrinsic<[llvm_anyint_ty],
45                                                 [llvm_anyfloat_ty],
46                                                 [IntrNoMem, IntrSpeculatable]>;
47
48//===----------------------------------------------------------------------===//
49// Exception handling intrinsics
50//===----------------------------------------------------------------------===//
51
52// throw / rethrow
53def int_wasm_throw : Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty],
54                               [Throws, IntrNoReturn, ImmArg<ArgIndex<0>>]>;
55def int_wasm_rethrow_in_catch : Intrinsic<[], [], [Throws, IntrNoReturn]>;
56
57// Since wasm does not use landingpad instructions, these instructions return
58// exception pointer and selector values until we lower them in WasmEHPrepare.
59def int_wasm_get_exception : Intrinsic<[llvm_ptr_ty], [llvm_token_ty],
60                                       [IntrHasSideEffects]>;
61def int_wasm_get_ehselector : Intrinsic<[llvm_i32_ty], [llvm_token_ty],
62                                        [IntrHasSideEffects]>;
63// This is the same as llvm.wasm.get.exception except that it does not take a
64// token operand. This is only for instruction selection purpose.
65def int_wasm_extract_exception : Intrinsic<[llvm_ptr_ty], [],
66                                           [IntrHasSideEffects]>;
67
68// WebAssembly EH must maintain the landingpads in the order assigned to them
69// by WasmEHPrepare pass to generate landingpad table in EHStreamer. This is
70// used in order to give them the indices in WasmEHPrepare.
71def int_wasm_landingpad_index: Intrinsic<[], [llvm_token_ty, llvm_i32_ty],
72                                         [IntrNoMem, ImmArg<ArgIndex<1>>]>;
73
74// Returns LSDA address of the current function.
75def int_wasm_lsda : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
76
77//===----------------------------------------------------------------------===//
78// Atomic intrinsics
79//===----------------------------------------------------------------------===//
80
81// wait / notify
82def int_wasm_atomic_wait_i32 :
83  Intrinsic<[llvm_i32_ty],
84            [LLVMPointerType<llvm_i32_ty>, llvm_i32_ty, llvm_i64_ty],
85            [IntrInaccessibleMemOrArgMemOnly, ReadOnly<ArgIndex<0>>, NoCapture<ArgIndex<0>>,
86             IntrHasSideEffects],
87             "", [SDNPMemOperand]>;
88def int_wasm_atomic_wait_i64 :
89  Intrinsic<[llvm_i32_ty],
90            [LLVMPointerType<llvm_i64_ty>, llvm_i64_ty, llvm_i64_ty],
91            [IntrInaccessibleMemOrArgMemOnly, ReadOnly<ArgIndex<0>>, NoCapture<ArgIndex<0>>,
92             IntrHasSideEffects],
93             "", [SDNPMemOperand]>;
94def int_wasm_atomic_notify:
95  Intrinsic<[llvm_i32_ty], [LLVMPointerType<llvm_i32_ty>, llvm_i32_ty],
96            [IntrInaccessibleMemOnly, NoCapture<ArgIndex<0>>, IntrHasSideEffects], "",
97            [SDNPMemOperand]>;
98
99//===----------------------------------------------------------------------===//
100// SIMD intrinsics
101//===----------------------------------------------------------------------===//
102
103def int_wasm_swizzle :
104  Intrinsic<[llvm_v16i8_ty],
105            [llvm_v16i8_ty, llvm_v16i8_ty],
106            [IntrNoMem, IntrSpeculatable]>;
107def int_wasm_shuffle :
108  Intrinsic<[llvm_v16i8_ty],
109            [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty, llvm_i32_ty,
110             llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
111             llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
112             llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
113            [IntrNoMem, IntrSpeculatable]>;
114def int_wasm_sub_saturate_signed :
115  Intrinsic<[llvm_anyvector_ty],
116            [LLVMMatchType<0>, LLVMMatchType<0>],
117            [IntrNoMem, IntrSpeculatable]>;
118def int_wasm_sub_saturate_unsigned :
119  Intrinsic<[llvm_anyvector_ty],
120            [LLVMMatchType<0>, LLVMMatchType<0>],
121            [IntrNoMem, IntrSpeculatable]>;
122def int_wasm_avgr_unsigned :
123  Intrinsic<[llvm_anyvector_ty],
124            [LLVMMatchType<0>, LLVMMatchType<0>],
125            [IntrNoMem, IntrSpeculatable]>;
126def int_wasm_bitselect :
127  Intrinsic<[llvm_anyvector_ty],
128            [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
129            [IntrNoMem, IntrSpeculatable]>;
130def int_wasm_anytrue :
131  Intrinsic<[llvm_i32_ty],
132            [llvm_anyvector_ty],
133            [IntrNoMem, IntrSpeculatable]>;
134def int_wasm_alltrue :
135  Intrinsic<[llvm_i32_ty],
136            [llvm_anyvector_ty],
137            [IntrNoMem, IntrSpeculatable]>;
138def int_wasm_bitmask :
139  Intrinsic<[llvm_i32_ty],
140            [llvm_anyvector_ty],
141            [IntrNoMem, IntrSpeculatable]>;
142def int_wasm_qfma :
143  Intrinsic<[llvm_anyvector_ty],
144            [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
145            [IntrNoMem, IntrSpeculatable]>;
146def int_wasm_qfms :
147  Intrinsic<[llvm_anyvector_ty],
148            [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
149            [IntrNoMem, IntrSpeculatable]>;
150def int_wasm_dot :
151  Intrinsic<[llvm_v4i32_ty],
152            [llvm_v8i16_ty, llvm_v8i16_ty],
153            [IntrNoMem, IntrSpeculatable]>;
154def int_wasm_narrow_signed :
155  Intrinsic<[llvm_anyvector_ty],
156            [llvm_anyvector_ty, LLVMMatchType<1>],
157            [IntrNoMem, IntrSpeculatable]>;
158def int_wasm_narrow_unsigned :
159  Intrinsic<[llvm_anyvector_ty],
160            [llvm_anyvector_ty, LLVMMatchType<1>],
161            [IntrNoMem, IntrSpeculatable]>;
162def int_wasm_widen_low_signed :
163  Intrinsic<[llvm_anyvector_ty],
164            [llvm_anyvector_ty],
165            [IntrNoMem, IntrSpeculatable]>;
166def int_wasm_widen_high_signed :
167  Intrinsic<[llvm_anyvector_ty],
168            [llvm_anyvector_ty],
169            [IntrNoMem, IntrSpeculatable]>;
170def int_wasm_widen_low_unsigned :
171  Intrinsic<[llvm_anyvector_ty],
172            [llvm_anyvector_ty],
173            [IntrNoMem, IntrSpeculatable]>;
174def int_wasm_widen_high_unsigned :
175  Intrinsic<[llvm_anyvector_ty],
176            [llvm_anyvector_ty],
177            [IntrNoMem, IntrSpeculatable]>;
178
179// TODO: Replace these intrinsics with normal ISel patterns
180def int_wasm_pmin :
181  Intrinsic<[llvm_anyvector_ty],
182            [LLVMMatchType<0>, LLVMMatchType<0>],
183            [IntrNoMem, IntrSpeculatable]>;
184def int_wasm_pmax :
185  Intrinsic<[llvm_anyvector_ty],
186            [LLVMMatchType<0>, LLVMMatchType<0>],
187            [IntrNoMem, IntrSpeculatable]>;
188
189// TODO: Replace these instrinsics with normal ISel patterns once the
190// rounding instructions are merged to the proposal
191// (https://github.com/WebAssembly/simd/pull/232).
192def int_wasm_ceil :
193  Intrinsic<[llvm_anyvector_ty],
194            [LLVMMatchType<0>],
195            [IntrNoMem, IntrSpeculatable]>;
196def int_wasm_floor :
197  Intrinsic<[llvm_anyvector_ty],
198            [LLVMMatchType<0>],
199            [IntrNoMem, IntrSpeculatable]>;
200def int_wasm_trunc :
201  Intrinsic<[llvm_anyvector_ty],
202            [LLVMMatchType<0>],
203            [IntrNoMem, IntrSpeculatable]>;
204def int_wasm_nearest :
205  Intrinsic<[llvm_anyvector_ty],
206            [LLVMMatchType<0>],
207            [IntrNoMem, IntrSpeculatable]>;
208
209//===----------------------------------------------------------------------===//
210// Thread-local storage intrinsics
211//===----------------------------------------------------------------------===//
212
213def int_wasm_tls_size :
214  Intrinsic<[llvm_anyint_ty],
215            [],
216            [IntrNoMem, IntrSpeculatable]>;
217
218def int_wasm_tls_align :
219  Intrinsic<[llvm_anyint_ty],
220            [],
221            [IntrNoMem, IntrSpeculatable]>;
222
223def int_wasm_tls_base :
224  Intrinsic<[llvm_ptr_ty],
225            [],
226            [IntrReadMem]>;
227
228} // TargetPrefix = "wasm"
229