xref: /freebsd/contrib/llvm-project/clang/lib/CodeGen/TargetBuiltins/WebAssembly.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1*700637cbSDimitry Andric //===-- WebAssembly.cpp - Emit LLVM Code for builtins ---------------------===//
2*700637cbSDimitry Andric //
3*700637cbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*700637cbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*700637cbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*700637cbSDimitry Andric //
7*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
8*700637cbSDimitry Andric //
9*700637cbSDimitry Andric // This contains code to emit Builtin calls as LLVM code.
10*700637cbSDimitry Andric //
11*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
12*700637cbSDimitry Andric 
13*700637cbSDimitry Andric #include "CGBuiltin.h"
14*700637cbSDimitry Andric #include "clang/Basic/TargetBuiltins.h"
15*700637cbSDimitry Andric #include "llvm/IR/IntrinsicsWebAssembly.h"
16*700637cbSDimitry Andric 
17*700637cbSDimitry Andric using namespace clang;
18*700637cbSDimitry Andric using namespace CodeGen;
19*700637cbSDimitry Andric using namespace llvm;
20*700637cbSDimitry Andric 
EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,const CallExpr * E)21*700637cbSDimitry Andric Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
22*700637cbSDimitry Andric                                                    const CallExpr *E) {
23*700637cbSDimitry Andric   switch (BuiltinID) {
24*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_memory_size: {
25*700637cbSDimitry Andric     llvm::Type *ResultType = ConvertType(E->getType());
26*700637cbSDimitry Andric     Value *I = EmitScalarExpr(E->getArg(0));
27*700637cbSDimitry Andric     Function *Callee =
28*700637cbSDimitry Andric         CGM.getIntrinsic(Intrinsic::wasm_memory_size, ResultType);
29*700637cbSDimitry Andric     return Builder.CreateCall(Callee, I);
30*700637cbSDimitry Andric   }
31*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_memory_grow: {
32*700637cbSDimitry Andric     llvm::Type *ResultType = ConvertType(E->getType());
33*700637cbSDimitry Andric     Value *Args[] = {EmitScalarExpr(E->getArg(0)),
34*700637cbSDimitry Andric                      EmitScalarExpr(E->getArg(1))};
35*700637cbSDimitry Andric     Function *Callee =
36*700637cbSDimitry Andric         CGM.getIntrinsic(Intrinsic::wasm_memory_grow, ResultType);
37*700637cbSDimitry Andric     return Builder.CreateCall(Callee, Args);
38*700637cbSDimitry Andric   }
39*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_tls_size: {
40*700637cbSDimitry Andric     llvm::Type *ResultType = ConvertType(E->getType());
41*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_tls_size, ResultType);
42*700637cbSDimitry Andric     return Builder.CreateCall(Callee);
43*700637cbSDimitry Andric   }
44*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_tls_align: {
45*700637cbSDimitry Andric     llvm::Type *ResultType = ConvertType(E->getType());
46*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_tls_align, ResultType);
47*700637cbSDimitry Andric     return Builder.CreateCall(Callee);
48*700637cbSDimitry Andric   }
49*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_tls_base: {
50*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_tls_base);
51*700637cbSDimitry Andric     return Builder.CreateCall(Callee);
52*700637cbSDimitry Andric   }
53*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_throw: {
54*700637cbSDimitry Andric     Value *Tag = EmitScalarExpr(E->getArg(0));
55*700637cbSDimitry Andric     Value *Obj = EmitScalarExpr(E->getArg(1));
56*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_throw);
57*700637cbSDimitry Andric     return EmitRuntimeCallOrInvoke(Callee, {Tag, Obj});
58*700637cbSDimitry Andric   }
59*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_rethrow: {
60*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_rethrow);
61*700637cbSDimitry Andric     return EmitRuntimeCallOrInvoke(Callee);
62*700637cbSDimitry Andric   }
63*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_memory_atomic_wait32: {
64*700637cbSDimitry Andric     Value *Addr = EmitScalarExpr(E->getArg(0));
65*700637cbSDimitry Andric     Value *Expected = EmitScalarExpr(E->getArg(1));
66*700637cbSDimitry Andric     Value *Timeout = EmitScalarExpr(E->getArg(2));
67*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_memory_atomic_wait32);
68*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Addr, Expected, Timeout});
69*700637cbSDimitry Andric   }
70*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_memory_atomic_wait64: {
71*700637cbSDimitry Andric     Value *Addr = EmitScalarExpr(E->getArg(0));
72*700637cbSDimitry Andric     Value *Expected = EmitScalarExpr(E->getArg(1));
73*700637cbSDimitry Andric     Value *Timeout = EmitScalarExpr(E->getArg(2));
74*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_memory_atomic_wait64);
75*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Addr, Expected, Timeout});
76*700637cbSDimitry Andric   }
77*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_memory_atomic_notify: {
78*700637cbSDimitry Andric     Value *Addr = EmitScalarExpr(E->getArg(0));
79*700637cbSDimitry Andric     Value *Count = EmitScalarExpr(E->getArg(1));
80*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_memory_atomic_notify);
81*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Addr, Count});
82*700637cbSDimitry Andric   }
83*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_s_i32_f32:
84*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_s_i32_f64:
85*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_s_i64_f32:
86*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_s_i64_f64: {
87*700637cbSDimitry Andric     Value *Src = EmitScalarExpr(E->getArg(0));
88*700637cbSDimitry Andric     llvm::Type *ResT = ConvertType(E->getType());
89*700637cbSDimitry Andric     Function *Callee =
90*700637cbSDimitry Andric         CGM.getIntrinsic(Intrinsic::wasm_trunc_signed, {ResT, Src->getType()});
91*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Src});
92*700637cbSDimitry Andric   }
93*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_u_i32_f32:
94*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_u_i32_f64:
95*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_u_i64_f32:
96*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_u_i64_f64: {
97*700637cbSDimitry Andric     Value *Src = EmitScalarExpr(E->getArg(0));
98*700637cbSDimitry Andric     llvm::Type *ResT = ConvertType(E->getType());
99*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_trunc_unsigned,
100*700637cbSDimitry Andric                                         {ResT, Src->getType()});
101*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Src});
102*700637cbSDimitry Andric   }
103*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i32_f32:
104*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i32_f64:
105*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i64_f32:
106*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i64_f64:
107*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i16x8_f16x8:
108*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i32x4_f32x4: {
109*700637cbSDimitry Andric     Value *Src = EmitScalarExpr(E->getArg(0));
110*700637cbSDimitry Andric     llvm::Type *ResT = ConvertType(E->getType());
111*700637cbSDimitry Andric     Function *Callee =
112*700637cbSDimitry Andric         CGM.getIntrinsic(Intrinsic::fptosi_sat, {ResT, Src->getType()});
113*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Src});
114*700637cbSDimitry Andric   }
115*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i32_f32:
116*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i32_f64:
117*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i64_f32:
118*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i64_f64:
119*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i16x8_f16x8:
120*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i32x4_f32x4: {
121*700637cbSDimitry Andric     Value *Src = EmitScalarExpr(E->getArg(0));
122*700637cbSDimitry Andric     llvm::Type *ResT = ConvertType(E->getType());
123*700637cbSDimitry Andric     Function *Callee =
124*700637cbSDimitry Andric         CGM.getIntrinsic(Intrinsic::fptoui_sat, {ResT, Src->getType()});
125*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Src});
126*700637cbSDimitry Andric   }
127*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_min_f32:
128*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_min_f64:
129*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_min_f16x8:
130*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_min_f32x4:
131*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_min_f64x2: {
132*700637cbSDimitry Andric     Value *LHS = EmitScalarExpr(E->getArg(0));
133*700637cbSDimitry Andric     Value *RHS = EmitScalarExpr(E->getArg(1));
134*700637cbSDimitry Andric     Function *Callee =
135*700637cbSDimitry Andric         CGM.getIntrinsic(Intrinsic::minimum, ConvertType(E->getType()));
136*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {LHS, RHS});
137*700637cbSDimitry Andric   }
138*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_max_f32:
139*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_max_f64:
140*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_max_f16x8:
141*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_max_f32x4:
142*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_max_f64x2: {
143*700637cbSDimitry Andric     Value *LHS = EmitScalarExpr(E->getArg(0));
144*700637cbSDimitry Andric     Value *RHS = EmitScalarExpr(E->getArg(1));
145*700637cbSDimitry Andric     Function *Callee =
146*700637cbSDimitry Andric         CGM.getIntrinsic(Intrinsic::maximum, ConvertType(E->getType()));
147*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {LHS, RHS});
148*700637cbSDimitry Andric   }
149*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_pmin_f16x8:
150*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_pmin_f32x4:
151*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_pmin_f64x2: {
152*700637cbSDimitry Andric     Value *LHS = EmitScalarExpr(E->getArg(0));
153*700637cbSDimitry Andric     Value *RHS = EmitScalarExpr(E->getArg(1));
154*700637cbSDimitry Andric     Function *Callee =
155*700637cbSDimitry Andric         CGM.getIntrinsic(Intrinsic::wasm_pmin, ConvertType(E->getType()));
156*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {LHS, RHS});
157*700637cbSDimitry Andric   }
158*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_pmax_f16x8:
159*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_pmax_f32x4:
160*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_pmax_f64x2: {
161*700637cbSDimitry Andric     Value *LHS = EmitScalarExpr(E->getArg(0));
162*700637cbSDimitry Andric     Value *RHS = EmitScalarExpr(E->getArg(1));
163*700637cbSDimitry Andric     Function *Callee =
164*700637cbSDimitry Andric         CGM.getIntrinsic(Intrinsic::wasm_pmax, ConvertType(E->getType()));
165*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {LHS, RHS});
166*700637cbSDimitry Andric   }
167*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_ceil_f16x8:
168*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_floor_f16x8:
169*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_f16x8:
170*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_nearest_f16x8:
171*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_ceil_f32x4:
172*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_floor_f32x4:
173*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_f32x4:
174*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_nearest_f32x4:
175*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_ceil_f64x2:
176*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_floor_f64x2:
177*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_f64x2:
178*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_nearest_f64x2: {
179*700637cbSDimitry Andric     unsigned IntNo;
180*700637cbSDimitry Andric     switch (BuiltinID) {
181*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_ceil_f16x8:
182*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_ceil_f32x4:
183*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_ceil_f64x2:
184*700637cbSDimitry Andric       IntNo = Intrinsic::ceil;
185*700637cbSDimitry Andric       break;
186*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_floor_f16x8:
187*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_floor_f32x4:
188*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_floor_f64x2:
189*700637cbSDimitry Andric       IntNo = Intrinsic::floor;
190*700637cbSDimitry Andric       break;
191*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_trunc_f16x8:
192*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_trunc_f32x4:
193*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_trunc_f64x2:
194*700637cbSDimitry Andric       IntNo = Intrinsic::trunc;
195*700637cbSDimitry Andric       break;
196*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_nearest_f16x8:
197*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_nearest_f32x4:
198*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_nearest_f64x2:
199*700637cbSDimitry Andric       IntNo = Intrinsic::nearbyint;
200*700637cbSDimitry Andric       break;
201*700637cbSDimitry Andric     default:
202*700637cbSDimitry Andric       llvm_unreachable("unexpected builtin ID");
203*700637cbSDimitry Andric     }
204*700637cbSDimitry Andric     Value *Value = EmitScalarExpr(E->getArg(0));
205*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(IntNo, ConvertType(E->getType()));
206*700637cbSDimitry Andric     return Builder.CreateCall(Callee, Value);
207*700637cbSDimitry Andric   }
208*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_ref_null_extern: {
209*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_ref_null_extern);
210*700637cbSDimitry Andric     return Builder.CreateCall(Callee);
211*700637cbSDimitry Andric   }
212*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_ref_is_null_extern: {
213*700637cbSDimitry Andric     Value *Src = EmitScalarExpr(E->getArg(0));
214*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_ref_is_null_extern);
215*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Src});
216*700637cbSDimitry Andric   }
217*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_ref_null_func: {
218*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_ref_null_func);
219*700637cbSDimitry Andric     return Builder.CreateCall(Callee);
220*700637cbSDimitry Andric   }
221*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_swizzle_i8x16: {
222*700637cbSDimitry Andric     Value *Src = EmitScalarExpr(E->getArg(0));
223*700637cbSDimitry Andric     Value *Indices = EmitScalarExpr(E->getArg(1));
224*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_swizzle);
225*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Src, Indices});
226*700637cbSDimitry Andric   }
227*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_abs_i8x16:
228*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_abs_i16x8:
229*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_abs_i32x4:
230*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_abs_i64x2: {
231*700637cbSDimitry Andric     Value *Vec = EmitScalarExpr(E->getArg(0));
232*700637cbSDimitry Andric     Value *Neg = Builder.CreateNeg(Vec, "neg");
233*700637cbSDimitry Andric     Constant *Zero = llvm::Constant::getNullValue(Vec->getType());
234*700637cbSDimitry Andric     Value *ICmp = Builder.CreateICmpSLT(Vec, Zero, "abscond");
235*700637cbSDimitry Andric     return Builder.CreateSelect(ICmp, Neg, Vec, "abs");
236*700637cbSDimitry Andric   }
237*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_avgr_u_i8x16:
238*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_avgr_u_i16x8: {
239*700637cbSDimitry Andric     Value *LHS = EmitScalarExpr(E->getArg(0));
240*700637cbSDimitry Andric     Value *RHS = EmitScalarExpr(E->getArg(1));
241*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_avgr_unsigned,
242*700637cbSDimitry Andric                                         ConvertType(E->getType()));
243*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {LHS, RHS});
244*700637cbSDimitry Andric   }
245*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_q15mulr_sat_s_i16x8: {
246*700637cbSDimitry Andric     Value *LHS = EmitScalarExpr(E->getArg(0));
247*700637cbSDimitry Andric     Value *RHS = EmitScalarExpr(E->getArg(1));
248*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_q15mulr_sat_signed);
249*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {LHS, RHS});
250*700637cbSDimitry Andric   }
251*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_extadd_pairwise_i8x16_s_i16x8:
252*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_extadd_pairwise_i8x16_u_i16x8:
253*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_extadd_pairwise_i16x8_s_i32x4:
254*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_extadd_pairwise_i16x8_u_i32x4: {
255*700637cbSDimitry Andric     Value *Vec = EmitScalarExpr(E->getArg(0));
256*700637cbSDimitry Andric     unsigned IntNo;
257*700637cbSDimitry Andric     switch (BuiltinID) {
258*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_extadd_pairwise_i8x16_s_i16x8:
259*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_extadd_pairwise_i16x8_s_i32x4:
260*700637cbSDimitry Andric       IntNo = Intrinsic::wasm_extadd_pairwise_signed;
261*700637cbSDimitry Andric       break;
262*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_extadd_pairwise_i8x16_u_i16x8:
263*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_extadd_pairwise_i16x8_u_i32x4:
264*700637cbSDimitry Andric       IntNo = Intrinsic::wasm_extadd_pairwise_unsigned;
265*700637cbSDimitry Andric       break;
266*700637cbSDimitry Andric     default:
267*700637cbSDimitry Andric       llvm_unreachable("unexpected builtin ID");
268*700637cbSDimitry Andric     }
269*700637cbSDimitry Andric 
270*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(IntNo, ConvertType(E->getType()));
271*700637cbSDimitry Andric     return Builder.CreateCall(Callee, Vec);
272*700637cbSDimitry Andric   }
273*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_bitselect: {
274*700637cbSDimitry Andric     Value *V1 = EmitScalarExpr(E->getArg(0));
275*700637cbSDimitry Andric     Value *V2 = EmitScalarExpr(E->getArg(1));
276*700637cbSDimitry Andric     Value *C = EmitScalarExpr(E->getArg(2));
277*700637cbSDimitry Andric     Function *Callee =
278*700637cbSDimitry Andric         CGM.getIntrinsic(Intrinsic::wasm_bitselect, ConvertType(E->getType()));
279*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {V1, V2, C});
280*700637cbSDimitry Andric   }
281*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_dot_s_i32x4_i16x8: {
282*700637cbSDimitry Andric     Value *LHS = EmitScalarExpr(E->getArg(0));
283*700637cbSDimitry Andric     Value *RHS = EmitScalarExpr(E->getArg(1));
284*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_dot);
285*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {LHS, RHS});
286*700637cbSDimitry Andric   }
287*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_any_true_v128:
288*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_all_true_i8x16:
289*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_all_true_i16x8:
290*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_all_true_i32x4:
291*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_all_true_i64x2: {
292*700637cbSDimitry Andric     unsigned IntNo;
293*700637cbSDimitry Andric     switch (BuiltinID) {
294*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_any_true_v128:
295*700637cbSDimitry Andric       IntNo = Intrinsic::wasm_anytrue;
296*700637cbSDimitry Andric       break;
297*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_all_true_i8x16:
298*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_all_true_i16x8:
299*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_all_true_i32x4:
300*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_all_true_i64x2:
301*700637cbSDimitry Andric       IntNo = Intrinsic::wasm_alltrue;
302*700637cbSDimitry Andric       break;
303*700637cbSDimitry Andric     default:
304*700637cbSDimitry Andric       llvm_unreachable("unexpected builtin ID");
305*700637cbSDimitry Andric     }
306*700637cbSDimitry Andric     Value *Vec = EmitScalarExpr(E->getArg(0));
307*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(IntNo, Vec->getType());
308*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Vec});
309*700637cbSDimitry Andric   }
310*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_bitmask_i8x16:
311*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_bitmask_i16x8:
312*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_bitmask_i32x4:
313*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_bitmask_i64x2: {
314*700637cbSDimitry Andric     Value *Vec = EmitScalarExpr(E->getArg(0));
315*700637cbSDimitry Andric     Function *Callee =
316*700637cbSDimitry Andric         CGM.getIntrinsic(Intrinsic::wasm_bitmask, Vec->getType());
317*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Vec});
318*700637cbSDimitry Andric   }
319*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_abs_f16x8:
320*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_abs_f32x4:
321*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_abs_f64x2: {
322*700637cbSDimitry Andric     Value *Vec = EmitScalarExpr(E->getArg(0));
323*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::fabs, Vec->getType());
324*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Vec});
325*700637cbSDimitry Andric   }
326*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_sqrt_f16x8:
327*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_sqrt_f32x4:
328*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_sqrt_f64x2: {
329*700637cbSDimitry Andric     Value *Vec = EmitScalarExpr(E->getArg(0));
330*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::sqrt, Vec->getType());
331*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Vec});
332*700637cbSDimitry Andric   }
333*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_narrow_s_i8x16_i16x8:
334*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_narrow_u_i8x16_i16x8:
335*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_narrow_s_i16x8_i32x4:
336*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_narrow_u_i16x8_i32x4: {
337*700637cbSDimitry Andric     Value *Low = EmitScalarExpr(E->getArg(0));
338*700637cbSDimitry Andric     Value *High = EmitScalarExpr(E->getArg(1));
339*700637cbSDimitry Andric     unsigned IntNo;
340*700637cbSDimitry Andric     switch (BuiltinID) {
341*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_narrow_s_i8x16_i16x8:
342*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_narrow_s_i16x8_i32x4:
343*700637cbSDimitry Andric       IntNo = Intrinsic::wasm_narrow_signed;
344*700637cbSDimitry Andric       break;
345*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_narrow_u_i8x16_i16x8:
346*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_narrow_u_i16x8_i32x4:
347*700637cbSDimitry Andric       IntNo = Intrinsic::wasm_narrow_unsigned;
348*700637cbSDimitry Andric       break;
349*700637cbSDimitry Andric     default:
350*700637cbSDimitry Andric       llvm_unreachable("unexpected builtin ID");
351*700637cbSDimitry Andric     }
352*700637cbSDimitry Andric     Function *Callee =
353*700637cbSDimitry Andric         CGM.getIntrinsic(IntNo, {ConvertType(E->getType()), Low->getType()});
354*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Low, High});
355*700637cbSDimitry Andric   }
356*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_sat_s_zero_f64x2_i32x4:
357*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_trunc_sat_u_zero_f64x2_i32x4: {
358*700637cbSDimitry Andric     Value *Vec = EmitScalarExpr(E->getArg(0));
359*700637cbSDimitry Andric     unsigned IntNo;
360*700637cbSDimitry Andric     switch (BuiltinID) {
361*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_trunc_sat_s_zero_f64x2_i32x4:
362*700637cbSDimitry Andric       IntNo = Intrinsic::fptosi_sat;
363*700637cbSDimitry Andric       break;
364*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_trunc_sat_u_zero_f64x2_i32x4:
365*700637cbSDimitry Andric       IntNo = Intrinsic::fptoui_sat;
366*700637cbSDimitry Andric       break;
367*700637cbSDimitry Andric     default:
368*700637cbSDimitry Andric       llvm_unreachable("unexpected builtin ID");
369*700637cbSDimitry Andric     }
370*700637cbSDimitry Andric     llvm::Type *SrcT = Vec->getType();
371*700637cbSDimitry Andric     llvm::Type *TruncT = SrcT->getWithNewType(Builder.getInt32Ty());
372*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(IntNo, {TruncT, SrcT});
373*700637cbSDimitry Andric     Value *Trunc = Builder.CreateCall(Callee, Vec);
374*700637cbSDimitry Andric     Value *Splat = Constant::getNullValue(TruncT);
375*700637cbSDimitry Andric     return Builder.CreateShuffleVector(Trunc, Splat, {0, 1, 2, 3});
376*700637cbSDimitry Andric   }
377*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_shuffle_i8x16: {
378*700637cbSDimitry Andric     Value *Ops[18];
379*700637cbSDimitry Andric     size_t OpIdx = 0;
380*700637cbSDimitry Andric     Ops[OpIdx++] = EmitScalarExpr(E->getArg(0));
381*700637cbSDimitry Andric     Ops[OpIdx++] = EmitScalarExpr(E->getArg(1));
382*700637cbSDimitry Andric     while (OpIdx < 18) {
383*700637cbSDimitry Andric       std::optional<llvm::APSInt> LaneConst =
384*700637cbSDimitry Andric           E->getArg(OpIdx)->getIntegerConstantExpr(getContext());
385*700637cbSDimitry Andric       assert(LaneConst && "Constant arg isn't actually constant?");
386*700637cbSDimitry Andric       Ops[OpIdx++] = llvm::ConstantInt::get(getLLVMContext(), *LaneConst);
387*700637cbSDimitry Andric     }
388*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_shuffle);
389*700637cbSDimitry Andric     return Builder.CreateCall(Callee, Ops);
390*700637cbSDimitry Andric   }
391*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_madd_f16x8:
392*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_nmadd_f16x8:
393*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_madd_f32x4:
394*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_nmadd_f32x4:
395*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_madd_f64x2:
396*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_nmadd_f64x2: {
397*700637cbSDimitry Andric     Value *A = EmitScalarExpr(E->getArg(0));
398*700637cbSDimitry Andric     Value *B = EmitScalarExpr(E->getArg(1));
399*700637cbSDimitry Andric     Value *C = EmitScalarExpr(E->getArg(2));
400*700637cbSDimitry Andric     unsigned IntNo;
401*700637cbSDimitry Andric     switch (BuiltinID) {
402*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_relaxed_madd_f16x8:
403*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_relaxed_madd_f32x4:
404*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_relaxed_madd_f64x2:
405*700637cbSDimitry Andric       IntNo = Intrinsic::wasm_relaxed_madd;
406*700637cbSDimitry Andric       break;
407*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_relaxed_nmadd_f16x8:
408*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_relaxed_nmadd_f32x4:
409*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_relaxed_nmadd_f64x2:
410*700637cbSDimitry Andric       IntNo = Intrinsic::wasm_relaxed_nmadd;
411*700637cbSDimitry Andric       break;
412*700637cbSDimitry Andric     default:
413*700637cbSDimitry Andric       llvm_unreachable("unexpected builtin ID");
414*700637cbSDimitry Andric     }
415*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(IntNo, A->getType());
416*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {A, B, C});
417*700637cbSDimitry Andric   }
418*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_laneselect_i8x16:
419*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_laneselect_i16x8:
420*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_laneselect_i32x4:
421*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_laneselect_i64x2: {
422*700637cbSDimitry Andric     Value *A = EmitScalarExpr(E->getArg(0));
423*700637cbSDimitry Andric     Value *B = EmitScalarExpr(E->getArg(1));
424*700637cbSDimitry Andric     Value *C = EmitScalarExpr(E->getArg(2));
425*700637cbSDimitry Andric     Function *Callee =
426*700637cbSDimitry Andric         CGM.getIntrinsic(Intrinsic::wasm_relaxed_laneselect, A->getType());
427*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {A, B, C});
428*700637cbSDimitry Andric   }
429*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_swizzle_i8x16: {
430*700637cbSDimitry Andric     Value *Src = EmitScalarExpr(E->getArg(0));
431*700637cbSDimitry Andric     Value *Indices = EmitScalarExpr(E->getArg(1));
432*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_relaxed_swizzle);
433*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Src, Indices});
434*700637cbSDimitry Andric   }
435*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_min_f32x4:
436*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_max_f32x4:
437*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_min_f64x2:
438*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_max_f64x2: {
439*700637cbSDimitry Andric     Value *LHS = EmitScalarExpr(E->getArg(0));
440*700637cbSDimitry Andric     Value *RHS = EmitScalarExpr(E->getArg(1));
441*700637cbSDimitry Andric     unsigned IntNo;
442*700637cbSDimitry Andric     switch (BuiltinID) {
443*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_relaxed_min_f32x4:
444*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_relaxed_min_f64x2:
445*700637cbSDimitry Andric       IntNo = Intrinsic::wasm_relaxed_min;
446*700637cbSDimitry Andric       break;
447*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_relaxed_max_f32x4:
448*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_relaxed_max_f64x2:
449*700637cbSDimitry Andric       IntNo = Intrinsic::wasm_relaxed_max;
450*700637cbSDimitry Andric       break;
451*700637cbSDimitry Andric     default:
452*700637cbSDimitry Andric       llvm_unreachable("unexpected builtin ID");
453*700637cbSDimitry Andric     }
454*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(IntNo, LHS->getType());
455*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {LHS, RHS});
456*700637cbSDimitry Andric   }
457*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_trunc_s_i32x4_f32x4:
458*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_trunc_u_i32x4_f32x4:
459*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_trunc_s_zero_i32x4_f64x2:
460*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_trunc_u_zero_i32x4_f64x2: {
461*700637cbSDimitry Andric     Value *Vec = EmitScalarExpr(E->getArg(0));
462*700637cbSDimitry Andric     unsigned IntNo;
463*700637cbSDimitry Andric     switch (BuiltinID) {
464*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_relaxed_trunc_s_i32x4_f32x4:
465*700637cbSDimitry Andric       IntNo = Intrinsic::wasm_relaxed_trunc_signed;
466*700637cbSDimitry Andric       break;
467*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_relaxed_trunc_u_i32x4_f32x4:
468*700637cbSDimitry Andric       IntNo = Intrinsic::wasm_relaxed_trunc_unsigned;
469*700637cbSDimitry Andric       break;
470*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_relaxed_trunc_s_zero_i32x4_f64x2:
471*700637cbSDimitry Andric       IntNo = Intrinsic::wasm_relaxed_trunc_signed_zero;
472*700637cbSDimitry Andric       break;
473*700637cbSDimitry Andric     case WebAssembly::BI__builtin_wasm_relaxed_trunc_u_zero_i32x4_f64x2:
474*700637cbSDimitry Andric       IntNo = Intrinsic::wasm_relaxed_trunc_unsigned_zero;
475*700637cbSDimitry Andric       break;
476*700637cbSDimitry Andric     default:
477*700637cbSDimitry Andric       llvm_unreachable("unexpected builtin ID");
478*700637cbSDimitry Andric     }
479*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(IntNo);
480*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Vec});
481*700637cbSDimitry Andric   }
482*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_q15mulr_s_i16x8: {
483*700637cbSDimitry Andric     Value *LHS = EmitScalarExpr(E->getArg(0));
484*700637cbSDimitry Andric     Value *RHS = EmitScalarExpr(E->getArg(1));
485*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_relaxed_q15mulr_signed);
486*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {LHS, RHS});
487*700637cbSDimitry Andric   }
488*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_dot_i8x16_i7x16_s_i16x8: {
489*700637cbSDimitry Andric     Value *LHS = EmitScalarExpr(E->getArg(0));
490*700637cbSDimitry Andric     Value *RHS = EmitScalarExpr(E->getArg(1));
491*700637cbSDimitry Andric     Function *Callee =
492*700637cbSDimitry Andric         CGM.getIntrinsic(Intrinsic::wasm_relaxed_dot_i8x16_i7x16_signed);
493*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {LHS, RHS});
494*700637cbSDimitry Andric   }
495*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_dot_i8x16_i7x16_add_s_i32x4: {
496*700637cbSDimitry Andric     Value *LHS = EmitScalarExpr(E->getArg(0));
497*700637cbSDimitry Andric     Value *RHS = EmitScalarExpr(E->getArg(1));
498*700637cbSDimitry Andric     Value *Acc = EmitScalarExpr(E->getArg(2));
499*700637cbSDimitry Andric     Function *Callee =
500*700637cbSDimitry Andric         CGM.getIntrinsic(Intrinsic::wasm_relaxed_dot_i8x16_i7x16_add_signed);
501*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {LHS, RHS, Acc});
502*700637cbSDimitry Andric   }
503*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_relaxed_dot_bf16x8_add_f32_f32x4: {
504*700637cbSDimitry Andric     Value *LHS = EmitScalarExpr(E->getArg(0));
505*700637cbSDimitry Andric     Value *RHS = EmitScalarExpr(E->getArg(1));
506*700637cbSDimitry Andric     Value *Acc = EmitScalarExpr(E->getArg(2));
507*700637cbSDimitry Andric     Function *Callee =
508*700637cbSDimitry Andric         CGM.getIntrinsic(Intrinsic::wasm_relaxed_dot_bf16x8_add_f32);
509*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {LHS, RHS, Acc});
510*700637cbSDimitry Andric   }
511*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_loadf16_f32: {
512*700637cbSDimitry Andric     Value *Addr = EmitScalarExpr(E->getArg(0));
513*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_loadf16_f32);
514*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Addr});
515*700637cbSDimitry Andric   }
516*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_storef16_f32: {
517*700637cbSDimitry Andric     Value *Val = EmitScalarExpr(E->getArg(0));
518*700637cbSDimitry Andric     Value *Addr = EmitScalarExpr(E->getArg(1));
519*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_storef16_f32);
520*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Val, Addr});
521*700637cbSDimitry Andric   }
522*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_splat_f16x8: {
523*700637cbSDimitry Andric     Value *Val = EmitScalarExpr(E->getArg(0));
524*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_splat_f16x8);
525*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Val});
526*700637cbSDimitry Andric   }
527*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_extract_lane_f16x8: {
528*700637cbSDimitry Andric     Value *Vector = EmitScalarExpr(E->getArg(0));
529*700637cbSDimitry Andric     Value *Index = EmitScalarExpr(E->getArg(1));
530*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_extract_lane_f16x8);
531*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Vector, Index});
532*700637cbSDimitry Andric   }
533*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_replace_lane_f16x8: {
534*700637cbSDimitry Andric     Value *Vector = EmitScalarExpr(E->getArg(0));
535*700637cbSDimitry Andric     Value *Index = EmitScalarExpr(E->getArg(1));
536*700637cbSDimitry Andric     Value *Val = EmitScalarExpr(E->getArg(2));
537*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_replace_lane_f16x8);
538*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Vector, Index, Val});
539*700637cbSDimitry Andric   }
540*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_table_get: {
541*700637cbSDimitry Andric     assert(E->getArg(0)->getType()->isArrayType());
542*700637cbSDimitry Andric     Value *Table = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this);
543*700637cbSDimitry Andric     Value *Index = EmitScalarExpr(E->getArg(1));
544*700637cbSDimitry Andric     Function *Callee;
545*700637cbSDimitry Andric     if (E->getType().isWebAssemblyExternrefType())
546*700637cbSDimitry Andric       Callee = CGM.getIntrinsic(Intrinsic::wasm_table_get_externref);
547*700637cbSDimitry Andric     else if (E->getType().isWebAssemblyFuncrefType())
548*700637cbSDimitry Andric       Callee = CGM.getIntrinsic(Intrinsic::wasm_table_get_funcref);
549*700637cbSDimitry Andric     else
550*700637cbSDimitry Andric       llvm_unreachable(
551*700637cbSDimitry Andric           "Unexpected reference type for __builtin_wasm_table_get");
552*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Table, Index});
553*700637cbSDimitry Andric   }
554*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_table_set: {
555*700637cbSDimitry Andric     assert(E->getArg(0)->getType()->isArrayType());
556*700637cbSDimitry Andric     Value *Table = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this);
557*700637cbSDimitry Andric     Value *Index = EmitScalarExpr(E->getArg(1));
558*700637cbSDimitry Andric     Value *Val = EmitScalarExpr(E->getArg(2));
559*700637cbSDimitry Andric     Function *Callee;
560*700637cbSDimitry Andric     if (E->getArg(2)->getType().isWebAssemblyExternrefType())
561*700637cbSDimitry Andric       Callee = CGM.getIntrinsic(Intrinsic::wasm_table_set_externref);
562*700637cbSDimitry Andric     else if (E->getArg(2)->getType().isWebAssemblyFuncrefType())
563*700637cbSDimitry Andric       Callee = CGM.getIntrinsic(Intrinsic::wasm_table_set_funcref);
564*700637cbSDimitry Andric     else
565*700637cbSDimitry Andric       llvm_unreachable(
566*700637cbSDimitry Andric           "Unexpected reference type for __builtin_wasm_table_set");
567*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Table, Index, Val});
568*700637cbSDimitry Andric   }
569*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_table_size: {
570*700637cbSDimitry Andric     assert(E->getArg(0)->getType()->isArrayType());
571*700637cbSDimitry Andric     Value *Value = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this);
572*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_table_size);
573*700637cbSDimitry Andric     return Builder.CreateCall(Callee, Value);
574*700637cbSDimitry Andric   }
575*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_table_grow: {
576*700637cbSDimitry Andric     assert(E->getArg(0)->getType()->isArrayType());
577*700637cbSDimitry Andric     Value *Table = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this);
578*700637cbSDimitry Andric     Value *Val = EmitScalarExpr(E->getArg(1));
579*700637cbSDimitry Andric     Value *NElems = EmitScalarExpr(E->getArg(2));
580*700637cbSDimitry Andric 
581*700637cbSDimitry Andric     Function *Callee;
582*700637cbSDimitry Andric     if (E->getArg(1)->getType().isWebAssemblyExternrefType())
583*700637cbSDimitry Andric       Callee = CGM.getIntrinsic(Intrinsic::wasm_table_grow_externref);
584*700637cbSDimitry Andric     else if (E->getArg(2)->getType().isWebAssemblyFuncrefType())
585*700637cbSDimitry Andric       Callee = CGM.getIntrinsic(Intrinsic::wasm_table_fill_funcref);
586*700637cbSDimitry Andric     else
587*700637cbSDimitry Andric       llvm_unreachable(
588*700637cbSDimitry Andric           "Unexpected reference type for __builtin_wasm_table_grow");
589*700637cbSDimitry Andric 
590*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Table, Val, NElems});
591*700637cbSDimitry Andric   }
592*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_table_fill: {
593*700637cbSDimitry Andric     assert(E->getArg(0)->getType()->isArrayType());
594*700637cbSDimitry Andric     Value *Table = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this);
595*700637cbSDimitry Andric     Value *Index = EmitScalarExpr(E->getArg(1));
596*700637cbSDimitry Andric     Value *Val = EmitScalarExpr(E->getArg(2));
597*700637cbSDimitry Andric     Value *NElems = EmitScalarExpr(E->getArg(3));
598*700637cbSDimitry Andric 
599*700637cbSDimitry Andric     Function *Callee;
600*700637cbSDimitry Andric     if (E->getArg(2)->getType().isWebAssemblyExternrefType())
601*700637cbSDimitry Andric       Callee = CGM.getIntrinsic(Intrinsic::wasm_table_fill_externref);
602*700637cbSDimitry Andric     else if (E->getArg(2)->getType().isWebAssemblyFuncrefType())
603*700637cbSDimitry Andric       Callee = CGM.getIntrinsic(Intrinsic::wasm_table_fill_funcref);
604*700637cbSDimitry Andric     else
605*700637cbSDimitry Andric       llvm_unreachable(
606*700637cbSDimitry Andric           "Unexpected reference type for __builtin_wasm_table_fill");
607*700637cbSDimitry Andric 
608*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {Table, Index, Val, NElems});
609*700637cbSDimitry Andric   }
610*700637cbSDimitry Andric   case WebAssembly::BI__builtin_wasm_table_copy: {
611*700637cbSDimitry Andric     assert(E->getArg(0)->getType()->isArrayType());
612*700637cbSDimitry Andric     Value *TableX = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this);
613*700637cbSDimitry Andric     Value *TableY = EmitArrayToPointerDecay(E->getArg(1)).emitRawPointer(*this);
614*700637cbSDimitry Andric     Value *DstIdx = EmitScalarExpr(E->getArg(2));
615*700637cbSDimitry Andric     Value *SrcIdx = EmitScalarExpr(E->getArg(3));
616*700637cbSDimitry Andric     Value *NElems = EmitScalarExpr(E->getArg(4));
617*700637cbSDimitry Andric 
618*700637cbSDimitry Andric     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_table_copy);
619*700637cbSDimitry Andric 
620*700637cbSDimitry Andric     return Builder.CreateCall(Callee, {TableX, TableY, SrcIdx, DstIdx, NElems});
621*700637cbSDimitry Andric   }
622*700637cbSDimitry Andric   default:
623*700637cbSDimitry Andric     return nullptr;
624*700637cbSDimitry Andric   }
625*700637cbSDimitry Andric }
626