1// CodeGen/RuntimeLibcallSignatures.cpp - R.T. Lib. Call Signatures -*- C++ -*--
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 contains signature information for runtime libcalls.
11///
12/// CodeGen uses external symbols, which it refers to by name. The WebAssembly
13/// target needs type information for all functions. This file contains a big
14/// table providing type signatures for all runtime library functions that LLVM
15/// uses.
16///
17/// This is currently a fairly heavy-handed solution.
18///
19//===----------------------------------------------------------------------===//
20
21#include "WebAssemblyRuntimeLibcallSignatures.h"
22#include "WebAssemblySubtarget.h"
23#include "llvm/CodeGen/RuntimeLibcalls.h"
24
25using namespace llvm;
26
27namespace {
28
29enum RuntimeLibcallSignature {
30  func,
31  f32_func_f32,
32  f32_func_f64,
33  f32_func_i32,
34  f32_func_i64,
35  f32_func_i16,
36  f64_func_f32,
37  f64_func_f64,
38  f64_func_i32,
39  f64_func_i64,
40  i32_func_f32,
41  i32_func_f64,
42  i32_func_i32,
43  i64_func_f32,
44  i64_func_f64,
45  i64_func_i64,
46  f32_func_f32_f32,
47  f32_func_f32_i32,
48  f32_func_i64_i64,
49  f64_func_f64_f64,
50  f64_func_f64_i32,
51  f64_func_i64_i64,
52  i16_func_f32,
53  i16_func_f64,
54  i16_func_i64_i64,
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_i32,
66  i64_i64_func_i64,
67  i64_i64_func_f32,
68  i64_i64_func_f64,
69  i16_i16_func_i16_i16,
70  i32_i32_func_i32_i32,
71  i64_i64_func_i64_i64,
72  i64_i64_func_i64_i64_i64_i64,
73  i64_i64_func_i64_i64_i64_i64_iPTR,
74  i64_i64_i64_i64_func_i64_i64_i64_i64,
75  i64_i64_func_i64_i64_i32,
76  i64_i64_func_i64_i64_i64_i64_i64_i64,
77  iPTR_func_i32,
78  iPTR_func_iPTR_i32_iPTR,
79  iPTR_func_iPTR_iPTR_iPTR,
80  f32_func_f32_f32_f32,
81  f64_func_f64_f64_f64,
82  func_i64_i64_iPTR_iPTR,
83  i32_func_i64_i64,
84  i32_func_i64_i64_i64_i64,
85  iPTR_func_f32,
86  iPTR_func_f64,
87  iPTR_func_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] = i64_i64_func_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] = i64_i64_func_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] = i64_i64_func_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] = i64_i64_func_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] = i64_i64_func_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] = i64_i64_func_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] = i64_i64_func_i64_i64_i32;
173    Table[RTLIB::SQRT_F32] = f32_func_f32;
174    Table[RTLIB::SQRT_F64] = f64_func_f64;
175    Table[RTLIB::SQRT_F128] = i64_i64_func_i64_i64;
176    Table[RTLIB::CBRT_F32] = f32_func_f32;
177    Table[RTLIB::CBRT_F64] = f64_func_f64;
178    Table[RTLIB::CBRT_F128] = i64_i64_func_i64_i64;
179    Table[RTLIB::LOG_F32] = f32_func_f32;
180    Table[RTLIB::LOG_F64] = f64_func_f64;
181    Table[RTLIB::LOG_F128] = i64_i64_func_i64_i64;
182    Table[RTLIB::LOG2_F32] = f32_func_f32;
183    Table[RTLIB::LOG2_F64] = f64_func_f64;
184    Table[RTLIB::LOG2_F128] = i64_i64_func_i64_i64;
185    Table[RTLIB::LOG10_F32] = f32_func_f32;
186    Table[RTLIB::LOG10_F64] = f64_func_f64;
187    Table[RTLIB::LOG10_F128] = i64_i64_func_i64_i64;
188    Table[RTLIB::EXP_F32] = f32_func_f32;
189    Table[RTLIB::EXP_F64] = f64_func_f64;
190    Table[RTLIB::EXP_F128] = i64_i64_func_i64_i64;
191    Table[RTLIB::EXP2_F32] = f32_func_f32;
192    Table[RTLIB::EXP2_F64] = f64_func_f64;
193    Table[RTLIB::EXP2_F128] = i64_i64_func_i64_i64;
194    Table[RTLIB::EXP10_F32] = f32_func_f32;
195    Table[RTLIB::EXP10_F64] = f64_func_f64;
196    Table[RTLIB::EXP10_F128] = i64_i64_func_i64_i64;
197    Table[RTLIB::SIN_F32] = f32_func_f32;
198    Table[RTLIB::SIN_F64] = f64_func_f64;
199    Table[RTLIB::SIN_F128] = i64_i64_func_i64_i64;
200    Table[RTLIB::COS_F32] = f32_func_f32;
201    Table[RTLIB::COS_F64] = f64_func_f64;
202    Table[RTLIB::COS_F128] = i64_i64_func_i64_i64;
203    Table[RTLIB::SINCOS_F32] = func_f32_iPTR_iPTR;
204    Table[RTLIB::SINCOS_F64] = func_f64_iPTR_iPTR;
205    Table[RTLIB::SINCOS_F128] = func_i64_i64_iPTR_iPTR;
206    Table[RTLIB::POW_F32] = f32_func_f32_f32;
207    Table[RTLIB::POW_F64] = f64_func_f64_f64;
208    Table[RTLIB::POW_F128] = i64_i64_func_i64_i64_i64_i64;
209    Table[RTLIB::CEIL_F32] = f32_func_f32;
210    Table[RTLIB::CEIL_F64] = f64_func_f64;
211    Table[RTLIB::CEIL_F128] = i64_i64_func_i64_i64;
212    Table[RTLIB::TRUNC_F32] = f32_func_f32;
213    Table[RTLIB::TRUNC_F64] = f64_func_f64;
214    Table[RTLIB::TRUNC_F128] = i64_i64_func_i64_i64;
215    Table[RTLIB::RINT_F32] = f32_func_f32;
216    Table[RTLIB::RINT_F64] = f64_func_f64;
217    Table[RTLIB::RINT_F128] = i64_i64_func_i64_i64;
218    Table[RTLIB::NEARBYINT_F32] = f32_func_f32;
219    Table[RTLIB::NEARBYINT_F64] = f64_func_f64;
220    Table[RTLIB::NEARBYINT_F128] = i64_i64_func_i64_i64;
221    Table[RTLIB::ROUND_F32] = f32_func_f32;
222    Table[RTLIB::ROUND_F64] = f64_func_f64;
223    Table[RTLIB::ROUND_F128] = i64_i64_func_i64_i64;
224    Table[RTLIB::ROUNDEVEN_F32] = f32_func_f32;
225    Table[RTLIB::ROUNDEVEN_F64] = f64_func_f64;
226    Table[RTLIB::ROUNDEVEN_F128] = i64_i64_func_i64_i64;
227    Table[RTLIB::LROUND_F32] = iPTR_func_f32;
228    Table[RTLIB::LROUND_F64] = iPTR_func_f64;
229    Table[RTLIB::LROUND_F128] = iPTR_func_i64_i64;
230    Table[RTLIB::LLROUND_F32] = i64_func_f32;
231    Table[RTLIB::LLROUND_F64] = i64_func_f64;
232    Table[RTLIB::LLROUND_F128] = i64_func_i64_i64;
233    Table[RTLIB::LRINT_F32] = iPTR_func_f32;
234    Table[RTLIB::LRINT_F64] = iPTR_func_f64;
235    Table[RTLIB::LRINT_F128] = iPTR_func_i64_i64;
236    Table[RTLIB::LLRINT_F32] = i64_func_f32;
237    Table[RTLIB::LLRINT_F64] = i64_func_f64;
238    Table[RTLIB::LLRINT_F128] = i64_func_i64_i64;
239    Table[RTLIB::FLOOR_F32] = f32_func_f32;
240    Table[RTLIB::FLOOR_F64] = f64_func_f64;
241    Table[RTLIB::FLOOR_F128] = i64_i64_func_i64_i64;
242    Table[RTLIB::COPYSIGN_F32] = f32_func_f32_f32;
243    Table[RTLIB::COPYSIGN_F64] = f64_func_f64_f64;
244    Table[RTLIB::COPYSIGN_F128] = i64_i64_func_i64_i64_i64_i64;
245    Table[RTLIB::FMIN_F32] = f32_func_f32_f32;
246    Table[RTLIB::FMIN_F64] = f64_func_f64_f64;
247    Table[RTLIB::FMIN_F128] = i64_i64_func_i64_i64_i64_i64;
248    Table[RTLIB::FMAX_F32] = f32_func_f32_f32;
249    Table[RTLIB::FMAX_F64] = f64_func_f64_f64;
250    Table[RTLIB::FMAX_F128] = i64_i64_func_i64_i64_i64_i64;
251    Table[RTLIB::LDEXP_F32] = f32_func_f32_i32;
252    Table[RTLIB::LDEXP_F64] = f64_func_f64_i32;
253    Table[RTLIB::LDEXP_F128] = i64_i64_func_i64_i64_i32;
254    Table[RTLIB::FREXP_F32] = f32_func_f32_i32;
255    Table[RTLIB::FREXP_F64] = f64_func_f64_i32;
256    Table[RTLIB::FREXP_F128] = i64_i64_func_i64_i64_i32;
257
258    // Conversion
259    // All F80 and PPCF128 routines are unsupported.
260    Table[RTLIB::FPEXT_F64_F128] = i64_i64_func_f64;
261    Table[RTLIB::FPEXT_F32_F128] = i64_i64_func_f32;
262    Table[RTLIB::FPEXT_F32_F64] = f64_func_f32;
263    Table[RTLIB::FPEXT_F16_F32] = f32_func_i16;
264    Table[RTLIB::FPROUND_F32_F16] = i16_func_f32;
265    Table[RTLIB::FPROUND_F64_F16] = i16_func_f64;
266    Table[RTLIB::FPROUND_F64_F32] = f32_func_f64;
267    Table[RTLIB::FPROUND_F128_F16] = i16_func_i64_i64;
268    Table[RTLIB::FPROUND_F128_F32] = f32_func_i64_i64;
269    Table[RTLIB::FPROUND_F128_F64] = f64_func_i64_i64;
270    Table[RTLIB::FPTOSINT_F32_I32] = i32_func_f32;
271    Table[RTLIB::FPTOSINT_F32_I64] = i64_func_f32;
272    Table[RTLIB::FPTOSINT_F32_I128] = i64_i64_func_f32;
273    Table[RTLIB::FPTOSINT_F64_I32] = i32_func_f64;
274    Table[RTLIB::FPTOSINT_F64_I64] = i64_func_f64;
275    Table[RTLIB::FPTOSINT_F64_I128] = i64_i64_func_f64;
276    Table[RTLIB::FPTOSINT_F128_I32] = i32_func_i64_i64;
277    Table[RTLIB::FPTOSINT_F128_I64] = i64_func_i64_i64;
278    Table[RTLIB::FPTOSINT_F128_I128] = i64_i64_func_i64_i64;
279    Table[RTLIB::FPTOUINT_F32_I32] = i32_func_f32;
280    Table[RTLIB::FPTOUINT_F32_I64] = i64_func_f32;
281    Table[RTLIB::FPTOUINT_F32_I128] = i64_i64_func_f32;
282    Table[RTLIB::FPTOUINT_F64_I32] = i32_func_f64;
283    Table[RTLIB::FPTOUINT_F64_I64] = i64_func_f64;
284    Table[RTLIB::FPTOUINT_F64_I128] = i64_i64_func_f64;
285    Table[RTLIB::FPTOUINT_F128_I32] = i32_func_i64_i64;
286    Table[RTLIB::FPTOUINT_F128_I64] = i64_func_i64_i64;
287    Table[RTLIB::FPTOUINT_F128_I128] = i64_i64_func_i64_i64;
288    Table[RTLIB::SINTTOFP_I32_F32] = f32_func_i32;
289    Table[RTLIB::SINTTOFP_I32_F64] = f64_func_i32;
290    Table[RTLIB::SINTTOFP_I32_F128] = i64_i64_func_i32;
291    Table[RTLIB::SINTTOFP_I64_F32] = f32_func_i64;
292    Table[RTLIB::SINTTOFP_I64_F64] = f64_func_i64;
293    Table[RTLIB::SINTTOFP_I64_F128] = i64_i64_func_i64;
294    Table[RTLIB::SINTTOFP_I128_F32] = f32_func_i64_i64;
295    Table[RTLIB::SINTTOFP_I128_F64] = f64_func_i64_i64;
296    Table[RTLIB::SINTTOFP_I128_F128] = i64_i64_func_i64_i64;
297    Table[RTLIB::UINTTOFP_I32_F32] = f32_func_i32;
298    Table[RTLIB::UINTTOFP_I32_F64] = f64_func_i64;
299    Table[RTLIB::UINTTOFP_I32_F128] = i64_i64_func_i32;
300    Table[RTLIB::UINTTOFP_I64_F32] = f32_func_i64;
301    Table[RTLIB::UINTTOFP_I64_F64] = f64_func_i64;
302    Table[RTLIB::UINTTOFP_I64_F128] = i64_i64_func_i64;
303    Table[RTLIB::UINTTOFP_I128_F32] = f32_func_i64_i64;
304    Table[RTLIB::UINTTOFP_I128_F64] = f64_func_i64_i64;
305    Table[RTLIB::UINTTOFP_I128_F128] = i64_i64_func_i64_i64;
306
307    // Comparison
308    // ALl F80 and PPCF128 routines are unsupported.
309    Table[RTLIB::OEQ_F32] = i32_func_f32_f32;
310    Table[RTLIB::OEQ_F64] = i32_func_f64_f64;
311    Table[RTLIB::OEQ_F128] = i32_func_i64_i64_i64_i64;
312    Table[RTLIB::UNE_F32] = i32_func_f32_f32;
313    Table[RTLIB::UNE_F64] = i32_func_f64_f64;
314    Table[RTLIB::UNE_F128] = i32_func_i64_i64_i64_i64;
315    Table[RTLIB::OGE_F32] = i32_func_f32_f32;
316    Table[RTLIB::OGE_F64] = i32_func_f64_f64;
317    Table[RTLIB::OGE_F128] = i32_func_i64_i64_i64_i64;
318    Table[RTLIB::OLT_F32] = i32_func_f32_f32;
319    Table[RTLIB::OLT_F64] = i32_func_f64_f64;
320    Table[RTLIB::OLT_F128] = i32_func_i64_i64_i64_i64;
321    Table[RTLIB::OLE_F32] = i32_func_f32_f32;
322    Table[RTLIB::OLE_F64] = i32_func_f64_f64;
323    Table[RTLIB::OLE_F128] = i32_func_i64_i64_i64_i64;
324    Table[RTLIB::OGT_F32] = i32_func_f32_f32;
325    Table[RTLIB::OGT_F64] = i32_func_f64_f64;
326    Table[RTLIB::OGT_F128] = i32_func_i64_i64_i64_i64;
327    Table[RTLIB::UO_F32] = i32_func_f32_f32;
328    Table[RTLIB::UO_F64] = i32_func_f64_f64;
329    Table[RTLIB::UO_F128] = i32_func_i64_i64_i64_i64;
330
331    // Memory
332    Table[RTLIB::MEMCPY] = iPTR_func_iPTR_iPTR_iPTR;
333    Table[RTLIB::MEMSET] = iPTR_func_iPTR_i32_iPTR;
334    Table[RTLIB::MEMMOVE] = iPTR_func_iPTR_iPTR_iPTR;
335
336    // __stack_chk_fail
337    Table[RTLIB::STACKPROTECTOR_CHECK_FAIL] = func;
338
339    // Return address handling
340    Table[RTLIB::RETURN_ADDRESS] = iPTR_func_i32;
341
342    // Element-wise Atomic memory
343    // TODO: Fix these when we implement atomic support
344    Table[RTLIB::MEMCPY_ELEMENT_UNORDERED_ATOMIC_1] = unsupported;
345    Table[RTLIB::MEMCPY_ELEMENT_UNORDERED_ATOMIC_2] = unsupported;
346    Table[RTLIB::MEMCPY_ELEMENT_UNORDERED_ATOMIC_4] = unsupported;
347    Table[RTLIB::MEMCPY_ELEMENT_UNORDERED_ATOMIC_8] = unsupported;
348    Table[RTLIB::MEMCPY_ELEMENT_UNORDERED_ATOMIC_16] = unsupported;
349    Table[RTLIB::MEMMOVE_ELEMENT_UNORDERED_ATOMIC_1] = unsupported;
350    Table[RTLIB::MEMMOVE_ELEMENT_UNORDERED_ATOMIC_2] = unsupported;
351    Table[RTLIB::MEMMOVE_ELEMENT_UNORDERED_ATOMIC_4] = unsupported;
352    Table[RTLIB::MEMMOVE_ELEMENT_UNORDERED_ATOMIC_8] = unsupported;
353    Table[RTLIB::MEMMOVE_ELEMENT_UNORDERED_ATOMIC_16] = unsupported;
354
355    Table[RTLIB::MEMSET_ELEMENT_UNORDERED_ATOMIC_1] = unsupported;
356    Table[RTLIB::MEMSET_ELEMENT_UNORDERED_ATOMIC_2] = unsupported;
357    Table[RTLIB::MEMSET_ELEMENT_UNORDERED_ATOMIC_4] = unsupported;
358    Table[RTLIB::MEMSET_ELEMENT_UNORDERED_ATOMIC_8] = unsupported;
359    Table[RTLIB::MEMSET_ELEMENT_UNORDERED_ATOMIC_16] = unsupported;
360
361    // Atomic '__sync_*' libcalls.
362    // TODO: Fix these when we implement atomic support
363    Table[RTLIB::SYNC_VAL_COMPARE_AND_SWAP_1] = unsupported;
364    Table[RTLIB::SYNC_VAL_COMPARE_AND_SWAP_2] = unsupported;
365    Table[RTLIB::SYNC_VAL_COMPARE_AND_SWAP_4] = unsupported;
366    Table[RTLIB::SYNC_VAL_COMPARE_AND_SWAP_8] = unsupported;
367    Table[RTLIB::SYNC_VAL_COMPARE_AND_SWAP_16] = unsupported;
368    Table[RTLIB::SYNC_LOCK_TEST_AND_SET_1] = unsupported;
369    Table[RTLIB::SYNC_LOCK_TEST_AND_SET_2] = unsupported;
370    Table[RTLIB::SYNC_LOCK_TEST_AND_SET_4] = unsupported;
371    Table[RTLIB::SYNC_LOCK_TEST_AND_SET_8] = unsupported;
372    Table[RTLIB::SYNC_LOCK_TEST_AND_SET_16] = unsupported;
373    Table[RTLIB::SYNC_FETCH_AND_ADD_1] = unsupported;
374    Table[RTLIB::SYNC_FETCH_AND_ADD_2] = unsupported;
375    Table[RTLIB::SYNC_FETCH_AND_ADD_4] = unsupported;
376    Table[RTLIB::SYNC_FETCH_AND_ADD_8] = unsupported;
377    Table[RTLIB::SYNC_FETCH_AND_ADD_16] = unsupported;
378    Table[RTLIB::SYNC_FETCH_AND_SUB_1] = unsupported;
379    Table[RTLIB::SYNC_FETCH_AND_SUB_2] = unsupported;
380    Table[RTLIB::SYNC_FETCH_AND_SUB_4] = unsupported;
381    Table[RTLIB::SYNC_FETCH_AND_SUB_8] = unsupported;
382    Table[RTLIB::SYNC_FETCH_AND_SUB_16] = unsupported;
383    Table[RTLIB::SYNC_FETCH_AND_AND_1] = unsupported;
384    Table[RTLIB::SYNC_FETCH_AND_AND_2] = unsupported;
385    Table[RTLIB::SYNC_FETCH_AND_AND_4] = unsupported;
386    Table[RTLIB::SYNC_FETCH_AND_AND_8] = unsupported;
387    Table[RTLIB::SYNC_FETCH_AND_AND_16] = unsupported;
388    Table[RTLIB::SYNC_FETCH_AND_OR_1] = unsupported;
389    Table[RTLIB::SYNC_FETCH_AND_OR_2] = unsupported;
390    Table[RTLIB::SYNC_FETCH_AND_OR_4] = unsupported;
391    Table[RTLIB::SYNC_FETCH_AND_OR_8] = unsupported;
392    Table[RTLIB::SYNC_FETCH_AND_OR_16] = unsupported;
393    Table[RTLIB::SYNC_FETCH_AND_XOR_1] = unsupported;
394    Table[RTLIB::SYNC_FETCH_AND_XOR_2] = unsupported;
395    Table[RTLIB::SYNC_FETCH_AND_XOR_4] = unsupported;
396    Table[RTLIB::SYNC_FETCH_AND_XOR_8] = unsupported;
397    Table[RTLIB::SYNC_FETCH_AND_XOR_16] = unsupported;
398    Table[RTLIB::SYNC_FETCH_AND_NAND_1] = unsupported;
399    Table[RTLIB::SYNC_FETCH_AND_NAND_2] = unsupported;
400    Table[RTLIB::SYNC_FETCH_AND_NAND_4] = unsupported;
401    Table[RTLIB::SYNC_FETCH_AND_NAND_8] = unsupported;
402    Table[RTLIB::SYNC_FETCH_AND_NAND_16] = unsupported;
403    Table[RTLIB::SYNC_FETCH_AND_MAX_1] = unsupported;
404    Table[RTLIB::SYNC_FETCH_AND_MAX_2] = unsupported;
405    Table[RTLIB::SYNC_FETCH_AND_MAX_4] = unsupported;
406    Table[RTLIB::SYNC_FETCH_AND_MAX_8] = unsupported;
407    Table[RTLIB::SYNC_FETCH_AND_MAX_16] = unsupported;
408    Table[RTLIB::SYNC_FETCH_AND_UMAX_1] = unsupported;
409    Table[RTLIB::SYNC_FETCH_AND_UMAX_2] = unsupported;
410    Table[RTLIB::SYNC_FETCH_AND_UMAX_4] = unsupported;
411    Table[RTLIB::SYNC_FETCH_AND_UMAX_8] = unsupported;
412    Table[RTLIB::SYNC_FETCH_AND_UMAX_16] = unsupported;
413    Table[RTLIB::SYNC_FETCH_AND_MIN_1] = unsupported;
414    Table[RTLIB::SYNC_FETCH_AND_MIN_2] = unsupported;
415    Table[RTLIB::SYNC_FETCH_AND_MIN_4] = unsupported;
416    Table[RTLIB::SYNC_FETCH_AND_MIN_8] = unsupported;
417    Table[RTLIB::SYNC_FETCH_AND_MIN_16] = unsupported;
418    Table[RTLIB::SYNC_FETCH_AND_UMIN_1] = unsupported;
419    Table[RTLIB::SYNC_FETCH_AND_UMIN_2] = unsupported;
420    Table[RTLIB::SYNC_FETCH_AND_UMIN_4] = unsupported;
421    Table[RTLIB::SYNC_FETCH_AND_UMIN_8] = unsupported;
422    Table[RTLIB::SYNC_FETCH_AND_UMIN_16] = unsupported;
423
424    // Atomic '__atomic_*' libcalls.
425    // TODO: Fix these when we implement atomic support
426    Table[RTLIB::ATOMIC_LOAD] = unsupported;
427    Table[RTLIB::ATOMIC_LOAD_1] = unsupported;
428    Table[RTLIB::ATOMIC_LOAD_2] = unsupported;
429    Table[RTLIB::ATOMIC_LOAD_4] = unsupported;
430    Table[RTLIB::ATOMIC_LOAD_8] = unsupported;
431    Table[RTLIB::ATOMIC_LOAD_16] = unsupported;
432
433    Table[RTLIB::ATOMIC_STORE] = unsupported;
434    Table[RTLIB::ATOMIC_STORE_1] = unsupported;
435    Table[RTLIB::ATOMIC_STORE_2] = unsupported;
436    Table[RTLIB::ATOMIC_STORE_4] = unsupported;
437    Table[RTLIB::ATOMIC_STORE_8] = unsupported;
438    Table[RTLIB::ATOMIC_STORE_16] = unsupported;
439
440    Table[RTLIB::ATOMIC_EXCHANGE] = unsupported;
441    Table[RTLIB::ATOMIC_EXCHANGE_1] = unsupported;
442    Table[RTLIB::ATOMIC_EXCHANGE_2] = unsupported;
443    Table[RTLIB::ATOMIC_EXCHANGE_4] = unsupported;
444    Table[RTLIB::ATOMIC_EXCHANGE_8] = unsupported;
445    Table[RTLIB::ATOMIC_EXCHANGE_16] = unsupported;
446
447    Table[RTLIB::ATOMIC_COMPARE_EXCHANGE] = unsupported;
448    Table[RTLIB::ATOMIC_COMPARE_EXCHANGE_1] = unsupported;
449    Table[RTLIB::ATOMIC_COMPARE_EXCHANGE_2] = unsupported;
450    Table[RTLIB::ATOMIC_COMPARE_EXCHANGE_4] = unsupported;
451    Table[RTLIB::ATOMIC_COMPARE_EXCHANGE_8] = unsupported;
452    Table[RTLIB::ATOMIC_COMPARE_EXCHANGE_16] = unsupported;
453
454    Table[RTLIB::ATOMIC_FETCH_ADD_1] = unsupported;
455    Table[RTLIB::ATOMIC_FETCH_ADD_2] = unsupported;
456    Table[RTLIB::ATOMIC_FETCH_ADD_4] = unsupported;
457    Table[RTLIB::ATOMIC_FETCH_ADD_8] = unsupported;
458    Table[RTLIB::ATOMIC_FETCH_ADD_16] = unsupported;
459
460    Table[RTLIB::ATOMIC_FETCH_SUB_1] = unsupported;
461    Table[RTLIB::ATOMIC_FETCH_SUB_2] = unsupported;
462    Table[RTLIB::ATOMIC_FETCH_SUB_4] = unsupported;
463    Table[RTLIB::ATOMIC_FETCH_SUB_8] = unsupported;
464    Table[RTLIB::ATOMIC_FETCH_SUB_16] = unsupported;
465
466    Table[RTLIB::ATOMIC_FETCH_AND_1] = unsupported;
467    Table[RTLIB::ATOMIC_FETCH_AND_2] = unsupported;
468    Table[RTLIB::ATOMIC_FETCH_AND_4] = unsupported;
469    Table[RTLIB::ATOMIC_FETCH_AND_8] = unsupported;
470    Table[RTLIB::ATOMIC_FETCH_AND_16] = unsupported;
471
472    Table[RTLIB::ATOMIC_FETCH_OR_1] = unsupported;
473    Table[RTLIB::ATOMIC_FETCH_OR_2] = unsupported;
474    Table[RTLIB::ATOMIC_FETCH_OR_4] = unsupported;
475    Table[RTLIB::ATOMIC_FETCH_OR_8] = unsupported;
476    Table[RTLIB::ATOMIC_FETCH_OR_16] = unsupported;
477
478    Table[RTLIB::ATOMIC_FETCH_XOR_1] = unsupported;
479    Table[RTLIB::ATOMIC_FETCH_XOR_2] = unsupported;
480    Table[RTLIB::ATOMIC_FETCH_XOR_4] = unsupported;
481    Table[RTLIB::ATOMIC_FETCH_XOR_8] = unsupported;
482    Table[RTLIB::ATOMIC_FETCH_XOR_16] = unsupported;
483
484    Table[RTLIB::ATOMIC_FETCH_NAND_1] = unsupported;
485    Table[RTLIB::ATOMIC_FETCH_NAND_2] = unsupported;
486    Table[RTLIB::ATOMIC_FETCH_NAND_4] = unsupported;
487    Table[RTLIB::ATOMIC_FETCH_NAND_8] = unsupported;
488    Table[RTLIB::ATOMIC_FETCH_NAND_16] = unsupported;
489  }
490};
491
492RuntimeLibcallSignatureTable &getRuntimeLibcallSignatures() {
493  static RuntimeLibcallSignatureTable RuntimeLibcallSignatures;
494  return RuntimeLibcallSignatures;
495}
496
497// Maps libcall names to their RTLIB::Libcall number. Builds the map in a
498// constructor for use with a static variable
499struct StaticLibcallNameMap {
500  StringMap<RTLIB::Libcall> Map;
501  StaticLibcallNameMap() {
502    static const std::pair<const char *, RTLIB::Libcall> NameLibcalls[] = {
503#define HANDLE_LIBCALL(code, name) {(const char *)name, RTLIB::code},
504#include "llvm/IR/RuntimeLibcalls.def"
505#undef HANDLE_LIBCALL
506    };
507    for (const auto &NameLibcall : NameLibcalls) {
508      if (NameLibcall.first != nullptr &&
509          getRuntimeLibcallSignatures().Table[NameLibcall.second] !=
510              unsupported) {
511        assert(!Map.contains(NameLibcall.first) &&
512               "duplicate libcall names in name map");
513        Map[NameLibcall.first] = NameLibcall.second;
514      }
515    }
516    // Override the __gnu_f2h_ieee/__gnu_h2f_ieee names so that the f32 name is
517    // consistent with the f64 and f128 names.
518    Map["__extendhfsf2"] = RTLIB::FPEXT_F16_F32;
519    Map["__truncsfhf2"] = RTLIB::FPROUND_F32_F16;
520
521    Map["emscripten_return_address"] = RTLIB::RETURN_ADDRESS;
522  }
523};
524
525} // end anonymous namespace
526
527void llvm::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
528                               RTLIB::Libcall LC,
529                               SmallVectorImpl<wasm::ValType> &Rets,
530                               SmallVectorImpl<wasm::ValType> &Params) {
531  assert(Rets.empty());
532  assert(Params.empty());
533
534  wasm::ValType PtrTy =
535      Subtarget.hasAddr64() ? wasm::ValType::I64 : wasm::ValType::I32;
536
537  auto &Table = getRuntimeLibcallSignatures().Table;
538  switch (Table[LC]) {
539  case func:
540    break;
541  case f32_func_f32:
542    Rets.push_back(wasm::ValType::F32);
543    Params.push_back(wasm::ValType::F32);
544    break;
545  case f32_func_f64:
546    Rets.push_back(wasm::ValType::F32);
547    Params.push_back(wasm::ValType::F64);
548    break;
549  case f32_func_i32:
550    Rets.push_back(wasm::ValType::F32);
551    Params.push_back(wasm::ValType::I32);
552    break;
553  case f32_func_i64:
554    Rets.push_back(wasm::ValType::F32);
555    Params.push_back(wasm::ValType::I64);
556    break;
557  case f32_func_i16:
558    Rets.push_back(wasm::ValType::F32);
559    Params.push_back(wasm::ValType::I32);
560    break;
561  case f64_func_f32:
562    Rets.push_back(wasm::ValType::F64);
563    Params.push_back(wasm::ValType::F32);
564    break;
565  case f64_func_f64:
566    Rets.push_back(wasm::ValType::F64);
567    Params.push_back(wasm::ValType::F64);
568    break;
569  case f64_func_i32:
570    Rets.push_back(wasm::ValType::F64);
571    Params.push_back(wasm::ValType::I32);
572    break;
573  case f64_func_i64:
574    Rets.push_back(wasm::ValType::F64);
575    Params.push_back(wasm::ValType::I64);
576    break;
577  case i32_func_f32:
578    Rets.push_back(wasm::ValType::I32);
579    Params.push_back(wasm::ValType::F32);
580    break;
581  case i32_func_f64:
582    Rets.push_back(wasm::ValType::I32);
583    Params.push_back(wasm::ValType::F64);
584    break;
585  case i32_func_i32:
586    Rets.push_back(wasm::ValType::I32);
587    Params.push_back(wasm::ValType::I32);
588    break;
589  case i64_func_f32:
590    Rets.push_back(wasm::ValType::I64);
591    Params.push_back(wasm::ValType::F32);
592    break;
593  case i64_func_f64:
594    Rets.push_back(wasm::ValType::I64);
595    Params.push_back(wasm::ValType::F64);
596    break;
597  case i64_func_i64:
598    Rets.push_back(wasm::ValType::I64);
599    Params.push_back(wasm::ValType::I64);
600    break;
601  case f32_func_f32_f32:
602    Rets.push_back(wasm::ValType::F32);
603    Params.push_back(wasm::ValType::F32);
604    Params.push_back(wasm::ValType::F32);
605    break;
606  case f32_func_f32_i32:
607    Rets.push_back(wasm::ValType::F32);
608    Params.push_back(wasm::ValType::F32);
609    Params.push_back(wasm::ValType::I32);
610    break;
611  case f32_func_i64_i64:
612    Rets.push_back(wasm::ValType::F32);
613    Params.push_back(wasm::ValType::I64);
614    Params.push_back(wasm::ValType::I64);
615    break;
616  case f64_func_f64_f64:
617    Rets.push_back(wasm::ValType::F64);
618    Params.push_back(wasm::ValType::F64);
619    Params.push_back(wasm::ValType::F64);
620    break;
621  case f64_func_f64_i32:
622    Rets.push_back(wasm::ValType::F64);
623    Params.push_back(wasm::ValType::F64);
624    Params.push_back(wasm::ValType::I32);
625    break;
626  case f64_func_i64_i64:
627    Rets.push_back(wasm::ValType::F64);
628    Params.push_back(wasm::ValType::I64);
629    Params.push_back(wasm::ValType::I64);
630    break;
631  case i16_func_f32:
632    Rets.push_back(wasm::ValType::I32);
633    Params.push_back(wasm::ValType::F32);
634    break;
635  case i16_func_f64:
636    Rets.push_back(wasm::ValType::I32);
637    Params.push_back(wasm::ValType::F64);
638    break;
639  case i16_func_i64_i64:
640    Rets.push_back(wasm::ValType::I32);
641    Params.push_back(wasm::ValType::I64);
642    Params.push_back(wasm::ValType::I64);
643    break;
644  case i8_func_i8_i8:
645    Rets.push_back(wasm::ValType::I32);
646    Params.push_back(wasm::ValType::I32);
647    Params.push_back(wasm::ValType::I32);
648    break;
649  case func_f32_iPTR_iPTR:
650    Params.push_back(wasm::ValType::F32);
651    Params.push_back(PtrTy);
652    Params.push_back(PtrTy);
653    break;
654  case func_f64_iPTR_iPTR:
655    Params.push_back(wasm::ValType::F64);
656    Params.push_back(PtrTy);
657    Params.push_back(PtrTy);
658    break;
659  case i16_func_i16_i16:
660    Rets.push_back(wasm::ValType::I32);
661    Params.push_back(wasm::ValType::I32);
662    Params.push_back(wasm::ValType::I32);
663    break;
664  case i32_func_f32_f32:
665    Rets.push_back(wasm::ValType::I32);
666    Params.push_back(wasm::ValType::F32);
667    Params.push_back(wasm::ValType::F32);
668    break;
669  case i32_func_f64_f64:
670    Rets.push_back(wasm::ValType::I32);
671    Params.push_back(wasm::ValType::F64);
672    Params.push_back(wasm::ValType::F64);
673    break;
674  case i32_func_i32_i32:
675    Rets.push_back(wasm::ValType::I32);
676    Params.push_back(wasm::ValType::I32);
677    Params.push_back(wasm::ValType::I32);
678    break;
679  case i32_func_i32_i32_iPTR:
680    Rets.push_back(wasm::ValType::I32);
681    Params.push_back(wasm::ValType::I32);
682    Params.push_back(wasm::ValType::I32);
683    Params.push_back(PtrTy);
684    break;
685  case i64_func_i64_i64:
686    Rets.push_back(wasm::ValType::I64);
687    Params.push_back(wasm::ValType::I64);
688    Params.push_back(wasm::ValType::I64);
689    break;
690  case i64_func_i64_i64_iPTR:
691    Rets.push_back(wasm::ValType::I64);
692    Params.push_back(wasm::ValType::I64);
693    Params.push_back(wasm::ValType::I64);
694    Params.push_back(PtrTy);
695    break;
696  case i64_i64_func_f32:
697    if (Subtarget.hasMultivalue()) {
698      Rets.push_back(wasm::ValType::I64);
699      Rets.push_back(wasm::ValType::I64);
700    } else {
701      Params.push_back(PtrTy);
702    }
703    Params.push_back(wasm::ValType::F32);
704    break;
705  case i64_i64_func_f64:
706    if (Subtarget.hasMultivalue()) {
707      Rets.push_back(wasm::ValType::I64);
708      Rets.push_back(wasm::ValType::I64);
709    } else {
710      Params.push_back(PtrTy);
711    }
712    Params.push_back(wasm::ValType::F64);
713    break;
714  case i16_i16_func_i16_i16:
715    if (Subtarget.hasMultivalue()) {
716      Rets.push_back(wasm::ValType::I32);
717      Rets.push_back(wasm::ValType::I32);
718    } else {
719      Params.push_back(PtrTy);
720    }
721    Params.push_back(wasm::ValType::I32);
722    Params.push_back(wasm::ValType::I32);
723    break;
724  case i32_i32_func_i32_i32:
725    if (Subtarget.hasMultivalue()) {
726      Rets.push_back(wasm::ValType::I32);
727      Rets.push_back(wasm::ValType::I32);
728    } else {
729      Params.push_back(PtrTy);
730    }
731    Params.push_back(wasm::ValType::I32);
732    Params.push_back(wasm::ValType::I32);
733    break;
734  case i64_i64_func_i64_i64:
735    if (Subtarget.hasMultivalue()) {
736      Rets.push_back(wasm::ValType::I64);
737      Rets.push_back(wasm::ValType::I64);
738    } else {
739      Params.push_back(PtrTy);
740    }
741    Params.push_back(wasm::ValType::I64);
742    Params.push_back(wasm::ValType::I64);
743    break;
744  case i64_i64_func_i64_i64_i64_i64:
745    if (Subtarget.hasMultivalue()) {
746      Rets.push_back(wasm::ValType::I64);
747      Rets.push_back(wasm::ValType::I64);
748    } else {
749      Params.push_back(PtrTy);
750    }
751    Params.push_back(wasm::ValType::I64);
752    Params.push_back(wasm::ValType::I64);
753    Params.push_back(wasm::ValType::I64);
754    Params.push_back(wasm::ValType::I64);
755    break;
756  case i64_i64_func_i64_i64_i64_i64_iPTR:
757    if (Subtarget.hasMultivalue()) {
758      Rets.push_back(wasm::ValType::I64);
759      Rets.push_back(wasm::ValType::I64);
760    } else {
761      Params.push_back(PtrTy);
762    }
763    Params.push_back(wasm::ValType::I64);
764    Params.push_back(wasm::ValType::I64);
765    Params.push_back(wasm::ValType::I64);
766    Params.push_back(wasm::ValType::I64);
767    Params.push_back(PtrTy);
768    break;
769  case i64_i64_i64_i64_func_i64_i64_i64_i64:
770    if (Subtarget.hasMultivalue()) {
771      Rets.push_back(wasm::ValType::I64);
772      Rets.push_back(wasm::ValType::I64);
773      Rets.push_back(wasm::ValType::I64);
774      Rets.push_back(wasm::ValType::I64);
775    } else {
776      Params.push_back(PtrTy);
777    }
778    Params.push_back(wasm::ValType::I64);
779    Params.push_back(wasm::ValType::I64);
780    Params.push_back(wasm::ValType::I64);
781    Params.push_back(wasm::ValType::I64);
782    break;
783  case i64_i64_func_i64_i64_i32:
784    if (Subtarget.hasMultivalue()) {
785      Rets.push_back(wasm::ValType::I64);
786      Rets.push_back(wasm::ValType::I64);
787    } else {
788      Params.push_back(PtrTy);
789    }
790    Params.push_back(wasm::ValType::I64);
791    Params.push_back(wasm::ValType::I64);
792    Params.push_back(wasm::ValType::I32);
793    break;
794  case iPTR_func_i32:
795    Rets.push_back(PtrTy);
796    Params.push_back(wasm::ValType::I32);
797    break;
798  case iPTR_func_iPTR_i32_iPTR:
799    Rets.push_back(PtrTy);
800    Params.push_back(PtrTy);
801    Params.push_back(wasm::ValType::I32);
802    Params.push_back(PtrTy);
803    break;
804  case iPTR_func_iPTR_iPTR_iPTR:
805    Rets.push_back(PtrTy);
806    Params.push_back(PtrTy);
807    Params.push_back(PtrTy);
808    Params.push_back(PtrTy);
809    break;
810  case f32_func_f32_f32_f32:
811    Rets.push_back(wasm::ValType::F32);
812    Params.push_back(wasm::ValType::F32);
813    Params.push_back(wasm::ValType::F32);
814    Params.push_back(wasm::ValType::F32);
815    break;
816  case f64_func_f64_f64_f64:
817    Rets.push_back(wasm::ValType::F64);
818    Params.push_back(wasm::ValType::F64);
819    Params.push_back(wasm::ValType::F64);
820    Params.push_back(wasm::ValType::F64);
821    break;
822  case func_i64_i64_iPTR_iPTR:
823    Params.push_back(wasm::ValType::I64);
824    Params.push_back(wasm::ValType::I64);
825    Params.push_back(PtrTy);
826    Params.push_back(PtrTy);
827    break;
828  case i32_func_i64_i64:
829    Rets.push_back(wasm::ValType::I32);
830    Params.push_back(wasm::ValType::I64);
831    Params.push_back(wasm::ValType::I64);
832    break;
833  case i32_func_i64_i64_i64_i64:
834    Rets.push_back(wasm::ValType::I32);
835    Params.push_back(wasm::ValType::I64);
836    Params.push_back(wasm::ValType::I64);
837    Params.push_back(wasm::ValType::I64);
838    Params.push_back(wasm::ValType::I64);
839    break;
840  case iPTR_func_f32:
841    Rets.push_back(PtrTy);
842    Params.push_back(wasm::ValType::F32);
843    break;
844  case iPTR_func_f64:
845    Rets.push_back(PtrTy);
846    Params.push_back(wasm::ValType::F64);
847    break;
848  case iPTR_func_i64_i64:
849    Rets.push_back(PtrTy);
850    Params.push_back(wasm::ValType::I64);
851    Params.push_back(wasm::ValType::I64);
852    break;
853  case i64_i64_func_i64_i64_i64_i64_i64_i64:
854    if (Subtarget.hasMultivalue()) {
855      Rets.push_back(wasm::ValType::I64);
856      Rets.push_back(wasm::ValType::I64);
857    } else {
858      Params.push_back(PtrTy);
859    }
860    Params.push_back(wasm::ValType::I64);
861    Params.push_back(wasm::ValType::I64);
862    Params.push_back(wasm::ValType::I64);
863    Params.push_back(wasm::ValType::I64);
864    Params.push_back(wasm::ValType::I64);
865    Params.push_back(wasm::ValType::I64);
866    break;
867  case i64_i64_func_i32:
868    if (Subtarget.hasMultivalue()) {
869      Rets.push_back(wasm::ValType::I64);
870      Rets.push_back(wasm::ValType::I64);
871    } else {
872      Params.push_back(PtrTy);
873    }
874    Params.push_back(wasm::ValType::I32);
875    break;
876  case i64_i64_func_i64:
877    if (Subtarget.hasMultivalue()) {
878      Rets.push_back(wasm::ValType::I64);
879      Rets.push_back(wasm::ValType::I64);
880    } else {
881      Params.push_back(PtrTy);
882    }
883    Params.push_back(wasm::ValType::I64);
884    break;
885  case unsupported:
886    llvm_unreachable("unsupported runtime library signature");
887  }
888}
889
890// TODO: If the RTLIB::Libcall-taking flavor of GetSignature remains unused
891// other than here, just roll its logic into this version.
892void llvm::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
893                               StringRef Name,
894                               SmallVectorImpl<wasm::ValType> &Rets,
895                               SmallVectorImpl<wasm::ValType> &Params) {
896  static StaticLibcallNameMap LibcallNameMap;
897  auto &Map = LibcallNameMap.Map;
898  auto Val = Map.find(Name);
899#ifndef NDEBUG
900  if (Val == Map.end()) {
901    auto Message =
902        std::string("unexpected runtime library name: ") + std::string(Name);
903    llvm_unreachable(Message.c_str());
904  }
905#endif
906  return getLibcallSignature(Subtarget, Val->second, Rets, Params);
907}
908