CGBuiltin.cpp revision 5af93efc01f4acd247aa6d3124db6c92c3679198
169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===// 269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.// 3488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet// The LLVM Compiler Infrastructure 469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.// 569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.// This file is distributed under the University of Illinois Open Source 669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.// License. See LICENSE.TXT for details. 769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.// 869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.//===----------------------------------------------------------------------===// 969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.// 1069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.// This contains code to emit Builtin calls as LLVM code. 1169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.// 1269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.//===----------------------------------------------------------------------===// 1369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 1469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#include "TargetInfo.h" 1569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#include "CodeGenFunction.h" 1669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#include "CodeGenModule.h" 1769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#include "clang/Basic/TargetInfo.h" 1869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#include "clang/AST/APValue.h" 1969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#include "clang/AST/ASTContext.h" 2069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#include "clang/AST/Decl.h" 2169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#include "clang/Basic/TargetBuiltins.h" 2269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#include "llvm/Intrinsics.h" 2369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#include "llvm/Target/TargetData.h" 2469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.using namespace clang; 2569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.using namespace CodeGen; 2669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.using namespace llvm; 2769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 2869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.static void EmitMemoryBarrier(CodeGenFunction &CGF, 2969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. bool LoadLoad, bool LoadStore, 3069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. bool StoreLoad, bool StoreStore, 3169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. bool Device) { 328a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet Value *True = llvm::ConstantInt::getTrue(CGF.getLLVMContext()); 338a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet Value *False = llvm::ConstantInt::getFalse(CGF.getLLVMContext()); 348a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet Value *C[5] = { LoadLoad ? True : False, 3569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. LoadStore ? True : False, 3669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. StoreLoad ? True : False, 378a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet StoreStore ? True : False, 388a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet Device ? True : False }; 3969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. CGF.Builder.CreateCall(CGF.CGM.getIntrinsic(Intrinsic::memory_barrier), 4069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. C, C + 5); 416de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet} 426de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet 438a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet// The atomic builtins are also full memory barriers. This is a utility for 448a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet// wrapping a call to the builtins with memory barriers. 4569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.static Value *EmitCallWithBarrier(CodeGenFunction &CGF, Value *Fn, 4669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value **ArgBegin, Value **ArgEnd) { 478a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet // FIXME: We need a target hook for whether this applies to device memory or 488a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet // not. 498a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet bool Device = true; 50ceec6fa8492a5ff0ed163c96516716a3c2b09461Yann Collet 518a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet // Create barriers both before and after the call. 528a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet EmitMemoryBarrier(CGF, true, true, true, true, Device); 538a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet Value *Result = CGF.Builder.CreateCall(Fn, ArgBegin, ArgEnd); 5469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. EmitMemoryBarrier(CGF, true, true, true, true, Device); 558a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet return Result; 568a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet} 576de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet 5869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./// Utility to insert an atomic instruction based on Instrinsic::ID 5969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./// and the expression node. 608a9fb8cf3229c9a704c982667c63ac440b8487baYann Colletstatic RValue EmitBinaryAtomic(CodeGenFunction &CGF, 618a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet Intrinsic::ID Id, const CallExpr *E) { 628a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet Value *Args[2] = { CGF.EmitScalarExpr(E->getArg(0)), 6369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. CGF.EmitScalarExpr(E->getArg(1)) }; 648a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet const llvm::Type *ResType[2]; 65ceec6fa8492a5ff0ed163c96516716a3c2b09461Yann Collet ResType[0] = CGF.ConvertType(E->getType()); 66ceec6fa8492a5ff0ed163c96516716a3c2b09461Yann Collet ResType[1] = CGF.ConvertType(E->getArg(0)->getType()); 6741b6ed3c5bc7f0c85f1bfe3abc940d9b74581e7dTakayuki MATSUOKA Value *AtomF = CGF.CGM.getIntrinsic(Id, ResType, 2); 6841b6ed3c5bc7f0c85f1bfe3abc940d9b74581e7dTakayuki MATSUOKA return RValue::get(EmitCallWithBarrier(CGF, AtomF, Args, Args + 2)); 6941b6ed3c5bc7f0c85f1bfe3abc940d9b74581e7dTakayuki MATSUOKA} 7069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 7169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./// Utility to insert an atomic instruction based Instrinsic::ID and 7269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.// the expression node, where the return value is the result of the 7369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.// operation. 7469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.static RValue EmitBinaryAtomicPost(CodeGenFunction &CGF, 758a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet Intrinsic::ID Id, const CallExpr *E, 768a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet Instruction::BinaryOps Op) { 778a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet const llvm::Type *ResType[2]; 786de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet ResType[0] = CGF.ConvertType(E->getType()); 796de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet ResType[1] = CGF.ConvertType(E->getArg(0)->getType()); 8069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *AtomF = CGF.CGM.getIntrinsic(Id, ResType, 2); 8169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *Args[2] = { CGF.EmitScalarExpr(E->getArg(0)), 8269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. CGF.EmitScalarExpr(E->getArg(1)) }; 8369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *Result = EmitCallWithBarrier(CGF, AtomF, Args, Args + 2); 8469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return RValue::get(CGF.Builder.CreateBinOp(Op, Result, Args[1])); 8569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.} 8669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 8769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.static llvm::ConstantInt *getInt32(llvm::LLVMContext &Context, int32_t Value) { 8869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return llvm::ConstantInt::get(llvm::Type::getInt32Ty(Context), Value); 8969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.} 9069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 9169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 9269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./// EmitFAbs - Emit a call to fabs/fabsf/fabsl, depending on the type of ValTy, 9369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./// which must be a scalar floating point type. 9469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.static Value *EmitFAbs(CodeGenFunction &CGF, Value *V, QualType ValTy) { 9569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. const BuiltinType *ValTyP = ValTy->getAs<BuiltinType>(); 96d517d609d95bdbab665a6ddb6e018c450d1e5ae6Yann Collet assert(ValTyP && "isn't scalar fp type!"); 9769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 9869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. StringRef FnName; 9969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. switch (ValTyP->getKind()) { 10069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. default: assert(0 && "Isn't a scalar fp type!"); 10169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case BuiltinType::Float: FnName = "fabsf"; break; 10269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case BuiltinType::Double: FnName = "fabs"; break; 1038a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet case BuiltinType::LongDouble: FnName = "fabsl"; break; 1048a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet } 1058a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet 10669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // The prototype is something that takes and returns whatever V's type is. 10712ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet std::vector<const llvm::Type*> Args; 10812ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet Args.push_back(V->getType()); 10912ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet llvm::FunctionType *FT = llvm::FunctionType::get(V->getType(), Args, false); 11012ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet llvm::Value *Fn = CGF.CGM.CreateRuntimeFunction(FT, FnName); 11112ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet 1126de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet return CGF.Builder.CreateCall(Fn, V, "abs"); 11312ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet} 1146de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet 1156de52c2a8c40b7381e364ad87af9e80a60d95229Yann ColletRValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, 11669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. unsigned BuiltinID, const CallExpr *E) { 11769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // See if we can constant fold this builtin. If so, don't emit it at all. 1188a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet Expr::EvalResult Result; 1198a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet if (E->Evaluate(Result, CGM.getContext())) { 1208a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet if (Result.Val.isInt()) 12112ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet return RValue::get(llvm::ConstantInt::get(VMContext, 12212ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet Result.Val.getInt())); 12312ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet else if (Result.Val.isFloat()) 12412ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet return RValue::get(ConstantFP::get(VMContext, Result.Val.getFloat())); 12512ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet } 12612ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet 12769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. switch (BuiltinID) { 12869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. default: break; // Handle intrinsics and libm functions below. 12969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin___CFStringMakeConstantString: 13069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin___NSStringMakeConstantString: 131c5decf7562a3b4065922ae6460b7785eb91366f8Yann Collet return RValue::get(CGM.EmitConstantExpr(E, E->getType(), 0)); 1328a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet case Builtin::BI__builtin_stdarg_start: 1338a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet case Builtin::BI__builtin_va_start: 1348a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet case Builtin::BI__builtin_va_end: { 13569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *ArgValue = EmitVAListRef(E->getArg(0)); 13669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. const llvm::Type *DestType = llvm::Type::getInt8PtrTy(VMContext); 13769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. if (ArgValue->getType() != DestType) 13869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. ArgValue = Builder.CreateBitCast(ArgValue, DestType, 13969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. ArgValue->getName().data()); 14069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 14169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Intrinsic::ID inst = (BuiltinID == Builtin::BI__builtin_va_end) ? 14269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Intrinsic::vaend : Intrinsic::vastart; 14369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return RValue::get(Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue)); 14469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. } 14569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_va_copy: { 14669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *DstPtr = EmitVAListRef(E->getArg(0)); 1478a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet Value *SrcPtr = EmitVAListRef(E->getArg(1)); 1488a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet 1498a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet const llvm::Type *Type = llvm::Type::getInt8PtrTy(VMContext); 15069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 15169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. DstPtr = Builder.CreateBitCast(DstPtr, Type); 15269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. SrcPtr = Builder.CreateBitCast(SrcPtr, Type); 15369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return RValue::get(Builder.CreateCall2(CGM.getIntrinsic(Intrinsic::vacopy), 15469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. DstPtr, SrcPtr)); 15569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. } 15669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_abs: { 15769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *ArgValue = EmitScalarExpr(E->getArg(0)); 15869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 15969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *NegOp = Builder.CreateNeg(ArgValue, "neg"); 16069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *CmpResult = 16169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Builder.CreateICmpSGE(ArgValue, 16269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. llvm::Constant::getNullValue(ArgValue->getType()), 16312ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet "abscond"); 16412ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet Value *Result = 16569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs"); 16669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 16769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return RValue::get(Result); 16869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. } 16969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_ctz: 17069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_ctzl: 17169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_ctzll: { 17212ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet Value *ArgValue = EmitScalarExpr(E->getArg(0)); 17312ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet 17469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. const llvm::Type *ArgType = ArgValue->getType(); 17569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *F = CGM.getIntrinsic(Intrinsic::cttz, &ArgType, 1); 1766de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet 17769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. const llvm::Type *ResultType = ConvertType(E->getType()); 17812ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet Value *Result = Builder.CreateCall(F, ArgValue, "tmp"); 17912ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet if (Result->getType() != ResultType) 18069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 18169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. "cast"); 18269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return RValue::get(Result); 18369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. } 18469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_clz: 18512ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet case Builtin::BI__builtin_clzl: 18612ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet case Builtin::BI__builtin_clzll: { 18769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *ArgValue = EmitScalarExpr(E->getArg(0)); 18869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 18969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. const llvm::Type *ArgType = ArgValue->getType(); 19069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *F = CGM.getIntrinsic(Intrinsic::ctlz, &ArgType, 1); 19169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 19212ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet const llvm::Type *ResultType = ConvertType(E->getType()); 19312ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet Value *Result = Builder.CreateCall(F, ArgValue, "tmp"); 19469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. if (Result->getType() != ResultType) 19569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 19669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. "cast"); 19769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return RValue::get(Result); 19869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. } 19912ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet case Builtin::BI__builtin_ffs: 20012ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet case Builtin::BI__builtin_ffsl: 20112ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet case Builtin::BI__builtin_ffsll: { 20212ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet // ffs(x) -> x ? cttz(x) + 1 : 0 20312ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet Value *ArgValue = EmitScalarExpr(E->getArg(0)); 20412ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet 20512ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet const llvm::Type *ArgType = ArgValue->getType(); 20612ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet Value *F = CGM.getIntrinsic(Intrinsic::cttz, &ArgType, 1); 20712ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet 20869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. const llvm::Type *ResultType = ConvertType(E->getType()); 20969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *Tmp = Builder.CreateAdd(Builder.CreateCall(F, ArgValue, "tmp"), 2106de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet llvm::ConstantInt::get(ArgType, 1), "tmp"); 2116de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Value *Zero = llvm::Constant::getNullValue(ArgType); 2126de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero"); 213c5decf7562a3b4065922ae6460b7785eb91366f8Yann Collet Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp, "ffs"); 2146de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet if (Result->getType() != ResultType) 2156de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 21669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. "cast"); 21769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return RValue::get(Result); 21869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. } 2193b4e3f2b01df752d82a51d7b7afaa9a2fd5a5ff8Yann Collet case Builtin::BI__builtin_parity: 22069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_parityl: 22169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_parityll: { 22269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // parity(x) -> ctpop(x) & 1 22369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *ArgValue = EmitScalarExpr(E->getArg(0)); 22469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 22569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. const llvm::Type *ArgType = ArgValue->getType(); 226488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet Value *F = CGM.getIntrinsic(Intrinsic::ctpop, &ArgType, 1); 22769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 22869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. const llvm::Type *ResultType = ConvertType(E->getType()); 22969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *Tmp = Builder.CreateCall(F, ArgValue, "tmp"); 23069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *Result = Builder.CreateAnd(Tmp, llvm::ConstantInt::get(ArgType, 1), 23169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. "tmp"); 23269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. if (Result->getType() != ResultType) 23369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 23469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. "cast"); 23569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return RValue::get(Result); 23669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. } 23769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_popcount: 23869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_popcountl: 23969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_popcountll: { 24069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *ArgValue = EmitScalarExpr(E->getArg(0)); 24169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 24269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. const llvm::Type *ArgType = ArgValue->getType(); 24369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *F = CGM.getIntrinsic(Intrinsic::ctpop, &ArgType, 1); 24469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 24569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. const llvm::Type *ResultType = ConvertType(E->getType()); 24669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *Result = Builder.CreateCall(F, ArgValue, "tmp"); 24769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. if (Result->getType() != ResultType) 2488a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 24969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. "cast"); 25069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return RValue::get(Result); 25169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. } 25269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_expect: 25369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // FIXME: pass expect through to LLVM 25412ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet return RValue::get(EmitScalarExpr(E->getArg(0))); 25569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_bswap32: 25669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_bswap64: { 25769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *ArgValue = EmitScalarExpr(E->getArg(0)); 25869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. const llvm::Type *ArgType = ArgValue->getType(); 25912ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet Value *F = CGM.getIntrinsic(Intrinsic::bswap, &ArgType, 1); 26069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return RValue::get(Builder.CreateCall(F, ArgValue, "tmp")); 26169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. } 26269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_object_size: { 26369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // We pass this builtin onto the optimizer so that it can 26469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // figure out the object size in more complex cases. 26569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. const llvm::Type *ResType[] = { 26669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. ConvertType(E->getType()) 26769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. }; 26869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 26969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // LLVM only supports 0 and 2, make sure that we pass along that 27069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // as a boolean. 27169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *Ty = EmitScalarExpr(E->getArg(1)); 27269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. ConstantInt *CI = dyn_cast<ConstantInt>(Ty); 27369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. assert(CI); 2746de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet uint64_t val = CI->getZExtValue(); 2756de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet CI = ConstantInt::get(llvm::Type::getInt1Ty(VMContext), (val & 0x2) >> 1); 2766de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet 2776de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Value *F = CGM.getIntrinsic(Intrinsic::objectsize, ResType, 1); 2786de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet return RValue::get(Builder.CreateCall2(F, 2796de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet EmitScalarExpr(E->getArg(0)), 2806de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet CI)); 2816de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet } 2826de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet case Builtin::BI__builtin_prefetch: { 283ceec6fa8492a5ff0ed163c96516716a3c2b09461Yann Collet Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0)); 2846de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet // FIXME: Technically these constants should of type 'int', yes? 2856de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet RW = (E->getNumArgs() > 1) ? EmitScalarExpr(E->getArg(1)) : 2866de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0); 2876de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : 2886de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 3); 2896de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Value *F = CGM.getIntrinsic(Intrinsic::prefetch, 0, 0); 2906de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet return RValue::get(Builder.CreateCall3(F, Address, RW, Locality)); 2916de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet } 2926de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet case Builtin::BI__builtin_trap: { 293488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet Value *F = CGM.getIntrinsic(Intrinsic::trap, 0, 0); 29469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return RValue::get(Builder.CreateCall(F)); 29569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. } 29669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_unreachable: { 29769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. if (CatchUndefined && HaveInsertPoint()) 29869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. EmitBranch(getTrapBB()); 29969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *V = Builder.CreateUnreachable(); 30069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Builder.ClearInsertionPoint(); 30169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return RValue::get(V); 30269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. } 30369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 30469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_powi: 30569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_powif: 3068a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet case Builtin::BI__builtin_powil: { 30769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *Base = EmitScalarExpr(E->getArg(0)); 3086de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Value *Exponent = EmitScalarExpr(E->getArg(1)); 3096de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet const llvm::Type *ArgType = Base->getType(); 31069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *F = CGM.getIntrinsic(Intrinsic::powi, &ArgType, 1); 31112ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp")); 31269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. } 3138a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet 31469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_isgreater: 31569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_isgreaterequal: 31669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_isless: 31769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_islessequal: 3188a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet case Builtin::BI__builtin_islessgreater: 3196de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet case Builtin::BI__builtin_isunordered: { 32069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // Ordered comparisons: we know the arguments to these are matching scalar 32169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // floating point values. 32269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *LHS = EmitScalarExpr(E->getArg(0)); 3238a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet Value *RHS = EmitScalarExpr(E->getArg(1)); 32469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 32569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. switch (BuiltinID) { 32669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. default: assert(0 && "Unknown ordered comparison"); 3278a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet case Builtin::BI__builtin_isgreater: 32869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp"); 32969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. break; 33069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_isgreaterequal: 33169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp"); 3328a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet break; 33369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_isless: 33469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp"); 3356de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet break; 33669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_islessequal: 3378a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp"); 3386de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet break; 33969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_islessgreater: 34069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp"); 34169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. break; 34269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_isunordered: 3438a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp"); 34469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. break; 34569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. } 34669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // ZExt bool to int type. 34769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType()), 34869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. "tmp")); 34969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. } 35069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_isnan: { 35169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *V = EmitScalarExpr(E->getArg(0)); 35269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. V = Builder.CreateFCmpUNO(V, V, "cmp"); 3538a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()), "tmp")); 35469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. } 35569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 35669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_isinf: { 35769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // isinf(x) --> fabs(x) == infinity 35869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *V = EmitScalarExpr(E->getArg(0)); 35969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. V = EmitFAbs(*this, V, E->getArg(0)->getType()); 36069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 36169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. V = Builder.CreateFCmpOEQ(V, ConstantFP::getInfinity(V->getType()),"isinf"); 36269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()), "tmp")); 3636de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet } 3646de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet 3656de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet // TODO: BI__builtin_isinf_sign 36669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0 367488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet 36869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_isnormal: { 36969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // isnormal(x) --> x == x && fabsf(x) < infinity && fabsf(x) >= float_min 37069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *V = EmitScalarExpr(E->getArg(0)); 37169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq"); 37269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 37369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *Abs = EmitFAbs(*this, V, E->getArg(0)->getType()); 37469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *IsLessThanInf = 37569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Builder.CreateFCmpULT(Abs, ConstantFP::getInfinity(V->getType()),"isinf"); 37669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. APFloat Smallest = APFloat::getSmallestNormalized( 3776de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet getContext().getFloatTypeSemantics(E->getArg(0)->getType())); 3786de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Value *IsNormal = 3796de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Builder.CreateFCmpUGE(Abs, ConstantFP::get(V->getContext(), Smallest), 380ceec6fa8492a5ff0ed163c96516716a3c2b09461Yann Collet "isnormal"); 38169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. V = Builder.CreateAnd(Eq, IsLessThanInf, "and"); 38269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. V = Builder.CreateAnd(V, IsNormal, "and"); 3838a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 38469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. } 385ceec6fa8492a5ff0ed163c96516716a3c2b09461Yann Collet 38612ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet case Builtin::BI__builtin_isfinite: { 3876de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet // isfinite(x) --> x == x && fabs(x) != infinity; } 3886de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Value *V = EmitScalarExpr(E->getArg(0)); 38969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq"); 39012ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet 39169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *Abs = EmitFAbs(*this, V, E->getArg(0)->getType()); 3928a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet Value *IsNotInf = 3936de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Builder.CreateFCmpUNE(Abs, ConstantFP::getInfinity(V->getType()),"isinf"); 3946de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet 39512ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet V = Builder.CreateAnd(Eq, IsNotInf, "and"); 39612ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 39712ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet } 3986de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet 3998a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet case Builtin::BIalloca: 40069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_alloca: { 4016de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Value *Size = EmitScalarExpr(E->getArg(0)); 4026de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet return RValue::get(Builder.CreateAlloca(llvm::Type::getInt8Ty(VMContext), Size, "tmp")); 4036de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet } 40469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BIbzero: 4058a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet case Builtin::BI__builtin_bzero: { 4066de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Value *Address = EmitScalarExpr(E->getArg(0)); 4076de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Value *SizeVal = EmitScalarExpr(E->getArg(1)); 4086de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Builder.CreateCall5(CGM.getMemSetFn(Address->getType(), SizeVal->getType()), 4096de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Address, 4106de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 0), 41169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. SizeVal, 4128a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1), 41369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0)); 4146de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet return RValue::get(Address); 41569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. } 4168a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet case Builtin::BImemcpy: 41769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_memcpy: { 41869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *Address = EmitScalarExpr(E->getArg(0)); 4196de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Value *SrcAddr = EmitScalarExpr(E->getArg(1)); 42069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *SizeVal = EmitScalarExpr(E->getArg(2)); 4218a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet Builder.CreateCall5(CGM.getMemCpyFn(Address->getType(), SrcAddr->getType(), 4226de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet SizeVal->getType()), 4236de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Address, SrcAddr, SizeVal, 4246de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1), 4256de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0)); 42669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return RValue::get(Address); 4278a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet } 4286de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet case Builtin::BImemmove: 4296de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet case Builtin::BI__builtin_memmove: { 43069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *Address = EmitScalarExpr(E->getArg(0)); 4318a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet Value *SrcAddr = EmitScalarExpr(E->getArg(1)); 43269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *SizeVal = EmitScalarExpr(E->getArg(2)); 4336de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Builder.CreateCall5(CGM.getMemMoveFn(Address->getType(), SrcAddr->getType(), 43469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. SizeVal->getType()), 43569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Address, SrcAddr, SizeVal, 4368a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1), 4376de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0)); 4386de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet return RValue::get(Address); 4396de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet } 4406de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet case Builtin::BImemset: 4416de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet case Builtin::BI__builtin_memset: { 4426de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Value *Address = EmitScalarExpr(E->getArg(0)); 44369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *SizeVal = EmitScalarExpr(E->getArg(2)); 4448a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet Builder.CreateCall5(CGM.getMemSetFn(Address->getType(), SizeVal->getType()), 44569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Address, 44669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), 44769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. llvm::Type::getInt8Ty(VMContext)), 44869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. SizeVal, 4496de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1), 4506de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0)); 45169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return RValue::get(Address); 4528a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet } 45369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_dwarf_cfa: { 45469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // The offset in bytes from the first argument to the CFA. 45569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // 45669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // Why on earth is this in the frontend? Is there any reason at 45769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // all that the backend can't reasonably determine this while 45869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // lowering llvm.eh.dwarf.cfa()? 45969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // 46069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // TODO: If there's a satisfactory reason, add a target hook for 46169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // this instead of hard-coding 0, which is correct for most targets. 46269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. int32_t Offset = 0; 46369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 46469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *F = CGM.getIntrinsic(Intrinsic::eh_dwarf_cfa, 0, 0); 46569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return RValue::get(Builder.CreateCall(F, getInt32(VMContext, Offset))); 466488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet } 467488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet case Builtin::BI__builtin_return_address: { 468488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet Value *Depth = EmitScalarExpr(E->getArg(0)); 469488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet Depth = Builder.CreateIntCast(Depth, 470488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet llvm::Type::getInt32Ty(VMContext), 471488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet false, "tmp"); 472488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet Value *F = CGM.getIntrinsic(Intrinsic::returnaddress, 0, 0); 473488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet return RValue::get(Builder.CreateCall(F, Depth)); 474488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet } 475488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet case Builtin::BI__builtin_frame_address: { 476ceec6fa8492a5ff0ed163c96516716a3c2b09461Yann Collet Value *Depth = EmitScalarExpr(E->getArg(0)); 477488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet Depth = Builder.CreateIntCast(Depth, 478488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet llvm::Type::getInt32Ty(VMContext), 479488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet false, "tmp"); 480488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet Value *F = CGM.getIntrinsic(Intrinsic::frameaddress, 0, 0); 481488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet return RValue::get(Builder.CreateCall(F, Depth)); 482488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet } 483488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet case Builtin::BI__builtin_extract_return_addr: { 484488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet Value *Address = EmitScalarExpr(E->getArg(0)); 485488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet Value *Result = getTargetHooks().decodeReturnAddress(*this, Address); 486488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet return RValue::get(Result); 48769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. } 488488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet case Builtin::BI__builtin_frob_return_addr: { 48969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *Address = EmitScalarExpr(E->getArg(0)); 49069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *Result = getTargetHooks().encodeReturnAddress(*this, Address); 4916de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet return RValue::get(Result); 4926de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet } 493ceec6fa8492a5ff0ed163c96516716a3c2b09461Yann Collet case Builtin::BI__builtin_dwarf_sp_column: { 4946de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet const llvm::IntegerType *Ty 4956de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet = cast<llvm::IntegerType>(ConvertType(E->getType())); 4966de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet int Column = getTargetHooks().getDwarfEHStackPointer(CGM); 4976de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet if (Column == -1) { 4986de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet CGM.ErrorUnsupported(E, "__builtin_dwarf_sp_column"); 4996de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet return RValue::get(llvm::UndefValue::get(Ty)); 5006de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet } 50169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return RValue::get(llvm::ConstantInt::get(Ty, Column, true)); 50269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. } 50369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_init_dwarf_reg_size_table: { 50469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *Address = EmitScalarExpr(E->getArg(0)); 50569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. if (getTargetHooks().initDwarfEHRegSizeTable(*this, Address)) 50669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. CGM.ErrorUnsupported(E, "__builtin_init_dwarf_reg_size_table"); 5078a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet return RValue::get(llvm::UndefValue::get(ConvertType(E->getType()))); 50869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. } 50969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_eh_return: { 51069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *Int = EmitScalarExpr(E->getArg(0)); 51169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *Ptr = EmitScalarExpr(E->getArg(1)); 5128a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet 51369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(Int->getType()); 51469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. assert((IntTy->getBitWidth() == 32 || IntTy->getBitWidth() == 64) && 51569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. "LLVM's __builtin_eh_return only supports 32- and 64-bit variants"); 51669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *F = CGM.getIntrinsic(IntTy->getBitWidth() == 32 517c5decf7562a3b4065922ae6460b7785eb91366f8Yann Collet ? Intrinsic::eh_return_i32 51869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. : Intrinsic::eh_return_i64, 5198a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet 0, 0); 5206de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Builder.CreateCall2(F, Int, Ptr); 5218a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet Value *V = Builder.CreateUnreachable(); 5228a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet Builder.ClearInsertionPoint(); 52369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return RValue::get(V); 5248a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet } 52569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__builtin_unwind_init: { 52669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init, 0, 0); 52769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return RValue::get(Builder.CreateCall(F)); 52869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. } 5298a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet case Builtin::BI__builtin_extend_pointer: { 53069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // Extends a pointer to the size of an _Unwind_Word, which is 53169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // uint64_t on all platforms. Generally this gets poked into a 5328a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet // register and eventually used as an address, so if the 53369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // addressing registers are wider than pointers and the platform 53469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // doesn't implicitly ignore high-order bits when doing 53569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // addressing, we need to make sure we zext / sext based on 53669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // the platform's expectations. 5378a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet // 53869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // See: http://gcc.gnu.org/ml/gcc-bugs/2002-02/msg00237.html 53969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 54069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. LLVMContext &C = CGM.getLLVMContext(); 54169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 5428a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet // Cast the pointer to intptr_t. 54369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *Ptr = EmitScalarExpr(E->getArg(0)); 54469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. const llvm::IntegerType *IntPtrTy = CGM.getTargetData().getIntPtrType(C); 54569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *Result = Builder.CreatePtrToInt(Ptr, IntPtrTy, "extend.cast"); 54669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 54769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // If that's 64 bits, we're done. 54869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. if (IntPtrTy->getBitWidth() == 64) 54969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return RValue::get(Result); 55069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 55169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. // Otherwise, ask the codegen data what to do. 55269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. const llvm::IntegerType *Int64Ty = llvm::IntegerType::get(C, 64); 55312ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet if (getTargetHooks().extendPointerWithSExt()) 55412ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet return RValue::get(Builder.CreateSExt(Result, Int64Ty, "extend.sext")); 5556de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet else 5566de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet return RValue::get(Builder.CreateZExt(Result, Int64Ty, "extend.zext")); 5576de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet } 5586de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet case Builtin::BI__builtin_setjmp: { 5596de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet // Buffer is a void**. 5606de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Value *Buf = EmitScalarExpr(E->getArg(0)); 561d517d609d95bdbab665a6ddb6e018c450d1e5ae6Yann Collet 5628a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet // Store the frame pointer to the setjmp buffer. 5636de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Value *FrameAddr = 5646de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress), 5656de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0)); 56669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Builder.CreateStore(FrameAddr, Buf); 5678a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet 5686de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet // Store the stack pointer to the setjmp buffer. 5696de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Value *StackAddr = 5706de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Builder.CreateCall(CGM.getIntrinsic(Intrinsic::stacksave)); 5716de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Value *StackSaveSlot = 5726de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Builder.CreateGEP(Buf, ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 5736de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet 2)); 5746de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Builder.CreateStore(StackAddr, StackSaveSlot); 5756de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet 5766de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet // Call LLVM's EH setjmp, which is lightweight. 57769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp); 5788a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet Buf = Builder.CreateBitCast(Buf, llvm::Type::getInt8PtrTy(VMContext)); 5796de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet return RValue::get(Builder.CreateCall(F, Buf)); 5806de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet } 58112ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet case Builtin::BI__builtin_longjmp: { 58212ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet Value *Buf = EmitScalarExpr(E->getArg(0)); 5836de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Buf = Builder.CreateBitCast(Buf, llvm::Type::getInt8PtrTy(VMContext)); 58469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 5858a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet // Call LLVM's EH longjmp, which is lightweight. 5866de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet Builder.CreateCall(CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp), Buf); 58769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 5886de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet // longjmp doesn't return; mark this as unreachable 58969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *V = Builder.CreateUnreachable(); 5908a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet Builder.ClearInsertionPoint(); 5916de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet return RValue::get(V); 5926de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet } 593d517d609d95bdbab665a6ddb6e018c450d1e5ae6Yann Collet case Builtin::BI__sync_fetch_and_add: 5948a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet case Builtin::BI__sync_fetch_and_sub: 5956de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet case Builtin::BI__sync_fetch_and_or: 5966de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet case Builtin::BI__sync_fetch_and_and: 5976de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet case Builtin::BI__sync_fetch_and_xor: 5986de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet case Builtin::BI__sync_add_and_fetch: 5996de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet case Builtin::BI__sync_sub_and_fetch: 60069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_and_and_fetch: 6018a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet case Builtin::BI__sync_or_and_fetch: 60212ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet case Builtin::BI__sync_xor_and_fetch: 60312ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet case Builtin::BI__sync_val_compare_and_swap: 60412ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet case Builtin::BI__sync_bool_compare_and_swap: 60512ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet case Builtin::BI__sync_lock_test_and_set: 60612ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet case Builtin::BI__sync_lock_release: 60712ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet assert(0 && "Shouldn't make it through sema"); 60812ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet case Builtin::BI__sync_fetch_and_add_1: 60912ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet case Builtin::BI__sync_fetch_and_add_2: 61012ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet case Builtin::BI__sync_fetch_and_add_4: 61112ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet case Builtin::BI__sync_fetch_and_add_8: 61212ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet case Builtin::BI__sync_fetch_and_add_16: 61312ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet return EmitBinaryAtomic(*this, Intrinsic::atomic_load_add, E); 61412ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet case Builtin::BI__sync_fetch_and_sub_1: 61512ab41571ef7fd11b8b2013aa943beae373cef8aYann Collet case Builtin::BI__sync_fetch_and_sub_2: 6166de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet case Builtin::BI__sync_fetch_and_sub_4: 6176de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet case Builtin::BI__sync_fetch_and_sub_8: 61869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_fetch_and_sub_16: 61969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return EmitBinaryAtomic(*this, Intrinsic::atomic_load_sub, E); 6208a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet case Builtin::BI__sync_fetch_and_or_1: 6216de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet case Builtin::BI__sync_fetch_and_or_2: 6226de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet case Builtin::BI__sync_fetch_and_or_4: 6236de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet case Builtin::BI__sync_fetch_and_or_8: 6246de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet case Builtin::BI__sync_fetch_and_or_16: 62569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return EmitBinaryAtomic(*this, Intrinsic::atomic_load_or, E); 62669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_fetch_and_and_1: 62769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_fetch_and_and_2: 62869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_fetch_and_and_4: 62969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_fetch_and_and_8: 63089d8b98d0dd896dccf6964fa3c6bb6ae6a2349b0Yann Collet case Builtin::BI__sync_fetch_and_and_16: 63169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return EmitBinaryAtomic(*this, Intrinsic::atomic_load_and, E); 63269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_fetch_and_xor_1: 6336de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet case Builtin::BI__sync_fetch_and_xor_2: 6346de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet case Builtin::BI__sync_fetch_and_xor_4: 63569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_fetch_and_xor_8: 63669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_fetch_and_xor_16: 63769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return EmitBinaryAtomic(*this, Intrinsic::atomic_load_xor, E); 6388a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet 6396de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet // Clang extensions: not overloaded yet. 6408a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet case Builtin::BI__sync_fetch_and_min: 6416de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet return EmitBinaryAtomic(*this, Intrinsic::atomic_load_min, E); 6428a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet case Builtin::BI__sync_fetch_and_max: 6438a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet return EmitBinaryAtomic(*this, Intrinsic::atomic_load_max, E); 64469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_fetch_and_umin: 64569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umin, E); 64669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_fetch_and_umax: 64769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umax, E); 64869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 64969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_add_and_fetch_1: 65069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_add_and_fetch_2: 65169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_add_and_fetch_4: 65269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_add_and_fetch_8: 65369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_add_and_fetch_16: 6546de52c2a8c40b7381e364ad87af9e80a60d95229Yann Collet return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_add, E, 65569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. llvm::Instruction::Add); 6568a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet case Builtin::BI__sync_sub_and_fetch_1: 65769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_sub_and_fetch_2: 65869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_sub_and_fetch_4: 65969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_sub_and_fetch_8: 66069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_sub_and_fetch_16: 66169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_sub, E, 6628a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet llvm::Instruction::Sub); 66369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_and_and_fetch_1: 66489d8b98d0dd896dccf6964fa3c6bb6ae6a2349b0Yann Collet case Builtin::BI__sync_and_and_fetch_2: 66569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_and_and_fetch_4: 66669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_and_and_fetch_8: 66769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_and_and_fetch_16: 66869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_and, E, 669488029ec3b23b1e00a69f1ac3fcdd49d24cb7d3fYann Collet llvm::Instruction::And); 67069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_or_and_fetch_1: 67169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_or_and_fetch_2: 67269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_or_and_fetch_4: 67369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_or_and_fetch_8: 67469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_or_and_fetch_16: 67569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_or, E, 67669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. llvm::Instruction::Or); 6778a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet case Builtin::BI__sync_xor_and_fetch_1: 67869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_xor_and_fetch_2: 67969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_xor_and_fetch_4: 68069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_xor_and_fetch_8: 6818a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet case Builtin::BI__sync_xor_and_fetch_16: 68269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_xor, E, 68369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. llvm::Instruction::Xor); 68469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 68589d8b98d0dd896dccf6964fa3c6bb6ae6a2349b0Yann Collet case Builtin::BI__sync_val_compare_and_swap_1: 68689d8b98d0dd896dccf6964fa3c6bb6ae6a2349b0Yann Collet case Builtin::BI__sync_val_compare_and_swap_2: 68789d8b98d0dd896dccf6964fa3c6bb6ae6a2349b0Yann Collet case Builtin::BI__sync_val_compare_and_swap_4: 68869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_val_compare_and_swap_8: 6898a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet case Builtin::BI__sync_val_compare_and_swap_16: { 69069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. const llvm::Type *ResType[2]; 69169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. ResType[0]= ConvertType(E->getType()); 69269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. ResType[1] = ConvertType(E->getArg(0)->getType()); 69369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap, ResType, 2); 69469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. Value *Args[3] = { EmitScalarExpr(E->getArg(0)), 69569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. EmitScalarExpr(E->getArg(1)), 69669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. EmitScalarExpr(E->getArg(2)) }; 69769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. return RValue::get(EmitCallWithBarrier(*this, AtomF, Args, Args + 3)); 6988a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet } 69969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. 70069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_bool_compare_and_swap_1: 70169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_bool_compare_and_swap_2: 7028a9fb8cf3229c9a704c982667c63ac440b8487baYann Collet case Builtin::BI__sync_bool_compare_and_swap_4: 70369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_bool_compare_and_swap_8: 70469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. case Builtin::BI__sync_bool_compare_and_swap_16: { 70569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet. const llvm::Type *ResType[2]; 706 ResType[0]= ConvertType(E->getArg(1)->getType()); 707 ResType[1] = llvm::PointerType::getUnqual(ResType[0]); 708 Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap, ResType, 2); 709 Value *OldVal = EmitScalarExpr(E->getArg(1)); 710 Value *Args[3] = { EmitScalarExpr(E->getArg(0)), 711 OldVal, 712 EmitScalarExpr(E->getArg(2)) }; 713 Value *PrevVal = EmitCallWithBarrier(*this, AtomF, Args, Args + 3); 714 Value *Result = Builder.CreateICmpEQ(PrevVal, OldVal); 715 // zext bool to int. 716 return RValue::get(Builder.CreateZExt(Result, ConvertType(E->getType()))); 717 } 718 719 case Builtin::BI__sync_lock_test_and_set_1: 720 case Builtin::BI__sync_lock_test_and_set_2: 721 case Builtin::BI__sync_lock_test_and_set_4: 722 case Builtin::BI__sync_lock_test_and_set_8: 723 case Builtin::BI__sync_lock_test_and_set_16: 724 return EmitBinaryAtomic(*this, Intrinsic::atomic_swap, E); 725 726 case Builtin::BI__sync_lock_release_1: 727 case Builtin::BI__sync_lock_release_2: 728 case Builtin::BI__sync_lock_release_4: 729 case Builtin::BI__sync_lock_release_8: 730 case Builtin::BI__sync_lock_release_16: { 731 Value *Ptr = EmitScalarExpr(E->getArg(0)); 732 const llvm::Type *ElTy = 733 cast<llvm::PointerType>(Ptr->getType())->getElementType(); 734 llvm::StoreInst *Store = 735 Builder.CreateStore(llvm::Constant::getNullValue(ElTy), Ptr); 736 Store->setVolatile(true); 737 return RValue::get(0); 738 } 739 740 case Builtin::BI__sync_synchronize: { 741 // We assume like gcc appears to, that this only applies to cached memory. 742 EmitMemoryBarrier(*this, true, true, true, true, false); 743 return RValue::get(0); 744 } 745 746 case Builtin::BI__builtin_llvm_memory_barrier: { 747 Value *C[5] = { 748 EmitScalarExpr(E->getArg(0)), 749 EmitScalarExpr(E->getArg(1)), 750 EmitScalarExpr(E->getArg(2)), 751 EmitScalarExpr(E->getArg(3)), 752 EmitScalarExpr(E->getArg(4)) 753 }; 754 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::memory_barrier), C, C + 5); 755 return RValue::get(0); 756 } 757 758 // Library functions with special handling. 759 case Builtin::BIsqrt: 760 case Builtin::BIsqrtf: 761 case Builtin::BIsqrtl: { 762 // TODO: there is currently no set of optimizer flags 763 // sufficient for us to rewrite sqrt to @llvm.sqrt. 764 // -fmath-errno=0 is not good enough; we need finiteness. 765 // We could probably precondition the call with an ult 766 // against 0, but is that worth the complexity? 767 break; 768 } 769 770 case Builtin::BIpow: 771 case Builtin::BIpowf: 772 case Builtin::BIpowl: { 773 // Rewrite sqrt to intrinsic if allowed. 774 if (!FD->hasAttr<ConstAttr>()) 775 break; 776 Value *Base = EmitScalarExpr(E->getArg(0)); 777 Value *Exponent = EmitScalarExpr(E->getArg(1)); 778 const llvm::Type *ArgType = Base->getType(); 779 Value *F = CGM.getIntrinsic(Intrinsic::pow, &ArgType, 1); 780 return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp")); 781 } 782 783 case Builtin::BI__builtin_signbit: 784 case Builtin::BI__builtin_signbitf: 785 case Builtin::BI__builtin_signbitl: { 786 LLVMContext &C = CGM.getLLVMContext(); 787 788 Value *Arg = EmitScalarExpr(E->getArg(0)); 789 const llvm::Type *ArgTy = Arg->getType(); 790 if (ArgTy->isPPC_FP128Ty()) 791 break; // FIXME: I'm not sure what the right implementation is here. 792 int ArgWidth = ArgTy->getPrimitiveSizeInBits(); 793 const llvm::Type *ArgIntTy = llvm::IntegerType::get(C, ArgWidth); 794 Value *BCArg = Builder.CreateBitCast(Arg, ArgIntTy); 795 Value *ZeroCmp = llvm::Constant::getNullValue(ArgIntTy); 796 Value *Result = Builder.CreateICmpSLT(BCArg, ZeroCmp); 797 return RValue::get(Builder.CreateZExt(Result, ConvertType(E->getType()))); 798 } 799 } 800 801 // If this is an alias for a libm function (e.g. __builtin_sin) turn it into 802 // that function. 803 if (getContext().BuiltinInfo.isLibFunction(BuiltinID) || 804 getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID)) 805 return EmitCall(E->getCallee()->getType(), 806 CGM.getBuiltinLibFunction(FD, BuiltinID), 807 ReturnValueSlot(), 808 E->arg_begin(), E->arg_end()); 809 810 // See if we have a target specific intrinsic. 811 const char *Name = getContext().BuiltinInfo.GetName(BuiltinID); 812 Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic; 813 if (const char *Prefix = 814 llvm::Triple::getArchTypePrefix(Target.getTriple().getArch())) 815 IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix, Name); 816 817 if (IntrinsicID != Intrinsic::not_intrinsic) { 818 SmallVector<Value*, 16> Args; 819 820 Function *F = CGM.getIntrinsic(IntrinsicID); 821 const llvm::FunctionType *FTy = F->getFunctionType(); 822 823 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 824 Value *ArgValue = EmitScalarExpr(E->getArg(i)); 825 826 // If the intrinsic arg type is different from the builtin arg type 827 // we need to do a bit cast. 828 const llvm::Type *PTy = FTy->getParamType(i); 829 if (PTy != ArgValue->getType()) { 830 assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) && 831 "Must be able to losslessly bit cast to param"); 832 ArgValue = Builder.CreateBitCast(ArgValue, PTy); 833 } 834 835 Args.push_back(ArgValue); 836 } 837 838 Value *V = Builder.CreateCall(F, Args.data(), Args.data() + Args.size()); 839 QualType BuiltinRetType = E->getType(); 840 841 const llvm::Type *RetTy = llvm::Type::getVoidTy(VMContext); 842 if (!BuiltinRetType->isVoidType()) RetTy = ConvertType(BuiltinRetType); 843 844 if (RetTy != V->getType()) { 845 assert(V->getType()->canLosslesslyBitCastTo(RetTy) && 846 "Must be able to losslessly bit cast result type"); 847 V = Builder.CreateBitCast(V, RetTy); 848 } 849 850 return RValue::get(V); 851 } 852 853 // See if we have a target specific builtin that needs to be lowered. 854 if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E)) 855 return RValue::get(V); 856 857 ErrorUnsupported(E, "builtin function"); 858 859 // Unknown builtin, for now just dump it out and return undef. 860 if (hasAggregateLLVMType(E->getType())) 861 return RValue::getAggregate(CreateMemTemp(E->getType())); 862 return RValue::get(llvm::UndefValue::get(ConvertType(E->getType()))); 863} 864 865Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, 866 const CallExpr *E) { 867 switch (Target.getTriple().getArch()) { 868 case llvm::Triple::arm: 869 case llvm::Triple::thumb: 870 return EmitARMBuiltinExpr(BuiltinID, E); 871 case llvm::Triple::x86: 872 case llvm::Triple::x86_64: 873 return EmitX86BuiltinExpr(BuiltinID, E); 874 case llvm::Triple::ppc: 875 case llvm::Triple::ppc64: 876 return EmitPPCBuiltinExpr(BuiltinID, E); 877 default: 878 return 0; 879 } 880} 881 882const llvm::Type *GetNeonType(LLVMContext &Ctx, unsigned type, bool q) { 883 switch (type) { 884 default: break; 885 case 0: 886 case 5: return llvm::VectorType::get(llvm::Type::getInt8Ty(Ctx), 8 << q); 887 case 6: 888 case 7: 889 case 1: return llvm::VectorType::get(llvm::Type::getInt16Ty(Ctx), 4 << q); 890 case 2: return llvm::VectorType::get(llvm::Type::getInt32Ty(Ctx), 2 << q); 891 case 3: return llvm::VectorType::get(llvm::Type::getInt64Ty(Ctx), 1 << q); 892 case 4: return llvm::VectorType::get(llvm::Type::getFloatTy(Ctx), 2 << q); 893 }; 894 return 0; 895} 896 897Value *CodeGenFunction::EmitNeonSplat(Value *V, Constant *C) { 898 unsigned nElts = cast<llvm::VectorType>(V->getType())->getNumElements(); 899 SmallVector<Constant*, 16> Indices(nElts, C); 900 Value* SV = llvm::ConstantVector::get(Indices.begin(), Indices.size()); 901 return Builder.CreateShuffleVector(V, V, SV, "lane"); 902} 903 904Value *CodeGenFunction::EmitNeonCall(Function *F, SmallVectorImpl<Value*> &Ops, 905 const char *name, bool splat) { 906 unsigned j = 0; 907 for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end(); 908 ai != ae; ++ai, ++j) 909 Ops[j] = Builder.CreateBitCast(Ops[j], ai->getType(), name); 910 911 if (splat) { 912 Ops[j-1] = EmitNeonSplat(Ops[j-1], cast<Constant>(Ops[j])); 913 Ops.resize(j); 914 } 915 return Builder.CreateCall(F, Ops.begin(), Ops.end(), name); 916} 917 918Value *CodeGenFunction::EmitNeonShiftVector(Value *V, const llvm::Type *Ty, 919 bool neg) { 920 ConstantInt *CI = cast<ConstantInt>(V); 921 int SV = CI->getSExtValue(); 922 923 const llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 924 llvm::Constant *C = ConstantInt::get(VTy->getElementType(), neg ? -SV : SV); 925 SmallVector<llvm::Constant*, 16> CV(VTy->getNumElements(), C); 926 return llvm::ConstantVector::get(CV.begin(), CV.size()); 927} 928 929Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, 930 const CallExpr *E) { 931 if (BuiltinID == ARM::BI__clear_cache) { 932 const FunctionDecl *FD = E->getDirectCallee(); 933 Value *a = EmitScalarExpr(E->getArg(0)); 934 Value *b = EmitScalarExpr(E->getArg(1)); 935 const llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); 936 const llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); 937 llvm::StringRef Name = FD->getName(); 938 return Builder.CreateCall2(CGM.CreateRuntimeFunction(FTy, Name), 939 a, b); 940 } 941 942 // Determine the type of this overloaded NEON intrinsic. 943 assert(BuiltinID > ARM::BI__builtin_thread_pointer); 944 945 llvm::SmallVector<Value*, 4> Ops; 946 for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) 947 Ops.push_back(EmitScalarExpr(E->getArg(i))); 948 949 llvm::APSInt Result; 950 const Expr *Arg = E->getArg(E->getNumArgs()-1); 951 if (!Arg->isIntegerConstantExpr(Result, getContext())) 952 return 0; 953 954 unsigned type = Result.getZExtValue(); 955 bool usgn = type & 0x08; 956 bool quad = type & 0x10; 957 bool poly = type & 0x20; 958 bool splat = false; 959 960 const llvm::Type *Ty = GetNeonType(VMContext, type & 0x7, quad); 961 if (!Ty) 962 return 0; 963 964 unsigned Int; 965 switch (BuiltinID) { 966 default: return 0; 967 case ARM::BI__builtin_neon_vaba_v: 968 case ARM::BI__builtin_neon_vabaq_v: 969 Int = usgn ? Intrinsic::arm_neon_vabau : Intrinsic::arm_neon_vabas; 970 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vaba"); 971 case ARM::BI__builtin_neon_vabal_v: 972 Int = usgn ? Intrinsic::arm_neon_vabalu : Intrinsic::arm_neon_vabals; 973 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vabal"); 974 case ARM::BI__builtin_neon_vabd_v: 975 case ARM::BI__builtin_neon_vabdq_v: 976 Int = usgn ? Intrinsic::arm_neon_vabdu : Intrinsic::arm_neon_vabds; 977 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vabd"); 978 case ARM::BI__builtin_neon_vabdl_v: 979 Int = usgn ? Intrinsic::arm_neon_vabdlu : Intrinsic::arm_neon_vabdls; 980 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vabdl"); 981 case ARM::BI__builtin_neon_vabs_v: 982 case ARM::BI__builtin_neon_vabsq_v: 983 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vabs, &Ty, 1), 984 Ops, "vabs"); 985 case ARM::BI__builtin_neon_vaddhn_v: 986 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vaddhn, &Ty, 1), 987 Ops, "vaddhn"); 988 case ARM::BI__builtin_neon_vaddl_v: 989 Int = usgn ? Intrinsic::arm_neon_vaddlu : Intrinsic::arm_neon_vaddls; 990 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vaddl"); 991 case ARM::BI__builtin_neon_vaddw_v: 992 Int = usgn ? Intrinsic::arm_neon_vaddws : Intrinsic::arm_neon_vaddwu; 993 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vaddw"); 994 case ARM::BI__builtin_neon_vcale_v: 995 std::swap(Ops[0], Ops[1]); 996 case ARM::BI__builtin_neon_vcage_v: { 997 Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacged, &Ty, 1); 998 return EmitNeonCall(F, Ops, "vcage"); 999 } 1000 case ARM::BI__builtin_neon_vcaleq_v: 1001 std::swap(Ops[0], Ops[1]); 1002 case ARM::BI__builtin_neon_vcageq_v: { 1003 Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgeq, &Ty, 1); 1004 return EmitNeonCall(F, Ops, "vcage"); 1005 } 1006 case ARM::BI__builtin_neon_vcalt_v: 1007 std::swap(Ops[0], Ops[1]); 1008 case ARM::BI__builtin_neon_vcagt_v: { 1009 Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgtd, &Ty, 1); 1010 return EmitNeonCall(F, Ops, "vcagt"); 1011 } 1012 case ARM::BI__builtin_neon_vcaltq_v: 1013 std::swap(Ops[0], Ops[1]); 1014 case ARM::BI__builtin_neon_vcagtq_v: { 1015 Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgtq, &Ty, 1); 1016 return EmitNeonCall(F, Ops, "vcagt"); 1017 } 1018 case ARM::BI__builtin_neon_vcls_v: 1019 case ARM::BI__builtin_neon_vclsq_v: { 1020 Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcls, &Ty, 1); 1021 return EmitNeonCall(F, Ops, "vcls"); 1022 } 1023 case ARM::BI__builtin_neon_vclz_v: 1024 case ARM::BI__builtin_neon_vclzq_v: { 1025 Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vclz, &Ty, 1); 1026 return EmitNeonCall(F, Ops, "vclz"); 1027 } 1028 case ARM::BI__builtin_neon_vcnt_v: 1029 case ARM::BI__builtin_neon_vcntq_v: { 1030 Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcnt, &Ty, 1); 1031 return EmitNeonCall(F, Ops, "vcnt"); 1032 } 1033 // FIXME: intrinsics for f16<->f32 convert missing from ARM target. 1034 case ARM::BI__builtin_neon_vcvt_f32_v: 1035 case ARM::BI__builtin_neon_vcvtq_f32_v: { 1036 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 1037 Ty = GetNeonType(VMContext, 4, quad); 1038 return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") 1039 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); 1040 } 1041 case ARM::BI__builtin_neon_vcvt_s32_v: 1042 case ARM::BI__builtin_neon_vcvt_u32_v: 1043 case ARM::BI__builtin_neon_vcvtq_s32_v: 1044 case ARM::BI__builtin_neon_vcvtq_u32_v: { 1045 Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(VMContext, 4, quad)); 1046 return usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt") 1047 : Builder.CreateFPToSI(Ops[0], Ty, "vcvt"); 1048 } 1049 case ARM::BI__builtin_neon_vcvt_n_f32_v: 1050 case ARM::BI__builtin_neon_vcvtq_n_f32_v: { 1051 const llvm::Type *Tys[2] = { GetNeonType(VMContext, 4, quad), Ty }; 1052 Int = usgn ? Intrinsic::arm_neon_vcvtfxu2fp : Intrinsic::arm_neon_vcvtfxs2fp; 1053 Function *F = CGM.getIntrinsic(Int, Tys, 2); 1054 return EmitNeonCall(F, Ops, "vcvt_n"); 1055 } 1056 case ARM::BI__builtin_neon_vcvt_n_s32_v: 1057 case ARM::BI__builtin_neon_vcvt_n_u32_v: 1058 case ARM::BI__builtin_neon_vcvtq_n_s32_v: 1059 case ARM::BI__builtin_neon_vcvtq_n_u32_v: { 1060 const llvm::Type *Tys[2] = { Ty, GetNeonType(VMContext, 4, quad) }; 1061 Int = usgn ? Intrinsic::arm_neon_vcvtfp2fxu : Intrinsic::arm_neon_vcvtfp2fxs; 1062 Function *F = CGM.getIntrinsic(Int, Tys, 2); 1063 return EmitNeonCall(F, Ops, "vcvt_n"); 1064 } 1065 case ARM::BI__builtin_neon_vext_v: 1066 case ARM::BI__builtin_neon_vextq_v: { 1067 ConstantInt *C = dyn_cast<ConstantInt>(Ops[2]); 1068 int CV = C->getSExtValue(); 1069 const llvm::Type *I32Ty = llvm::Type::getInt32Ty(VMContext); 1070 1071 SmallVector<Constant*, 16> Indices; 1072 for (unsigned i = 0, e = cast<llvm::VectorType>(Ty)->getNumElements(); 1073 i != e; ++i) 1074 Indices.push_back(ConstantInt::get(I32Ty, i+CV)); 1075 1076 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 1077 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 1078 Value* SV = llvm::ConstantVector::get(Indices.begin(), Indices.size()); 1079 return Builder.CreateShuffleVector(Ops[0], Ops[1], SV, "vext"); 1080 } 1081 case ARM::BI__builtin_neon_vget_lane_i8: 1082 case ARM::BI__builtin_neon_vget_lane_i16: 1083 case ARM::BI__builtin_neon_vget_lane_i32: 1084 case ARM::BI__builtin_neon_vget_lane_i64: 1085 case ARM::BI__builtin_neon_vget_lane_f32: 1086 case ARM::BI__builtin_neon_vgetq_lane_i8: 1087 case ARM::BI__builtin_neon_vgetq_lane_i16: 1088 case ARM::BI__builtin_neon_vgetq_lane_i32: 1089 case ARM::BI__builtin_neon_vgetq_lane_i64: 1090 case ARM::BI__builtin_neon_vgetq_lane_f32: 1091 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 1092 "vget_lane"); 1093 case ARM::BI__builtin_neon_vhadd_v: 1094 case ARM::BI__builtin_neon_vhaddq_v: 1095 Int = usgn ? Intrinsic::arm_neon_vhaddu : Intrinsic::arm_neon_vhadds; 1096 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vhadd"); 1097 case ARM::BI__builtin_neon_vhsub_v: 1098 case ARM::BI__builtin_neon_vhsubq_v: 1099 Int = usgn ? Intrinsic::arm_neon_vhsubu : Intrinsic::arm_neon_vhsubs; 1100 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vhsub"); 1101 // FIXME: vld* 1102 case ARM::BI__builtin_neon_vmax_v: 1103 case ARM::BI__builtin_neon_vmaxq_v: 1104 Int = usgn ? Intrinsic::arm_neon_vmaxu : Intrinsic::arm_neon_vmaxs; 1105 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vmax"); 1106 case ARM::BI__builtin_neon_vmin_v: 1107 case ARM::BI__builtin_neon_vminq_v: 1108 Int = usgn ? Intrinsic::arm_neon_vminu : Intrinsic::arm_neon_vmins; 1109 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vmin"); 1110 case ARM::BI__builtin_neon_vmlal_lane_v: 1111 splat = true; 1112 case ARM::BI__builtin_neon_vmlal_v: 1113 Int = usgn ? Intrinsic::arm_neon_vmlalu : Intrinsic::arm_neon_vmlals; 1114 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vmlal", splat); 1115 case ARM::BI__builtin_neon_vmlsl_lane_v: 1116 splat = true; 1117 case ARM::BI__builtin_neon_vmlsl_v: 1118 Int = usgn ? Intrinsic::arm_neon_vmlslu : Intrinsic::arm_neon_vmlsls; 1119 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vmlsl", splat); 1120 case ARM::BI__builtin_neon_vmovl_v: 1121 Int = usgn ? Intrinsic::arm_neon_vmovlu : Intrinsic::arm_neon_vmovls; 1122 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vmovl"); 1123 case ARM::BI__builtin_neon_vmovn_v: 1124 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vmovn, &Ty, 1), 1125 Ops, "vmovn"); 1126 case ARM::BI__builtin_neon_vmull_lane_v: 1127 splat = true; 1128 case ARM::BI__builtin_neon_vmull_v: 1129 Int = usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls; 1130 Int = poly ? (unsigned)Intrinsic::arm_neon_vmullp : Int; 1131 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vmlal", splat); 1132 case ARM::BI__builtin_neon_vpadal_v: 1133 case ARM::BI__builtin_neon_vpadalq_v: 1134 Int = usgn ? Intrinsic::arm_neon_vpadalu : Intrinsic::arm_neon_vpadals; 1135 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vpadal"); 1136 case ARM::BI__builtin_neon_vpadd_v: 1137 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vpadd, &Ty, 1), 1138 Ops, "vpadd"); 1139 case ARM::BI__builtin_neon_vpaddl_v: 1140 case ARM::BI__builtin_neon_vpaddlq_v: 1141 Int = usgn ? Intrinsic::arm_neon_vpaddlu : Intrinsic::arm_neon_vpaddls; 1142 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vpaddl"); 1143 case ARM::BI__builtin_neon_vpmax_v: 1144 Int = usgn ? Intrinsic::arm_neon_vpmaxu : Intrinsic::arm_neon_vpmaxs; 1145 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vpmax"); 1146 case ARM::BI__builtin_neon_vpmin_v: 1147 Int = usgn ? Intrinsic::arm_neon_vpminu : Intrinsic::arm_neon_vpmins; 1148 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vpmin"); 1149 case ARM::BI__builtin_neon_vqabs_v: 1150 case ARM::BI__builtin_neon_vqabsq_v: 1151 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqabs, &Ty, 1), 1152 Ops, "vqabs"); 1153 case ARM::BI__builtin_neon_vqadd_v: 1154 case ARM::BI__builtin_neon_vqaddq_v: 1155 Int = usgn ? Intrinsic::arm_neon_vqaddu : Intrinsic::arm_neon_vqadds; 1156 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vqadd"); 1157 case ARM::BI__builtin_neon_vqdmlal_lane_v: 1158 splat = true; 1159 case ARM::BI__builtin_neon_vqdmlal_v: 1160 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmlal, &Ty, 1), 1161 Ops, "vqdmlal"); 1162 case ARM::BI__builtin_neon_vqdmlsl_lane_v: 1163 splat = true; 1164 case ARM::BI__builtin_neon_vqdmlsl_v: 1165 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmlsl, &Ty, 1), 1166 Ops, "vqdmlsl"); 1167 case ARM::BI__builtin_neon_vqdmulh_lane_v: 1168 case ARM::BI__builtin_neon_vqdmulhq_lane_v: 1169 splat = true; 1170 case ARM::BI__builtin_neon_vqdmulh_v: 1171 case ARM::BI__builtin_neon_vqdmulhq_v: 1172 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmulh, &Ty, 1), 1173 Ops, "vqdmulh"); 1174 case ARM::BI__builtin_neon_vqdmull_lane_v: 1175 splat = true; 1176 case ARM::BI__builtin_neon_vqdmull_v: 1177 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmull, &Ty, 1), 1178 Ops, "vqdmull"); 1179 case ARM::BI__builtin_neon_vqmovn_v: 1180 Int = usgn ? Intrinsic::arm_neon_vqmovnu : Intrinsic::arm_neon_vqmovns; 1181 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vqmovn"); 1182 case ARM::BI__builtin_neon_vqmovun_v: 1183 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqmovnsu, &Ty, 1), 1184 Ops, "vqdmull"); 1185 case ARM::BI__builtin_neon_vqneg_v: 1186 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqneg, &Ty, 1), 1187 Ops, "vqneg"); 1188 case ARM::BI__builtin_neon_vqrdmulh_lane_v: 1189 case ARM::BI__builtin_neon_vqrdmulhq_lane_v: 1190 splat = true; 1191 case ARM::BI__builtin_neon_vqrdmulh_v: 1192 case ARM::BI__builtin_neon_vqrdmulhq_v: 1193 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrdmulh, &Ty, 1), 1194 Ops, "vqrdmulh"); 1195 case ARM::BI__builtin_neon_vqrshl_v: 1196 case ARM::BI__builtin_neon_vqrshlq_v: 1197 Int = usgn ? Intrinsic::arm_neon_vqrshiftu : Intrinsic::arm_neon_vqrshifts; 1198 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vqrshl"); 1199 case ARM::BI__builtin_neon_vqrshrn_n_v: 1200 Int = usgn ? Intrinsic::arm_neon_vqrshiftnu : Intrinsic::arm_neon_vqrshiftns; 1201 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vqrshrn_n"); 1202 case ARM::BI__builtin_neon_vqrshrun_n_v: 1203 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrshiftnsu, &Ty, 1), 1204 Ops, "vqrshrun_n"); 1205 case ARM::BI__builtin_neon_vqsub_v: 1206 case ARM::BI__builtin_neon_vqsubq_v: 1207 Int = usgn ? Intrinsic::arm_neon_vqsubu : Intrinsic::arm_neon_vqsubs; 1208 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vqsub"); 1209 case ARM::BI__builtin_neon_vraddhn_v: 1210 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vraddhn, &Ty, 1), 1211 Ops, "vraddhn"); 1212 case ARM::BI__builtin_neon_vrecpe_v: 1213 case ARM::BI__builtin_neon_vrecpeq_v: 1214 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecpe, &Ty, 1), 1215 Ops, "vrecpe"); 1216 case ARM::BI__builtin_neon_vrecps_v: 1217 case ARM::BI__builtin_neon_vrecpsq_v: 1218 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecps, &Ty, 1), 1219 Ops, "vrecps"); 1220 case ARM::BI__builtin_neon_vrhadd_v: 1221 case ARM::BI__builtin_neon_vrhaddq_v: 1222 Int = usgn ? Intrinsic::arm_neon_vrhaddu : Intrinsic::arm_neon_vrhadds; 1223 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vrhadd"); 1224 case ARM::BI__builtin_neon_vrshl_v: 1225 case ARM::BI__builtin_neon_vrshlq_v: 1226 Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 1227 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vrshl"); 1228 case ARM::BI__builtin_neon_vrshrn_n_v: 1229 Ops[1] = EmitNeonShiftVector(Ops[1], Ty, true); 1230 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrshiftn, &Ty, 1), 1231 Ops, "vrshrn_n"); 1232 case ARM::BI__builtin_neon_vrshr_n_v: 1233 case ARM::BI__builtin_neon_vrshrq_n_v: 1234 Ops[1] = EmitNeonShiftVector(Ops[1], Ty, true); 1235 Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 1236 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vrshr_n"); 1237 case ARM::BI__builtin_neon_vrsqrte_v: 1238 case ARM::BI__builtin_neon_vrsqrteq_v: 1239 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsqrte, &Ty, 1), 1240 Ops, "vrsqrte"); 1241 case ARM::BI__builtin_neon_vrsqrts_v: 1242 case ARM::BI__builtin_neon_vrsqrtsq_v: 1243 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsqrts, &Ty, 1), 1244 Ops, "vrsqrts"); 1245 case ARM::BI__builtin_neon_vrsra_n_v: 1246 case ARM::BI__builtin_neon_vrsraq_n_v: 1247 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 1248 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 1249 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, true); 1250 Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 1251 Ops[1] = Builder.CreateCall2(CGM.getIntrinsic(Int, &Ty, 1), Ops[1], Ops[2]); 1252 return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n"); 1253 case ARM::BI__builtin_neon_vrsubhn_v: 1254 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsubhn, &Ty, 1), 1255 Ops, "vrsubhn"); 1256 case ARM::BI__builtin_neon_vset_lane_i8: 1257 case ARM::BI__builtin_neon_vset_lane_i16: 1258 case ARM::BI__builtin_neon_vset_lane_i32: 1259 case ARM::BI__builtin_neon_vset_lane_i64: 1260 case ARM::BI__builtin_neon_vset_lane_f32: 1261 case ARM::BI__builtin_neon_vsetq_lane_i8: 1262 case ARM::BI__builtin_neon_vsetq_lane_i16: 1263 case ARM::BI__builtin_neon_vsetq_lane_i32: 1264 case ARM::BI__builtin_neon_vsetq_lane_i64: 1265 case ARM::BI__builtin_neon_vsetq_lane_f32: 1266 Ops.push_back(EmitScalarExpr(E->getArg(2))); 1267 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 1268 case ARM::BI__builtin_neon_vshl_v: 1269 case ARM::BI__builtin_neon_vshlq_v: 1270 Int = usgn ? Intrinsic::arm_neon_vshiftu : Intrinsic::arm_neon_vshifts; 1271 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vshl"); 1272 case ARM::BI__builtin_neon_vshll_n_v: 1273 Ops[1] = EmitNeonShiftVector(Ops[1], Ty); 1274 Int = usgn ? Intrinsic::arm_neon_vshiftlu : Intrinsic::arm_neon_vshiftls; 1275 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vshll"); 1276 case ARM::BI__builtin_neon_vshl_n_v: 1277 case ARM::BI__builtin_neon_vshlq_n_v: 1278 Ops[1] = EmitNeonShiftVector(Ops[1], Ty); 1279 return Builder.CreateShl(Builder.CreateBitCast(Ops[0],Ty), Ops[1],"vshl_n"); 1280 case ARM::BI__builtin_neon_vshrn_n_v: 1281 Ops[1] = EmitNeonShiftVector(Ops[1], Ty, true); 1282 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftn, &Ty, 1), 1283 Ops, "vshrn_n"); 1284 case ARM::BI__builtin_neon_vshr_n_v: 1285 case ARM::BI__builtin_neon_vshrq_n_v: 1286 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 1287 Ops[1] = EmitNeonShiftVector(Ops[1], Ty); 1288 if (usgn) 1289 return Builder.CreateLShr(Ops[0], Ops[1], "vshr_n"); 1290 else 1291 return Builder.CreateAShr(Ops[0], Ops[1], "vshr_n"); 1292 case ARM::BI__builtin_neon_vsri_n_v: 1293 case ARM::BI__builtin_neon_vsriq_n_v: 1294 poly = true; 1295 case ARM::BI__builtin_neon_vsli_n_v: 1296 case ARM::BI__builtin_neon_vsliq_n_v: 1297 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, poly); 1298 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftins, &Ty, 1), 1299 Ops, "vsli_n"); 1300 case ARM::BI__builtin_neon_vsra_n_v: 1301 case ARM::BI__builtin_neon_vsraq_n_v: 1302 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 1303 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 1304 Ops[2] = EmitNeonShiftVector(Ops[2], Ty); 1305 if (usgn) 1306 Ops[1] = Builder.CreateLShr(Ops[1], Ops[2], "vsra_n"); 1307 else 1308 Ops[1] = Builder.CreateAShr(Ops[1], Ops[2], "vsra_n"); 1309 return Builder.CreateAdd(Ops[0], Ops[1]); 1310 case ARM::BI__builtin_neon_vst1_v: 1311 case ARM::BI__builtin_neon_vst1q_v: 1312 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, &Ty, 1), 1313 Ops, ""); 1314 case ARM::BI__builtin_neon_vst1_lane_v: 1315 case ARM::BI__builtin_neon_vst1q_lane_v: 1316 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 1317 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); 1318 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 1319 return Builder.CreateStore(Ops[1], Builder.CreateBitCast(Ops[0], Ty)); 1320 case ARM::BI__builtin_neon_vst2_v: 1321 case ARM::BI__builtin_neon_vst2q_v: 1322 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst2, &Ty, 1), 1323 Ops, ""); 1324 case ARM::BI__builtin_neon_vst2_lane_v: 1325 case ARM::BI__builtin_neon_vst2q_lane_v: 1326 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst2lane, &Ty, 1), 1327 Ops, ""); 1328 case ARM::BI__builtin_neon_vst3_v: 1329 case ARM::BI__builtin_neon_vst3q_v: 1330 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst3, &Ty, 1), 1331 Ops, ""); 1332 case ARM::BI__builtin_neon_vst3_lane_v: 1333 case ARM::BI__builtin_neon_vst3q_lane_v: 1334 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst3lane, &Ty, 1), 1335 Ops, ""); 1336 case ARM::BI__builtin_neon_vst4_v: 1337 case ARM::BI__builtin_neon_vst4q_v: 1338 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst4, &Ty, 1), 1339 Ops, ""); 1340 case ARM::BI__builtin_neon_vst4_lane_v: 1341 case ARM::BI__builtin_neon_vst4q_lane_v: 1342 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst4lane, &Ty, 1), 1343 Ops, ""); 1344 case ARM::BI__builtin_neon_vsubhn_v: 1345 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vsubhn, &Ty, 1), 1346 Ops, "vsubhn"); 1347 case ARM::BI__builtin_neon_vsubl_v: 1348 Int = usgn ? Intrinsic::arm_neon_vsublu : Intrinsic::arm_neon_vsubls; 1349 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vsubl"); 1350 case ARM::BI__builtin_neon_vsubw_v: 1351 Int = usgn ? Intrinsic::arm_neon_vsubws : Intrinsic::arm_neon_vsubwu; 1352 return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vsubw"); 1353 case ARM::BI__builtin_neon_vtbl1_v: 1354 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl1), 1355 Ops, "vtbl1"); 1356 case ARM::BI__builtin_neon_vtbl2_v: 1357 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl2), 1358 Ops, "vtbl2"); 1359 case ARM::BI__builtin_neon_vtbl3_v: 1360 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl3), 1361 Ops, "vtbl3"); 1362 case ARM::BI__builtin_neon_vtbl4_v: 1363 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl4), 1364 Ops, "vtbl4"); 1365 case ARM::BI__builtin_neon_vtbx1_v: 1366 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx1), 1367 Ops, "vtbx1"); 1368 case ARM::BI__builtin_neon_vtbx2_v: 1369 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx2), 1370 Ops, "vtbx2"); 1371 case ARM::BI__builtin_neon_vtbx3_v: 1372 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx3), 1373 Ops, "vtbx3"); 1374 case ARM::BI__builtin_neon_vtbx4_v: 1375 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx4), 1376 Ops, "vtbx4"); 1377 case ARM::BI__builtin_neon_vtst_v: 1378 case ARM::BI__builtin_neon_vtstq_v: { 1379 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 1380 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 1381 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]); 1382 Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0], 1383 ConstantAggregateZero::get(Ty)); 1384 return Builder.CreateSExt(Ops[0], Ty, "vtst"); 1385 } 1386 // FIXME: transpose/zip/unzip don't currently match patterns for 1387 // the non-q variants, but emitting 2 shufflevectors seems like a hack. 1388 case ARM::BI__builtin_neon_vtrn_v: 1389 case ARM::BI__builtin_neon_vtrnq_v: { 1390 const llvm::Type *I32Ty = llvm::Type::getInt32Ty(VMContext); 1391 SmallVector<Constant*, 32> Indices; 1392 unsigned nElts = cast<llvm::VectorType>(Ty)->getNumElements(); 1393 for (unsigned vi = 0; vi != 2; ++vi) { 1394 for (unsigned i = 0; i != nElts; i += 2) { 1395 Indices.push_back(ConstantInt::get(I32Ty, i+vi)); 1396 Indices.push_back(ConstantInt::get(I32Ty, i+nElts+vi)); 1397 } 1398 } 1399 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 1400 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 1401 Value* SV = llvm::ConstantVector::get(Indices.begin(), Indices.size()); 1402 return Builder.CreateShuffleVector(Ops[0], Ops[1], SV, "vtrn"); 1403 } 1404 case ARM::BI__builtin_neon_vuzp_v: 1405 case ARM::BI__builtin_neon_vuzpq_v: { 1406 const llvm::Type *I32Ty = llvm::Type::getInt32Ty(VMContext); 1407 SmallVector<Constant*, 32> Indices; 1408 unsigned nElts = cast<llvm::VectorType>(Ty)->getNumElements(); 1409 for (unsigned vi = 0; vi != 2; ++vi) 1410 for (unsigned i = 0; i != nElts; ++i) 1411 Indices.push_back(ConstantInt::get(I32Ty, 2*i+vi)); 1412 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 1413 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 1414 Value* SV = llvm::ConstantVector::get(Indices.begin(), Indices.size()); 1415 return Builder.CreateShuffleVector(Ops[0], Ops[1], SV, "vuzp"); 1416 } 1417 case ARM::BI__builtin_neon_vzip_v: 1418 case ARM::BI__builtin_neon_vzipq_v: { 1419 const llvm::Type *I32Ty = llvm::Type::getInt32Ty(VMContext); 1420 SmallVector<Constant*, 32> Indices; 1421 unsigned nElts = cast<llvm::VectorType>(Ty)->getNumElements(); 1422 for (unsigned i = 0; i != nElts; ++i) { 1423 Indices.push_back(ConstantInt::get(I32Ty, i)); 1424 Indices.push_back(ConstantInt::get(I32Ty, i+nElts)); 1425 } 1426 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 1427 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 1428 Value* SV = llvm::ConstantVector::get(Indices.begin(), Indices.size()); 1429 return Builder.CreateShuffleVector(Ops[0], Ops[1], SV, "vzip"); 1430 } 1431 } 1432} 1433 1434Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, 1435 const CallExpr *E) { 1436 1437 llvm::SmallVector<Value*, 4> Ops; 1438 1439 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) 1440 Ops.push_back(EmitScalarExpr(E->getArg(i))); 1441 1442 switch (BuiltinID) { 1443 default: return 0; 1444 case X86::BI__builtin_ia32_pslldi128: 1445 case X86::BI__builtin_ia32_psllqi128: 1446 case X86::BI__builtin_ia32_psllwi128: 1447 case X86::BI__builtin_ia32_psradi128: 1448 case X86::BI__builtin_ia32_psrawi128: 1449 case X86::BI__builtin_ia32_psrldi128: 1450 case X86::BI__builtin_ia32_psrlqi128: 1451 case X86::BI__builtin_ia32_psrlwi128: { 1452 Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::getInt64Ty(VMContext), "zext"); 1453 const llvm::Type *Ty = llvm::VectorType::get(llvm::Type::getInt64Ty(VMContext), 2); 1454 llvm::Value *Zero = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0); 1455 Ops[1] = Builder.CreateInsertElement(llvm::UndefValue::get(Ty), 1456 Ops[1], Zero, "insert"); 1457 Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType(), "bitcast"); 1458 const char *name = 0; 1459 Intrinsic::ID ID = Intrinsic::not_intrinsic; 1460 1461 switch (BuiltinID) { 1462 default: assert(0 && "Unsupported shift intrinsic!"); 1463 case X86::BI__builtin_ia32_pslldi128: 1464 name = "pslldi"; 1465 ID = Intrinsic::x86_sse2_psll_d; 1466 break; 1467 case X86::BI__builtin_ia32_psllqi128: 1468 name = "psllqi"; 1469 ID = Intrinsic::x86_sse2_psll_q; 1470 break; 1471 case X86::BI__builtin_ia32_psllwi128: 1472 name = "psllwi"; 1473 ID = Intrinsic::x86_sse2_psll_w; 1474 break; 1475 case X86::BI__builtin_ia32_psradi128: 1476 name = "psradi"; 1477 ID = Intrinsic::x86_sse2_psra_d; 1478 break; 1479 case X86::BI__builtin_ia32_psrawi128: 1480 name = "psrawi"; 1481 ID = Intrinsic::x86_sse2_psra_w; 1482 break; 1483 case X86::BI__builtin_ia32_psrldi128: 1484 name = "psrldi"; 1485 ID = Intrinsic::x86_sse2_psrl_d; 1486 break; 1487 case X86::BI__builtin_ia32_psrlqi128: 1488 name = "psrlqi"; 1489 ID = Intrinsic::x86_sse2_psrl_q; 1490 break; 1491 case X86::BI__builtin_ia32_psrlwi128: 1492 name = "psrlwi"; 1493 ID = Intrinsic::x86_sse2_psrl_w; 1494 break; 1495 } 1496 llvm::Function *F = CGM.getIntrinsic(ID); 1497 return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name); 1498 } 1499 case X86::BI__builtin_ia32_pslldi: 1500 case X86::BI__builtin_ia32_psllqi: 1501 case X86::BI__builtin_ia32_psllwi: 1502 case X86::BI__builtin_ia32_psradi: 1503 case X86::BI__builtin_ia32_psrawi: 1504 case X86::BI__builtin_ia32_psrldi: 1505 case X86::BI__builtin_ia32_psrlqi: 1506 case X86::BI__builtin_ia32_psrlwi: { 1507 Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::getInt64Ty(VMContext), "zext"); 1508 const llvm::Type *Ty = llvm::VectorType::get(llvm::Type::getInt64Ty(VMContext), 1); 1509 Ops[1] = Builder.CreateBitCast(Ops[1], Ty, "bitcast"); 1510 const char *name = 0; 1511 Intrinsic::ID ID = Intrinsic::not_intrinsic; 1512 1513 switch (BuiltinID) { 1514 default: assert(0 && "Unsupported shift intrinsic!"); 1515 case X86::BI__builtin_ia32_pslldi: 1516 name = "pslldi"; 1517 ID = Intrinsic::x86_mmx_psll_d; 1518 break; 1519 case X86::BI__builtin_ia32_psllqi: 1520 name = "psllqi"; 1521 ID = Intrinsic::x86_mmx_psll_q; 1522 break; 1523 case X86::BI__builtin_ia32_psllwi: 1524 name = "psllwi"; 1525 ID = Intrinsic::x86_mmx_psll_w; 1526 break; 1527 case X86::BI__builtin_ia32_psradi: 1528 name = "psradi"; 1529 ID = Intrinsic::x86_mmx_psra_d; 1530 break; 1531 case X86::BI__builtin_ia32_psrawi: 1532 name = "psrawi"; 1533 ID = Intrinsic::x86_mmx_psra_w; 1534 break; 1535 case X86::BI__builtin_ia32_psrldi: 1536 name = "psrldi"; 1537 ID = Intrinsic::x86_mmx_psrl_d; 1538 break; 1539 case X86::BI__builtin_ia32_psrlqi: 1540 name = "psrlqi"; 1541 ID = Intrinsic::x86_mmx_psrl_q; 1542 break; 1543 case X86::BI__builtin_ia32_psrlwi: 1544 name = "psrlwi"; 1545 ID = Intrinsic::x86_mmx_psrl_w; 1546 break; 1547 } 1548 llvm::Function *F = CGM.getIntrinsic(ID); 1549 return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name); 1550 } 1551 case X86::BI__builtin_ia32_cmpps: { 1552 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ps); 1553 return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpps"); 1554 } 1555 case X86::BI__builtin_ia32_cmpss: { 1556 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ss); 1557 return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpss"); 1558 } 1559 case X86::BI__builtin_ia32_ldmxcsr: { 1560 const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext); 1561 Value *One = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1); 1562 Value *Tmp = Builder.CreateAlloca(llvm::Type::getInt32Ty(VMContext), One, "tmp"); 1563 Builder.CreateStore(Ops[0], Tmp); 1564 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr), 1565 Builder.CreateBitCast(Tmp, PtrTy)); 1566 } 1567 case X86::BI__builtin_ia32_stmxcsr: { 1568 const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext); 1569 Value *One = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1); 1570 Value *Tmp = Builder.CreateAlloca(llvm::Type::getInt32Ty(VMContext), One, "tmp"); 1571 One = Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr), 1572 Builder.CreateBitCast(Tmp, PtrTy)); 1573 return Builder.CreateLoad(Tmp, "stmxcsr"); 1574 } 1575 case X86::BI__builtin_ia32_cmppd: { 1576 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_pd); 1577 return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmppd"); 1578 } 1579 case X86::BI__builtin_ia32_cmpsd: { 1580 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_sd); 1581 return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpsd"); 1582 } 1583 case X86::BI__builtin_ia32_storehps: 1584 case X86::BI__builtin_ia32_storelps: { 1585 const llvm::Type *EltTy = llvm::Type::getInt64Ty(VMContext); 1586 llvm::Type *PtrTy = llvm::PointerType::getUnqual(EltTy); 1587 llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2); 1588 1589 // cast val v2i64 1590 Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast"); 1591 1592 // extract (0, 1) 1593 unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1; 1594 llvm::Value *Idx = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Index); 1595 Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract"); 1596 1597 // cast pointer to i64 & store 1598 Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy); 1599 return Builder.CreateStore(Ops[1], Ops[0]); 1600 } 1601 case X86::BI__builtin_ia32_palignr: { 1602 unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 1603 1604 // If palignr is shifting the pair of input vectors less than 9 bytes, 1605 // emit a shuffle instruction. 1606 if (shiftVal <= 8) { 1607 const llvm::Type *IntTy = llvm::Type::getInt32Ty(VMContext); 1608 1609 llvm::SmallVector<llvm::Constant*, 8> Indices; 1610 for (unsigned i = 0; i != 8; ++i) 1611 Indices.push_back(llvm::ConstantInt::get(IntTy, shiftVal + i)); 1612 1613 Value* SV = llvm::ConstantVector::get(Indices.begin(), Indices.size()); 1614 return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 1615 } 1616 1617 // If palignr is shifting the pair of input vectors more than 8 but less 1618 // than 16 bytes, emit a logical right shift of the destination. 1619 if (shiftVal < 16) { 1620 // MMX has these as 1 x i64 vectors for some odd optimization reasons. 1621 const llvm::Type *EltTy = llvm::Type::getInt64Ty(VMContext); 1622 const llvm::Type *VecTy = llvm::VectorType::get(EltTy, 1); 1623 1624 Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 1625 Ops[1] = llvm::ConstantInt::get(VecTy, (shiftVal-8) * 8); 1626 1627 // create i32 constant 1628 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_mmx_psrl_q); 1629 return Builder.CreateCall(F, &Ops[0], &Ops[0] + 2, "palignr"); 1630 } 1631 1632 // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 1633 return llvm::Constant::getNullValue(ConvertType(E->getType())); 1634 } 1635 case X86::BI__builtin_ia32_palignr128: { 1636 unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 1637 1638 // If palignr is shifting the pair of input vectors less than 17 bytes, 1639 // emit a shuffle instruction. 1640 if (shiftVal <= 16) { 1641 const llvm::Type *IntTy = llvm::Type::getInt32Ty(VMContext); 1642 1643 llvm::SmallVector<llvm::Constant*, 16> Indices; 1644 for (unsigned i = 0; i != 16; ++i) 1645 Indices.push_back(llvm::ConstantInt::get(IntTy, shiftVal + i)); 1646 1647 Value* SV = llvm::ConstantVector::get(Indices.begin(), Indices.size()); 1648 return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 1649 } 1650 1651 // If palignr is shifting the pair of input vectors more than 16 but less 1652 // than 32 bytes, emit a logical right shift of the destination. 1653 if (shiftVal < 32) { 1654 const llvm::Type *EltTy = llvm::Type::getInt64Ty(VMContext); 1655 const llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2); 1656 const llvm::Type *IntTy = llvm::Type::getInt32Ty(VMContext); 1657 1658 Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 1659 Ops[1] = llvm::ConstantInt::get(IntTy, (shiftVal-16) * 8); 1660 1661 // create i32 constant 1662 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_psrl_dq); 1663 return Builder.CreateCall(F, &Ops[0], &Ops[0] + 2, "palignr"); 1664 } 1665 1666 // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 1667 return llvm::Constant::getNullValue(ConvertType(E->getType())); 1668 } 1669 } 1670} 1671 1672Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, 1673 const CallExpr *E) { 1674 llvm::SmallVector<Value*, 4> Ops; 1675 1676 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) 1677 Ops.push_back(EmitScalarExpr(E->getArg(i))); 1678 1679 Intrinsic::ID ID = Intrinsic::not_intrinsic; 1680 1681 switch (BuiltinID) { 1682 default: return 0; 1683 1684 // vec_st 1685 case PPC::BI__builtin_altivec_stvx: 1686 case PPC::BI__builtin_altivec_stvxl: 1687 case PPC::BI__builtin_altivec_stvebx: 1688 case PPC::BI__builtin_altivec_stvehx: 1689 case PPC::BI__builtin_altivec_stvewx: 1690 { 1691 Ops[2] = Builder.CreateBitCast(Ops[2], llvm::Type::getInt8PtrTy(VMContext)); 1692 Ops[1] = !isa<Constant>(Ops[1]) || !cast<Constant>(Ops[1])->isNullValue() 1693 ? Builder.CreateGEP(Ops[2], Ops[1], "tmp") : Ops[2]; 1694 Ops.pop_back(); 1695 1696 switch (BuiltinID) { 1697 default: assert(0 && "Unsupported vavg intrinsic!"); 1698 case PPC::BI__builtin_altivec_stvx: 1699 ID = Intrinsic::ppc_altivec_stvx; 1700 break; 1701 case PPC::BI__builtin_altivec_stvxl: 1702 ID = Intrinsic::ppc_altivec_stvxl; 1703 break; 1704 case PPC::BI__builtin_altivec_stvebx: 1705 ID = Intrinsic::ppc_altivec_stvebx; 1706 break; 1707 case PPC::BI__builtin_altivec_stvehx: 1708 ID = Intrinsic::ppc_altivec_stvehx; 1709 break; 1710 case PPC::BI__builtin_altivec_stvewx: 1711 ID = Intrinsic::ppc_altivec_stvewx; 1712 break; 1713 } 1714 llvm::Function *F = CGM.getIntrinsic(ID); 1715 return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), ""); 1716 } 1717 } 1718 return 0; 1719} 1720