blob: 27c82e8cd03cb81702e25441ae726bbf9018c1f6 [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"
Chris Lattnerbef20ac2007-08-31 04:31:45 +000016#include "clang/AST/ASTContext.h"
Anders Carlsson022012e2007-08-20 18:05:56 +000017#include "clang/AST/Builtins.h"
18#include "clang/AST/Expr.h"
Chris Lattner6de93ff2007-08-26 04:17:05 +000019#include "llvm/Constants.h"
Chris Lattnerc5e940f2007-08-31 04:44:06 +000020#include "llvm/Function.h"
Anders Carlsson793680e2007-10-12 23:56:29 +000021#include "llvm/Intrinsics.h"
22
Anders Carlsson022012e2007-08-20 18:05:56 +000023using namespace clang;
24using namespace CodeGen;
25
Chris Lattner6de93ff2007-08-26 04:17:05 +000026RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) {
27 switch (BuiltinID) {
28 default:
Chris Lattnerc5e940f2007-08-31 04:44:06 +000029 if (getContext().BuiltinInfo.isLibFunction(BuiltinID))
30 return EmitCallExpr(CGM.getBuiltinLibFunction(BuiltinID), E);
31
Chris Lattnerdc4d2802007-12-02 01:49:16 +000032 WarnUnsupported(E, "builtin function");
Chris Lattner6de93ff2007-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 Carlssond6a275f2007-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 Lattner6de93ff2007-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 Carlsson793680e2007-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 Carlsson89799cf2007-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 Carlsson022012e2007-08-20 18:05:56 +000078 }
Anders Carlssond6a275f2007-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 Carlssonc2251dc2007-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 Hunt6f0768b2007-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 Carlssondf4852a2007-12-02 21:58:10 +0000103 case Builtin::BI__builtin_bswap32:
104 case Builtin::BI__builtin_bswap64: {
105 llvm::Value *ArgValue = EmitScalarExpr(E->getArg(0));
106 const llvm::Type *ArgType = ArgValue->getType();
107 llvm::Value *F =
108 llvm::Intrinsic::getDeclaration(&CGM.getModule(),
109 llvm::Intrinsic::bswap,
110 &ArgType, 1);
111 llvm::Value *V = Builder.CreateCall(F, ArgValue, "tmp");
112
113 return RValue::get(V);
114 }
Anders Carlsson89799cf2007-10-29 02:59:40 +0000115 }
116
Anders Carlsson022012e2007-08-20 18:05:56 +0000117 return RValue::get(0);
118}