WebAssemblyRuntimeLibcallSignatures.cpp revision 344779
1// CodeGen/RuntimeLibcallSignatures.cpp - R.T. Lib. Call Signatures -*- C++ -*--
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// This file contains signature information for runtime libcalls.
12///
13/// CodeGen uses external symbols, which it refers to by name. The WebAssembly
14/// target needs type information for all functions. This file contains a big
15/// table providing type signatures for all runtime library functions that LLVM
16/// uses.
17///
18/// This is currently a fairly heavy-handed solution.
19///
20//===----------------------------------------------------------------------===//
21
22#include "WebAssemblyRuntimeLibcallSignatures.h"
23#include "WebAssemblySubtarget.h"
24#include "llvm/CodeGen/RuntimeLibcalls.h"
25#include "llvm/Support/ManagedStatic.h"
26
27using namespace llvm;
28
29namespace {
30
31enum RuntimeLibcallSignature {
32  func,
33  f32_func_f32,
34  f32_func_f64,
35  f32_func_i32,
36  f32_func_i64,
37  f32_func_i16,
38  f64_func_f32,
39  f64_func_f64,
40  f64_func_i32,
41  f64_func_i64,
42  i32_func_f32,
43  i32_func_f64,
44  i32_func_i32,
45  i64_func_f32,
46  i64_func_f64,
47  i64_func_i64,
48  f32_func_f32_f32,
49  f32_func_f32_i32,
50  f32_func_i64_i64,
51  f64_func_f64_f64,
52  f64_func_f64_i32,
53  f64_func_i64_i64,
54  i16_func_f32,
55  i8_func_i8_i8,
56  func_f32_iPTR_iPTR,
57  func_f64_iPTR_iPTR,
58  i16_func_i16_i16,
59  i32_func_f32_f32,
60  i32_func_f64_f64,
61  i32_func_i32_i32,
62  i32_func_i32_i32_iPTR,
63  i64_func_i64_i64,
64  i64_func_i64_i64_iPTR,
65  i64_i64_func_f32,
66  i64_i64_func_f64,
67  i16_i16_func_i16_i16,
68  i32_i32_func_i32_i32,
69  i64_i64_func_i64_i64,
70  i64_i64_func_i64_i64_i64_i64,
71  i64_i64_func_i64_i64_i64_i64_iPTR,
72  i64_i64_i64_i64_func_i64_i64_i64_i64,
73  i64_i64_func_i64_i64_i32,
74  iPTR_func_iPTR_i32_iPTR,
75  iPTR_func_iPTR_iPTR_iPTR,
76  f32_func_f32_f32_f32,
77  f64_func_f64_f64_f64,
78  func_i64_i64_iPTR_iPTR,
79  func_iPTR_f32,
80  func_iPTR_f64,
81  func_iPTR_i32,
82  func_iPTR_i64,
83  func_iPTR_i64_i64,
84  func_iPTR_i64_i64_i64_i64,
85  func_iPTR_i64_i64_i64_i64_i64_i64,
86  i32_func_i64_i64,
87  i32_func_i64_i64_i64_i64,
88  unsupported
89};
90
91struct RuntimeLibcallSignatureTable {
92  std::vector<RuntimeLibcallSignature> Table;
93
94  // Any newly-added libcalls will be unsupported by default.
95  RuntimeLibcallSignatureTable() : Table(RTLIB::UNKNOWN_LIBCALL, unsupported) {
96    // Integer
97    Table[RTLIB::SHL_I16] = i16_func_i16_i16;
98    Table[RTLIB::SHL_I32] = i32_func_i32_i32;
99    Table[RTLIB::SHL_I64] = i64_func_i64_i64;
100    Table[RTLIB::SHL_I128] = i64_i64_func_i64_i64_i32;
101    Table[RTLIB::SRL_I16] = i16_func_i16_i16;
102    Table[RTLIB::SRL_I32] = i32_func_i32_i32;
103    Table[RTLIB::SRL_I64] = i64_func_i64_i64;
104    Table[RTLIB::SRL_I128] = i64_i64_func_i64_i64_i32;
105    Table[RTLIB::SRA_I16] = i16_func_i16_i16;
106    Table[RTLIB::SRA_I32] = i32_func_i32_i32;
107    Table[RTLIB::SRA_I64] = i64_func_i64_i64;
108    Table[RTLIB::SRA_I128] = i64_i64_func_i64_i64_i32;
109    Table[RTLIB::MUL_I8] = i8_func_i8_i8;
110    Table[RTLIB::MUL_I16] = i16_func_i16_i16;
111    Table[RTLIB::MUL_I32] = i32_func_i32_i32;
112    Table[RTLIB::MUL_I64] = i64_func_i64_i64;
113    Table[RTLIB::MUL_I128] = i64_i64_func_i64_i64_i64_i64;
114    Table[RTLIB::MULO_I32] = i32_func_i32_i32_iPTR;
115    Table[RTLIB::MULO_I64] = i64_func_i64_i64_iPTR;
116    Table[RTLIB::MULO_I128] = i64_i64_func_i64_i64_i64_i64_iPTR;
117    Table[RTLIB::SDIV_I8] = i8_func_i8_i8;
118    Table[RTLIB::SDIV_I16] = i16_func_i16_i16;
119    Table[RTLIB::SDIV_I32] = i32_func_i32_i32;
120    Table[RTLIB::SDIV_I64] = i64_func_i64_i64;
121    Table[RTLIB::SDIV_I128] = i64_i64_func_i64_i64_i64_i64;
122    Table[RTLIB::UDIV_I8] = i8_func_i8_i8;
123    Table[RTLIB::UDIV_I16] = i16_func_i16_i16;
124    Table[RTLIB::UDIV_I32] = i32_func_i32_i32;
125    Table[RTLIB::UDIV_I64] = i64_func_i64_i64;
126    Table[RTLIB::UDIV_I128] = i64_i64_func_i64_i64_i64_i64;
127    Table[RTLIB::SREM_I8] = i8_func_i8_i8;
128    Table[RTLIB::SREM_I16] = i16_func_i16_i16;
129    Table[RTLIB::SREM_I32] = i32_func_i32_i32;
130    Table[RTLIB::SREM_I64] = i64_func_i64_i64;
131    Table[RTLIB::SREM_I128] = i64_i64_func_i64_i64_i64_i64;
132    Table[RTLIB::UREM_I8] = i8_func_i8_i8;
133    Table[RTLIB::UREM_I16] = i16_func_i16_i16;
134    Table[RTLIB::UREM_I32] = i32_func_i32_i32;
135    Table[RTLIB::UREM_I64] = i64_func_i64_i64;
136    Table[RTLIB::UREM_I128] = i64_i64_func_i64_i64_i64_i64;
137    Table[RTLIB::SDIVREM_I8] = i8_func_i8_i8;
138    Table[RTLIB::SDIVREM_I16] = i16_i16_func_i16_i16;
139    Table[RTLIB::SDIVREM_I32] = i32_i32_func_i32_i32;
140    Table[RTLIB::SDIVREM_I64] = i64_func_i64_i64;
141    Table[RTLIB::SDIVREM_I128] = i64_i64_i64_i64_func_i64_i64_i64_i64;
142    Table[RTLIB::UDIVREM_I8] = i8_func_i8_i8;
143    Table[RTLIB::UDIVREM_I16] = i16_i16_func_i16_i16;
144    Table[RTLIB::UDIVREM_I32] = i32_i32_func_i32_i32;
145    Table[RTLIB::UDIVREM_I64] = i64_i64_func_i64_i64;
146    Table[RTLIB::UDIVREM_I128] = i64_i64_i64_i64_func_i64_i64_i64_i64;
147    Table[RTLIB::NEG_I32] = i32_func_i32;
148    Table[RTLIB::NEG_I64] = i64_func_i64;
149
150    // Floating-point.
151    // All F80 and PPCF128 routines are unsupported.
152    Table[RTLIB::ADD_F32] = f32_func_f32_f32;
153    Table[RTLIB::ADD_F64] = f64_func_f64_f64;
154    Table[RTLIB::ADD_F128] = func_iPTR_i64_i64_i64_i64;
155    Table[RTLIB::SUB_F32] = f32_func_f32_f32;
156    Table[RTLIB::SUB_F64] = f64_func_f64_f64;
157    Table[RTLIB::SUB_F128] = func_iPTR_i64_i64_i64_i64;
158    Table[RTLIB::MUL_F32] = f32_func_f32_f32;
159    Table[RTLIB::MUL_F64] = f64_func_f64_f64;
160    Table[RTLIB::MUL_F128] = func_iPTR_i64_i64_i64_i64;
161    Table[RTLIB::DIV_F32] = f32_func_f32_f32;
162    Table[RTLIB::DIV_F64] = f64_func_f64_f64;
163    Table[RTLIB::DIV_F128] = func_iPTR_i64_i64_i64_i64;
164    Table[RTLIB::REM_F32] = f32_func_f32_f32;
165    Table[RTLIB::REM_F64] = f64_func_f64_f64;
166    Table[RTLIB::REM_F128] = func_iPTR_i64_i64_i64_i64;
167    Table[RTLIB::FMA_F32] = f32_func_f32_f32_f32;
168    Table[RTLIB::FMA_F64] = f64_func_f64_f64_f64;
169    Table[RTLIB::FMA_F128] = func_iPTR_i64_i64_i64_i64_i64_i64;
170    Table[RTLIB::POWI_F32] = f32_func_f32_i32;
171    Table[RTLIB::POWI_F64] = f64_func_f64_i32;
172    Table[RTLIB::POWI_F128] = func_iPTR_i64_i64_i64_i64;
173    Table[RTLIB::SQRT_F32] = f32_func_f32;
174    Table[RTLIB::SQRT_F64] = f64_func_f64;
175    Table[RTLIB::SQRT_F128] = func_iPTR_i64_i64;
176    Table[RTLIB::LOG_F32] = f32_func_f32;
177    Table[RTLIB::LOG_F64] = f64_func_f64;
178    Table[RTLIB::LOG_F128] = func_iPTR_i64_i64;
179    Table[RTLIB::LOG2_F32] = f32_func_f32;
180    Table[RTLIB::LOG2_F64] = f64_func_f64;
181    Table[RTLIB::LOG2_F128] = func_iPTR_i64_i64;
182    Table[RTLIB::LOG10_F32] = f32_func_f32;
183    Table[RTLIB::LOG10_F64] = f64_func_f64;
184    Table[RTLIB::LOG10_F128] = func_iPTR_i64_i64;
185    Table[RTLIB::EXP_F32] = f32_func_f32;
186    Table[RTLIB::EXP_F64] = f64_func_f64;
187    Table[RTLIB::EXP_F128] = func_iPTR_i64_i64;
188    Table[RTLIB::EXP2_F32] = f32_func_f32;
189    Table[RTLIB::EXP2_F64] = f64_func_f64;
190    Table[RTLIB::EXP2_F128] = func_iPTR_i64_i64;
191    Table[RTLIB::SIN_F32] = f32_func_f32;
192    Table[RTLIB::SIN_F64] = f64_func_f64;
193    Table[RTLIB::SIN_F128] = func_iPTR_i64_i64;
194    Table[RTLIB::COS_F32] = f32_func_f32;
195    Table[RTLIB::COS_F64] = f64_func_f64;
196    Table[RTLIB::COS_F128] = func_iPTR_i64_i64;
197    Table[RTLIB::SINCOS_F32] = func_f32_iPTR_iPTR;
198    Table[RTLIB::SINCOS_F64] = func_f64_iPTR_iPTR;
199    Table[RTLIB::SINCOS_F128] = func_i64_i64_iPTR_iPTR;
200    Table[RTLIB::POW_F32] = f32_func_f32_f32;
201    Table[RTLIB::POW_F64] = f64_func_f64_f64;
202    Table[RTLIB::POW_F128] = func_iPTR_i64_i64_i64_i64;
203    Table[RTLIB::CEIL_F32] = f32_func_f32;
204    Table[RTLIB::CEIL_F64] = f64_func_f64;
205    Table[RTLIB::CEIL_F128] = func_iPTR_i64_i64;
206    Table[RTLIB::TRUNC_F32] = f32_func_f32;
207    Table[RTLIB::TRUNC_F64] = f64_func_f64;
208    Table[RTLIB::TRUNC_F128] = func_iPTR_i64_i64;
209    Table[RTLIB::RINT_F32] = f32_func_f32;
210    Table[RTLIB::RINT_F64] = f64_func_f64;
211    Table[RTLIB::RINT_F128] = func_iPTR_i64_i64;
212    Table[RTLIB::NEARBYINT_F32] = f32_func_f32;
213    Table[RTLIB::NEARBYINT_F64] = f64_func_f64;
214    Table[RTLIB::NEARBYINT_F128] = func_iPTR_i64_i64;
215    Table[RTLIB::ROUND_F32] = f32_func_f32;
216    Table[RTLIB::ROUND_F64] = f64_func_f64;
217    Table[RTLIB::ROUND_F128] = func_iPTR_i64_i64;
218    Table[RTLIB::FLOOR_F32] = f32_func_f32;
219    Table[RTLIB::FLOOR_F64] = f64_func_f64;
220    Table[RTLIB::FLOOR_F128] = func_iPTR_i64_i64;
221    Table[RTLIB::COPYSIGN_F32] = f32_func_f32_f32;
222    Table[RTLIB::COPYSIGN_F64] = f64_func_f64_f64;
223    Table[RTLIB::COPYSIGN_F128] = func_iPTR_i64_i64_i64_i64;
224    Table[RTLIB::FMIN_F32] = f32_func_f32_f32;
225    Table[RTLIB::FMIN_F64] = f64_func_f64_f64;
226    Table[RTLIB::FMIN_F128] = func_iPTR_i64_i64_i64_i64;
227    Table[RTLIB::FMAX_F32] = f32_func_f32_f32;
228    Table[RTLIB::FMAX_F64] = f64_func_f64_f64;
229    Table[RTLIB::FMAX_F128] = func_iPTR_i64_i64_i64_i64;
230
231    // Conversion
232    // All F80 and PPCF128 routines are unspported.
233    Table[RTLIB::FPEXT_F64_F128] = func_iPTR_f64;
234    Table[RTLIB::FPEXT_F32_F128] = func_iPTR_f32;
235    Table[RTLIB::FPEXT_F32_F64] = f64_func_f32;
236    Table[RTLIB::FPEXT_F16_F32] = f32_func_i16;
237    Table[RTLIB::FPROUND_F32_F16] = i16_func_f32;
238    Table[RTLIB::FPROUND_F64_F32] = f32_func_f64;
239    Table[RTLIB::FPROUND_F128_F32] = f32_func_i64_i64;
240    Table[RTLIB::FPROUND_F128_F64] = f64_func_i64_i64;
241    Table[RTLIB::FPTOSINT_F32_I32] = i32_func_f32;
242    Table[RTLIB::FPTOSINT_F32_I64] = i64_func_f32;
243    Table[RTLIB::FPTOSINT_F32_I128] = i64_i64_func_f32;
244    Table[RTLIB::FPTOSINT_F64_I32] = i32_func_f64;
245    Table[RTLIB::FPTOSINT_F64_I64] = i64_func_f64;
246    Table[RTLIB::FPTOSINT_F64_I128] = i64_i64_func_f64;
247    Table[RTLIB::FPTOSINT_F128_I32] = i32_func_i64_i64;
248    Table[RTLIB::FPTOSINT_F128_I64] = i64_func_i64_i64;
249    Table[RTLIB::FPTOSINT_F128_I128] = i64_i64_func_i64_i64;
250    Table[RTLIB::FPTOUINT_F32_I32] = i32_func_f32;
251    Table[RTLIB::FPTOUINT_F32_I64] = i64_func_f32;
252    Table[RTLIB::FPTOUINT_F32_I128] = i64_i64_func_f32;
253    Table[RTLIB::FPTOUINT_F64_I32] = i32_func_f64;
254    Table[RTLIB::FPTOUINT_F64_I64] = i64_func_f64;
255    Table[RTLIB::FPTOUINT_F64_I128] = i64_i64_func_f64;
256    Table[RTLIB::FPTOUINT_F128_I32] = i32_func_i64_i64;
257    Table[RTLIB::FPTOUINT_F128_I64] = i64_func_i64_i64;
258    Table[RTLIB::FPTOUINT_F128_I128] = i64_i64_func_i64_i64;
259    Table[RTLIB::SINTTOFP_I32_F32] = f32_func_i32;
260    Table[RTLIB::SINTTOFP_I32_F64] = f64_func_i32;
261    Table[RTLIB::SINTTOFP_I32_F128] = func_iPTR_i32;
262    Table[RTLIB::SINTTOFP_I64_F32] = f32_func_i64;
263    Table[RTLIB::SINTTOFP_I64_F64] = f64_func_i64;
264    Table[RTLIB::SINTTOFP_I64_F128] = func_iPTR_i64;
265    Table[RTLIB::SINTTOFP_I128_F32] = f32_func_i64_i64;
266    Table[RTLIB::SINTTOFP_I128_F64] = f64_func_i64_i64;
267    Table[RTLIB::SINTTOFP_I128_F128] = func_iPTR_i64_i64;
268    Table[RTLIB::UINTTOFP_I32_F32] = f32_func_i32;
269    Table[RTLIB::UINTTOFP_I32_F64] = f64_func_i64;
270    Table[RTLIB::UINTTOFP_I32_F128] = func_iPTR_i32;
271    Table[RTLIB::UINTTOFP_I64_F32] = f32_func_i64;
272    Table[RTLIB::UINTTOFP_I64_F64] = f64_func_i64;
273    Table[RTLIB::UINTTOFP_I64_F128] = func_iPTR_i64;
274    Table[RTLIB::UINTTOFP_I128_F32] = f32_func_i64_i64;
275    Table[RTLIB::UINTTOFP_I128_F64] = f64_func_i64_i64;
276    Table[RTLIB::UINTTOFP_I128_F128] = func_iPTR_i64_i64;
277
278    // Comparison
279    // ALl F80 and PPCF128 routines are unsupported.
280    Table[RTLIB::OEQ_F32] = i32_func_f32_f32;
281    Table[RTLIB::OEQ_F64] = i32_func_f64_f64;
282    Table[RTLIB::OEQ_F128] = i32_func_i64_i64_i64_i64;
283    Table[RTLIB::UNE_F32] = i32_func_f32_f32;
284    Table[RTLIB::UNE_F64] = i32_func_f64_f64;
285    Table[RTLIB::UNE_F128] = i32_func_i64_i64_i64_i64;
286    Table[RTLIB::OGE_F32] = i32_func_f32_f32;
287    Table[RTLIB::OGE_F64] = i32_func_f64_f64;
288    Table[RTLIB::OGE_F128] = i32_func_i64_i64_i64_i64;
289    Table[RTLIB::OLT_F32] = i32_func_f32_f32;
290    Table[RTLIB::OLT_F64] = i32_func_f64_f64;
291    Table[RTLIB::OLT_F128] = i32_func_i64_i64_i64_i64;
292    Table[RTLIB::OLE_F32] = i32_func_f32_f32;
293    Table[RTLIB::OLE_F64] = i32_func_f64_f64;
294    Table[RTLIB::OLE_F128] = i32_func_i64_i64_i64_i64;
295    Table[RTLIB::OGT_F32] = i32_func_f32_f32;
296    Table[RTLIB::OGT_F64] = i32_func_f64_f64;
297    Table[RTLIB::OGT_F128] = i32_func_i64_i64_i64_i64;
298    Table[RTLIB::UO_F32] = i32_func_f32_f32;
299    Table[RTLIB::UO_F64] = i32_func_f64_f64;
300    Table[RTLIB::UO_F128] = i32_func_i64_i64_i64_i64;
301    // O_FXX has the weird property that it uses the same libcall name as UO_FXX
302    // This breaks our name-based lookup. Fortunately only the UO family of
303    // libcalls appears to be actually used.
304    Table[RTLIB::O_F32] = unsupported;
305    Table[RTLIB::O_F64] = unsupported;
306    Table[RTLIB::O_F128] = unsupported;
307
308    // Memory
309    Table[RTLIB::MEMCPY] = iPTR_func_iPTR_iPTR_iPTR;
310    Table[RTLIB::MEMSET] = iPTR_func_iPTR_i32_iPTR;
311    Table[RTLIB::MEMMOVE] = iPTR_func_iPTR_iPTR_iPTR;
312
313    // Element-wise Atomic memory
314    // TODO: Fix these when we implement atomic support
315    Table[RTLIB::MEMCPY_ELEMENT_UNORDERED_ATOMIC_1] = unsupported;
316    Table[RTLIB::MEMCPY_ELEMENT_UNORDERED_ATOMIC_2] = unsupported;
317    Table[RTLIB::MEMCPY_ELEMENT_UNORDERED_ATOMIC_4] = unsupported;
318    Table[RTLIB::MEMCPY_ELEMENT_UNORDERED_ATOMIC_8] = unsupported;
319    Table[RTLIB::MEMCPY_ELEMENT_UNORDERED_ATOMIC_16] = unsupported;
320    Table[RTLIB::MEMMOVE_ELEMENT_UNORDERED_ATOMIC_1] = unsupported;
321    Table[RTLIB::MEMMOVE_ELEMENT_UNORDERED_ATOMIC_2] = unsupported;
322    Table[RTLIB::MEMMOVE_ELEMENT_UNORDERED_ATOMIC_4] = unsupported;
323    Table[RTLIB::MEMMOVE_ELEMENT_UNORDERED_ATOMIC_8] = unsupported;
324    Table[RTLIB::MEMMOVE_ELEMENT_UNORDERED_ATOMIC_16] = unsupported;
325
326    Table[RTLIB::MEMSET_ELEMENT_UNORDERED_ATOMIC_1] = unsupported;
327    Table[RTLIB::MEMSET_ELEMENT_UNORDERED_ATOMIC_2] = unsupported;
328    Table[RTLIB::MEMSET_ELEMENT_UNORDERED_ATOMIC_4] = unsupported;
329    Table[RTLIB::MEMSET_ELEMENT_UNORDERED_ATOMIC_8] = unsupported;
330    Table[RTLIB::MEMSET_ELEMENT_UNORDERED_ATOMIC_16] = unsupported;
331
332    // Atomic '__sync_*' libcalls.
333    // TODO: Fix these when we implement atomic support
334    Table[RTLIB::SYNC_VAL_COMPARE_AND_SWAP_1] = unsupported;
335    Table[RTLIB::SYNC_VAL_COMPARE_AND_SWAP_2] = unsupported;
336    Table[RTLIB::SYNC_VAL_COMPARE_AND_SWAP_4] = unsupported;
337    Table[RTLIB::SYNC_VAL_COMPARE_AND_SWAP_8] = unsupported;
338    Table[RTLIB::SYNC_VAL_COMPARE_AND_SWAP_16] = unsupported;
339    Table[RTLIB::SYNC_LOCK_TEST_AND_SET_1] = unsupported;
340    Table[RTLIB::SYNC_LOCK_TEST_AND_SET_2] = unsupported;
341    Table[RTLIB::SYNC_LOCK_TEST_AND_SET_4] = unsupported;
342    Table[RTLIB::SYNC_LOCK_TEST_AND_SET_8] = unsupported;
343    Table[RTLIB::SYNC_LOCK_TEST_AND_SET_16] = unsupported;
344    Table[RTLIB::SYNC_FETCH_AND_ADD_1] = unsupported;
345    Table[RTLIB::SYNC_FETCH_AND_ADD_2] = unsupported;
346    Table[RTLIB::SYNC_FETCH_AND_ADD_4] = unsupported;
347    Table[RTLIB::SYNC_FETCH_AND_ADD_8] = unsupported;
348    Table[RTLIB::SYNC_FETCH_AND_ADD_16] = unsupported;
349    Table[RTLIB::SYNC_FETCH_AND_SUB_1] = unsupported;
350    Table[RTLIB::SYNC_FETCH_AND_SUB_2] = unsupported;
351    Table[RTLIB::SYNC_FETCH_AND_SUB_4] = unsupported;
352    Table[RTLIB::SYNC_FETCH_AND_SUB_8] = unsupported;
353    Table[RTLIB::SYNC_FETCH_AND_SUB_16] = unsupported;
354    Table[RTLIB::SYNC_FETCH_AND_AND_1] = unsupported;
355    Table[RTLIB::SYNC_FETCH_AND_AND_2] = unsupported;
356    Table[RTLIB::SYNC_FETCH_AND_AND_4] = unsupported;
357    Table[RTLIB::SYNC_FETCH_AND_AND_8] = unsupported;
358    Table[RTLIB::SYNC_FETCH_AND_AND_16] = unsupported;
359    Table[RTLIB::SYNC_FETCH_AND_OR_1] = unsupported;
360    Table[RTLIB::SYNC_FETCH_AND_OR_2] = unsupported;
361    Table[RTLIB::SYNC_FETCH_AND_OR_4] = unsupported;
362    Table[RTLIB::SYNC_FETCH_AND_OR_8] = unsupported;
363    Table[RTLIB::SYNC_FETCH_AND_OR_16] = unsupported;
364    Table[RTLIB::SYNC_FETCH_AND_XOR_1] = unsupported;
365    Table[RTLIB::SYNC_FETCH_AND_XOR_2] = unsupported;
366    Table[RTLIB::SYNC_FETCH_AND_XOR_4] = unsupported;
367    Table[RTLIB::SYNC_FETCH_AND_XOR_8] = unsupported;
368    Table[RTLIB::SYNC_FETCH_AND_XOR_16] = unsupported;
369    Table[RTLIB::SYNC_FETCH_AND_NAND_1] = unsupported;
370    Table[RTLIB::SYNC_FETCH_AND_NAND_2] = unsupported;
371    Table[RTLIB::SYNC_FETCH_AND_NAND_4] = unsupported;
372    Table[RTLIB::SYNC_FETCH_AND_NAND_8] = unsupported;
373    Table[RTLIB::SYNC_FETCH_AND_NAND_16] = unsupported;
374    Table[RTLIB::SYNC_FETCH_AND_MAX_1] = unsupported;
375    Table[RTLIB::SYNC_FETCH_AND_MAX_2] = unsupported;
376    Table[RTLIB::SYNC_FETCH_AND_MAX_4] = unsupported;
377    Table[RTLIB::SYNC_FETCH_AND_MAX_8] = unsupported;
378    Table[RTLIB::SYNC_FETCH_AND_MAX_16] = unsupported;
379    Table[RTLIB::SYNC_FETCH_AND_UMAX_1] = unsupported;
380    Table[RTLIB::SYNC_FETCH_AND_UMAX_2] = unsupported;
381    Table[RTLIB::SYNC_FETCH_AND_UMAX_4] = unsupported;
382    Table[RTLIB::SYNC_FETCH_AND_UMAX_8] = unsupported;
383    Table[RTLIB::SYNC_FETCH_AND_UMAX_16] = unsupported;
384    Table[RTLIB::SYNC_FETCH_AND_MIN_1] = unsupported;
385    Table[RTLIB::SYNC_FETCH_AND_MIN_2] = unsupported;
386    Table[RTLIB::SYNC_FETCH_AND_MIN_4] = unsupported;
387    Table[RTLIB::SYNC_FETCH_AND_MIN_8] = unsupported;
388    Table[RTLIB::SYNC_FETCH_AND_MIN_16] = unsupported;
389    Table[RTLIB::SYNC_FETCH_AND_UMIN_1] = unsupported;
390    Table[RTLIB::SYNC_FETCH_AND_UMIN_2] = unsupported;
391    Table[RTLIB::SYNC_FETCH_AND_UMIN_4] = unsupported;
392    Table[RTLIB::SYNC_FETCH_AND_UMIN_8] = unsupported;
393    Table[RTLIB::SYNC_FETCH_AND_UMIN_16] = unsupported;
394
395    // Atomic '__atomic_*' libcalls.
396    // TODO: Fix these when we implement atomic support
397    Table[RTLIB::ATOMIC_LOAD] = unsupported;
398    Table[RTLIB::ATOMIC_LOAD_1] = unsupported;
399    Table[RTLIB::ATOMIC_LOAD_2] = unsupported;
400    Table[RTLIB::ATOMIC_LOAD_4] = unsupported;
401    Table[RTLIB::ATOMIC_LOAD_8] = unsupported;
402    Table[RTLIB::ATOMIC_LOAD_16] = unsupported;
403
404    Table[RTLIB::ATOMIC_STORE] = unsupported;
405    Table[RTLIB::ATOMIC_STORE_1] = unsupported;
406    Table[RTLIB::ATOMIC_STORE_2] = unsupported;
407    Table[RTLIB::ATOMIC_STORE_4] = unsupported;
408    Table[RTLIB::ATOMIC_STORE_8] = unsupported;
409    Table[RTLIB::ATOMIC_STORE_16] = unsupported;
410
411    Table[RTLIB::ATOMIC_EXCHANGE] = unsupported;
412    Table[RTLIB::ATOMIC_EXCHANGE_1] = unsupported;
413    Table[RTLIB::ATOMIC_EXCHANGE_2] = unsupported;
414    Table[RTLIB::ATOMIC_EXCHANGE_4] = unsupported;
415    Table[RTLIB::ATOMIC_EXCHANGE_8] = unsupported;
416    Table[RTLIB::ATOMIC_EXCHANGE_16] = unsupported;
417
418    Table[RTLIB::ATOMIC_COMPARE_EXCHANGE] = unsupported;
419    Table[RTLIB::ATOMIC_COMPARE_EXCHANGE_1] = unsupported;
420    Table[RTLIB::ATOMIC_COMPARE_EXCHANGE_2] = unsupported;
421    Table[RTLIB::ATOMIC_COMPARE_EXCHANGE_4] = unsupported;
422    Table[RTLIB::ATOMIC_COMPARE_EXCHANGE_8] = unsupported;
423    Table[RTLIB::ATOMIC_COMPARE_EXCHANGE_16] = unsupported;
424
425    Table[RTLIB::ATOMIC_FETCH_ADD_1] = unsupported;
426    Table[RTLIB::ATOMIC_FETCH_ADD_2] = unsupported;
427    Table[RTLIB::ATOMIC_FETCH_ADD_4] = unsupported;
428    Table[RTLIB::ATOMIC_FETCH_ADD_8] = unsupported;
429    Table[RTLIB::ATOMIC_FETCH_ADD_16] = unsupported;
430
431    Table[RTLIB::ATOMIC_FETCH_SUB_1] = unsupported;
432    Table[RTLIB::ATOMIC_FETCH_SUB_2] = unsupported;
433    Table[RTLIB::ATOMIC_FETCH_SUB_4] = unsupported;
434    Table[RTLIB::ATOMIC_FETCH_SUB_8] = unsupported;
435    Table[RTLIB::ATOMIC_FETCH_SUB_16] = unsupported;
436
437    Table[RTLIB::ATOMIC_FETCH_AND_1] = unsupported;
438    Table[RTLIB::ATOMIC_FETCH_AND_2] = unsupported;
439    Table[RTLIB::ATOMIC_FETCH_AND_4] = unsupported;
440    Table[RTLIB::ATOMIC_FETCH_AND_8] = unsupported;
441    Table[RTLIB::ATOMIC_FETCH_AND_16] = unsupported;
442
443    Table[RTLIB::ATOMIC_FETCH_OR_1] = unsupported;
444    Table[RTLIB::ATOMIC_FETCH_OR_2] = unsupported;
445    Table[RTLIB::ATOMIC_FETCH_OR_4] = unsupported;
446    Table[RTLIB::ATOMIC_FETCH_OR_8] = unsupported;
447    Table[RTLIB::ATOMIC_FETCH_OR_16] = unsupported;
448
449    Table[RTLIB::ATOMIC_FETCH_XOR_1] = unsupported;
450    Table[RTLIB::ATOMIC_FETCH_XOR_2] = unsupported;
451    Table[RTLIB::ATOMIC_FETCH_XOR_4] = unsupported;
452    Table[RTLIB::ATOMIC_FETCH_XOR_8] = unsupported;
453    Table[RTLIB::ATOMIC_FETCH_XOR_16] = unsupported;
454
455    Table[RTLIB::ATOMIC_FETCH_NAND_1] = unsupported;
456    Table[RTLIB::ATOMIC_FETCH_NAND_2] = unsupported;
457    Table[RTLIB::ATOMIC_FETCH_NAND_4] = unsupported;
458    Table[RTLIB::ATOMIC_FETCH_NAND_8] = unsupported;
459    Table[RTLIB::ATOMIC_FETCH_NAND_16] = unsupported;
460  }
461};
462
463ManagedStatic<RuntimeLibcallSignatureTable> RuntimeLibcallSignatures;
464
465// Maps libcall names to their RTLIB::Libcall number. Builds the map in a
466// constructor for use with ManagedStatic
467struct StaticLibcallNameMap {
468  StringMap<RTLIB::Libcall> Map;
469  StaticLibcallNameMap() {
470    static const std::pair<const char *, RTLIB::Libcall> NameLibcalls[] = {
471#define HANDLE_LIBCALL(code, name) {(const char *)name, RTLIB::code},
472#include "llvm/IR/RuntimeLibcalls.def"
473#undef HANDLE_LIBCALL
474    };
475    for (const auto &NameLibcall : NameLibcalls) {
476      if (NameLibcall.first != nullptr &&
477          RuntimeLibcallSignatures->Table[NameLibcall.second] != unsupported) {
478        assert(Map.find(NameLibcall.first) == Map.end() &&
479               "duplicate libcall names in name map");
480        Map[NameLibcall.first] = NameLibcall.second;
481      }
482    }
483  }
484};
485
486} // end anonymous namespace
487
488void llvm::GetLibcallSignature(const WebAssemblySubtarget &Subtarget,
489                               RTLIB::Libcall LC,
490                               SmallVectorImpl<wasm::ValType> &Rets,
491                               SmallVectorImpl<wasm::ValType> &Params) {
492  assert(Rets.empty());
493  assert(Params.empty());
494
495  wasm::ValType iPTR =
496      Subtarget.hasAddr64() ? wasm::ValType::I64 : wasm::ValType::I32;
497
498  auto &Table = RuntimeLibcallSignatures->Table;
499  switch (Table[LC]) {
500  case func:
501    break;
502  case f32_func_f32:
503    Rets.push_back(wasm::ValType::F32);
504    Params.push_back(wasm::ValType::F32);
505    break;
506  case f32_func_f64:
507    Rets.push_back(wasm::ValType::F32);
508    Params.push_back(wasm::ValType::F64);
509    break;
510  case f32_func_i32:
511    Rets.push_back(wasm::ValType::F32);
512    Params.push_back(wasm::ValType::I32);
513    break;
514  case f32_func_i64:
515    Rets.push_back(wasm::ValType::F32);
516    Params.push_back(wasm::ValType::I64);
517    break;
518  case f32_func_i16:
519    Rets.push_back(wasm::ValType::F32);
520    Params.push_back(wasm::ValType::I32);
521    break;
522  case f64_func_f32:
523    Rets.push_back(wasm::ValType::F64);
524    Params.push_back(wasm::ValType::F32);
525    break;
526  case f64_func_f64:
527    Rets.push_back(wasm::ValType::F64);
528    Params.push_back(wasm::ValType::F64);
529    break;
530  case f64_func_i32:
531    Rets.push_back(wasm::ValType::F64);
532    Params.push_back(wasm::ValType::I32);
533    break;
534  case f64_func_i64:
535    Rets.push_back(wasm::ValType::F64);
536    Params.push_back(wasm::ValType::I64);
537    break;
538  case i32_func_f32:
539    Rets.push_back(wasm::ValType::I32);
540    Params.push_back(wasm::ValType::F32);
541    break;
542  case i32_func_f64:
543    Rets.push_back(wasm::ValType::I32);
544    Params.push_back(wasm::ValType::F64);
545    break;
546  case i32_func_i32:
547    Rets.push_back(wasm::ValType::I32);
548    Params.push_back(wasm::ValType::I32);
549    break;
550  case i64_func_f32:
551    Rets.push_back(wasm::ValType::I64);
552    Params.push_back(wasm::ValType::F32);
553    break;
554  case i64_func_f64:
555    Rets.push_back(wasm::ValType::I64);
556    Params.push_back(wasm::ValType::F64);
557    break;
558  case i64_func_i64:
559    Rets.push_back(wasm::ValType::I64);
560    Params.push_back(wasm::ValType::I64);
561    break;
562  case f32_func_f32_f32:
563    Rets.push_back(wasm::ValType::F32);
564    Params.push_back(wasm::ValType::F32);
565    Params.push_back(wasm::ValType::F32);
566    break;
567  case f32_func_f32_i32:
568    Rets.push_back(wasm::ValType::F32);
569    Params.push_back(wasm::ValType::F32);
570    Params.push_back(wasm::ValType::I32);
571    break;
572  case f32_func_i64_i64:
573    Rets.push_back(wasm::ValType::F32);
574    Params.push_back(wasm::ValType::I64);
575    Params.push_back(wasm::ValType::I64);
576    break;
577  case f64_func_f64_f64:
578    Rets.push_back(wasm::ValType::F64);
579    Params.push_back(wasm::ValType::F64);
580    Params.push_back(wasm::ValType::F64);
581    break;
582  case f64_func_f64_i32:
583    Rets.push_back(wasm::ValType::F64);
584    Params.push_back(wasm::ValType::F64);
585    Params.push_back(wasm::ValType::I32);
586    break;
587  case f64_func_i64_i64:
588    Rets.push_back(wasm::ValType::F64);
589    Params.push_back(wasm::ValType::I64);
590    Params.push_back(wasm::ValType::I64);
591    break;
592  case i16_func_f32:
593    Rets.push_back(wasm::ValType::I32);
594    Params.push_back(wasm::ValType::F32);
595    break;
596  case i8_func_i8_i8:
597    Rets.push_back(wasm::ValType::I32);
598    Params.push_back(wasm::ValType::I32);
599    Params.push_back(wasm::ValType::I32);
600    break;
601  case func_f32_iPTR_iPTR:
602    Params.push_back(wasm::ValType::F32);
603    Params.push_back(iPTR);
604    Params.push_back(iPTR);
605    break;
606  case func_f64_iPTR_iPTR:
607    Params.push_back(wasm::ValType::F64);
608    Params.push_back(iPTR);
609    Params.push_back(iPTR);
610    break;
611  case i16_func_i16_i16:
612    Rets.push_back(wasm::ValType::I32);
613    Params.push_back(wasm::ValType::I32);
614    Params.push_back(wasm::ValType::I32);
615    break;
616  case i32_func_f32_f32:
617    Rets.push_back(wasm::ValType::I32);
618    Params.push_back(wasm::ValType::F32);
619    Params.push_back(wasm::ValType::F32);
620    break;
621  case i32_func_f64_f64:
622    Rets.push_back(wasm::ValType::I32);
623    Params.push_back(wasm::ValType::F64);
624    Params.push_back(wasm::ValType::F64);
625    break;
626  case i32_func_i32_i32:
627    Rets.push_back(wasm::ValType::I32);
628    Params.push_back(wasm::ValType::I32);
629    Params.push_back(wasm::ValType::I32);
630    break;
631  case i32_func_i32_i32_iPTR:
632    Rets.push_back(wasm::ValType::I32);
633    Params.push_back(wasm::ValType::I32);
634    Params.push_back(wasm::ValType::I32);
635    Params.push_back(iPTR);
636    break;
637  case i64_func_i64_i64:
638    Rets.push_back(wasm::ValType::I64);
639    Params.push_back(wasm::ValType::I64);
640    Params.push_back(wasm::ValType::I64);
641    break;
642  case i64_func_i64_i64_iPTR:
643    Rets.push_back(wasm::ValType::I64);
644    Params.push_back(wasm::ValType::I64);
645    Params.push_back(wasm::ValType::I64);
646    Params.push_back(iPTR);
647    break;
648  case i64_i64_func_f32:
649#if 0 // TODO: Enable this when wasm gets multiple-return-value support.
650    Rets.push_back(wasm::ValType::I64);
651    Rets.push_back(wasm::ValType::I64);
652#else
653    Params.push_back(iPTR);
654#endif
655    Params.push_back(wasm::ValType::F32);
656    break;
657  case i64_i64_func_f64:
658#if 0 // TODO: Enable this when wasm gets multiple-return-value support.
659    Rets.push_back(wasm::ValType::I64);
660    Rets.push_back(wasm::ValType::I64);
661#else
662    Params.push_back(iPTR);
663#endif
664    Params.push_back(wasm::ValType::F64);
665    break;
666  case i16_i16_func_i16_i16:
667#if 0 // TODO: Enable this when wasm gets multiple-return-value support.
668    Rets.push_back(wasm::ValType::I32);
669    Rets.push_back(wasm::ValType::I32);
670#else
671    Params.push_back(iPTR);
672#endif
673    Params.push_back(wasm::ValType::I32);
674    Params.push_back(wasm::ValType::I32);
675    break;
676  case i32_i32_func_i32_i32:
677#if 0 // TODO: Enable this when wasm gets multiple-return-value support.
678    Rets.push_back(wasm::ValType::I32);
679    Rets.push_back(wasm::ValType::I32);
680#else
681    Params.push_back(iPTR);
682#endif
683    Params.push_back(wasm::ValType::I32);
684    Params.push_back(wasm::ValType::I32);
685    break;
686  case i64_i64_func_i64_i64:
687#if 0 // TODO: Enable this when wasm gets multiple-return-value support.
688    Rets.push_back(wasm::ValType::I64);
689    Rets.push_back(wasm::ValType::I64);
690#else
691    Params.push_back(iPTR);
692#endif
693    Params.push_back(wasm::ValType::I64);
694    Params.push_back(wasm::ValType::I64);
695    break;
696  case i64_i64_func_i64_i64_i64_i64:
697#if 0 // TODO: Enable this when wasm gets multiple-return-value support.
698    Rets.push_back(wasm::ValType::I64);
699    Rets.push_back(wasm::ValType::I64);
700#else
701    Params.push_back(iPTR);
702#endif
703    Params.push_back(wasm::ValType::I64);
704    Params.push_back(wasm::ValType::I64);
705    Params.push_back(wasm::ValType::I64);
706    Params.push_back(wasm::ValType::I64);
707    break;
708  case i64_i64_func_i64_i64_i64_i64_iPTR:
709#if 0 // TODO: Enable this when wasm gets multiple-return-value support.
710    Rets.push_back(wasm::ValType::I64);
711    Rets.push_back(wasm::ValType::I64);
712#else
713    Params.push_back(iPTR);
714#endif
715    Params.push_back(wasm::ValType::I64);
716    Params.push_back(wasm::ValType::I64);
717    Params.push_back(wasm::ValType::I64);
718    Params.push_back(wasm::ValType::I64);
719    Params.push_back(iPTR);
720    break;
721  case i64_i64_i64_i64_func_i64_i64_i64_i64:
722#if 0 // TODO: Enable this when wasm gets multiple-return-value support.
723    Rets.push_back(wasm::ValType::I64);
724    Rets.push_back(wasm::ValType::I64);
725    Rets.push_back(wasm::ValType::I64);
726    Rets.push_back(wasm::ValType::I64);
727#else
728    Params.push_back(iPTR);
729#endif
730    Params.push_back(wasm::ValType::I64);
731    Params.push_back(wasm::ValType::I64);
732    Params.push_back(wasm::ValType::I64);
733    Params.push_back(wasm::ValType::I64);
734    break;
735  case i64_i64_func_i64_i64_i32:
736#if 0 // TODO: Enable this when wasm gets multiple-return-value support.
737    Rets.push_back(wasm::ValType::I64);
738    Rets.push_back(wasm::ValType::I64);
739    Rets.push_back(wasm::ValType::I64);
740    Rets.push_back(wasm::ValType::I64);
741#else
742    Params.push_back(iPTR);
743#endif
744    Params.push_back(wasm::ValType::I64);
745    Params.push_back(wasm::ValType::I64);
746    Params.push_back(wasm::ValType::I32);
747    break;
748  case iPTR_func_iPTR_i32_iPTR:
749    Rets.push_back(iPTR);
750    Params.push_back(iPTR);
751    Params.push_back(wasm::ValType::I32);
752    Params.push_back(iPTR);
753    break;
754  case iPTR_func_iPTR_iPTR_iPTR:
755    Rets.push_back(iPTR);
756    Params.push_back(iPTR);
757    Params.push_back(iPTR);
758    Params.push_back(iPTR);
759    break;
760  case f32_func_f32_f32_f32:
761    Rets.push_back(wasm::ValType::F32);
762    Params.push_back(wasm::ValType::F32);
763    Params.push_back(wasm::ValType::F32);
764    Params.push_back(wasm::ValType::F32);
765    break;
766  case f64_func_f64_f64_f64:
767    Rets.push_back(wasm::ValType::F64);
768    Params.push_back(wasm::ValType::F64);
769    Params.push_back(wasm::ValType::F64);
770    Params.push_back(wasm::ValType::F64);
771    break;
772  case func_i64_i64_iPTR_iPTR:
773    Params.push_back(wasm::ValType::I64);
774    Params.push_back(wasm::ValType::I64);
775    Params.push_back(iPTR);
776    Params.push_back(iPTR);
777    break;
778  case func_iPTR_f32:
779    Params.push_back(iPTR);
780    Params.push_back(wasm::ValType::F32);
781    break;
782  case func_iPTR_f64:
783    Params.push_back(iPTR);
784    Params.push_back(wasm::ValType::F64);
785    break;
786  case func_iPTR_i32:
787    Params.push_back(iPTR);
788    Params.push_back(wasm::ValType::I32);
789    break;
790  case func_iPTR_i64:
791    Params.push_back(iPTR);
792    Params.push_back(wasm::ValType::I64);
793    break;
794  case func_iPTR_i64_i64:
795    Params.push_back(iPTR);
796    Params.push_back(wasm::ValType::I64);
797    Params.push_back(wasm::ValType::I64);
798    break;
799  case func_iPTR_i64_i64_i64_i64:
800    Params.push_back(iPTR);
801    Params.push_back(wasm::ValType::I64);
802    Params.push_back(wasm::ValType::I64);
803    Params.push_back(wasm::ValType::I64);
804    Params.push_back(wasm::ValType::I64);
805    break;
806  case func_iPTR_i64_i64_i64_i64_i64_i64:
807    Params.push_back(iPTR);
808    Params.push_back(wasm::ValType::I64);
809    Params.push_back(wasm::ValType::I64);
810    Params.push_back(wasm::ValType::I64);
811    Params.push_back(wasm::ValType::I64);
812    Params.push_back(wasm::ValType::I64);
813    Params.push_back(wasm::ValType::I64);
814    break;
815  case i32_func_i64_i64:
816    Rets.push_back(wasm::ValType::I32);
817    Params.push_back(wasm::ValType::I64);
818    Params.push_back(wasm::ValType::I64);
819    break;
820  case i32_func_i64_i64_i64_i64:
821    Rets.push_back(wasm::ValType::I32);
822    Params.push_back(wasm::ValType::I64);
823    Params.push_back(wasm::ValType::I64);
824    Params.push_back(wasm::ValType::I64);
825    Params.push_back(wasm::ValType::I64);
826    break;
827  case unsupported:
828    llvm_unreachable("unsupported runtime library signature");
829  }
830}
831
832static ManagedStatic<StaticLibcallNameMap> LibcallNameMap;
833// TODO: If the RTLIB::Libcall-taking flavor of GetSignature remains unsed
834// other than here, just roll its logic into this version.
835void llvm::GetLibcallSignature(const WebAssemblySubtarget &Subtarget,
836                               const char *Name,
837                               SmallVectorImpl<wasm::ValType> &Rets,
838                               SmallVectorImpl<wasm::ValType> &Params) {
839  auto &Map = LibcallNameMap->Map;
840  auto val = Map.find(Name);
841  assert(val != Map.end() && "unexpected runtime library name");
842  return GetLibcallSignature(Subtarget, val->second, Rets, Params);
843}
844