blob: a1d5af19dda399e7912eee264e10180a1cfd01e0 [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//
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"
Chris Lattnerab862cc2007-08-31 04:31:45 +000016#include "clang/AST/ASTContext.h"
Anders Carlsson49865302007-08-20 18:05:56 +000017#include "clang/AST/Builtins.h"
18#include "clang/AST/Expr.h"
Chris Lattner783a78f2007-08-26 04:17:05 +000019#include "llvm/Constants.h"
Chris Lattner02c60f52007-08-31 04:44:06 +000020#include "llvm/Function.h"
Anders Carlssoncebb8d62007-10-12 23:56:29 +000021#include "llvm/Intrinsics.h"
22
Anders Carlsson49865302007-08-20 18:05:56 +000023using namespace clang;
24using namespace CodeGen;
25
Chris Lattner783a78f2007-08-26 04:17:05 +000026RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) {
27 switch (BuiltinID) {
28 default:
Chris Lattner02c60f52007-08-31 04:44:06 +000029 if (getContext().BuiltinInfo.isLibFunction(BuiltinID))
30 return EmitCallExpr(CGM.getBuiltinLibFunction(BuiltinID), E);
31
Chris Lattnere8f49632007-12-02 01:49:16 +000032 WarnUnsupported(E, "builtin function");
Chris Lattner783a78f2007-08-26 04:17:05 +000033
34 // Unknown builtin, for now just dump it out and return undef.
35 if (hasAggregateLLVMType(E->getType()))
36 return RValue::getAggregate(CreateTempAlloca(ConvertType(E->getType())));
37 return RValue::get(llvm::UndefValue::get(ConvertType(E->getType())));
38
39 case Builtin::BI__builtin___CFStringMakeConstantString: {
40 const Expr *Arg = E->getArg(0);
41
Anders Carlsson783e1432007-11-01 00:39:26 +000042 while (1) {
43 if (const ParenExpr *PE = dyn_cast<ParenExpr>(Arg))
44 Arg = PE->getSubExpr();
45 else if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(Arg))
46 Arg = CE->getSubExpr();
47 else
48 break;
49 }
Chris Lattner783a78f2007-08-26 04:17:05 +000050
51 const StringLiteral *Literal = cast<StringLiteral>(Arg);
52 std::string S(Literal->getStrData(), Literal->getByteLength());
53
54 return RValue::get(CGM.GetAddrOfConstantCFString(S));
Anders Carlssoncebb8d62007-10-12 23:56:29 +000055 }
56 case Builtin::BI__builtin_va_start:
57 case Builtin::BI__builtin_va_end: {
58 llvm::Value *ArgValue = EmitScalarExpr(E->getArg(0));
59 const llvm::Type *DestType = llvm::PointerType::get(llvm::Type::Int8Ty);
60 if (ArgValue->getType() != DestType)
61 ArgValue = Builder.CreateBitCast(ArgValue, DestType,
62 ArgValue->getNameStart());
63
64 llvm::Intrinsic::ID inst = (BuiltinID == Builtin::BI__builtin_va_start) ?
65 llvm::Intrinsic::vastart : llvm::Intrinsic::vaend;
66 llvm::Value *F = llvm::Intrinsic::getDeclaration(&CGM.getModule(), inst);
67 llvm::Value *V = Builder.CreateCall(F, ArgValue);
68
69 return RValue::get(V);
70 }
Anders Carlsson40438402007-10-29 02:59:40 +000071 case Builtin::BI__builtin_classify_type: {
72 llvm::APSInt Result(32);
73
74 if (!E->isBuiltinClassifyType(Result))
75 assert(0 && "Expr not __builtin_classify_type!");
76
77 return RValue::get(llvm::ConstantInt::get(Result));
Anders Carlsson49865302007-08-20 18:05:56 +000078 }
Anders Carlsson783e1432007-11-01 00:39:26 +000079 case Builtin::BI__builtin_constant_p: {
80 llvm::APSInt Result(32);
81
82 // FIXME: Analyze the parameter and check if it is a constant.
83 Result = 0;
84
85 return RValue::get(llvm::ConstantInt::get(Result));
86 }
Anders Carlssone79dbe22007-11-20 19:05:17 +000087 case Builtin::BI__builtin_abs: {
88 llvm::Value *ArgValue = EmitScalarExpr(E->getArg(0));
89
90 llvm::BinaryOperator *NegOp =
91 Builder.CreateNeg(ArgValue, (ArgValue->getName() + "neg").c_str());
92 llvm::Value *CmpResult =
93 Builder.CreateICmpSGE(ArgValue, NegOp->getOperand(0), "abscond");
94 llvm::Value *Result =
95 Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs");
96
97 return RValue::get(Result);
98 }
Oliver Huntb8eb0072007-12-02 01:03:24 +000099 case Builtin::BI__builtin_expect: {
100 llvm::Value *Condition = EmitScalarExpr(E->getArg(0));
101 return RValue::get(Condition);
102 }
Anders Carlsson40438402007-10-29 02:59:40 +0000103 }
104
Anders Carlsson49865302007-08-20 18:05:56 +0000105 return RValue::get(0);
106}