blob: d8fe060eb7afb05105f38ef7027ae0695685fa9d [file] [log] [blame]
Anders Carlsson49865302007-08-20 18:05:56 +00001//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner959e5be2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Anders Carlsson49865302007-08-20 18:05:56 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This contains code to emit Builtin calls as LLVM code.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CodeGenFunction.h"
15#include "CodeGenModule.h"
Anders Carlsson6f6c6482007-12-09 21:20:04 +000016#include "clang/Basic/TargetInfo.h"
Chris Lattnerab862cc2007-08-31 04:31:45 +000017#include "clang/AST/ASTContext.h"
Anders Carlsson49865302007-08-20 18:05:56 +000018#include "clang/AST/Builtins.h"
19#include "clang/AST/Expr.h"
Anders Carlssone1449c12007-12-09 23:17:02 +000020#include "clang/AST/TargetBuiltins.h"
Chris Lattner783a78f2007-08-26 04:17:05 +000021#include "llvm/Constants.h"
Chris Lattner02c60f52007-08-31 04:44:06 +000022#include "llvm/Function.h"
Anders Carlssoncebb8d62007-10-12 23:56:29 +000023#include "llvm/Intrinsics.h"
Anders Carlsson49865302007-08-20 18:05:56 +000024using namespace clang;
25using namespace CodeGen;
Anders Carlsson6f6c6482007-12-09 21:20:04 +000026using namespace llvm;
27
Chris Lattner783a78f2007-08-26 04:17:05 +000028RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) {
29 switch (BuiltinID) {
Anders Carlsson6f6c6482007-12-09 21:20:04 +000030 default: {
Chris Lattner02c60f52007-08-31 04:44:06 +000031 if (getContext().BuiltinInfo.isLibFunction(BuiltinID))
Nate Begeman33a50432008-01-17 18:06:09 +000032 return EmitCallExpr(CGM.getBuiltinLibFunction(BuiltinID),
33 E->getCallee()->getType(), E->arg_begin());
Anders Carlsson6f6c6482007-12-09 21:20:04 +000034
35 // See if we have a target specific intrinsic.
Chris Lattner9d37e132007-12-13 07:34:23 +000036 Intrinsic::ID IntrinsicID;
Anders Carlsson6f6c6482007-12-09 21:20:04 +000037 const char *TargetPrefix = Target.getTargetPrefix();
38 const char *BuiltinName = getContext().BuiltinInfo.GetName(BuiltinID);
39#define GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
40#include "llvm/Intrinsics.gen"
41#undef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
42
43 if (IntrinsicID != Intrinsic::not_intrinsic) {
Chris Lattner9d37e132007-12-13 07:34:23 +000044 SmallVector<Value*, 16> Args;
Anders Carlsson6f6c6482007-12-09 21:20:04 +000045
Chris Lattner4b23f942007-12-18 00:25:38 +000046 Function *F = CGM.getIntrinsic(IntrinsicID);
Anders Carlsson6f6c6482007-12-09 21:20:04 +000047 const llvm::FunctionType *FTy = F->getFunctionType();
48
49 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
Chris Lattner9d37e132007-12-13 07:34:23 +000050 Value *ArgValue = EmitScalarExpr(E->getArg(i));
Anders Carlsson6f6c6482007-12-09 21:20:04 +000051
52 // If the intrinsic arg type is different from the builtin arg type
53 // we need to do a bit cast.
54 const llvm::Type *PTy = FTy->getParamType(i);
55 if (PTy != ArgValue->getType()) {
56 assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) &&
57 "Must be able to losslessly bit cast to param");
58 ArgValue = Builder.CreateBitCast(ArgValue, PTy);
59 }
60
61 Args.push_back(ArgValue);
62 }
63
Chris Lattner9d37e132007-12-13 07:34:23 +000064 Value *V = Builder.CreateCall(F, &Args[0], &Args[0] + Args.size());
Anders Carlsson6f6c6482007-12-09 21:20:04 +000065 QualType BuiltinRetType = E->getType();
66
Chris Lattner9d37e132007-12-13 07:34:23 +000067 const llvm::Type *RetTy = llvm::Type::VoidTy;
68 if (!BuiltinRetType->isVoidType()) RetTy = ConvertType(BuiltinRetType);
Anders Carlsson6f6c6482007-12-09 21:20:04 +000069
70 if (RetTy != V->getType()) {
71 assert(V->getType()->canLosslesslyBitCastTo(RetTy) &&
72 "Must be able to losslessly bit cast result type");
Anders Carlsson6f6c6482007-12-09 21:20:04 +000073 V = Builder.CreateBitCast(V, RetTy);
74 }
75
76 return RValue::get(V);
77 }
Anders Carlssone1449c12007-12-09 23:17:02 +000078
79 // See if we have a target specific builtin that needs to be lowered.
Chris Lattner9d37e132007-12-13 07:34:23 +000080 Value *V = 0;
Chris Lattner02c60f52007-08-31 04:44:06 +000081
Anders Carlssone1449c12007-12-09 23:17:02 +000082 if (strcmp(TargetPrefix, "x86") == 0)
83 V = EmitX86BuiltinExpr(BuiltinID, E);
84 else if (strcmp(TargetPrefix, "ppc") == 0)
85 V = EmitPPCBuiltinExpr(BuiltinID, E);
86
87 if (V)
88 return RValue::get(V);
89
Chris Lattnere8f49632007-12-02 01:49:16 +000090 WarnUnsupported(E, "builtin function");
Chris Lattner783a78f2007-08-26 04:17:05 +000091
92 // Unknown builtin, for now just dump it out and return undef.
93 if (hasAggregateLLVMType(E->getType()))
94 return RValue::getAggregate(CreateTempAlloca(ConvertType(E->getType())));
Chris Lattner9d37e132007-12-13 07:34:23 +000095 return RValue::get(UndefValue::get(ConvertType(E->getType())));
Anders Carlsson6f6c6482007-12-09 21:20:04 +000096 }
Chris Lattner783a78f2007-08-26 04:17:05 +000097 case Builtin::BI__builtin___CFStringMakeConstantString: {
98 const Expr *Arg = E->getArg(0);
99
Anders Carlsson783e1432007-11-01 00:39:26 +0000100 while (1) {
101 if (const ParenExpr *PE = dyn_cast<ParenExpr>(Arg))
102 Arg = PE->getSubExpr();
103 else if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(Arg))
104 Arg = CE->getSubExpr();
105 else
106 break;
107 }
Chris Lattner783a78f2007-08-26 04:17:05 +0000108
109 const StringLiteral *Literal = cast<StringLiteral>(Arg);
110 std::string S(Literal->getStrData(), Literal->getByteLength());
111
112 return RValue::get(CGM.GetAddrOfConstantCFString(S));
Anders Carlssoncebb8d62007-10-12 23:56:29 +0000113 }
114 case Builtin::BI__builtin_va_start:
115 case Builtin::BI__builtin_va_end: {
Chris Lattner9d37e132007-12-13 07:34:23 +0000116 Value *ArgValue = EmitScalarExpr(E->getArg(0));
Christopher Lamb4fe5e702007-12-17 01:11:20 +0000117 const llvm::Type *DestType =
118 llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
Anders Carlssoncebb8d62007-10-12 23:56:29 +0000119 if (ArgValue->getType() != DestType)
120 ArgValue = Builder.CreateBitCast(ArgValue, DestType,
121 ArgValue->getNameStart());
122
Chris Lattner9d37e132007-12-13 07:34:23 +0000123 Intrinsic::ID inst = (BuiltinID == Builtin::BI__builtin_va_start) ?
124 Intrinsic::vastart : Intrinsic::vaend;
Chris Lattner4b23f942007-12-18 00:25:38 +0000125 return RValue::get(Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue));
Anders Carlssoncebb8d62007-10-12 23:56:29 +0000126 }
Anders Carlsson40438402007-10-29 02:59:40 +0000127 case Builtin::BI__builtin_classify_type: {
Chris Lattner9d37e132007-12-13 07:34:23 +0000128 APSInt Result(32);
Anders Carlsson40438402007-10-29 02:59:40 +0000129 if (!E->isBuiltinClassifyType(Result))
130 assert(0 && "Expr not __builtin_classify_type!");
Chris Lattner9d37e132007-12-13 07:34:23 +0000131 return RValue::get(ConstantInt::get(Result));
Anders Carlsson49865302007-08-20 18:05:56 +0000132 }
Anders Carlsson783e1432007-11-01 00:39:26 +0000133 case Builtin::BI__builtin_constant_p: {
Chris Lattner9d37e132007-12-13 07:34:23 +0000134 APSInt Result(32);
Anders Carlsson783e1432007-11-01 00:39:26 +0000135 // FIXME: Analyze the parameter and check if it is a constant.
136 Result = 0;
Chris Lattner9d37e132007-12-13 07:34:23 +0000137 return RValue::get(ConstantInt::get(Result));
Anders Carlsson783e1432007-11-01 00:39:26 +0000138 }
Anders Carlssone79dbe22007-11-20 19:05:17 +0000139 case Builtin::BI__builtin_abs: {
Chris Lattner9d37e132007-12-13 07:34:23 +0000140 Value *ArgValue = EmitScalarExpr(E->getArg(0));
Anders Carlssone79dbe22007-11-20 19:05:17 +0000141
142 llvm::BinaryOperator *NegOp =
143 Builder.CreateNeg(ArgValue, (ArgValue->getName() + "neg").c_str());
Chris Lattner9d37e132007-12-13 07:34:23 +0000144 Value *CmpResult =
Anders Carlssone79dbe22007-11-20 19:05:17 +0000145 Builder.CreateICmpSGE(ArgValue, NegOp->getOperand(0), "abscond");
Chris Lattner9d37e132007-12-13 07:34:23 +0000146 Value *Result =
Anders Carlssone79dbe22007-11-20 19:05:17 +0000147 Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs");
148
149 return RValue::get(Result);
150 }
Chris Lattner9d37e132007-12-13 07:34:23 +0000151 case Builtin::BI__builtin_expect:
152 return RValue::get(EmitScalarExpr(E->getArg(0)));
Anders Carlsson56118002007-12-02 21:58:10 +0000153 case Builtin::BI__builtin_bswap32:
154 case Builtin::BI__builtin_bswap64: {
Chris Lattner9d37e132007-12-13 07:34:23 +0000155 Value *ArgValue = EmitScalarExpr(E->getArg(0));
Anders Carlsson56118002007-12-02 21:58:10 +0000156 const llvm::Type *ArgType = ArgValue->getType();
Chris Lattner4b23f942007-12-18 00:25:38 +0000157 Value *F = CGM.getIntrinsic(Intrinsic::bswap, &ArgType, 1);
Chris Lattner9d37e132007-12-13 07:34:23 +0000158 return RValue::get(Builder.CreateCall(F, ArgValue, "tmp"));
Anders Carlsson56118002007-12-02 21:58:10 +0000159 }
Anders Carlssona8897f02007-12-05 07:22:48 +0000160 case Builtin::BI__builtin_inff: {
Chris Lattner9d37e132007-12-13 07:34:23 +0000161 APFloat f(APFloat::IEEEsingle, APFloat::fcInfinity, false);
162 return RValue::get(ConstantFP::get(llvm::Type::FloatTy, f));
Anders Carlssona8897f02007-12-05 07:22:48 +0000163 }
164 case Builtin::BI__builtin_inf:
165 // FIXME: mapping long double onto double.
166 case Builtin::BI__builtin_infl: {
Chris Lattner9d37e132007-12-13 07:34:23 +0000167 APFloat f(APFloat::IEEEdouble, APFloat::fcInfinity, false);
168 return RValue::get(ConstantFP::get(llvm::Type::DoubleTy, f));
Anders Carlssona8897f02007-12-05 07:22:48 +0000169 }
Chris Lattnerd1f26b32007-12-20 00:44:32 +0000170 case Builtin::BI__builtin_isgreater:
171 case Builtin::BI__builtin_isgreaterequal:
172 case Builtin::BI__builtin_isless:
173 case Builtin::BI__builtin_islessequal:
174 case Builtin::BI__builtin_islessgreater:
175 case Builtin::BI__builtin_isunordered: {
176 // Ordered comparisons: we know the arguments to these are matching scalar
177 // floating point values.
178 Value *LHS = EmitScalarExpr(E->getArg(0));
179 Value *RHS = EmitScalarExpr(E->getArg(1));
180
181 switch (BuiltinID) {
182 default: assert(0 && "Unknown ordered comparison");
183 case Builtin::BI__builtin_isgreater:
184 LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp");
185 break;
186 case Builtin::BI__builtin_isgreaterequal:
187 LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp");
188 break;
189 case Builtin::BI__builtin_isless:
190 LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp");
191 break;
192 case Builtin::BI__builtin_islessequal:
193 LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp");
194 break;
195 case Builtin::BI__builtin_islessgreater:
196 LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp");
197 break;
198 case Builtin::BI__builtin_isunordered:
199 LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp");
200 break;
201 }
202 // ZExt bool to int type.
203 return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType()),
204 "tmp"));
205 }
Anders Carlsson40438402007-10-29 02:59:40 +0000206 }
Anders Carlsson49865302007-08-20 18:05:56 +0000207 return RValue::get(0);
208}
Anders Carlssone1449c12007-12-09 23:17:02 +0000209
Chris Lattner9d37e132007-12-13 07:34:23 +0000210Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
211 const CallExpr *E) {
Anders Carlsson04c4b752007-12-14 17:48:24 +0000212
213 llvm::SmallVector<Value*, 4> Ops;
214
215 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++)
216 Ops.push_back(EmitScalarExpr(E->getArg(i)));
217
Anders Carlssone1449c12007-12-09 23:17:02 +0000218 switch (BuiltinID) {
Anders Carlsson0a35a812007-12-09 23:39:18 +0000219 default: return 0;
220 case X86::BI__builtin_ia32_mulps:
Anders Carlsson04c4b752007-12-14 17:48:24 +0000221 return Builder.CreateMul(Ops[0], Ops[1], "mulps");
Anders Carlsson17b80c12007-12-11 02:25:54 +0000222 case X86::BI__builtin_ia32_pand:
Anders Carlsson04c4b752007-12-14 17:48:24 +0000223 return Builder.CreateAnd(Ops[0], Ops[1], "pand");
Anders Carlsson17b80c12007-12-11 02:25:54 +0000224 case X86::BI__builtin_ia32_por:
Anders Carlsson04c4b752007-12-14 17:48:24 +0000225 return Builder.CreateAnd(Ops[0], Ops[1], "por");
Anders Carlsson17b80c12007-12-11 02:25:54 +0000226 case X86::BI__builtin_ia32_pxor:
Anders Carlsson04c4b752007-12-14 17:48:24 +0000227 return Builder.CreateAnd(Ops[0], Ops[1], "pxor");
Chris Lattner70376292007-12-11 04:33:00 +0000228 case X86::BI__builtin_ia32_pandn: {
Anders Carlsson04c4b752007-12-14 17:48:24 +0000229 Ops[0] = Builder.CreateNot(Ops[0], "tmp");
230 return Builder.CreateAnd(Ops[0], Ops[1], "pandn");
Chris Lattner70376292007-12-11 04:33:00 +0000231 }
Anders Carlsson17b80c12007-12-11 02:25:54 +0000232 case X86::BI__builtin_ia32_paddb:
233 case X86::BI__builtin_ia32_paddd:
234 case X86::BI__builtin_ia32_paddq:
235 case X86::BI__builtin_ia32_paddw:
Anders Carlsson1ad775f2007-12-16 22:33:50 +0000236 case X86::BI__builtin_ia32_addps:
237 return Builder.CreateAdd(Ops[0], Ops[1], "add");
Anders Carlsson17b80c12007-12-11 02:25:54 +0000238 case X86::BI__builtin_ia32_psubb:
239 case X86::BI__builtin_ia32_psubd:
240 case X86::BI__builtin_ia32_psubq:
241 case X86::BI__builtin_ia32_psubw:
Anders Carlsson1ad775f2007-12-16 22:33:50 +0000242 case X86::BI__builtin_ia32_subps:
243 return Builder.CreateSub(Ops[0], Ops[1], "sub");
244 case X86::BI__builtin_ia32_divps:
245 return Builder.CreateFDiv(Ops[0], Ops[1], "divps");
Anders Carlsson820cb742007-12-11 03:09:22 +0000246 case X86::BI__builtin_ia32_pmullw:
Anders Carlsson04c4b752007-12-14 17:48:24 +0000247 return Builder.CreateMul(Ops[0], Ops[1], "pmul");
Anders Carlsson820cb742007-12-11 03:09:22 +0000248 case X86::BI__builtin_ia32_punpckhbw:
Chris Lattner4b23f942007-12-18 00:25:38 +0000249 return EmitShuffleVector(Ops[0], Ops[1], 4, 12, 5, 13, 6, 14, 7, 15,
Anders Carlsson820cb742007-12-11 03:09:22 +0000250 "punpckhbw");
251 case X86::BI__builtin_ia32_punpckhwd:
Chris Lattner4b23f942007-12-18 00:25:38 +0000252 return EmitShuffleVector(Ops[0], Ops[1], 2, 6, 3, 7, "punpckhwd");
Anders Carlsson820cb742007-12-11 03:09:22 +0000253 case X86::BI__builtin_ia32_punpckhdq:
Chris Lattner4b23f942007-12-18 00:25:38 +0000254 return EmitShuffleVector(Ops[0], Ops[1], 1, 3, "punpckhdq");
Anders Carlsson820cb742007-12-11 03:09:22 +0000255 case X86::BI__builtin_ia32_punpcklbw:
Chris Lattner4b23f942007-12-18 00:25:38 +0000256 return EmitShuffleVector(Ops[0], Ops[1], 0, 8, 1, 9, 2, 10, 3, 11,
Anders Carlsson820cb742007-12-11 03:09:22 +0000257 "punpcklbw");
258 case X86::BI__builtin_ia32_punpcklwd:
Chris Lattner4b23f942007-12-18 00:25:38 +0000259 return EmitShuffleVector(Ops[0], Ops[1], 0, 4, 1, 5, "punpcklwd");
Anders Carlsson820cb742007-12-11 03:09:22 +0000260 case X86::BI__builtin_ia32_punpckldq:
Chris Lattner4b23f942007-12-18 00:25:38 +0000261 return EmitShuffleVector(Ops[0], Ops[1], 0, 2, "punpckldq");
Anders Carlsson04c4b752007-12-14 17:48:24 +0000262 case X86::BI__builtin_ia32_pslldi:
263 case X86::BI__builtin_ia32_psllqi:
264 case X86::BI__builtin_ia32_psllwi:
265 case X86::BI__builtin_ia32_psradi:
266 case X86::BI__builtin_ia32_psrawi:
267 case X86::BI__builtin_ia32_psrldi:
268 case X86::BI__builtin_ia32_psrlqi:
269 case X86::BI__builtin_ia32_psrlwi: {
270 Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::Int64Ty, "zext");
271 const llvm::Type *Ty = llvm::VectorType::get(llvm::Type::Int64Ty, 1);
272 Ops[1] = Builder.CreateBitCast(Ops[1], Ty, "bitcast");
Anders Carlsson04c4b752007-12-14 17:48:24 +0000273 const char *name = 0;
274 Intrinsic::ID ID = Intrinsic::not_intrinsic;
275
276 switch (BuiltinID) {
277 default: assert(0 && "Unsupported shift intrinsic!");
278 case X86::BI__builtin_ia32_pslldi:
279 name = "pslldi";
280 ID = Intrinsic::x86_mmx_psll_d;
281 break;
282 case X86::BI__builtin_ia32_psllqi:
283 name = "psllqi";
284 ID = Intrinsic::x86_mmx_psll_q;
285 break;
286 case X86::BI__builtin_ia32_psllwi:
287 name = "psllwi";
288 ID = Intrinsic::x86_mmx_psll_w;
289 break;
290 case X86::BI__builtin_ia32_psradi:
291 name = "psradi";
292 ID = Intrinsic::x86_mmx_psra_d;
293 break;
294 case X86::BI__builtin_ia32_psrawi:
295 name = "psrawi";
296 ID = Intrinsic::x86_mmx_psra_w;
297 break;
298 case X86::BI__builtin_ia32_psrldi:
299 name = "psrldi";
300 ID = Intrinsic::x86_mmx_psrl_d;
301 break;
302 case X86::BI__builtin_ia32_psrlqi:
303 name = "psrlqi";
304 ID = Intrinsic::x86_mmx_psrl_q;
305 break;
306 case X86::BI__builtin_ia32_psrlwi:
307 name = "psrlwi";
308 ID = Intrinsic::x86_mmx_psrl_w;
309 break;
310 }
Chris Lattner4b23f942007-12-18 00:25:38 +0000311 llvm::Function *F = CGM.getIntrinsic(ID);
Anders Carlsson04c4b752007-12-14 17:48:24 +0000312 return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
313 }
314 case X86::BI__builtin_ia32_pshufd: {
Chris Lattner4b23f942007-12-18 00:25:38 +0000315 unsigned i = cast<ConstantInt>(Ops[1])->getZExtValue();
Anders Carlsson04c4b752007-12-14 17:48:24 +0000316 return EmitShuffleVector(Ops[0], Ops[0],
Anders Carlsson17b80c12007-12-11 02:25:54 +0000317 i & 0x3, (i & 0xc) >> 2,
318 (i & 0x30) >> 4, (i & 0xc0) >> 6,
319 "pshufd");
320 }
Anders Carlsson68b8be92007-12-15 21:23:30 +0000321 case X86::BI__builtin_ia32_vec_init_v4hi:
322 case X86::BI__builtin_ia32_vec_init_v8qi:
323 case X86::BI__builtin_ia32_vec_init_v2si:
324 return EmitVector(&Ops[0], Ops.size());
325 case X86::BI__builtin_ia32_vec_ext_v2si:
326 return Builder.CreateExtractElement(Ops[0], Ops[1], "result");
Anders Carlsson1ad775f2007-12-16 22:33:50 +0000327 case X86::BI__builtin_ia32_cmpordss:
328 case X86::BI__builtin_ia32_cmpunordss:
329 case X86::BI__builtin_ia32_cmpeqss:
330 case X86::BI__builtin_ia32_cmpltss:
331 case X86::BI__builtin_ia32_cmpless:
332 case X86::BI__builtin_ia32_cmpneqss:
333 case X86::BI__builtin_ia32_cmpnltss:
334 case X86::BI__builtin_ia32_cmpnless: {
Chris Lattner4b23f942007-12-18 00:25:38 +0000335 unsigned i = 0;
Anders Carlsson1ad775f2007-12-16 22:33:50 +0000336 const char *name = 0;
337 switch (BuiltinID) {
338 default: assert(0 && "Unknown compare builtin!");
339 case X86::BI__builtin_ia32_cmpeqss:
340 i = 0;
341 name = "cmpeqss";
342 break;
343 case X86::BI__builtin_ia32_cmpltss:
344 i = 1;
345 name = "cmpltss";
346 break;
347 case X86::BI__builtin_ia32_cmpless:
348 i = 2;
349 name = "cmpless";
350 break;
351 case X86::BI__builtin_ia32_cmpunordss:
352 i = 3;
353 name = "cmpunordss";
354 break;
355 case X86::BI__builtin_ia32_cmpneqss:
356 i = 4;
357 name = "cmpneqss";
358 break;
359 case X86::BI__builtin_ia32_cmpnltss:
360 i = 5;
361 name = "cmpntlss";
362 break;
363 case X86::BI__builtin_ia32_cmpnless:
364 i = 6;
365 name = "cmpnless";
366 break;
367 case X86::BI__builtin_ia32_cmpordss:
368 i = 7;
369 name = "cmpordss";
370 break;
371 }
372
373 Ops.push_back(llvm::ConstantInt::get(llvm::Type::Int8Ty, i));
Chris Lattner4b23f942007-12-18 00:25:38 +0000374 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ss);
Anders Carlsson1ad775f2007-12-16 22:33:50 +0000375 return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
376 }
377 case X86::BI__builtin_ia32_cmpordps:
378 case X86::BI__builtin_ia32_cmpunordps:
379 case X86::BI__builtin_ia32_cmpeqps:
380 case X86::BI__builtin_ia32_cmpltps:
381 case X86::BI__builtin_ia32_cmpleps:
382 case X86::BI__builtin_ia32_cmpneqps:
383 case X86::BI__builtin_ia32_cmpngtps:
384 case X86::BI__builtin_ia32_cmpnltps:
385 case X86::BI__builtin_ia32_cmpgtps:
386 case X86::BI__builtin_ia32_cmpgeps:
387 case X86::BI__builtin_ia32_cmpngeps:
388 case X86::BI__builtin_ia32_cmpnleps: {
Chris Lattner4b23f942007-12-18 00:25:38 +0000389 unsigned i = 0;
Anders Carlsson1ad775f2007-12-16 22:33:50 +0000390 const char *name = 0;
391 bool ShouldSwap = false;
392 switch (BuiltinID) {
393 default: assert(0 && "Unknown compare builtin!");
Chris Lattner4b23f942007-12-18 00:25:38 +0000394 case X86::BI__builtin_ia32_cmpeqps: i = 0; name = "cmpeqps"; break;
395 case X86::BI__builtin_ia32_cmpltps: i = 1; name = "cmpltps"; break;
396 case X86::BI__builtin_ia32_cmpleps: i = 2; name = "cmpleps"; break;
397 case X86::BI__builtin_ia32_cmpunordps: i = 3; name = "cmpunordps"; break;
398 case X86::BI__builtin_ia32_cmpneqps: i = 4; name = "cmpneqps"; break;
399 case X86::BI__builtin_ia32_cmpnltps: i = 5; name = "cmpntlps"; break;
400 case X86::BI__builtin_ia32_cmpnleps: i = 6; name = "cmpnleps"; break;
401 case X86::BI__builtin_ia32_cmpordps: i = 7; name = "cmpordps"; break;
Anders Carlsson1ad775f2007-12-16 22:33:50 +0000402 case X86::BI__builtin_ia32_cmpgtps:
Chris Lattner4b23f942007-12-18 00:25:38 +0000403 ShouldSwap = true;
Anders Carlsson1ad775f2007-12-16 22:33:50 +0000404 i = 1;
405 name = "cmpgtps";
Anders Carlsson1ad775f2007-12-16 22:33:50 +0000406 break;
407 case X86::BI__builtin_ia32_cmpgeps:
408 i = 2;
409 name = "cmpgeps";
410 ShouldSwap = true;
411 break;
412 case X86::BI__builtin_ia32_cmpngtps:
413 i = 5;
414 name = "cmpngtps";
415 ShouldSwap = true;
416 break;
417 case X86::BI__builtin_ia32_cmpngeps:
418 i = 6;
419 name = "cmpngeps";
420 ShouldSwap = true;
421 break;
422 }
423
424 if (ShouldSwap)
425 std::swap(Ops[0], Ops[1]);
426
427 Ops.push_back(llvm::ConstantInt::get(llvm::Type::Int8Ty, i));
Chris Lattner4b23f942007-12-18 00:25:38 +0000428 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ps);
Anders Carlsson1ad775f2007-12-16 22:33:50 +0000429 return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
430 }
431 case X86::BI__builtin_ia32_movss:
432 return EmitShuffleVector(Ops[0], Ops[1], 4, 1, 2, 3, "movss");
433 case X86::BI__builtin_ia32_shufps:
Chris Lattner4b23f942007-12-18 00:25:38 +0000434 unsigned i = cast<ConstantInt>(Ops[2])->getZExtValue();
Anders Carlsson1ad775f2007-12-16 22:33:50 +0000435 return EmitShuffleVector(Ops[0], Ops[1],
436 i & 0x3, (i & 0xc) >> 2,
437 ((i & 0x30) >> 4) + 4,
438 ((i & 0x60) >> 6) + 4, "shufps");
Anders Carlssone1449c12007-12-09 23:17:02 +0000439 }
440}
441
Chris Lattner9d37e132007-12-13 07:34:23 +0000442Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
443 const CallExpr *E) {
Anders Carlssone1449c12007-12-09 23:17:02 +0000444 switch (BuiltinID) {
Anders Carlsson0a35a812007-12-09 23:39:18 +0000445 default: return 0;
Anders Carlssone1449c12007-12-09 23:17:02 +0000446 }
447}