blob: 8f079102dbd306d6514ec5b55216a51e1939ce39 [file] [log] [blame]
Anders Carlsson022012e2007-08-20 18:05:56 +00001//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Anders Carlsson and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
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 Carlssonca6fcfa2007-12-09 21:20:04 +000016#include "clang/Basic/TargetInfo.h"
Chris Lattnerbef20ac2007-08-31 04:31:45 +000017#include "clang/AST/ASTContext.h"
Anders Carlsson022012e2007-08-20 18:05:56 +000018#include "clang/AST/Builtins.h"
19#include "clang/AST/Expr.h"
Anders Carlsson564f1de2007-12-09 23:17:02 +000020#include "clang/AST/TargetBuiltins.h"
Chris Lattner6de93ff2007-08-26 04:17:05 +000021#include "llvm/Constants.h"
Chris Lattnerc5e940f2007-08-31 04:44:06 +000022#include "llvm/Function.h"
Anders Carlsson793680e2007-10-12 23:56:29 +000023#include "llvm/Intrinsics.h"
24
Anders Carlsson022012e2007-08-20 18:05:56 +000025using namespace clang;
26using namespace CodeGen;
27
Anders Carlssonca6fcfa2007-12-09 21:20:04 +000028using namespace llvm;
29
Chris Lattner6de93ff2007-08-26 04:17:05 +000030RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) {
31 switch (BuiltinID) {
Anders Carlssonca6fcfa2007-12-09 21:20:04 +000032 default: {
Chris Lattnerc5e940f2007-08-31 04:44:06 +000033 if (getContext().BuiltinInfo.isLibFunction(BuiltinID))
34 return EmitCallExpr(CGM.getBuiltinLibFunction(BuiltinID), E);
Anders Carlssonca6fcfa2007-12-09 21:20:04 +000035
36 // See if we have a target specific intrinsic.
37 llvm::Intrinsic::ID IntrinsicID;
38 const char *TargetPrefix = Target.getTargetPrefix();
39 const char *BuiltinName = getContext().BuiltinInfo.GetName(BuiltinID);
40#define GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
41#include "llvm/Intrinsics.gen"
42#undef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
43
44 if (IntrinsicID != Intrinsic::not_intrinsic) {
45 llvm::SmallVector<llvm::Value*, 16> Args;
46
47 llvm::Function *F = llvm::Intrinsic::getDeclaration(&CGM.getModule(),
48 IntrinsicID);
49
50 const llvm::FunctionType *FTy = F->getFunctionType();
51
52 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
53 llvm::Value *ArgValue = EmitScalarExpr(E->getArg(i));
54
55 // If the intrinsic arg type is different from the builtin arg type
56 // we need to do a bit cast.
57 const llvm::Type *PTy = FTy->getParamType(i);
58 if (PTy != ArgValue->getType()) {
59 assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) &&
60 "Must be able to losslessly bit cast to param");
61 ArgValue = Builder.CreateBitCast(ArgValue, PTy);
62 }
63
64 Args.push_back(ArgValue);
65 }
66
67 llvm::Value *V = Builder.CreateCall(F, &Args[0], &Args[0] + Args.size());
68
69 QualType BuiltinRetType = E->getType();
70
71 const llvm::Type *RetTy = BuiltinRetType->isVoidType() ?
72 llvm::Type::VoidTy : ConvertType(BuiltinRetType);
73
74 if (RetTy != V->getType()) {
75 assert(V->getType()->canLosslesslyBitCastTo(RetTy) &&
76 "Must be able to losslessly bit cast result type");
77
78 V = Builder.CreateBitCast(V, RetTy);
79 }
80
81 return RValue::get(V);
82 }
Anders Carlsson564f1de2007-12-09 23:17:02 +000083
84 // See if we have a target specific builtin that needs to be lowered.
85 llvm::Value *V = 0;
Chris Lattnerc5e940f2007-08-31 04:44:06 +000086
Anders Carlsson564f1de2007-12-09 23:17:02 +000087 if (strcmp(TargetPrefix, "x86") == 0)
88 V = EmitX86BuiltinExpr(BuiltinID, E);
89 else if (strcmp(TargetPrefix, "ppc") == 0)
90 V = EmitPPCBuiltinExpr(BuiltinID, E);
91
92 if (V)
93 return RValue::get(V);
94
Chris Lattnerdc4d2802007-12-02 01:49:16 +000095 WarnUnsupported(E, "builtin function");
Chris Lattner6de93ff2007-08-26 04:17:05 +000096
97 // Unknown builtin, for now just dump it out and return undef.
98 if (hasAggregateLLVMType(E->getType()))
99 return RValue::getAggregate(CreateTempAlloca(ConvertType(E->getType())));
100 return RValue::get(llvm::UndefValue::get(ConvertType(E->getType())));
Anders Carlssonca6fcfa2007-12-09 21:20:04 +0000101 }
Chris Lattner6de93ff2007-08-26 04:17:05 +0000102 case Builtin::BI__builtin___CFStringMakeConstantString: {
103 const Expr *Arg = E->getArg(0);
104
Anders Carlssond6a275f2007-11-01 00:39:26 +0000105 while (1) {
106 if (const ParenExpr *PE = dyn_cast<ParenExpr>(Arg))
107 Arg = PE->getSubExpr();
108 else if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(Arg))
109 Arg = CE->getSubExpr();
110 else
111 break;
112 }
Chris Lattner6de93ff2007-08-26 04:17:05 +0000113
114 const StringLiteral *Literal = cast<StringLiteral>(Arg);
115 std::string S(Literal->getStrData(), Literal->getByteLength());
116
117 return RValue::get(CGM.GetAddrOfConstantCFString(S));
Anders Carlsson793680e2007-10-12 23:56:29 +0000118 }
119 case Builtin::BI__builtin_va_start:
120 case Builtin::BI__builtin_va_end: {
121 llvm::Value *ArgValue = EmitScalarExpr(E->getArg(0));
122 const llvm::Type *DestType = llvm::PointerType::get(llvm::Type::Int8Ty);
123 if (ArgValue->getType() != DestType)
124 ArgValue = Builder.CreateBitCast(ArgValue, DestType,
125 ArgValue->getNameStart());
126
127 llvm::Intrinsic::ID inst = (BuiltinID == Builtin::BI__builtin_va_start) ?
128 llvm::Intrinsic::vastart : llvm::Intrinsic::vaend;
129 llvm::Value *F = llvm::Intrinsic::getDeclaration(&CGM.getModule(), inst);
130 llvm::Value *V = Builder.CreateCall(F, ArgValue);
131
132 return RValue::get(V);
133 }
Anders Carlsson89799cf2007-10-29 02:59:40 +0000134 case Builtin::BI__builtin_classify_type: {
135 llvm::APSInt Result(32);
136
137 if (!E->isBuiltinClassifyType(Result))
138 assert(0 && "Expr not __builtin_classify_type!");
139
140 return RValue::get(llvm::ConstantInt::get(Result));
Anders Carlsson022012e2007-08-20 18:05:56 +0000141 }
Anders Carlssond6a275f2007-11-01 00:39:26 +0000142 case Builtin::BI__builtin_constant_p: {
143 llvm::APSInt Result(32);
144
145 // FIXME: Analyze the parameter and check if it is a constant.
146 Result = 0;
147
148 return RValue::get(llvm::ConstantInt::get(Result));
149 }
Anders Carlssonc2251dc2007-11-20 19:05:17 +0000150 case Builtin::BI__builtin_abs: {
151 llvm::Value *ArgValue = EmitScalarExpr(E->getArg(0));
152
153 llvm::BinaryOperator *NegOp =
154 Builder.CreateNeg(ArgValue, (ArgValue->getName() + "neg").c_str());
155 llvm::Value *CmpResult =
156 Builder.CreateICmpSGE(ArgValue, NegOp->getOperand(0), "abscond");
157 llvm::Value *Result =
158 Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs");
159
160 return RValue::get(Result);
161 }
Oliver Hunt6f0768b2007-12-02 01:03:24 +0000162 case Builtin::BI__builtin_expect: {
163 llvm::Value *Condition = EmitScalarExpr(E->getArg(0));
164 return RValue::get(Condition);
165 }
Anders Carlssondf4852a2007-12-02 21:58:10 +0000166 case Builtin::BI__builtin_bswap32:
167 case Builtin::BI__builtin_bswap64: {
168 llvm::Value *ArgValue = EmitScalarExpr(E->getArg(0));
169 const llvm::Type *ArgType = ArgValue->getType();
170 llvm::Value *F =
171 llvm::Intrinsic::getDeclaration(&CGM.getModule(),
172 llvm::Intrinsic::bswap,
173 &ArgType, 1);
174 llvm::Value *V = Builder.CreateCall(F, ArgValue, "tmp");
175
176 return RValue::get(V);
177 }
Anders Carlssonc8ee7982007-12-05 07:22:48 +0000178 case Builtin::BI__builtin_inff: {
179 llvm::APFloat f(llvm::APFloat::IEEEsingle,
180 llvm::APFloat::fcInfinity, false);
181
182 llvm::Value *V = llvm::ConstantFP::get(llvm::Type::FloatTy, f);
183 return RValue::get(V);
184 }
185 case Builtin::BI__builtin_inf:
186 // FIXME: mapping long double onto double.
187 case Builtin::BI__builtin_infl: {
188 llvm::APFloat f(llvm::APFloat::IEEEdouble,
189 llvm::APFloat::fcInfinity, false);
190
191 llvm::Value *V = llvm::ConstantFP::get(llvm::Type::DoubleTy, f);
192 return RValue::get(V);
193 }
Anders Carlsson89799cf2007-10-29 02:59:40 +0000194 }
Anders Carlsson022012e2007-08-20 18:05:56 +0000195 return RValue::get(0);
196}
Anders Carlsson564f1de2007-12-09 23:17:02 +0000197
198llvm::Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
199 const CallExpr *E)
200{
201 switch (BuiltinID) {
Anders Carlsson46a26b02007-12-09 23:39:18 +0000202 default: return 0;
203 case X86::BI__builtin_ia32_mulps:
204 return Builder.CreateMul(EmitScalarExpr(E->getArg(0)),
205 EmitScalarExpr(E->getArg(1)),
206 "mulps");
Anders Carlsson4e4ee212007-12-11 02:25:54 +0000207 case X86::BI__builtin_ia32_pand:
208 return Builder.CreateAnd(EmitScalarExpr(E->getArg(0)),
209 EmitScalarExpr(E->getArg(1)),
210 "pand");
211 case X86::BI__builtin_ia32_por:
212 return Builder.CreateAnd(EmitScalarExpr(E->getArg(0)),
213 EmitScalarExpr(E->getArg(1)),
214 "por");
215 case X86::BI__builtin_ia32_pxor:
216 return Builder.CreateAnd(EmitScalarExpr(E->getArg(0)),
217 EmitScalarExpr(E->getArg(1)),
218 "pxor");
219 case X86::BI__builtin_ia32_pandn:
220 llvm::Value *V1 = Builder.CreateNot(EmitScalarExpr(E->getArg(0)), "tmp");
221 return Builder.CreateAnd(V1, EmitScalarExpr(E->getArg(1)), "pandn");
222 case X86::BI__builtin_ia32_paddb:
223 case X86::BI__builtin_ia32_paddd:
224 case X86::BI__builtin_ia32_paddq:
225 case X86::BI__builtin_ia32_paddw:
226 return Builder.CreateAdd(EmitScalarExpr(E->getArg(0)),
227 EmitScalarExpr(E->getArg(1)), "padd");
228 case X86::BI__builtin_ia32_psubb:
229 case X86::BI__builtin_ia32_psubd:
230 case X86::BI__builtin_ia32_psubq:
231 case X86::BI__builtin_ia32_psubw:
232 return Builder.CreateSub(EmitScalarExpr(E->getArg(0)),
233 EmitScalarExpr(E->getArg(1)), "psub");
Anders Carlssondb832302007-12-11 03:09:22 +0000234 case X86::BI__builtin_ia32_pmullw:
235 return Builder.CreateMul(EmitScalarExpr(E->getArg(0)),
236 EmitScalarExpr(E->getArg(1)), "pmul");
237 case X86::BI__builtin_ia32_punpckhbw:
238 return EmitShuffleVector(EmitScalarExpr(E->getArg(0)),
239 EmitScalarExpr(E->getArg(1)),
240 4, 12, 5, 13, 6, 14, 7, 15,
241 "punpckhbw");
242 case X86::BI__builtin_ia32_punpckhwd:
243 return EmitShuffleVector(EmitScalarExpr(E->getArg(0)),
244 EmitScalarExpr(E->getArg(1)),
245 2, 6, 3, 7,
246 "punpckhwd");
247 case X86::BI__builtin_ia32_punpckhdq:
248 return EmitShuffleVector(EmitScalarExpr(E->getArg(0)),
249 EmitScalarExpr(E->getArg(1)),
250 1, 3,
251 "punpckhdq");
252 case X86::BI__builtin_ia32_punpcklbw:
253 return EmitShuffleVector(EmitScalarExpr(E->getArg(0)),
254 EmitScalarExpr(E->getArg(1)),
255 0, 8, 1, 9, 2, 10, 3, 11,
256 "punpcklbw");
257 case X86::BI__builtin_ia32_punpcklwd:
258 return EmitShuffleVector(EmitScalarExpr(E->getArg(0)),
259 EmitScalarExpr(E->getArg(1)),
260 0, 4, 1, 5,
261 "punpcklwd");
262 case X86::BI__builtin_ia32_punpckldq:
263 return EmitShuffleVector(EmitScalarExpr(E->getArg(0)),
264 EmitScalarExpr(E->getArg(1)),
265 0, 2,
266 "punpckldq");
Anders Carlsson4e4ee212007-12-11 02:25:54 +0000267 case X86::BI__builtin_ia32_pshufd: {
268 llvm::Value *V = EmitScalarExpr(E->getArg(0));
269 llvm::ConstantInt *I =
270 cast<llvm::ConstantInt>(EmitScalarExpr(E->getArg(1)));
271 int i = I->getZExtValue();
272
273 return EmitShuffleVector(V, V,
274 i & 0x3, (i & 0xc) >> 2,
275 (i & 0x30) >> 4, (i & 0xc0) >> 6,
276 "pshufd");
277 }
Anders Carlsson564f1de2007-12-09 23:17:02 +0000278 }
279}
280
281llvm::Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
282 const CallExpr *E)
283{
284 switch (BuiltinID) {
Anders Carlsson46a26b02007-12-09 23:39:18 +0000285 default: return 0;
Anders Carlsson564f1de2007-12-09 23:17:02 +0000286 }
287}