CGBuiltin.cpp revision ea93e40785ffeadfac66b948c95f9490ec26207a
1022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===// 2022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson// 3022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson// The LLVM Compiler Infrastructure 4022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 7022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson// 8022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson//===----------------------------------------------------------------------===// 9022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson// 10022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson// This contains code to emit Builtin calls as LLVM code. 11022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson// 12022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson//===----------------------------------------------------------------------===// 13022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson 14d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall#include "TargetInfo.h" 15022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson#include "CodeGenFunction.h" 16022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson#include "CodeGenModule.h" 1755bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian#include "CGObjCRuntime.h" 18ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson#include "clang/Basic/TargetInfo.h" 19bef20ac367a09555b30d6eb3847a81ec164caf88Chris Lattner#include "clang/AST/ASTContext.h" 20c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbar#include "clang/AST/Decl.h" 216b15cdc1312f8fc45c86ee75e2a85106700e97f6Chris Lattner#include "clang/Basic/TargetBuiltins.h" 22793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson#include "llvm/Intrinsics.h" 23d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall#include "llvm/Target/TargetData.h" 24558229f267d2cdee69639df04382082e7c7ad54cJakub Staszak 25022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlssonusing namespace clang; 26022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlssonusing namespace CodeGen; 27ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlssonusing namespace llvm; 28ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson 29a45680b7e7c49ea9893c6cff585984f3e4120366John McCall/// getBuiltinLibFunction - Given a builtin id for a function like 30a45680b7e7c49ea9893c6cff585984f3e4120366John McCall/// "__builtin_fabsf", return a Function* for "fabsf". 31a45680b7e7c49ea9893c6cff585984f3e4120366John McCallllvm::Value *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD, 32a45680b7e7c49ea9893c6cff585984f3e4120366John McCall unsigned BuiltinID) { 33a45680b7e7c49ea9893c6cff585984f3e4120366John McCall assert(Context.BuiltinInfo.isLibFunction(BuiltinID)); 34a45680b7e7c49ea9893c6cff585984f3e4120366John McCall 35a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // Get the name, skip over the __builtin_ prefix (if necessary). 36a45680b7e7c49ea9893c6cff585984f3e4120366John McCall StringRef Name; 37a45680b7e7c49ea9893c6cff585984f3e4120366John McCall GlobalDecl D(FD); 38a45680b7e7c49ea9893c6cff585984f3e4120366John McCall 39a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // If the builtin has been declared explicitly with an assembler label, 40a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // use the mangled name. This differs from the plain label on platforms 41a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // that prefix labels. 42a45680b7e7c49ea9893c6cff585984f3e4120366John McCall if (FD->hasAttr<AsmLabelAttr>()) 43a45680b7e7c49ea9893c6cff585984f3e4120366John McCall Name = getMangledName(D); 44a45680b7e7c49ea9893c6cff585984f3e4120366John McCall else 45a45680b7e7c49ea9893c6cff585984f3e4120366John McCall Name = Context.BuiltinInfo.GetName(BuiltinID) + 10; 46a45680b7e7c49ea9893c6cff585984f3e4120366John McCall 47a45680b7e7c49ea9893c6cff585984f3e4120366John McCall llvm::FunctionType *Ty = 48a45680b7e7c49ea9893c6cff585984f3e4120366John McCall cast<llvm::FunctionType>(getTypes().ConvertType(FD->getType())); 49a45680b7e7c49ea9893c6cff585984f3e4120366John McCall 50a45680b7e7c49ea9893c6cff585984f3e4120366John McCall return GetOrCreateLLVMFunction(Name, Ty, D, /*ForVTable=*/false); 51a45680b7e7c49ea9893c6cff585984f3e4120366John McCall} 52a45680b7e7c49ea9893c6cff585984f3e4120366John McCall 5326815d97c5743481e317f17a8d53a6819d061862John McCall/// Emit the conversions required to turn the given value into an 5426815d97c5743481e317f17a8d53a6819d061862John McCall/// integer of the given size. 5526815d97c5743481e317f17a8d53a6819d061862John McCallstatic Value *EmitToInt(CodeGenFunction &CGF, llvm::Value *V, 562acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner QualType T, llvm::IntegerType *IntType) { 5726815d97c5743481e317f17a8d53a6819d061862John McCall V = CGF.EmitToMemory(V, T); 5826815d97c5743481e317f17a8d53a6819d061862John McCall 5926815d97c5743481e317f17a8d53a6819d061862John McCall if (V->getType()->isPointerTy()) 6026815d97c5743481e317f17a8d53a6819d061862John McCall return CGF.Builder.CreatePtrToInt(V, IntType); 6126815d97c5743481e317f17a8d53a6819d061862John McCall 6226815d97c5743481e317f17a8d53a6819d061862John McCall assert(V->getType() == IntType); 6326815d97c5743481e317f17a8d53a6819d061862John McCall return V; 64db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth} 65db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth 6626815d97c5743481e317f17a8d53a6819d061862John McCallstatic Value *EmitFromInt(CodeGenFunction &CGF, llvm::Value *V, 672acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner QualType T, llvm::Type *ResultType) { 6826815d97c5743481e317f17a8d53a6819d061862John McCall V = CGF.EmitFromMemory(V, T); 6926815d97c5743481e317f17a8d53a6819d061862John McCall 7026815d97c5743481e317f17a8d53a6819d061862John McCall if (ResultType->isPointerTy()) 7126815d97c5743481e317f17a8d53a6819d061862John McCall return CGF.Builder.CreateIntToPtr(V, ResultType); 7226815d97c5743481e317f17a8d53a6819d061862John McCall 7326815d97c5743481e317f17a8d53a6819d061862John McCall assert(V->getType() == ResultType); 7426815d97c5743481e317f17a8d53a6819d061862John McCall return V; 75db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth} 76db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth 770002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar/// Utility to insert an atomic instruction based on Instrinsic::ID 780002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar/// and the expression node. 79cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbarstatic RValue EmitBinaryAtomic(CodeGenFunction &CGF, 80c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman llvm::AtomicRMWInst::BinOp Kind, 81c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman const CallExpr *E) { 8226815d97c5743481e317f17a8d53a6819d061862John McCall QualType T = E->getType(); 8326815d97c5743481e317f17a8d53a6819d061862John McCall assert(E->getArg(0)->getType()->isPointerType()); 8426815d97c5743481e317f17a8d53a6819d061862John McCall assert(CGF.getContext().hasSameUnqualifiedType(T, 8526815d97c5743481e317f17a8d53a6819d061862John McCall E->getArg(0)->getType()->getPointeeType())); 8626815d97c5743481e317f17a8d53a6819d061862John McCall assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType())); 8726815d97c5743481e317f17a8d53a6819d061862John McCall 884f209445c06a43283c6f72dda7c925538b1578e9Chris Lattner llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); 894f209445c06a43283c6f72dda7c925538b1578e9Chris Lattner unsigned AddrSpace = 904f209445c06a43283c6f72dda7c925538b1578e9Chris Lattner cast<llvm::PointerType>(DestPtr->getType())->getAddressSpace(); 9126815d97c5743481e317f17a8d53a6819d061862John McCall 929cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::IntegerType *IntType = 93db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth llvm::IntegerType::get(CGF.getLLVMContext(), 9426815d97c5743481e317f17a8d53a6819d061862John McCall CGF.getContext().getTypeSize(T)); 959cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 9626815d97c5743481e317f17a8d53a6819d061862John McCall 9726815d97c5743481e317f17a8d53a6819d061862John McCall llvm::Value *Args[2]; 9826815d97c5743481e317f17a8d53a6819d061862John McCall Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType); 9926815d97c5743481e317f17a8d53a6819d061862John McCall Args[1] = CGF.EmitScalarExpr(E->getArg(1)); 1002acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ValueType = Args[1]->getType(); 10126815d97c5743481e317f17a8d53a6819d061862John McCall Args[1] = EmitToInt(CGF, Args[1], T, IntType); 10226815d97c5743481e317f17a8d53a6819d061862John McCall 103c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman llvm::Value *Result = 104c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman CGF.Builder.CreateAtomicRMW(Kind, Args[0], Args[1], 105c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman llvm::SequentiallyConsistent); 10626815d97c5743481e317f17a8d53a6819d061862John McCall Result = EmitFromInt(CGF, Result, T, ValueType); 10726815d97c5743481e317f17a8d53a6819d061862John McCall return RValue::get(Result); 1080002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar} 1090002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar 1100002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar/// Utility to insert an atomic instruction based Instrinsic::ID and 11126815d97c5743481e317f17a8d53a6819d061862John McCall/// the expression node, where the return value is the result of the 11226815d97c5743481e317f17a8d53a6819d061862John McCall/// operation. 113420b11850d3f4557421f43f519b59d528329c668Chris Lattnerstatic RValue EmitBinaryAtomicPost(CodeGenFunction &CGF, 114c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman llvm::AtomicRMWInst::BinOp Kind, 115c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman const CallExpr *E, 1160002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Instruction::BinaryOps Op) { 11726815d97c5743481e317f17a8d53a6819d061862John McCall QualType T = E->getType(); 11826815d97c5743481e317f17a8d53a6819d061862John McCall assert(E->getArg(0)->getType()->isPointerType()); 11926815d97c5743481e317f17a8d53a6819d061862John McCall assert(CGF.getContext().hasSameUnqualifiedType(T, 12026815d97c5743481e317f17a8d53a6819d061862John McCall E->getArg(0)->getType()->getPointeeType())); 12126815d97c5743481e317f17a8d53a6819d061862John McCall assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType())); 12226815d97c5743481e317f17a8d53a6819d061862John McCall 1234f209445c06a43283c6f72dda7c925538b1578e9Chris Lattner llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); 1244f209445c06a43283c6f72dda7c925538b1578e9Chris Lattner unsigned AddrSpace = 1254f209445c06a43283c6f72dda7c925538b1578e9Chris Lattner cast<llvm::PointerType>(DestPtr->getType())->getAddressSpace(); 12626815d97c5743481e317f17a8d53a6819d061862John McCall 1279cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::IntegerType *IntType = 128db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth llvm::IntegerType::get(CGF.getLLVMContext(), 12926815d97c5743481e317f17a8d53a6819d061862John McCall CGF.getContext().getTypeSize(T)); 1309cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 13126815d97c5743481e317f17a8d53a6819d061862John McCall 13226815d97c5743481e317f17a8d53a6819d061862John McCall llvm::Value *Args[2]; 13326815d97c5743481e317f17a8d53a6819d061862John McCall Args[1] = CGF.EmitScalarExpr(E->getArg(1)); 1342acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ValueType = Args[1]->getType(); 13526815d97c5743481e317f17a8d53a6819d061862John McCall Args[1] = EmitToInt(CGF, Args[1], T, IntType); 13626815d97c5743481e317f17a8d53a6819d061862John McCall Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType); 13726815d97c5743481e317f17a8d53a6819d061862John McCall 138c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman llvm::Value *Result = 139c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman CGF.Builder.CreateAtomicRMW(Kind, Args[0], Args[1], 140c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman llvm::SequentiallyConsistent); 14126815d97c5743481e317f17a8d53a6819d061862John McCall Result = CGF.Builder.CreateBinOp(Op, Result, Args[1]); 14226815d97c5743481e317f17a8d53a6819d061862John McCall Result = EmitFromInt(CGF, Result, T, ValueType); 14326815d97c5743481e317f17a8d53a6819d061862John McCall return RValue::get(Result); 1441ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang} 1451ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang 146420b11850d3f4557421f43f519b59d528329c668Chris Lattner/// EmitFAbs - Emit a call to fabs/fabsf/fabsl, depending on the type of ValTy, 147420b11850d3f4557421f43f519b59d528329c668Chris Lattner/// which must be a scalar floating point type. 148420b11850d3f4557421f43f519b59d528329c668Chris Lattnerstatic Value *EmitFAbs(CodeGenFunction &CGF, Value *V, QualType ValTy) { 149420b11850d3f4557421f43f519b59d528329c668Chris Lattner const BuiltinType *ValTyP = ValTy->getAs<BuiltinType>(); 150420b11850d3f4557421f43f519b59d528329c668Chris Lattner assert(ValTyP && "isn't scalar fp type!"); 151420b11850d3f4557421f43f519b59d528329c668Chris Lattner 152420b11850d3f4557421f43f519b59d528329c668Chris Lattner StringRef FnName; 153420b11850d3f4557421f43f519b59d528329c668Chris Lattner switch (ValTyP->getKind()) { 154b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("Isn't a scalar fp type!"); 155420b11850d3f4557421f43f519b59d528329c668Chris Lattner case BuiltinType::Float: FnName = "fabsf"; break; 156420b11850d3f4557421f43f519b59d528329c668Chris Lattner case BuiltinType::Double: FnName = "fabs"; break; 157420b11850d3f4557421f43f519b59d528329c668Chris Lattner case BuiltinType::LongDouble: FnName = "fabsl"; break; 158420b11850d3f4557421f43f519b59d528329c668Chris Lattner } 159420b11850d3f4557421f43f519b59d528329c668Chris Lattner 160420b11850d3f4557421f43f519b59d528329c668Chris Lattner // The prototype is something that takes and returns whatever V's type is. 161da549e8995c447542d5631b8b67fcc3a9582797aJay Foad llvm::FunctionType *FT = llvm::FunctionType::get(V->getType(), V->getType(), 16295d318c4c10437db40ca6e15fdf32e04012da58eBenjamin Kramer false); 163420b11850d3f4557421f43f519b59d528329c668Chris Lattner llvm::Value *Fn = CGF.CGM.CreateRuntimeFunction(FT, FnName); 164420b11850d3f4557421f43f519b59d528329c668Chris Lattner 165420b11850d3f4557421f43f519b59d528329c668Chris Lattner return CGF.Builder.CreateCall(Fn, V, "abs"); 166420b11850d3f4557421f43f519b59d528329c668Chris Lattner} 167420b11850d3f4557421f43f519b59d528329c668Chris Lattner 168a45680b7e7c49ea9893c6cff585984f3e4120366John McCallstatic RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *Fn, 169a45680b7e7c49ea9893c6cff585984f3e4120366John McCall const CallExpr *E, llvm::Value *calleeValue) { 170a45680b7e7c49ea9893c6cff585984f3e4120366John McCall return CGF.EmitCall(E->getCallee()->getType(), calleeValue, 171a45680b7e7c49ea9893c6cff585984f3e4120366John McCall ReturnValueSlot(), E->arg_begin(), E->arg_end(), Fn); 172a45680b7e7c49ea9893c6cff585984f3e4120366John McCall} 173a45680b7e7c49ea9893c6cff585984f3e4120366John McCall 1741eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpRValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, 175ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar unsigned BuiltinID, const CallExpr *E) { 176564ea2a99b3afeac9ded332730a56db1f6358a58Chris Lattner // See if we can constant fold this builtin. If so, don't emit it at all. 177f35d35a2316dcb65d078844696c2032b71a7f103Anders Carlsson Expr::EvalResult Result; 17852a27f5be98d99fd5339949d8a3d0b2aec655e0bEli Friedman if (E->EvaluateAsRValue(Result, CGM.getContext()) && 179dd697bc8629f0fa6777245610d52ca7ceb3b67f4Fariborz Jahanian !Result.hasSideEffects()) { 180f35d35a2316dcb65d078844696c2032b71a7f103Anders Carlsson if (Result.Val.isInt()) 181d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall return RValue::get(llvm::ConstantInt::get(getLLVMContext(), 1824a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Result.Val.getInt())); 183a1aa9e36e6e21f74c56cf9e72cb5bd9aa2a92fd4Chris Lattner if (Result.Val.isFloat()) 184d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall return RValue::get(llvm::ConstantFP::get(getLLVMContext(), 185d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Result.Val.getFloat())); 1861f32999ec79a980576e100d64d5f3267eb19ea49Chris Lattner } 1871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 188564ea2a99b3afeac9ded332730a56db1f6358a58Chris Lattner switch (BuiltinID) { 189564ea2a99b3afeac9ded332730a56db1f6358a58Chris Lattner default: break; // Handle intrinsics and libm functions below. 190506ff88f44562df267b6a06608ab841b76df2a2bChris Lattner case Builtin::BI__builtin___CFStringMakeConstantString: 1910d13f6fdbdd6f06e2449b8834dda53334abd399aDavid Chisnall case Builtin::BI__builtin___NSStringMakeConstantString: 192e9352cc9818ba59e7cf88500ef048991c90f3821Anders Carlsson return RValue::get(CGM.EmitConstantExpr(E, E->getType(), 0)); 1936a705f0443f8398ece14d80e71d8e8c9e71aa84aChris Lattner case Builtin::BI__builtin_stdarg_start: 194793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson case Builtin::BI__builtin_va_start: 195793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson case Builtin::BI__builtin_va_end: { 1960785570af3ef5f8c5a0377129e41efe6f3f8d770Daniel Dunbar Value *ArgValue = EmitVAListRef(E->getArg(0)); 1972acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *DestType = Int8PtrTy; 198793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson if (ArgValue->getType() != DestType) 1991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ArgValue = Builder.CreateBitCast(ArgValue, DestType, 200b27ffbef8e8aa1e87b63cbc0d9cd630aba30dae5Daniel Dunbar ArgValue->getName().data()); 201793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson 2021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Intrinsic::ID inst = (BuiltinID == Builtin::BI__builtin_va_end) ? 2036a705f0443f8398ece14d80e71d8e8c9e71aa84aChris Lattner Intrinsic::vaend : Intrinsic::vastart; 2047acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner return RValue::get(Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue)); 205793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson } 206a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson case Builtin::BI__builtin_va_copy: { 2074fd0aa5803357d8c72eeac2cae15e12649ea08feEli Friedman Value *DstPtr = EmitVAListRef(E->getArg(0)); 2084fd0aa5803357d8c72eeac2cae15e12649ea08feEli Friedman Value *SrcPtr = EmitVAListRef(E->getArg(1)); 209a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson 2102acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Type = Int8PtrTy; 211a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson 212a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson DstPtr = Builder.CreateBitCast(DstPtr, Type); 213a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson SrcPtr = Builder.CreateBitCast(SrcPtr, Type); 2141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return RValue::get(Builder.CreateCall2(CGM.getIntrinsic(Intrinsic::vacopy), 2153eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner DstPtr, SrcPtr)); 216a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson } 217f7b2d8b3b1971e73e2d2f0662520dc7693235a7fEli Friedman case Builtin::BI__builtin_abs: 218f7b2d8b3b1971e73e2d2f0662520dc7693235a7fEli Friedman case Builtin::BI__builtin_labs: 219f7b2d8b3b1971e73e2d2f0662520dc7693235a7fEli Friedman case Builtin::BI__builtin_llabs: { 2201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *ArgValue = EmitScalarExpr(E->getArg(0)); 2211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2229a847f598c4907a72b8593b364b9e6b94b086e75Chris Lattner Value *NegOp = Builder.CreateNeg(ArgValue, "neg"); 2231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *CmpResult = 2241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Builder.CreateICmpSGE(ArgValue, 225c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson llvm::Constant::getNullValue(ArgValue->getType()), 2269a847f598c4907a72b8593b364b9e6b94b086e75Chris Lattner "abscond"); 2271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *Result = 228c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs"); 2291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 230c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson return RValue::get(Result); 231c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson } 232ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian 233ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian case Builtin::BI__builtin_conj: 234ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian case Builtin::BI__builtin_conjf: 235ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian case Builtin::BI__builtin_conjl: { 236ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); 237ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian Value *Real = ComplexVal.first; 238ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian Value *Imag = ComplexVal.second; 239ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian Value *Zero = 240ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian Imag->getType()->isFPOrFPVectorTy() 241ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian ? llvm::ConstantFP::getZeroValueForNegation(Imag->getType()) 242ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian : llvm::Constant::getNullValue(Imag->getType()); 243ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian 244ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian Imag = Builder.CreateFSub(Zero, Imag, "sub"); 245ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian return RValue::getComplex(std::make_pair(Real, Imag)); 246ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian } 247ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian case Builtin::BI__builtin_creal: 248ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian case Builtin::BI__builtin_crealf: 249ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian case Builtin::BI__builtin_creall: { 250ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); 251ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian return RValue::get(ComplexVal.first); 252ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian } 253ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian 254ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian case Builtin::BI__builtin_cimag: 255ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian case Builtin::BI__builtin_cimagf: 256ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian case Builtin::BI__builtin_cimagl: { 257ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); 258ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian return RValue::get(ComplexVal.second); 259ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian } 260ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian 261a49a2839266f0bac2b6286e9f49fdc0c292938feBenjamin Kramer case Builtin::BI__builtin_ctzs: 2623a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson case Builtin::BI__builtin_ctz: 2633a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson case Builtin::BI__builtin_ctzl: 2643a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson case Builtin::BI__builtin_ctzll: { 2653a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson Value *ArgValue = EmitScalarExpr(E->getArg(0)); 2661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2679cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ArgType = ArgValue->getType(); 2688dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType); 2693a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson 2702acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ResultType = ConvertType(E->getType()); 2718b30a9379f730875ba8fb2d0fe2d43611e0c20ffBob Wilson Value *ZeroUndef = Builder.getInt1(Target.isCLZForZeroUndef()); 2728b30a9379f730875ba8fb2d0fe2d43611e0c20ffBob Wilson Value *Result = Builder.CreateCall2(F, ArgValue, ZeroUndef); 2733a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson if (Result->getType() != ResultType) 274eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 275eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 2763a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson return RValue::get(Result); 2773a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson } 278a49a2839266f0bac2b6286e9f49fdc0c292938feBenjamin Kramer case Builtin::BI__builtin_clzs: 279f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman case Builtin::BI__builtin_clz: 280f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman case Builtin::BI__builtin_clzl: 281f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman case Builtin::BI__builtin_clzll: { 282f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman Value *ArgValue = EmitScalarExpr(E->getArg(0)); 2831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2849cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ArgType = ArgValue->getType(); 2858dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType); 286f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman 2872acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ResultType = ConvertType(E->getType()); 2888b30a9379f730875ba8fb2d0fe2d43611e0c20ffBob Wilson Value *ZeroUndef = Builder.getInt1(Target.isCLZForZeroUndef()); 2898b30a9379f730875ba8fb2d0fe2d43611e0c20ffBob Wilson Value *Result = Builder.CreateCall2(F, ArgValue, ZeroUndef); 290f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman if (Result->getType() != ResultType) 291eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 292eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 293f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman return RValue::get(Result); 294f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman } 29504b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_ffs: 29604b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_ffsl: 29704b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_ffsll: { 29804b290030eee33295600728450f348989d1a627eDaniel Dunbar // ffs(x) -> x ? cttz(x) + 1 : 0 29904b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *ArgValue = EmitScalarExpr(E->getArg(0)); 3001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3019cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ArgType = ArgValue->getType(); 3028dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType); 3031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3042acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ResultType = ConvertType(E->getType()); 30550058ec63f38eabeb94391a61d2e7fb18a062173Chandler Carruth Value *Tmp = Builder.CreateAdd(Builder.CreateCall2(F, ArgValue, 30650058ec63f38eabeb94391a61d2e7fb18a062173Chandler Carruth Builder.getTrue()), 307578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer llvm::ConstantInt::get(ArgType, 1)); 308c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Value *Zero = llvm::Constant::getNullValue(ArgType); 30904b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero"); 31004b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp, "ffs"); 31104b290030eee33295600728450f348989d1a627eDaniel Dunbar if (Result->getType() != ResultType) 312eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 313eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 31404b290030eee33295600728450f348989d1a627eDaniel Dunbar return RValue::get(Result); 31504b290030eee33295600728450f348989d1a627eDaniel Dunbar } 31604b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_parity: 31704b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_parityl: 31804b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_parityll: { 31904b290030eee33295600728450f348989d1a627eDaniel Dunbar // parity(x) -> ctpop(x) & 1 32004b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *ArgValue = EmitScalarExpr(E->getArg(0)); 3211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3229cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ArgType = ArgValue->getType(); 3238dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType); 3241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3252acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ResultType = ConvertType(E->getType()); 326578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Value *Tmp = Builder.CreateCall(F, ArgValue); 327578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Value *Result = Builder.CreateAnd(Tmp, llvm::ConstantInt::get(ArgType, 1)); 32804b290030eee33295600728450f348989d1a627eDaniel Dunbar if (Result->getType() != ResultType) 329eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 330eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 33104b290030eee33295600728450f348989d1a627eDaniel Dunbar return RValue::get(Result); 33204b290030eee33295600728450f348989d1a627eDaniel Dunbar } 33304b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_popcount: 33404b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_popcountl: 33504b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_popcountll: { 33604b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *ArgValue = EmitScalarExpr(E->getArg(0)); 3371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3389cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ArgType = ArgValue->getType(); 3398dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType); 3401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3412acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ResultType = ConvertType(E->getType()); 342578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Value *Result = Builder.CreateCall(F, ArgValue); 34304b290030eee33295600728450f348989d1a627eDaniel Dunbar if (Result->getType() != ResultType) 344eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 345eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 34604b290030eee33295600728450f348989d1a627eDaniel Dunbar return RValue::get(Result); 34704b290030eee33295600728450f348989d1a627eDaniel Dunbar } 348e42b8a596886fc98e367c73e54d761446700029eFariborz Jahanian case Builtin::BI__builtin_expect: { 349dd697bc8629f0fa6777245610d52ca7ceb3b67f4Fariborz Jahanian Value *ArgValue = EmitScalarExpr(E->getArg(0)); 3509cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ArgType = ArgValue->getType(); 351558229f267d2cdee69639df04382082e7c7ad54cJakub Staszak 3528dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *FnExpect = CGM.getIntrinsic(Intrinsic::expect, ArgType); 353558229f267d2cdee69639df04382082e7c7ad54cJakub Staszak Value *ExpectedValue = EmitScalarExpr(E->getArg(1)); 354558229f267d2cdee69639df04382082e7c7ad54cJakub Staszak 355558229f267d2cdee69639df04382082e7c7ad54cJakub Staszak Value *Result = Builder.CreateCall2(FnExpect, ArgValue, ExpectedValue, 356558229f267d2cdee69639df04382082e7c7ad54cJakub Staszak "expval"); 357558229f267d2cdee69639df04382082e7c7ad54cJakub Staszak return RValue::get(Result); 358e42b8a596886fc98e367c73e54d761446700029eFariborz Jahanian } 359df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson case Builtin::BI__builtin_bswap32: 360df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson case Builtin::BI__builtin_bswap64: { 3611feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner Value *ArgValue = EmitScalarExpr(E->getArg(0)); 3629cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ArgType = ArgValue->getType(); 3638dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::bswap, ArgType); 364578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return RValue::get(Builder.CreateCall(F, ArgValue)); 3651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 366d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar case Builtin::BI__builtin_object_size: { 367c6794850a570a91c5f224b6f0293db9f560f4213Richard Smith // We rely on constant folding to deal with expressions with side effects. 368c6794850a570a91c5f224b6f0293db9f560f4213Richard Smith assert(!E->getArg(0)->HasSideEffects(getContext()) && 369c6794850a570a91c5f224b6f0293db9f560f4213Richard Smith "should have been constant folded"); 370c6794850a570a91c5f224b6f0293db9f560f4213Richard Smith 371b16d32f74ffc467a5604934a1f844906be20cf7dMike Stump // We pass this builtin onto the optimizer so that it can 372b16d32f74ffc467a5604934a1f844906be20cf7dMike Stump // figure out the object size in more complex cases. 3738dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer llvm::Type *ResType = ConvertType(E->getType()); 374fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher 375fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher // LLVM only supports 0 and 2, make sure that we pass along that 376fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher // as a boolean. 377fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher Value *Ty = EmitScalarExpr(E->getArg(1)); 378fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher ConstantInt *CI = dyn_cast<ConstantInt>(Ty); 379fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher assert(CI); 380fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher uint64_t val = CI->getZExtValue(); 381d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall CI = ConstantInt::get(Builder.getInt1Ty(), (val & 0x2) >> 1); 382fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher 3838dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::objectsize, ResType); 3843e86a0433db4c664d29f2b19eb977138e071a68aNuno Lopes return RValue::get(Builder.CreateCall2(F, EmitScalarExpr(E->getArg(0)),CI)); 385d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar } 3864493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar case Builtin::BI__builtin_prefetch: { 3874493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0)); 3884493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar // FIXME: Technically these constants should of type 'int', yes? 3891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump RW = (E->getNumArgs() > 1) ? EmitScalarExpr(E->getArg(1)) : 39077b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::ConstantInt::get(Int32Ty, 0); 3911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : 39277b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::ConstantInt::get(Int32Ty, 3); 3932eccb672799d19fb535ce349566fea6729cbb891Bruno Cardoso Lopes Value *Data = llvm::ConstantInt::get(Int32Ty, 1); 3948dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 3952eccb672799d19fb535ce349566fea6729cbb891Bruno Cardoso Lopes return RValue::get(Builder.CreateCall4(F, Address, RW, Locality, Data)); 3964493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar } 397a841c19f7860393d6319bf40e9d662284462771dHal Finkel case Builtin::BI__builtin_readcyclecounter: { 398a841c19f7860393d6319bf40e9d662284462771dHal Finkel Value *F = CGM.getIntrinsic(Intrinsic::readcyclecounter); 399a841c19f7860393d6319bf40e9d662284462771dHal Finkel return RValue::get(Builder.CreateCall(F)); 400a841c19f7860393d6319bf40e9d662284462771dHal Finkel } 4014493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar case Builtin::BI__builtin_trap: { 4028dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::trap); 4034493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar return RValue::get(Builder.CreateCall(F)); 404df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson } 40521190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner case Builtin::BI__builtin_unreachable: { 406cd5b22e12b6513163dd131589746c194090f14e6John McCall if (CatchUndefined) 407fba565d044a8979cfd916ce52655a6847bfaa601Mike Stump EmitBranch(getTrapBB()); 408cd5b22e12b6513163dd131589746c194090f14e6John McCall else 409cd5b22e12b6513163dd131589746c194090f14e6John McCall Builder.CreateUnreachable(); 410cd5b22e12b6513163dd131589746c194090f14e6John McCall 411cd5b22e12b6513163dd131589746c194090f14e6John McCall // We do need to preserve an insertion point. 412d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall EmitBlock(createBasicBlock("unreachable.cont")); 413cd5b22e12b6513163dd131589746c194090f14e6John McCall 414cd5b22e12b6513163dd131589746c194090f14e6John McCall return RValue::get(0); 41521190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner } 41621190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner 417a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar case Builtin::BI__builtin_powi: 418a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar case Builtin::BI__builtin_powif: 419a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar case Builtin::BI__builtin_powil: { 420a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar Value *Base = EmitScalarExpr(E->getArg(0)); 421a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar Value *Exponent = EmitScalarExpr(E->getArg(1)); 4229cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ArgType = Base->getType(); 4238dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::powi, ArgType); 424578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return RValue::get(Builder.CreateCall2(F, Base, Exponent)); 425a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar } 426a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar 427fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isgreater: 428fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isgreaterequal: 429fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isless: 430fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_islessequal: 431fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_islessgreater: 432fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isunordered: { 433fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner // Ordered comparisons: we know the arguments to these are matching scalar 434fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner // floating point values. 4351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *LHS = EmitScalarExpr(E->getArg(0)); 436fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner Value *RHS = EmitScalarExpr(E->getArg(1)); 4371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 438fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner switch (BuiltinID) { 439b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("Unknown ordered comparison"); 440fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isgreater: 441fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp"); 442fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 443fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isgreaterequal: 444fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp"); 445fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 446fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isless: 447fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp"); 448fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 449fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_islessequal: 450fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp"); 451fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 452fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_islessgreater: 453fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp"); 454fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 4551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case Builtin::BI__builtin_isunordered: 456fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp"); 457fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 458fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner } 459fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner // ZExt bool to int type. 460578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType()))); 461fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner } 462d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman case Builtin::BI__builtin_isnan: { 463d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman Value *V = EmitScalarExpr(E->getArg(0)); 464d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman V = Builder.CreateFCmpUNO(V, V, "cmp"); 465578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 466d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman } 467420b11850d3f4557421f43f519b59d528329c668Chris Lattner 468420b11850d3f4557421f43f519b59d528329c668Chris Lattner case Builtin::BI__builtin_isinf: { 469420b11850d3f4557421f43f519b59d528329c668Chris Lattner // isinf(x) --> fabs(x) == infinity 470420b11850d3f4557421f43f519b59d528329c668Chris Lattner Value *V = EmitScalarExpr(E->getArg(0)); 471420b11850d3f4557421f43f519b59d528329c668Chris Lattner V = EmitFAbs(*this, V, E->getArg(0)->getType()); 472420b11850d3f4557421f43f519b59d528329c668Chris Lattner 473420b11850d3f4557421f43f519b59d528329c668Chris Lattner V = Builder.CreateFCmpOEQ(V, ConstantFP::getInfinity(V->getType()),"isinf"); 474578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 475420b11850d3f4557421f43f519b59d528329c668Chris Lattner } 47658ae5b4b1e2fc02b95d6650af5755a59639aa153Chris Lattner 47758ae5b4b1e2fc02b95d6650af5755a59639aa153Chris Lattner // TODO: BI__builtin_isinf_sign 47858ae5b4b1e2fc02b95d6650af5755a59639aa153Chris Lattner // isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0 4796349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer 4806349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer case Builtin::BI__builtin_isnormal: { 4816349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer // isnormal(x) --> x == x && fabsf(x) < infinity && fabsf(x) >= float_min 4826349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer Value *V = EmitScalarExpr(E->getArg(0)); 4836349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq"); 4846349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer 4856349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer Value *Abs = EmitFAbs(*this, V, E->getArg(0)->getType()); 4866349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer Value *IsLessThanInf = 4876349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer Builder.CreateFCmpULT(Abs, ConstantFP::getInfinity(V->getType()),"isinf"); 4886349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer APFloat Smallest = APFloat::getSmallestNormalized( 4896349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer getContext().getFloatTypeSemantics(E->getArg(0)->getType())); 4906349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer Value *IsNormal = 4916349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer Builder.CreateFCmpUGE(Abs, ConstantFP::get(V->getContext(), Smallest), 4926349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer "isnormal"); 4936349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer V = Builder.CreateAnd(Eq, IsLessThanInf, "and"); 4946349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer V = Builder.CreateAnd(V, IsNormal, "and"); 4956349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 4966349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer } 4976349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer 498ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner case Builtin::BI__builtin_isfinite: { 499ef004ec5adb0e11815cef3435fa5ac7366d783a9Julien Lerouge // isfinite(x) --> x == x && fabs(x) != infinity; 500ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner Value *V = EmitScalarExpr(E->getArg(0)); 501ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq"); 502ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner 503ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner Value *Abs = EmitFAbs(*this, V, E->getArg(0)->getType()); 504ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner Value *IsNotInf = 505ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner Builder.CreateFCmpUNE(Abs, ConstantFP::getInfinity(V->getType()),"isinf"); 506ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner 507ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner V = Builder.CreateAnd(Eq, IsNotInf, "and"); 508ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 509ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner } 5107867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer 5117867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer case Builtin::BI__builtin_fpclassify: { 5127867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *V = EmitScalarExpr(E->getArg(5)); 5132acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Ty = ConvertType(E->getArg(5)->getType()); 5147867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer 5157867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer // Create Result 5167867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer BasicBlock *Begin = Builder.GetInsertBlock(); 5177867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer BasicBlock *End = createBasicBlock("fpclassify_end", this->CurFn); 5187867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.SetInsertPoint(End); 5197867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer PHINode *Result = 520bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad Builder.CreatePHI(ConvertType(E->getArg(0)->getType()), 4, 5217867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer "fpclassify_result"); 5227867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer 5237867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer // if (V==0) return FP_ZERO 5247867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.SetInsertPoint(Begin); 5257867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *IsZero = Builder.CreateFCmpOEQ(V, Constant::getNullValue(Ty), 5267867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer "iszero"); 5277867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *ZeroLiteral = EmitScalarExpr(E->getArg(4)); 5287867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer BasicBlock *NotZero = createBasicBlock("fpclassify_not_zero", this->CurFn); 5297867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.CreateCondBr(IsZero, End, NotZero); 5307867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Result->addIncoming(ZeroLiteral, Begin); 5317867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer 5327867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer // if (V != V) return FP_NAN 5337867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.SetInsertPoint(NotZero); 5347867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *IsNan = Builder.CreateFCmpUNO(V, V, "cmp"); 5357867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *NanLiteral = EmitScalarExpr(E->getArg(0)); 5367867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer BasicBlock *NotNan = createBasicBlock("fpclassify_not_nan", this->CurFn); 5377867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.CreateCondBr(IsNan, End, NotNan); 5387867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Result->addIncoming(NanLiteral, NotZero); 5397867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer 5407867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer // if (fabs(V) == infinity) return FP_INFINITY 5417867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.SetInsertPoint(NotNan); 5427867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *VAbs = EmitFAbs(*this, V, E->getArg(5)->getType()); 5437867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *IsInf = 5447867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.CreateFCmpOEQ(VAbs, ConstantFP::getInfinity(V->getType()), 5457867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer "isinf"); 5467867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *InfLiteral = EmitScalarExpr(E->getArg(1)); 5477867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer BasicBlock *NotInf = createBasicBlock("fpclassify_not_inf", this->CurFn); 5487867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.CreateCondBr(IsInf, End, NotInf); 5497867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Result->addIncoming(InfLiteral, NotNan); 5507867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer 5517867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer // if (fabs(V) >= MIN_NORMAL) return FP_NORMAL else FP_SUBNORMAL 5527867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.SetInsertPoint(NotInf); 5537867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer APFloat Smallest = APFloat::getSmallestNormalized( 5547867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer getContext().getFloatTypeSemantics(E->getArg(5)->getType())); 5557867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *IsNormal = 5567867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.CreateFCmpUGE(VAbs, ConstantFP::get(V->getContext(), Smallest), 5577867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer "isnormal"); 5587867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *NormalResult = 5597867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.CreateSelect(IsNormal, EmitScalarExpr(E->getArg(2)), 5607867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer EmitScalarExpr(E->getArg(3))); 5617867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.CreateBr(End); 5627867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Result->addIncoming(NormalResult, NotInf); 5637867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer 5647867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer // return Result 5657867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.SetInsertPoint(End); 5667867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer return RValue::get(Result); 5677867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer } 568ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner 569b52fe9ce99970955a5f581f5c66fcd89be9a268bEli Friedman case Builtin::BIalloca: 5709e800e3dd80d77f6c47054738177bf824089f55aChris Lattner case Builtin::BI__builtin_alloca: { 5719e800e3dd80d77f6c47054738177bf824089f55aChris Lattner Value *Size = EmitScalarExpr(E->getArg(0)); 572578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return RValue::get(Builder.CreateAlloca(Builder.getInt8Ty(), Size)); 5731caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar } 574e6dddfd907f6ea58daed5e26eeaacd893d98db9bEli Friedman case Builtin::BIbzero: 5751caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar case Builtin::BI__builtin_bzero: { 576ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Dest = 577ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(0)); 5783ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Value *SizeVal = EmitScalarExpr(E->getArg(1)); 579ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Builder.CreateMemSet(Dest.first, Builder.getInt8(0), SizeVal, 580ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Dest.second, false); 581ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return RValue::get(Dest.first); 5829e800e3dd80d77f6c47054738177bf824089f55aChris Lattner } 583e6ec205d6d0f4aec27bf49ca1e8fbb139acc2f2bEli Friedman case Builtin::BImemcpy: 584d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman case Builtin::BI__builtin_memcpy: { 585ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Dest = 586ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(0)); 587ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Src = 588ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(1)); 5893ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Value *SizeVal = EmitScalarExpr(E->getArg(2)); 590ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman unsigned Align = std::min(Dest.second, Src.second); 591ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Builder.CreateMemCpy(Dest.first, Src.first, SizeVal, Align, false); 592ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return RValue::get(Dest.first); 5931caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar } 59455bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian 595a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner case Builtin::BI__builtin___memcpy_chk: { 596ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman // fold __builtin_memcpy_chk(x, y, cst1, cst2) to memcpy iff cst1<=cst2. 597a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith llvm::APSInt Size, DstSize; 598a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || 599a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) 600a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner break; 601a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner if (Size.ugt(DstSize)) 602a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner break; 603ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Dest = 604ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(0)); 605ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Src = 606ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(1)); 607a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); 608ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman unsigned Align = std::min(Dest.second, Src.second); 609ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Builder.CreateMemCpy(Dest.first, Src.first, SizeVal, Align, false); 610ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return RValue::get(Dest.first); 611a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner } 612a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner 6138e2eab27056a78bf1db50ee09929438ed5ea9d93Fariborz Jahanian case Builtin::BI__builtin_objc_memmove_collectable: { 61455bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian Value *Address = EmitScalarExpr(E->getArg(0)); 61555bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian Value *SrcAddr = EmitScalarExpr(E->getArg(1)); 61655bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian Value *SizeVal = EmitScalarExpr(E->getArg(2)); 61755bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, 61855bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian Address, SrcAddr, SizeVal); 61955bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian return RValue::get(Address); 62055bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian } 621a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner 622a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner case Builtin::BI__builtin___memmove_chk: { 623ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman // fold __builtin_memmove_chk(x, y, cst1, cst2) to memmove iff cst1<=cst2. 624a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith llvm::APSInt Size, DstSize; 625a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || 626a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) 627a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner break; 628a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner if (Size.ugt(DstSize)) 629a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner break; 630ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Dest = 631ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(0)); 632ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Src = 633ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(1)); 634a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); 635ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman unsigned Align = std::min(Dest.second, Src.second); 636ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Builder.CreateMemMove(Dest.first, Src.first, SizeVal, Align, false); 637ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return RValue::get(Dest.first); 638a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner } 639a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner 640e6ec205d6d0f4aec27bf49ca1e8fbb139acc2f2bEli Friedman case Builtin::BImemmove: 6411caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar case Builtin::BI__builtin_memmove: { 642ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Dest = 643ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(0)); 644ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Src = 645ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(1)); 6463ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Value *SizeVal = EmitScalarExpr(E->getArg(2)); 647ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman unsigned Align = std::min(Dest.second, Src.second); 648ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Builder.CreateMemMove(Dest.first, Src.first, SizeVal, Align, false); 649ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return RValue::get(Dest.first); 6501caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar } 651e6ec205d6d0f4aec27bf49ca1e8fbb139acc2f2bEli Friedman case Builtin::BImemset: 6521caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar case Builtin::BI__builtin_memset: { 653ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Dest = 654ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(0)); 6559f0c7cc36d29cf591c33962931f5862847145f3eBenjamin Kramer Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), 6569f0c7cc36d29cf591c33962931f5862847145f3eBenjamin Kramer Builder.getInt8Ty()); 6573ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Value *SizeVal = EmitScalarExpr(E->getArg(2)); 658ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Builder.CreateMemSet(Dest.first, ByteVal, SizeVal, Dest.second, false); 659ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return RValue::get(Dest.first); 660d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman } 661a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner case Builtin::BI__builtin___memset_chk: { 662a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner // fold __builtin_memset_chk(x, y, cst1, cst2) to memset iff cst1<=cst2. 663a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith llvm::APSInt Size, DstSize; 664a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || 665a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) 666a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner break; 667a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner if (Size.ugt(DstSize)) 668a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner break; 669ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Dest = 670ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(0)); 671a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), 672a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner Builder.getInt8Ty()); 673a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); 674ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Builder.CreateMemSet(Dest.first, ByteVal, SizeVal, Dest.second, false); 675ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return RValue::get(Dest.first); 676a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner } 677fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall case Builtin::BI__builtin_dwarf_cfa: { 678fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // The offset in bytes from the first argument to the CFA. 679fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // 680fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // Why on earth is this in the frontend? Is there any reason at 681fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // all that the backend can't reasonably determine this while 682fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // lowering llvm.eh.dwarf.cfa()? 683fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // 684fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // TODO: If there's a satisfactory reason, add a target hook for 685fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // this instead of hard-coding 0, which is correct for most targets. 686fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall int32_t Offset = 0; 687fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall 6888dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::eh_dwarf_cfa); 68977b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner return RValue::get(Builder.CreateCall(F, 69077b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::ConstantInt::get(Int32Ty, Offset))); 691fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall } 692256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman case Builtin::BI__builtin_return_address: { 69383c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov Value *Depth = EmitScalarExpr(E->getArg(0)); 694578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Depth = Builder.CreateIntCast(Depth, Int32Ty, false); 6958dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::returnaddress); 69683c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov return RValue::get(Builder.CreateCall(F, Depth)); 697256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman } 698256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman case Builtin::BI__builtin_frame_address: { 69983c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov Value *Depth = EmitScalarExpr(E->getArg(0)); 700578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Depth = Builder.CreateIntCast(Depth, Int32Ty, false); 7018dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::frameaddress); 70283c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov return RValue::get(Builder.CreateCall(F, Depth)); 703256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman } 7043b660efb9f9fa3e87096f4a96a2093cd17c43c2eEli Friedman case Builtin::BI__builtin_extract_return_addr: { 705492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall Value *Address = EmitScalarExpr(E->getArg(0)); 706492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall Value *Result = getTargetHooks().decodeReturnAddress(*this, Address); 707492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall return RValue::get(Result); 708492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall } 709492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall case Builtin::BI__builtin_frob_return_addr: { 710492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall Value *Address = EmitScalarExpr(E->getArg(0)); 711492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall Value *Result = getTargetHooks().encodeReturnAddress(*this, Address); 712492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall return RValue::get(Result); 7133b660efb9f9fa3e87096f4a96a2093cd17c43c2eEli Friedman } 7146374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall case Builtin::BI__builtin_dwarf_sp_column: { 7152acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::IntegerType *Ty 7166374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall = cast<llvm::IntegerType>(ConvertType(E->getType())); 7176374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall int Column = getTargetHooks().getDwarfEHStackPointer(CGM); 7186374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall if (Column == -1) { 7196374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall CGM.ErrorUnsupported(E, "__builtin_dwarf_sp_column"); 7206374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall return RValue::get(llvm::UndefValue::get(Ty)); 7216374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall } 7226374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall return RValue::get(llvm::ConstantInt::get(Ty, Column, true)); 7236374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall } 7246374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall case Builtin::BI__builtin_init_dwarf_reg_size_table: { 7256374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall Value *Address = EmitScalarExpr(E->getArg(0)); 7266374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall if (getTargetHooks().initDwarfEHRegSizeTable(*this, Address)) 7276374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall CGM.ErrorUnsupported(E, "__builtin_init_dwarf_reg_size_table"); 7286374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall return RValue::get(llvm::UndefValue::get(ConvertType(E->getType()))); 7296374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall } 7307ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall case Builtin::BI__builtin_eh_return: { 7317ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall Value *Int = EmitScalarExpr(E->getArg(0)); 7327ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall Value *Ptr = EmitScalarExpr(E->getArg(1)); 7337ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall 7342acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::IntegerType *IntTy = cast<llvm::IntegerType>(Int->getType()); 7357ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall assert((IntTy->getBitWidth() == 32 || IntTy->getBitWidth() == 64) && 7367ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall "LLVM's __builtin_eh_return only supports 32- and 64-bit variants"); 7377ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall Value *F = CGM.getIntrinsic(IntTy->getBitWidth() == 32 7387ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall ? Intrinsic::eh_return_i32 7398dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer : Intrinsic::eh_return_i64); 7407ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall Builder.CreateCall2(F, Int, Ptr); 741cd5b22e12b6513163dd131589746c194090f14e6John McCall Builder.CreateUnreachable(); 742cd5b22e12b6513163dd131589746c194090f14e6John McCall 743cd5b22e12b6513163dd131589746c194090f14e6John McCall // We do need to preserve an insertion point. 744d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall EmitBlock(createBasicBlock("builtin_eh_return.cont")); 745cd5b22e12b6513163dd131589746c194090f14e6John McCall 746cd5b22e12b6513163dd131589746c194090f14e6John McCall return RValue::get(0); 7477ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall } 748a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman case Builtin::BI__builtin_unwind_init: { 7498dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init); 750a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman return RValue::get(Builder.CreateCall(F)); 751a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman } 7525e11085830d4d4c53ff75575ab75889ee5126854John McCall case Builtin::BI__builtin_extend_pointer: { 7535e11085830d4d4c53ff75575ab75889ee5126854John McCall // Extends a pointer to the size of an _Unwind_Word, which is 754d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // uint64_t on all platforms. Generally this gets poked into a 755d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // register and eventually used as an address, so if the 756d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // addressing registers are wider than pointers and the platform 757d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // doesn't implicitly ignore high-order bits when doing 758d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // addressing, we need to make sure we zext / sext based on 759d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // the platform's expectations. 7605e11085830d4d4c53ff75575ab75889ee5126854John McCall // 7615e11085830d4d4c53ff75575ab75889ee5126854John McCall // See: http://gcc.gnu.org/ml/gcc-bugs/2002-02/msg00237.html 762d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall 763d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // Cast the pointer to intptr_t. 7645e11085830d4d4c53ff75575ab75889ee5126854John McCall Value *Ptr = EmitScalarExpr(E->getArg(0)); 765d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall Value *Result = Builder.CreatePtrToInt(Ptr, IntPtrTy, "extend.cast"); 766d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall 767d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // If that's 64 bits, we're done. 768d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall if (IntPtrTy->getBitWidth() == 64) 769d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall return RValue::get(Result); 770d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall 771d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // Otherwise, ask the codegen data what to do. 772492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall if (getTargetHooks().extendPointerWithSExt()) 773d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall return RValue::get(Builder.CreateSExt(Result, Int64Ty, "extend.sext")); 774d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall else 775d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall return RValue::get(Builder.CreateZExt(Result, Int64Ty, "extend.zext")); 7765e11085830d4d4c53ff75575ab75889ee5126854John McCall } 777a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman case Builtin::BI__builtin_setjmp: { 77878673d9f910e8dfe13248c2426c51d8f9fb28572John McCall // Buffer is a void**. 779a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *Buf = EmitScalarExpr(E->getArg(0)); 78078673d9f910e8dfe13248c2426c51d8f9fb28572John McCall 78178673d9f910e8dfe13248c2426c51d8f9fb28572John McCall // Store the frame pointer to the setjmp buffer. 782a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *FrameAddr = 78378673d9f910e8dfe13248c2426c51d8f9fb28572John McCall Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress), 78477b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner ConstantInt::get(Int32Ty, 0)); 785a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Builder.CreateStore(FrameAddr, Buf); 78678673d9f910e8dfe13248c2426c51d8f9fb28572John McCall 7876d172e2985346e55095c75f456901ea5d40fddaaJim Grosbach // Store the stack pointer to the setjmp buffer. 7886d172e2985346e55095c75f456901ea5d40fddaaJim Grosbach Value *StackAddr = 7896d172e2985346e55095c75f456901ea5d40fddaaJim Grosbach Builder.CreateCall(CGM.getIntrinsic(Intrinsic::stacksave)); 7906d172e2985346e55095c75f456901ea5d40fddaaJim Grosbach Value *StackSaveSlot = 79177b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Builder.CreateGEP(Buf, ConstantInt::get(Int32Ty, 2)); 7926d172e2985346e55095c75f456901ea5d40fddaaJim Grosbach Builder.CreateStore(StackAddr, StackSaveSlot); 7936d172e2985346e55095c75f456901ea5d40fddaaJim Grosbach 79478673d9f910e8dfe13248c2426c51d8f9fb28572John McCall // Call LLVM's EH setjmp, which is lightweight. 79578673d9f910e8dfe13248c2426c51d8f9fb28572John McCall Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp); 796d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Buf = Builder.CreateBitCast(Buf, Int8PtrTy); 797a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman return RValue::get(Builder.CreateCall(F, Buf)); 798a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman } 799a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman case Builtin::BI__builtin_longjmp: { 800a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *Buf = EmitScalarExpr(E->getArg(0)); 801d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Buf = Builder.CreateBitCast(Buf, Int8PtrTy); 80278673d9f910e8dfe13248c2426c51d8f9fb28572John McCall 80378673d9f910e8dfe13248c2426c51d8f9fb28572John McCall // Call LLVM's EH longjmp, which is lightweight. 80478673d9f910e8dfe13248c2426c51d8f9fb28572John McCall Builder.CreateCall(CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp), Buf); 80578673d9f910e8dfe13248c2426c51d8f9fb28572John McCall 806cd5b22e12b6513163dd131589746c194090f14e6John McCall // longjmp doesn't return; mark this as unreachable. 807cd5b22e12b6513163dd131589746c194090f14e6John McCall Builder.CreateUnreachable(); 808cd5b22e12b6513163dd131589746c194090f14e6John McCall 809cd5b22e12b6513163dd131589746c194090f14e6John McCall // We do need to preserve an insertion point. 810d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall EmitBlock(createBasicBlock("longjmp.cont")); 811cd5b22e12b6513163dd131589746c194090f14e6John McCall 812cd5b22e12b6513163dd131589746c194090f14e6John McCall return RValue::get(0); 813a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman } 8141ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_add: 8151ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_sub: 8165caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or: 8175caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and: 8185caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor: 8195caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch: 8205caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch: 8215caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch: 8225caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch: 8235caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch: 8245caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap: 8255caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap: 8265caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set: 8275caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release: 82823aa9c8ca0bc441aab2a38a4c9fc7a1c9e9ac16aChris Lattner case Builtin::BI__sync_swap: 829b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Shouldn't make it through sema"); 8305caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_1: 8315caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_2: 8325caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_4: 8335caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_8: 8345caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_16: 835c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Add, E); 8365caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_1: 8375caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_2: 8385caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_4: 8395caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_8: 8405caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_16: 841c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Sub, E); 8425caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_1: 8435caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_2: 8445caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_4: 8455caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_8: 8465caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_16: 847c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Or, E); 8485caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_1: 8495caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_2: 8505caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_4: 8515caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_8: 8525caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_16: 853c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::And, E); 8545caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_1: 8555caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_2: 8565caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_4: 8575caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_8: 8585caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_16: 859c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xor, E); 8601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8615caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // Clang extensions: not overloaded yet. 8621ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_min: 863c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Min, E); 8641ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_max: 865c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Max, E); 8661ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_umin: 867c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::UMin, E); 8681ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_umax: 869c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::UMax, E); 8700002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar 8715caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_1: 8725caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_2: 8735caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_4: 8745caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_8: 8755caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_16: 876c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Add, E, 8770002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::Add); 8785caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_1: 8795caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_2: 8805caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_4: 8815caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_8: 8825caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_16: 883c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Sub, E, 8840002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::Sub); 8855caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_1: 8865caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_2: 8875caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_4: 8885caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_8: 8895caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_16: 890c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::And, E, 8910002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::And); 8925caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_1: 8935caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_2: 8945caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_4: 8955caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_8: 8965caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_16: 897c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Or, E, 8980002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::Or); 8995caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_1: 9005caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_2: 9015caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_4: 9025caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_8: 9035caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_16: 904c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Xor, E, 9050002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::Xor); 9061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9075caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap_1: 9085caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap_2: 9095caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap_4: 9105caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap_8: 911cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar case Builtin::BI__sync_val_compare_and_swap_16: { 91226815d97c5743481e317f17a8d53a6819d061862John McCall QualType T = E->getType(); 913d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::Value *DestPtr = EmitScalarExpr(E->getArg(0)); 914780a2eb227c3f395a390a143f61bba1724913817Chris Lattner unsigned AddrSpace = 9154f209445c06a43283c6f72dda7c925538b1578e9Chris Lattner cast<llvm::PointerType>(DestPtr->getType())->getAddressSpace(); 91626815d97c5743481e317f17a8d53a6819d061862John McCall 9179cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::IntegerType *IntType = 918d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::IntegerType::get(getLLVMContext(), 919d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall getContext().getTypeSize(T)); 9209cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 921db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth 92226815d97c5743481e317f17a8d53a6819d061862John McCall Value *Args[3]; 92326815d97c5743481e317f17a8d53a6819d061862John McCall Args[0] = Builder.CreateBitCast(DestPtr, IntPtrType); 924d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Args[1] = EmitScalarExpr(E->getArg(1)); 9252acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ValueType = Args[1]->getType(); 926d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Args[1] = EmitToInt(*this, Args[1], T, IntType); 927d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Args[2] = EmitToInt(*this, EmitScalarExpr(E->getArg(2)), T, IntType); 92826815d97c5743481e317f17a8d53a6819d061862John McCall 929c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman Value *Result = Builder.CreateAtomicCmpXchg(Args[0], Args[1], Args[2], 930c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman llvm::SequentiallyConsistent); 931d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Result = EmitFromInt(*this, Result, T, ValueType); 93226815d97c5743481e317f17a8d53a6819d061862John McCall return RValue::get(Result); 933022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson } 9340002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar 9355caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap_1: 9365caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap_2: 9375caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap_4: 9385caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap_8: 939cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar case Builtin::BI__sync_bool_compare_and_swap_16: { 94026815d97c5743481e317f17a8d53a6819d061862John McCall QualType T = E->getArg(1)->getType(); 941d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::Value *DestPtr = EmitScalarExpr(E->getArg(0)); 942f2b95277be59f7d2a82cef8ea9f4cf6a36074593Chris Lattner unsigned AddrSpace = 9434f209445c06a43283c6f72dda7c925538b1578e9Chris Lattner cast<llvm::PointerType>(DestPtr->getType())->getAddressSpace(); 94426815d97c5743481e317f17a8d53a6819d061862John McCall 9459cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::IntegerType *IntType = 946d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::IntegerType::get(getLLVMContext(), 947d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall getContext().getTypeSize(T)); 9489cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 949db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth 95026815d97c5743481e317f17a8d53a6819d061862John McCall Value *Args[3]; 95126815d97c5743481e317f17a8d53a6819d061862John McCall Args[0] = Builder.CreateBitCast(DestPtr, IntPtrType); 952d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Args[1] = EmitToInt(*this, EmitScalarExpr(E->getArg(1)), T, IntType); 953d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Args[2] = EmitToInt(*this, EmitScalarExpr(E->getArg(2)), T, IntType); 95426815d97c5743481e317f17a8d53a6819d061862John McCall 955db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth Value *OldVal = Args[1]; 956c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman Value *PrevVal = Builder.CreateAtomicCmpXchg(Args[0], Args[1], Args[2], 957c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman llvm::SequentiallyConsistent); 9580002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Value *Result = Builder.CreateICmpEQ(PrevVal, OldVal); 9590002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar // zext bool to int. 96026815d97c5743481e317f17a8d53a6819d061862John McCall Result = Builder.CreateZExt(Result, ConvertType(E->getType())); 96126815d97c5743481e317f17a8d53a6819d061862John McCall return RValue::get(Result); 9620002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar } 9630002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar 96423aa9c8ca0bc441aab2a38a4c9fc7a1c9e9ac16aChris Lattner case Builtin::BI__sync_swap_1: 96523aa9c8ca0bc441aab2a38a4c9fc7a1c9e9ac16aChris Lattner case Builtin::BI__sync_swap_2: 96623aa9c8ca0bc441aab2a38a4c9fc7a1c9e9ac16aChris Lattner case Builtin::BI__sync_swap_4: 96723aa9c8ca0bc441aab2a38a4c9fc7a1c9e9ac16aChris Lattner case Builtin::BI__sync_swap_8: 96823aa9c8ca0bc441aab2a38a4c9fc7a1c9e9ac16aChris Lattner case Builtin::BI__sync_swap_16: 969c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E); 97023aa9c8ca0bc441aab2a38a4c9fc7a1c9e9ac16aChris Lattner 9715caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_1: 9725caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_2: 9735caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_4: 9745caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_8: 9755caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_16: 976c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E); 977cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar 9785caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release_1: 9795caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release_2: 9805caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release_4: 9815caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release_8: 982f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner case Builtin::BI__sync_lock_release_16: { 983f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner Value *Ptr = EmitScalarExpr(E->getArg(0)); 984eb43f4a8f133c2bc510ae136a556e92b68a6ff44Eli Friedman QualType ElTy = E->getArg(0)->getType()->getPointeeType(); 985eb43f4a8f133c2bc510ae136a556e92b68a6ff44Eli Friedman CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy); 986ff993202abf6f5dc41c584c7103f5d39f248b3ddEli Friedman llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), 987ff993202abf6f5dc41c584c7103f5d39f248b3ddEli Friedman StoreSize.getQuantity() * 8); 988ff993202abf6f5dc41c584c7103f5d39f248b3ddEli Friedman Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); 989ff993202abf6f5dc41c584c7103f5d39f248b3ddEli Friedman llvm::StoreInst *Store = 990ff993202abf6f5dc41c584c7103f5d39f248b3ddEli Friedman Builder.CreateStore(llvm::Constant::getNullValue(ITy), Ptr); 991eb43f4a8f133c2bc510ae136a556e92b68a6ff44Eli Friedman Store->setAlignment(StoreSize.getQuantity()); 992eb43f4a8f133c2bc510ae136a556e92b68a6ff44Eli Friedman Store->setAtomic(llvm::Release); 993eb4f81e174b11633f7b85f555ea5d2834d6dae8aDaniel Dunbar return RValue::get(0); 994f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner } 995ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar 996f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner case Builtin::BI__sync_synchronize: { 997c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman // We assume this is supposed to correspond to a C++0x-style 998c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman // sequentially-consistent fence (i.e. this is only usable for 999c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman // synchonization, not device I/O or anything like that). This intrinsic 1000c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman // is really badly designed in the sense that in theory, there isn't 1001c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman // any way to safely use it... but in practice, it mostly works 1002c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman // to use it with non-atomic loads and stores to get acquire/release 1003c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman // semantics. 1004c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman Builder.CreateFence(llvm::SequentiallyConsistent); 1005eb4f81e174b11633f7b85f555ea5d2834d6dae8aDaniel Dunbar return RValue::get(0); 1006f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner } 10071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10082c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case Builtin::BI__c11_atomic_is_lock_free: 10092c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case Builtin::BI__atomic_is_lock_free: { 10102c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith // Call "bool __atomic_is_lock_free(size_t size, void *ptr)". For the 10112c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith // __c11 builtin, ptr is 0 (indicating a properly-aligned object), since 10122c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith // _Atomic(T) is always properly-aligned. 10132c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith const char *LibCallName = "__atomic_is_lock_free"; 10142c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith CallArgList Args; 10152c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Args.add(RValue::get(EmitScalarExpr(E->getArg(0))), 10162c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith getContext().getSizeType()); 10172c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith if (BuiltinID == Builtin::BI__atomic_is_lock_free) 10182c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Args.add(RValue::get(EmitScalarExpr(E->getArg(1))), 10192c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith getContext().VoidPtrTy); 10202c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith else 10212c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Args.add(RValue::get(llvm::Constant::getNullValue(VoidPtrTy)), 10222c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith getContext().VoidPtrTy); 10232c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith const CGFunctionInfo &FuncInfo = 10240f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall CGM.getTypes().arrangeFreeFunctionCall(E->getType(), Args, 10250f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall FunctionType::ExtInfo(), 10260f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall RequiredArgs::All); 10272c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo); 10282c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName); 10292c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith return EmitCall(FuncInfo, Func, ReturnValueSlot(), Args); 10302c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith } 10312c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 10322c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case Builtin::BI__atomic_test_and_set: { 10332c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith // Look at the argument type to determine whether this is a volatile 10342c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith // operation. The parameter type is always volatile. 10352c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType(); 10362c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith bool Volatile = 10372c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified(); 10382c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 10392c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Value *Ptr = EmitScalarExpr(E->getArg(0)); 10402c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith unsigned AddrSpace = 10412c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith cast<llvm::PointerType>(Ptr->getType())->getAddressSpace(); 10422c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Ptr = Builder.CreateBitCast(Ptr, Int8Ty->getPointerTo(AddrSpace)); 10432c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Value *NewVal = Builder.getInt8(1); 10442c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Value *Order = EmitScalarExpr(E->getArg(1)); 10452c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith if (isa<llvm::ConstantInt>(Order)) { 10462c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 10472c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith AtomicRMWInst *Result = 0; 10482c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith switch (ord) { 10492c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case 0: // memory_order_relaxed 10502c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith default: // invalid order 10512c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, 10522c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Ptr, NewVal, 10532c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::Monotonic); 10542c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith break; 10552c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case 1: // memory_order_consume 10562c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case 2: // memory_order_acquire 10572c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, 10582c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Ptr, NewVal, 10592c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::Acquire); 10602c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith break; 10612c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case 3: // memory_order_release 10622c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, 10632c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Ptr, NewVal, 10642c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::Release); 10652c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith break; 10662c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case 4: // memory_order_acq_rel 10672c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, 10682c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Ptr, NewVal, 10692c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::AcquireRelease); 10702c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith break; 10712c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case 5: // memory_order_seq_cst 10722c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, 10732c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Ptr, NewVal, 10742c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::SequentiallyConsistent); 10752c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith break; 10762c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith } 10772c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Result->setVolatile(Volatile); 10782c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith return RValue::get(Builder.CreateIsNotNull(Result, "tobool")); 10792c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith } 10802c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 10812c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 10822c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 10832c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::BasicBlock *BBs[5] = { 10842c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith createBasicBlock("monotonic", CurFn), 10852c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith createBasicBlock("acquire", CurFn), 10862c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith createBasicBlock("release", CurFn), 10872c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith createBasicBlock("acqrel", CurFn), 10882c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith createBasicBlock("seqcst", CurFn) 10892c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith }; 10902c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::AtomicOrdering Orders[5] = { 10912c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::Monotonic, llvm::Acquire, llvm::Release, 10922c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::AcquireRelease, llvm::SequentiallyConsistent 10932c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith }; 10942c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 10952c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 10962c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::SwitchInst *SI = Builder.CreateSwitch(Order, BBs[0]); 10972c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 10982c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Builder.SetInsertPoint(ContBB); 10992c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith PHINode *Result = Builder.CreatePHI(Int8Ty, 5, "was_set"); 11002c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11012c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith for (unsigned i = 0; i < 5; ++i) { 11022c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Builder.SetInsertPoint(BBs[i]); 11032c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith AtomicRMWInst *RMW = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, 11042c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Ptr, NewVal, Orders[i]); 11052c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith RMW->setVolatile(Volatile); 11062c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Result->addIncoming(RMW, BBs[i]); 11072c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Builder.CreateBr(ContBB); 11082c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith } 11092c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11102c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith SI->addCase(Builder.getInt32(0), BBs[0]); 11112c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith SI->addCase(Builder.getInt32(1), BBs[1]); 11122c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith SI->addCase(Builder.getInt32(2), BBs[1]); 11132c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith SI->addCase(Builder.getInt32(3), BBs[2]); 11142c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith SI->addCase(Builder.getInt32(4), BBs[3]); 11152c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith SI->addCase(Builder.getInt32(5), BBs[4]); 11162c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11172c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Builder.SetInsertPoint(ContBB); 11182c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith return RValue::get(Builder.CreateIsNotNull(Result, "tobool")); 11192c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith } 11202c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11212c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case Builtin::BI__atomic_clear: { 11222c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType(); 11232c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith bool Volatile = 11242c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified(); 11252c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11262c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Value *Ptr = EmitScalarExpr(E->getArg(0)); 11272c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith unsigned AddrSpace = 11282c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith cast<llvm::PointerType>(Ptr->getType())->getAddressSpace(); 11292c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Ptr = Builder.CreateBitCast(Ptr, Int8Ty->getPointerTo(AddrSpace)); 11302c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Value *NewVal = Builder.getInt8(0); 11312c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Value *Order = EmitScalarExpr(E->getArg(1)); 11322c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith if (isa<llvm::ConstantInt>(Order)) { 11332c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 11342c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith StoreInst *Store = Builder.CreateStore(NewVal, Ptr, Volatile); 11352c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Store->setAlignment(1); 11362c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith switch (ord) { 11372c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case 0: // memory_order_relaxed 11382c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith default: // invalid order 11392c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Store->setOrdering(llvm::Monotonic); 11402c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith break; 11412c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case 3: // memory_order_release 11422c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Store->setOrdering(llvm::Release); 11432c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith break; 11442c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case 5: // memory_order_seq_cst 11452c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Store->setOrdering(llvm::SequentiallyConsistent); 11462c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith break; 11472c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith } 11482c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith return RValue::get(0); 11492c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith } 11502c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11512c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 11522c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11532c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::BasicBlock *BBs[3] = { 11542c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith createBasicBlock("monotonic", CurFn), 11552c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith createBasicBlock("release", CurFn), 11562c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith createBasicBlock("seqcst", CurFn) 11572c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith }; 11582c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::AtomicOrdering Orders[3] = { 11592c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::Monotonic, llvm::Release, llvm::SequentiallyConsistent 11602c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith }; 11612c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11622c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 11632c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::SwitchInst *SI = Builder.CreateSwitch(Order, BBs[0]); 11642c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11652c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith for (unsigned i = 0; i < 3; ++i) { 11662c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Builder.SetInsertPoint(BBs[i]); 11672c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith StoreInst *Store = Builder.CreateStore(NewVal, Ptr, Volatile); 11682c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Store->setAlignment(1); 11692c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Store->setOrdering(Orders[i]); 11702c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Builder.CreateBr(ContBB); 11712c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith } 11722c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11732c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith SI->addCase(Builder.getInt32(0), BBs[0]); 11742c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith SI->addCase(Builder.getInt32(3), BBs[1]); 11752c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith SI->addCase(Builder.getInt32(5), BBs[2]); 11762c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11772c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Builder.SetInsertPoint(ContBB); 11782c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith return RValue::get(0); 11792c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith } 11802c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 1181276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman case Builtin::BI__atomic_thread_fence: 1182fafbf06732746f3ceca21d452d77b144ba8652aeRichard Smith case Builtin::BI__atomic_signal_fence: 1183fafbf06732746f3ceca21d452d77b144ba8652aeRichard Smith case Builtin::BI__c11_atomic_thread_fence: 1184fafbf06732746f3ceca21d452d77b144ba8652aeRichard Smith case Builtin::BI__c11_atomic_signal_fence: { 1185276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman llvm::SynchronizationScope Scope; 1186fafbf06732746f3ceca21d452d77b144ba8652aeRichard Smith if (BuiltinID == Builtin::BI__atomic_signal_fence || 1187fafbf06732746f3ceca21d452d77b144ba8652aeRichard Smith BuiltinID == Builtin::BI__c11_atomic_signal_fence) 1188276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Scope = llvm::SingleThread; 1189276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman else 1190276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Scope = llvm::CrossThread; 1191276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Value *Order = EmitScalarExpr(E->getArg(0)); 1192276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman if (isa<llvm::ConstantInt>(Order)) { 1193276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 1194276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman switch (ord) { 1195276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman case 0: // memory_order_relaxed 1196276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman default: // invalid order 1197276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman break; 1198276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman case 1: // memory_order_consume 1199276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman case 2: // memory_order_acquire 1200276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateFence(llvm::Acquire, Scope); 1201276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman break; 1202276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman case 3: // memory_order_release 1203276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateFence(llvm::Release, Scope); 1204276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman break; 1205276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman case 4: // memory_order_acq_rel 1206276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateFence(llvm::AcquireRelease, Scope); 1207276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman break; 1208276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman case 5: // memory_order_seq_cst 1209276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateFence(llvm::SequentiallyConsistent, Scope); 1210276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman break; 1211276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman } 1212276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman return RValue::get(0); 1213276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman } 1214276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman 1215276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman llvm::BasicBlock *AcquireBB, *ReleaseBB, *AcqRelBB, *SeqCstBB; 1216276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman AcquireBB = createBasicBlock("acquire", CurFn); 1217276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman ReleaseBB = createBasicBlock("release", CurFn); 1218276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman AcqRelBB = createBasicBlock("acqrel", CurFn); 1219276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman SeqCstBB = createBasicBlock("seqcst", CurFn); 1220276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 1221276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman 1222276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 1223276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman llvm::SwitchInst *SI = Builder.CreateSwitch(Order, ContBB); 1224276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman 1225276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.SetInsertPoint(AcquireBB); 1226276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateFence(llvm::Acquire, Scope); 1227276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateBr(ContBB); 1228276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman SI->addCase(Builder.getInt32(1), AcquireBB); 1229276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman SI->addCase(Builder.getInt32(2), AcquireBB); 1230276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman 1231276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.SetInsertPoint(ReleaseBB); 1232276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateFence(llvm::Release, Scope); 1233276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateBr(ContBB); 1234276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman SI->addCase(Builder.getInt32(3), ReleaseBB); 1235276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman 1236276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.SetInsertPoint(AcqRelBB); 1237276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateFence(llvm::AcquireRelease, Scope); 1238276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateBr(ContBB); 1239276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman SI->addCase(Builder.getInt32(4), AcqRelBB); 1240276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman 1241276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.SetInsertPoint(SeqCstBB); 1242276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateFence(llvm::SequentiallyConsistent, Scope); 1243276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateBr(ContBB); 1244276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman SI->addCase(Builder.getInt32(5), SeqCstBB); 1245276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman 1246276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.SetInsertPoint(ContBB); 1247276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman return RValue::get(0); 1248276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman } 1249276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman 1250ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar // Library functions with special handling. 1251ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIsqrt: 1252ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIsqrtf: 1253ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIsqrtl: { 1254beb41281f8355caa05700d0a77539defbdf428f8John McCall // TODO: there is currently no set of optimizer flags 1255beb41281f8355caa05700d0a77539defbdf428f8John McCall // sufficient for us to rewrite sqrt to @llvm.sqrt. 1256beb41281f8355caa05700d0a77539defbdf428f8John McCall // -fmath-errno=0 is not good enough; we need finiteness. 1257beb41281f8355caa05700d0a77539defbdf428f8John McCall // We could probably precondition the call with an ult 1258beb41281f8355caa05700d0a77539defbdf428f8John McCall // against 0, but is that worth the complexity? 1259beb41281f8355caa05700d0a77539defbdf428f8John McCall break; 1260ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar } 1261ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar 1262ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIpow: 1263ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIpowf: 1264ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIpowl: { 1265ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar // Rewrite sqrt to intrinsic if allowed. 126640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis if (!FD->hasAttr<ConstAttr>()) 1267ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar break; 1268ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar Value *Base = EmitScalarExpr(E->getArg(0)); 1269ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar Value *Exponent = EmitScalarExpr(E->getArg(1)); 12709cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ArgType = Base->getType(); 12718dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::pow, ArgType); 1272578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return RValue::get(Builder.CreateCall2(F, Base, Exponent)); 1273ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar } 1274ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman 1275094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BIfma: 1276094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BIfmaf: 1277094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BIfmal: 1278094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BI__builtin_fma: 1279094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BI__builtin_fmaf: 1280094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BI__builtin_fmal: { 1281094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich // Rewrite fma to intrinsic. 1282094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich Value *FirstArg = EmitScalarExpr(E->getArg(0)); 12839cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ArgType = FirstArg->getType(); 12848dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::fma, ArgType); 1285094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich return RValue::get(Builder.CreateCall3(F, FirstArg, 1286094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich EmitScalarExpr(E->getArg(1)), 1287578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer EmitScalarExpr(E->getArg(2)))); 1288094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich } 1289094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich 1290ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman case Builtin::BI__builtin_signbit: 1291ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman case Builtin::BI__builtin_signbitf: 1292ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman case Builtin::BI__builtin_signbitl: { 1293ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman LLVMContext &C = CGM.getLLVMContext(); 1294ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman 1295ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *Arg = EmitScalarExpr(E->getArg(0)); 12962acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ArgTy = Arg->getType(); 1297ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman if (ArgTy->isPPC_FP128Ty()) 1298ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman break; // FIXME: I'm not sure what the right implementation is here. 1299ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman int ArgWidth = ArgTy->getPrimitiveSizeInBits(); 13002acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ArgIntTy = llvm::IntegerType::get(C, ArgWidth); 1301ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *BCArg = Builder.CreateBitCast(Arg, ArgIntTy); 1302ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *ZeroCmp = llvm::Constant::getNullValue(ArgIntTy); 1303ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *Result = Builder.CreateICmpSLT(BCArg, ZeroCmp); 1304ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman return RValue::get(Builder.CreateZExt(Result, ConvertType(E->getType()))); 1305ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman } 130677f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge case Builtin::BI__builtin_annotation: { 130777f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge llvm::Value *AnnVal = EmitScalarExpr(E->getArg(0)); 130877f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::annotation, 130977f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge AnnVal->getType()); 131077f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge 131177f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge // Get the annotation string, go through casts. Sema requires this to be a 131277f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge // non-wide string literal, potentially casted, so the cast<> is safe. 131377f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge const Expr *AnnotationStrExpr = E->getArg(1)->IgnoreParenCasts(); 131477f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge llvm::StringRef Str = cast<StringLiteral>(AnnotationStrExpr)->getString(); 131577f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge return RValue::get(EmitAnnotationCall(F, AnnVal, Str, E->getExprLoc())); 131677f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge } 13177ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman } 13181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1319a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // If this is an alias for a lib function (e.g. __builtin_sin), emit 1320a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // the call using the normal call path, but using the unmangled 1321a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // version of the function name. 1322a45680b7e7c49ea9893c6cff585984f3e4120366John McCall if (getContext().BuiltinInfo.isLibFunction(BuiltinID)) 1323a45680b7e7c49ea9893c6cff585984f3e4120366John McCall return emitLibraryCall(*this, FD, E, 1324a45680b7e7c49ea9893c6cff585984f3e4120366John McCall CGM.getBuiltinLibFunction(FD, BuiltinID)); 1325a45680b7e7c49ea9893c6cff585984f3e4120366John McCall 1326a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // If this is a predefined lib function (e.g. malloc), emit the call 1327a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // using exactly the normal call path. 1328a45680b7e7c49ea9893c6cff585984f3e4120366John McCall if (getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID)) 1329a45680b7e7c49ea9893c6cff585984f3e4120366John McCall return emitLibraryCall(*this, FD, E, EmitScalarExpr(E->getCallee())); 13301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1331b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // See if we have a target specific intrinsic. 1332a6f80ef997f0363386749087b325607eaa5adcfcDale Johannesen const char *Name = getContext().BuiltinInfo.GetName(BuiltinID); 133355cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic; 133455cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar if (const char *Prefix = 13351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Triple::getArchTypePrefix(Target.getTriple().getArch())) 133655cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix, Name); 13371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1338b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (IntrinsicID != Intrinsic::not_intrinsic) { 1339b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner SmallVector<Value*, 16> Args; 13401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 134146c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // Find out if any arguments are required to be integer constant 134246c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // expressions. 134346c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner unsigned ICEArguments = 0; 134446c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner ASTContext::GetBuiltinTypeError Error; 134546c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 134646c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner assert(Error == ASTContext::GE_None && "Should not codegen an error"); 134746c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner 1348b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner Function *F = CGM.getIntrinsic(IntrinsicID); 13492acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = F->getFunctionType(); 13501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1351b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 135246c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner Value *ArgValue; 135346c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // If this is a normal argument, just emit it as a scalar. 135446c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner if ((ICEArguments & (1 << i)) == 0) { 135546c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner ArgValue = EmitScalarExpr(E->getArg(i)); 135646c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner } else { 135746c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // If this is required to be a constant, constant fold it so that we 135846c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // know that the generated intrinsic gets a ConstantInt. 135946c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner llvm::APSInt Result; 136046c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result,getContext()); 136146c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner assert(IsConst && "Constant arg isn't actually constant?"); 136246c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner (void)IsConst; 1363d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall ArgValue = llvm::ConstantInt::get(getLLVMContext(), Result); 136446c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner } 13651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1366b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // If the intrinsic arg type is different from the builtin arg type 1367b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // we need to do a bit cast. 13682acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PTy = FTy->getParamType(i); 1369b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (PTy != ArgValue->getType()) { 1370b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) && 1371b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner "Must be able to losslessly bit cast to param"); 1372b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner ArgValue = Builder.CreateBitCast(ArgValue, PTy); 1373b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 13741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1375b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner Args.push_back(ArgValue); 1376b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 13771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13784c7d9f1507d0f102bd4133bba63348636facd469Jay Foad Value *V = Builder.CreateCall(F, Args); 1379b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner QualType BuiltinRetType = E->getType(); 13801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13818b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner llvm::Type *RetTy = VoidTy; 13828b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner if (!BuiltinRetType->isVoidType()) 13838b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner RetTy = ConvertType(BuiltinRetType); 13841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1385b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (RetTy != V->getType()) { 1386b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner assert(V->getType()->canLosslesslyBitCastTo(RetTy) && 1387b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner "Must be able to losslessly bit cast result type"); 1388b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner V = Builder.CreateBitCast(V, RetTy); 1389b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 13901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1391b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner return RValue::get(V); 1392b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 13931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1394b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // See if we have a target specific builtin that needs to be lowered. 1395f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E)) 1396b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner return RValue::get(V); 13971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1398488e993a135ce700b982bf099c3d6b856301d642Daniel Dunbar ErrorUnsupported(E, "builtin function"); 13991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1400b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // Unknown builtin, for now just dump it out and return undef. 1401b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (hasAggregateLLVMType(E->getType())) 1402195337d2e5d4625ae9dc1328c7cdbc7115b0261bDaniel Dunbar return RValue::getAggregate(CreateMemTemp(E->getType())); 140303e205031b08669f05c41eed5b896fc94c4a12bbOwen Anderson return RValue::get(llvm::UndefValue::get(ConvertType(E->getType()))); 14041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 1405564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson 1406f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel DunbarValue *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, 1407f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar const CallExpr *E) { 140855cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar switch (Target.getTriple().getArch()) { 14092752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner case llvm::Triple::arm: 14102752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner case llvm::Triple::thumb: 14112752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner return EmitARMBuiltinExpr(BuiltinID, E); 141255cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::x86: 141355cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::x86_64: 1414f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar return EmitX86BuiltinExpr(BuiltinID, E); 141555cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::ppc: 141655cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::ppc64: 1417f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar return EmitPPCBuiltinExpr(BuiltinID, E); 141855cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar default: 141955cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar return 0; 142055cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar } 1421f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar} 1422f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar 14238b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattnerstatic llvm::VectorType *GetNeonType(CodeGenFunction *CGF, 14248b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner NeonTypeFlags TypeFlags) { 142583084c863572b48579767a4dd5dc686e1a8d669dNAKAMURA Takumi int IsQuad = TypeFlags.isQuad(); 142683084c863572b48579767a4dd5dc686e1a8d669dNAKAMURA Takumi switch (TypeFlags.getEltType()) { 1427da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Int8: 1428da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Poly8: 14298b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner return llvm::VectorType::get(CGF->Int8Ty, 8 << IsQuad); 1430da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Int16: 1431da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Poly16: 1432da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Float16: 14338b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner return llvm::VectorType::get(CGF->Int16Ty, 4 << IsQuad); 1434da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Int32: 14358b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner return llvm::VectorType::get(CGF->Int32Ty, 2 << IsQuad); 1436da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Int64: 14378b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner return llvm::VectorType::get(CGF->Int64Ty, 1 << IsQuad); 1438da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Float32: 14398b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner return llvm::VectorType::get(CGF->FloatTy, 2 << IsQuad); 1440561d3abc881033776ece385a01a510e1cbc1fa92David Blaikie } 1441561d3abc881033776ece385a01a510e1cbc1fa92David Blaikie llvm_unreachable("Invalid NeonTypeFlags element type!"); 1442998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman} 1443998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman 1444cf55652cf668c1402eee0b12edd2e5a1bc34d7a1Bob WilsonValue *CodeGenFunction::EmitNeonSplat(Value *V, Constant *C) { 1445d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman unsigned nElts = cast<llvm::VectorType>(V->getType())->getNumElements(); 14462ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner Value* SV = llvm::ConstantVector::getSplat(nElts, C); 1447d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman return Builder.CreateShuffleVector(V, V, SV, "lane"); 1448d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman} 1449d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman 145030d91718a676177f0d0d0210ce4fdb4f616df6e5Nate BegemanValue *CodeGenFunction::EmitNeonCall(Function *F, SmallVectorImpl<Value*> &Ops, 1451db3d4d036037f379f12643e067b229862d61e932Bob Wilson const char *name, 145261eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman unsigned shift, bool rightshift) { 145330d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman unsigned j = 0; 145430d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end(); 145530d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman ai != ae; ++ai, ++j) 145661eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman if (shift > 0 && shift == j) 145761eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[j] = EmitNeonShiftVector(Ops[j], ai->getType(), rightshift); 145861eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman else 145961eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[j] = Builder.CreateBitCast(Ops[j], ai->getType(), name); 146030d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman 14614c7d9f1507d0f102bd4133bba63348636facd469Jay Foad return Builder.CreateCall(F, Ops, name); 146230d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman} 146330d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman 14642acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris LattnerValue *CodeGenFunction::EmitNeonShiftVector(Value *V, llvm::Type *Ty, 1465464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman bool neg) { 14662ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner int SV = cast<ConstantInt>(V)->getSExtValue(); 1467464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman 14682acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 1469464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman llvm::Constant *C = ConstantInt::get(VTy->getElementType(), neg ? -SV : SV); 14702ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner return llvm::ConstantVector::getSplat(VTy->getNumElements(), C); 1471464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman} 1472464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman 147306b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson/// GetPointeeAlignment - Given an expression with a pointer type, find the 147406b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson/// alignment of the type referenced by the pointer. Skip over implicit 147506b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson/// casts. 1476ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedmanstd::pair<llvm::Value*, unsigned> 1477ea93e40785ffeadfac66b948c95f9490ec26207aEli FriedmanCodeGenFunction::EmitPointerWithAlignment(const Expr *Addr) { 1478ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman assert(Addr->getType()->isPointerType()); 1479ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Addr = Addr->IgnoreParens(); 1480ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Addr)) { 1481ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (ICE->getCastKind() == CK_BitCast || ICE->getCastKind() == CK_NoOp) { 1482ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Ptr = 1483ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(ICE->getSubExpr()); 1484ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ptr.first = Builder.CreateBitCast(Ptr.first, 1485ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman ConvertType(Addr->getType())); 1486ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return Ptr; 1487ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } else if (ICE->getCastKind() == CK_ArrayToPointerDecay) { 1488ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman LValue LV = EmitLValue(ICE->getSubExpr()); 1489ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return std::make_pair(LV.getAddress(), LV.getAlignment().getQuantity()); 1490d6e73569ccf09369f9bd2021d53c88e7bded06e3Chris Lattner } 1491ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 1492ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(Addr)) { 1493ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (UO->getOpcode() == UO_AddrOf) { 1494ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman LValue LV = EmitLValue(UO->getSubExpr()); 1495ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return std::make_pair(LV.getAddress(), LV.getAlignment().getQuantity()); 149606b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson } 149706b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson } 1498f4c3db175101cbf94dad59419c3ed7aed51bf606Jay Foad 1499ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman unsigned Align = 1; 1500ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman QualType PtTy = Addr->getType()->getPointeeType(); 1501ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (!PtTy->isIncompleteType()) 1502ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Align = getContext().getTypeAlignInChars(PtTy).getQuantity(); 1503ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman 1504ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return std::make_pair(EmitScalarExpr(Addr), Align); 150506b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson} 150606b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson 15072752c0137d95aa2f4ee1cdff4b564bac842e041bChris LattnerValue *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, 15082752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner const CallExpr *E) { 1509e140af3e27016f902146023fba7680b43043ec07Rafael Espindola if (BuiltinID == ARM::BI__clear_cache) { 151079ba509b0106fd0a1ff832baeb1fdb5430527efeRafael Espindola const FunctionDecl *FD = E->getDirectCallee(); 15118a37c79f03e62aecfa2c58b9179f90dd1fcdb253Eric Christopher // Oddly people write this call without args on occasion and gcc accepts 15128a37c79f03e62aecfa2c58b9179f90dd1fcdb253Eric Christopher // it - it's also marked as varargs in the description file. 15135f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Value*, 2> Ops; 15148a37c79f03e62aecfa2c58b9179f90dd1fcdb253Eric Christopher for (unsigned i = 0; i < E->getNumArgs(); i++) 15158a37c79f03e62aecfa2c58b9179f90dd1fcdb253Eric Christopher Ops.push_back(EmitScalarExpr(E->getArg(i))); 15162acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); 15172acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); 15185f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Name = FD->getName(); 15194c7d9f1507d0f102bd4133bba63348636facd469Jay Foad return Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); 15202752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner } 1521e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 152226c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes if (BuiltinID == ARM::BI__builtin_arm_ldrexd) { 152326c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Function *F = CGM.getIntrinsic(Intrinsic::arm_ldrexd); 152426c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 152526c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *LdPtr = EmitScalarExpr(E->getArg(0)); 152626c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *Val = Builder.CreateCall(F, LdPtr, "ldrexd"); 152726c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 152826c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *Val0 = Builder.CreateExtractValue(Val, 1); 152926c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *Val1 = Builder.CreateExtractValue(Val, 0); 153026c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Val0 = Builder.CreateZExt(Val0, Int64Ty); 153126c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Val1 = Builder.CreateZExt(Val1, Int64Ty); 153226c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 153326c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *ShiftCst = llvm::ConstantInt::get(Int64Ty, 32); 153426c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */); 153526c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes return Builder.CreateOr(Val, Val1); 153626c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes } 153726c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 153826c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes if (BuiltinID == ARM::BI__builtin_arm_strexd) { 153926c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Function *F = CGM.getIntrinsic(Intrinsic::arm_strexd); 15407650d95a1a616ea300f37126a8dfc93dc19a662aChris Lattner llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, NULL); 154126c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 154226c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *One = llvm::ConstantInt::get(Int32Ty, 1); 1543578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Value *Tmp = Builder.CreateAlloca(Int64Ty, One); 154426c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *Val = EmitScalarExpr(E->getArg(0)); 154526c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Builder.CreateStore(Val, Tmp); 154626c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 154726c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *LdPtr = Builder.CreateBitCast(Tmp,llvm::PointerType::getUnqual(STy)); 154826c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Val = Builder.CreateLoad(LdPtr); 154926c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 155026c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *Arg0 = Builder.CreateExtractValue(Val, 0); 155126c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *Arg1 = Builder.CreateExtractValue(Val, 1); 155226c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *StPtr = EmitScalarExpr(E->getArg(1)); 155326c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes return Builder.CreateCall3(F, Arg0, Arg1, StPtr, "strexd"); 155426c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes } 155526c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 15565f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Value*, 4> Ops; 1557ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman llvm::Value *Align = 0; 1558ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) { 1559ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (i == 0) { 1560ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman switch (BuiltinID) { 1561ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1_v: 1562ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1q_v: 1563ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1q_lane_v: 1564ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1_lane_v: 1565ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1_dup_v: 1566ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1q_dup_v: 1567ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst1_v: 1568ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst1q_v: 1569ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst1q_lane_v: 1570ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst1_lane_v: 1571ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst2_v: 1572ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst2q_v: 1573ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst2_lane_v: 1574ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst2q_lane_v: 1575ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst3_v: 1576ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst3q_v: 1577ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst3_lane_v: 1578ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst3q_lane_v: 1579ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst4_v: 1580ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst4q_v: 1581ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst4_lane_v: 1582ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst4q_lane_v: 1583ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman // Get the alignment for the argument in addition to the value; 1584ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman // we'll use it later. 1585ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Src = 1586ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(0)); 1587ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Src.first); 1588ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Align = Builder.getInt32(Src.second); 1589ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman continue; 1590ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 1591ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 1592ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (i == 1) { 1593ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman switch (BuiltinID) { 1594ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld2_v: 1595ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld2q_v: 1596ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld3_v: 1597ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld3q_v: 1598ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld4_v: 1599ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld4q_v: 1600ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld2_lane_v: 1601ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld2q_lane_v: 1602ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld3_lane_v: 1603ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld3q_lane_v: 1604ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld4_lane_v: 1605ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld4q_lane_v: 1606ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld2_dup_v: 1607ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld3_dup_v: 1608ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld4_dup_v: 1609ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman // Get the alignment for the argument in addition to the value; 1610ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman // we'll use it later. 1611ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Src = 1612ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(1)); 1613ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Src.first); 1614ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Align = Builder.getInt32(Src.second); 1615ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman continue; 1616ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 1617ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 1618e140af3e27016f902146023fba7680b43043ec07Rafael Espindola Ops.push_back(EmitScalarExpr(E->getArg(i))); 1619ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 1620e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 162183bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson // vget_lane and vset_lane are not overloaded and do not have an extra 162283bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson // argument that specifies the vector type. 162383bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson switch (BuiltinID) { 162483bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson default: break; 162583bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vget_lane_i8: 162683bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vget_lane_i16: 162783bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vget_lane_i32: 162883bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vget_lane_i64: 162983bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vget_lane_f32: 163083bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vgetq_lane_i8: 163183bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vgetq_lane_i16: 163283bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vgetq_lane_i32: 163383bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vgetq_lane_i64: 163483bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vgetq_lane_f32: 163583bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 163683bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson "vget_lane"); 163783bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vset_lane_i8: 163883bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vset_lane_i16: 163983bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vset_lane_i32: 164083bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vset_lane_i64: 164183bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vset_lane_f32: 164283bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vsetq_lane_i8: 164383bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vsetq_lane_i16: 164483bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vsetq_lane_i32: 164583bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vsetq_lane_i64: 164683bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vsetq_lane_f32: 164783bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson Ops.push_back(EmitScalarExpr(E->getArg(2))); 164883bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 164983bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson } 165083bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson 165183bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson // Get the last argument, which specifies the vector type. 1652e140af3e27016f902146023fba7680b43043ec07Rafael Espindola llvm::APSInt Result; 1653e140af3e27016f902146023fba7680b43043ec07Rafael Espindola const Expr *Arg = E->getArg(E->getNumArgs()-1); 1654e140af3e27016f902146023fba7680b43043ec07Rafael Espindola if (!Arg->isIntegerConstantExpr(Result, getContext())) 1655e140af3e27016f902146023fba7680b43043ec07Rafael Espindola return 0; 1656e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 165799c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f || 165899c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman BuiltinID == ARM::BI__builtin_arm_vcvtr_d) { 165999c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman // Determine the overloaded type of this builtin. 16609cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *Ty; 166199c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f) 16628b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner Ty = FloatTy; 166399c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman else 16648b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner Ty = DoubleTy; 166599c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman 166699c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman // Determine whether this is an unsigned conversion or not. 166799c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman bool usgn = Result.getZExtValue() == 1; 166899c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman unsigned Int = usgn ? Intrinsic::arm_vcvtru : Intrinsic::arm_vcvtr; 166999c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman 167099c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman // Call the appropriate intrinsic. 16718dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Int, Ty); 16724c7d9f1507d0f102bd4133bba63348636facd469Jay Foad return Builder.CreateCall(F, Ops, "vcvtr"); 167399c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman } 167499c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman 167599c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman // Determine the type of this overloaded NEON intrinsic. 1676da95f73b59f9af964e33725c515139d34c90c863Bob Wilson NeonTypeFlags Type(Result.getZExtValue()); 1677da95f73b59f9af964e33725c515139d34c90c863Bob Wilson bool usgn = Type.isUnsigned(); 1678da95f73b59f9af964e33725c515139d34c90c863Bob Wilson bool quad = Type.isQuad(); 16797965396d8d6ac23ec4c4f9d01d216f2e73d7fc72Bob Wilson bool rightShift = false; 1680e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 16818b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner llvm::VectorType *VTy = GetNeonType(this, Type); 16829cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *Ty = VTy; 1683e140af3e27016f902146023fba7680b43043ec07Rafael Espindola if (!Ty) 1684e140af3e27016f902146023fba7680b43043ec07Rafael Espindola return 0; 1685e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 1686e140af3e27016f902146023fba7680b43043ec07Rafael Espindola unsigned Int; 1687e140af3e27016f902146023fba7680b43043ec07Rafael Espindola switch (BuiltinID) { 1688e140af3e27016f902146023fba7680b43043ec07Rafael Espindola default: return 0; 1689537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vabd_v: 1690537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vabdq_v: 1691998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman Int = usgn ? Intrinsic::arm_neon_vabdu : Intrinsic::arm_neon_vabds; 16928dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vabd"); 1693537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vabs_v: 1694537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vabsq_v: 16958dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vabs, Ty), 1696548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vabs"); 1697537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vaddhn_v: 16988dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vaddhn, Ty), 1699548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vaddhn"); 1700537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcale_v: 17019eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman std::swap(Ops[0], Ops[1]); 1702537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcage_v: { 1703d185035263b98cdde75a869b26b5e5e2e6b13fdfBob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacged); 170430d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcage"); 170530d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 1706537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcaleq_v: 17079eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman std::swap(Ops[0], Ops[1]); 1708537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcageq_v: { 1709d185035263b98cdde75a869b26b5e5e2e6b13fdfBob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgeq); 171030d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcage"); 171130d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 1712537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcalt_v: 17139eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman std::swap(Ops[0], Ops[1]); 1714537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcagt_v: { 1715d185035263b98cdde75a869b26b5e5e2e6b13fdfBob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgtd); 171630d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcagt"); 171730d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 1718537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcaltq_v: 17199eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman std::swap(Ops[0], Ops[1]); 1720537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcagtq_v: { 1721d185035263b98cdde75a869b26b5e5e2e6b13fdfBob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgtq); 172230d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcagt"); 172330d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 1724537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcls_v: 1725537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vclsq_v: { 17268dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcls, Ty); 172730d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcls"); 17289eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 1729537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vclz_v: 1730537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vclzq_v: { 173171bcc68ba44a87a516d84461bc68475e43134338Eric Christopher // Generate target-independent intrinsic; also need to add second argument 173287d747b1fbf89aa0ba08cfc0e26655aa7739c77dJoel Jones // for whether or not clz of zero is undefined; on ARM it isn't. 173387d747b1fbf89aa0ba08cfc0e26655aa7739c77dJoel Jones Function *F = CGM.getIntrinsic(Intrinsic::ctlz, Ty); 173487d747b1fbf89aa0ba08cfc0e26655aa7739c77dJoel Jones Ops.push_back(Builder.getInt1(Target.isCLZForZeroUndef())); 173530d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vclz"); 17369eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 1737537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcnt_v: 1738537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcntq_v: { 17391638f2e8263df93b9fa055a12cc3f0968b9682d8Joel Jones // generate target-independent intrinsic 17401638f2e8263df93b9fa055a12cc3f0968b9682d8Joel Jones Function *F = CGM.getIntrinsic(Intrinsic::ctpop, Ty); 17411638f2e8263df93b9fa055a12cc3f0968b9682d8Joel Jones return EmitNeonCall(F, Ops, "vctpop"); 17429eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 1743537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_f16_v: { 1744da95f73b59f9af964e33725c515139d34c90c863Bob Wilson assert(Type.getEltType() == NeonTypeFlags::Float16 && !quad && 1745da95f73b59f9af964e33725c515139d34c90c863Bob Wilson "unexpected vcvt_f16_v builtin"); 174646e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcvtfp2hf); 174746e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson return EmitNeonCall(F, Ops, "vcvt"); 174846e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson } 1749537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_f32_f16: { 1750da95f73b59f9af964e33725c515139d34c90c863Bob Wilson assert(Type.getEltType() == NeonTypeFlags::Float16 && !quad && 1751da95f73b59f9af964e33725c515139d34c90c863Bob Wilson "unexpected vcvt_f32_f16 builtin"); 175246e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcvthf2fp); 175346e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson return EmitNeonCall(F, Ops, "vcvt"); 175446e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson } 1755537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_f32_v: 1756da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case ARM::BI__builtin_neon_vcvtq_f32_v: 175730d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 17588b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, quad)); 17599eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") 17609eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); 1761537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_s32_v: 1762537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_u32_v: 1763537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvtq_s32_v: 1764537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvtq_u32_v: { 1765da95f73b59f9af964e33725c515139d34c90c863Bob Wilson llvm::Type *FloatTy = 17668b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, quad)); 1767da95f73b59f9af964e33725c515139d34c90c863Bob Wilson Ops[0] = Builder.CreateBitCast(Ops[0], FloatTy); 17689eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman return usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt") 17699eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman : Builder.CreateFPToSI(Ops[0], Ty, "vcvt"); 17709eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 1771537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_n_f32_v: 1772537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvtq_n_f32_v: { 1773da95f73b59f9af964e33725c515139d34c90c863Bob Wilson llvm::Type *FloatTy = 17748b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, quad)); 1775da95f73b59f9af964e33725c515139d34c90c863Bob Wilson llvm::Type *Tys[2] = { FloatTy, Ty }; 1776da95f73b59f9af964e33725c515139d34c90c863Bob Wilson Int = usgn ? Intrinsic::arm_neon_vcvtfxu2fp 1777da95f73b59f9af964e33725c515139d34c90c863Bob Wilson : Intrinsic::arm_neon_vcvtfxs2fp; 17788dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Int, Tys); 177930d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcvt_n"); 17809eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 1781537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_n_s32_v: 1782537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_n_u32_v: 1783537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvtq_n_s32_v: 1784537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvtq_n_u32_v: { 1785da95f73b59f9af964e33725c515139d34c90c863Bob Wilson llvm::Type *FloatTy = 17868b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, quad)); 1787da95f73b59f9af964e33725c515139d34c90c863Bob Wilson llvm::Type *Tys[2] = { Ty, FloatTy }; 1788da95f73b59f9af964e33725c515139d34c90c863Bob Wilson Int = usgn ? Intrinsic::arm_neon_vcvtfp2fxu 1789da95f73b59f9af964e33725c515139d34c90c863Bob Wilson : Intrinsic::arm_neon_vcvtfp2fxs; 17908dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Int, Tys); 179130d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcvt_n"); 179230d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 1793537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vext_v: 1794537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vextq_v: { 1795fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner int CV = cast<ConstantInt>(Ops[2])->getSExtValue(); 17961c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman SmallVector<Constant*, 16> Indices; 17974be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 179877b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Indices.push_back(ConstantInt::get(Int32Ty, i+CV)); 179930d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman 180030d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 180130d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 1802fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner Value *SV = llvm::ConstantVector::get(Indices); 18031c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return Builder.CreateShuffleVector(Ops[0], Ops[1], SV, "vext"); 18041c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 1805537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vhadd_v: 1806537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vhaddq_v: 1807df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vhaddu : Intrinsic::arm_neon_vhadds; 18088dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vhadd"); 1809537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vhsub_v: 1810537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vhsubq_v: 1811df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vhsubu : Intrinsic::arm_neon_vhsubs; 18128dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vhsub"); 1813537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld1_v: 1814537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld1q_v: 1815ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 18168dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Ty), 18174be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops, "vld1"); 1818550a9d823a939366a9f776b58f18883acd905a93Bob Wilson case ARM::BI__builtin_neon_vld1q_lane_v: 1819550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // Handle 64-bit integer elements as a special case. Use shuffles of 1820550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // one-element vectors to avoid poor code for i64 in the backend. 1821550a9d823a939366a9f776b58f18883acd905a93Bob Wilson if (VTy->getElementType()->isIntegerTy(64)) { 1822550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // Extract the other lane. 1823550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 1824550a9d823a939366a9f776b58f18883acd905a93Bob Wilson int Lane = cast<ConstantInt>(Ops[2])->getZExtValue(); 1825550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Value *SV = llvm::ConstantVector::get(ConstantInt::get(Int32Ty, 1-Lane)); 1826550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); 1827550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // Load the value as a one-element vector. 1828550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ty = llvm::VectorType::get(VTy->getElementType(), 1); 1829550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Ty); 1830ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Value *Ld = Builder.CreateCall2(F, Ops[0], Align); 1831550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // Combine them. 1832550a9d823a939366a9f776b58f18883acd905a93Bob Wilson SmallVector<Constant*, 2> Indices; 1833550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Indices.push_back(ConstantInt::get(Int32Ty, 1-Lane)); 1834550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Indices.push_back(ConstantInt::get(Int32Ty, Lane)); 1835550a9d823a939366a9f776b58f18883acd905a93Bob Wilson SV = llvm::ConstantVector::get(Indices); 1836550a9d823a939366a9f776b58f18883acd905a93Bob Wilson return Builder.CreateShuffleVector(Ops[1], Ld, SV, "vld1q_lane"); 1837550a9d823a939366a9f776b58f18883acd905a93Bob Wilson } 1838550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // fall through 1839550a9d823a939366a9f776b58f18883acd905a93Bob Wilson case ARM::BI__builtin_neon_vld1_lane_v: { 18404be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 18414be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 18424be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 1843eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson LoadInst *Ld = Builder.CreateLoad(Ops[0]); 1844eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); 1845eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson return Builder.CreateInsertElement(Ops[1], Ld, Ops[2], "vld1_lane"); 1846eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson } 1847537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld1_dup_v: 1848537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld1q_dup_v: { 18494be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *V = UndefValue::get(Ty); 18504be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 18514be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 1852eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson LoadInst *Ld = Builder.CreateLoad(Ops[0]); 1853eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); 185477b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 1855eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson Ops[0] = Builder.CreateInsertElement(V, Ld, CI); 18564be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return EmitNeonSplat(Ops[0], CI); 18574be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 1858537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld2_v: 1859537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld2q_v: { 18608dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld2, Ty); 186106b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld2"); 18624be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 18634be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 18644be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 18654be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 1866537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3_v: 1867537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3q_v: { 18688dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld3, Ty); 186906b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld3"); 18704be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 18714be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 18724be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 18734be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 1874537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4_v: 1875537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4q_v: { 18768dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld4, Ty); 187706b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld4"); 18784be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 18794be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 18804be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 18814be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 1882537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld2_lane_v: 1883537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld2q_lane_v: { 18848dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld2lane, Ty); 18854be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 18864be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 1887ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 18881cbac8ac446cf513dbc7486dd50abd55bcfc62c6Frits van Bommel Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld2_lane"); 18894be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 18904be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 18914be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 18924be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 1893537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3_lane_v: 1894537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3q_lane_v: { 18958dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld3lane, Ty); 18964be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 18974be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 18984be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[4] = Builder.CreateBitCast(Ops[4], Ty); 1899ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 19001cbac8ac446cf513dbc7486dd50abd55bcfc62c6Frits van Bommel Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld3_lane"); 19014be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 19024be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 19034be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 19044be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 1905537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4_lane_v: 1906537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4q_lane_v: { 19078dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld4lane, Ty); 19084be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 19094be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 19104be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[4] = Builder.CreateBitCast(Ops[4], Ty); 19114be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[5] = Builder.CreateBitCast(Ops[5], Ty); 1912ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 19131cbac8ac446cf513dbc7486dd50abd55bcfc62c6Frits van Bommel Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld3_lane"); 19144be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 19154be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 19164be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 19174be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 1918537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld2_dup_v: 1919537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3_dup_v: 1920537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4_dup_v: { 1921a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson // Handle 64-bit elements as a special-case. There is no "dup" needed. 1922a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson if (VTy->getElementType()->getPrimitiveSizeInBits() == 64) { 1923a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson switch (BuiltinID) { 1924537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld2_dup_v: 1925a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson Int = Intrinsic::arm_neon_vld2; 1926a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson break; 1927537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3_dup_v: 1928bd86ad5c1a4ce7cd05f0370921b31a2eabf19f8fJames Molloy Int = Intrinsic::arm_neon_vld3; 1929a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson break; 1930537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4_dup_v: 1931bd86ad5c1a4ce7cd05f0370921b31a2eabf19f8fJames Molloy Int = Intrinsic::arm_neon_vld4; 1932a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson break; 1933b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("unknown vld_dup intrinsic?"); 1934a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson } 19358dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Int, Ty); 1936a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld_dup"); 1937a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 1938a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 1939a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson return Builder.CreateStore(Ops[1], Ops[0]); 1940a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson } 19414be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman switch (BuiltinID) { 1942537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld2_dup_v: 19434be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Int = Intrinsic::arm_neon_vld2lane; 19444be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman break; 1945537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3_dup_v: 1946bd86ad5c1a4ce7cd05f0370921b31a2eabf19f8fJames Molloy Int = Intrinsic::arm_neon_vld3lane; 19474be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman break; 1948537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4_dup_v: 1949bd86ad5c1a4ce7cd05f0370921b31a2eabf19f8fJames Molloy Int = Intrinsic::arm_neon_vld4lane; 19504be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman break; 1951b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("unknown vld_dup intrinsic?"); 19524be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 19538dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Int, Ty); 19542acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::StructType *STy = cast<llvm::StructType>(F->getReturnType()); 19554be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 19564be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SmallVector<Value*, 6> Args; 19574be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Args.push_back(Ops[1]); 19584be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Args.append(STy->getNumElements(), UndefValue::get(Ty)); 19594be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 196077b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 19614be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Args.push_back(CI); 1962ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Args.push_back(Align); 19634be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 19644c7d9f1507d0f102bd4133bba63348636facd469Jay Foad Ops[1] = Builder.CreateCall(F, Args, "vld_dup"); 19654be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman // splat lane 0 to all elts in each vector of the result. 19664be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { 19674be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Val = Builder.CreateExtractValue(Ops[1], i); 19684be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Elt = Builder.CreateBitCast(Val, Ty); 19694be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Elt = EmitNeonSplat(Elt, CI); 19704be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Elt = Builder.CreateBitCast(Elt, Val->getType()); 19714be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[1] = Builder.CreateInsertValue(Ops[1], Elt, i); 19724be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 19734be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 19744be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 19754be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 19764be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 1977537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmax_v: 1978537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmaxq_v: 1979df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vmaxu : Intrinsic::arm_neon_vmaxs; 19808dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmax"); 1981537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmin_v: 1982537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vminq_v: 1983df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vminu : Intrinsic::arm_neon_vmins; 19848dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmin"); 1985537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmovl_v: { 19862acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *DTy =llvm::VectorType::getTruncatedElementVectorType(VTy); 19872235941293353325835d182da4470f61828fe789Bob Wilson Ops[0] = Builder.CreateBitCast(Ops[0], DTy); 19887cea322bf019b0d38867a27e20e3771d84dbb1afBob Wilson if (usgn) 19897cea322bf019b0d38867a27e20e3771d84dbb1afBob Wilson return Builder.CreateZExt(Ops[0], Ty, "vmovl"); 19907cea322bf019b0d38867a27e20e3771d84dbb1afBob Wilson return Builder.CreateSExt(Ops[0], Ty, "vmovl"); 19912235941293353325835d182da4470f61828fe789Bob Wilson } 1992537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmovn_v: { 19932acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *QTy = llvm::VectorType::getExtendedElementVectorType(VTy); 19942235941293353325835d182da4470f61828fe789Bob Wilson Ops[0] = Builder.CreateBitCast(Ops[0], QTy); 19953b6081bf49b7506cb96131247f209d1e03610df8Bob Wilson return Builder.CreateTrunc(Ops[0], Ty, "vmovn"); 19962235941293353325835d182da4470f61828fe789Bob Wilson } 1997537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmul_v: 1998537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmulq_v: 1999da95f73b59f9af964e33725c515139d34c90c863Bob Wilson assert(Type.isPoly() && "vmul builtin only supported for polynomial types"); 20008dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vmulp, Ty), 2001953d513c7ee79b3d9e37597e64317e75c0fbf7f6Bob Wilson Ops, "vmul"); 2002537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmull_v: 20032d33e423d5091b7d2cb8618952752abd55bba965Bob Wilson Int = usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls; 2004da95f73b59f9af964e33725c515139d34c90c863Bob Wilson Int = Type.isPoly() ? (unsigned)Intrinsic::arm_neon_vmullp : Int; 20058dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull"); 2006537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpadal_v: 2007537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpadalq_v: { 2008df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vpadalu : Intrinsic::arm_neon_vpadals; 2009c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson // The source operand type has twice as many elements of half the size. 2010c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 20112acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *EltTy = 2012d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::IntegerType::get(getLLVMContext(), EltBits / 2); 20139cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *NarrowTy = 2014c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); 20159cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *Tys[2] = { Ty, NarrowTy }; 20168dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vpadal"); 2017c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson } 2018537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpadd_v: 20198dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vpadd, Ty), 2020548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vpadd"); 2021537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpaddl_v: 2022537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpaddlq_v: { 2023548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vpaddlu : Intrinsic::arm_neon_vpaddls; 2024c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson // The source operand type has twice as many elements of half the size. 2025c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 20262acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *EltTy = llvm::IntegerType::get(getLLVMContext(), EltBits / 2); 20279cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *NarrowTy = 2028c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); 20299cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *Tys[2] = { Ty, NarrowTy }; 20308dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vpaddl"); 2031c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson } 2032537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpmax_v: 2033548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vpmaxu : Intrinsic::arm_neon_vpmaxs; 20348dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmax"); 2035537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpmin_v: 2036548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vpminu : Intrinsic::arm_neon_vpmins; 20378dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmin"); 2038537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqabs_v: 2039537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqabsq_v: 20408dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqabs, Ty), 2041548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vqabs"); 2042537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqadd_v: 2043537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqaddq_v: 2044548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vqaddu : Intrinsic::arm_neon_vqadds; 20458dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqadd"); 2046537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqdmlal_v: 20478dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmlal, Ty), 2048db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqdmlal"); 2049537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqdmlsl_v: 20508dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmlsl, Ty), 2051db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqdmlsl"); 2052537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqdmulh_v: 2053537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqdmulhq_v: 20548dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmulh, Ty), 2055db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqdmulh"); 2056537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqdmull_v: 20578dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmull, Ty), 2058db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqdmull"); 2059537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqmovn_v: 2060548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vqmovnu : Intrinsic::arm_neon_vqmovns; 20618dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqmovn"); 2062537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqmovun_v: 20638dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqmovnsu, Ty), 2064548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vqdmull"); 2065537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqneg_v: 2066537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqnegq_v: 20678dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqneg, Ty), 206861eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops, "vqneg"); 2069537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrdmulh_v: 2070537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrdmulhq_v: 20718dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrdmulh, Ty), 2072db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqrdmulh"); 2073537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrshl_v: 2074537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrshlq_v: 2075548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vqrshiftu : Intrinsic::arm_neon_vqrshifts; 20768dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshl"); 2077537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrshrn_n_v: 2078548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vqrshiftnu : Intrinsic::arm_neon_vqrshiftns; 20798dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n", 208061eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman 1, true); 2081537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrshrun_n_v: 20828dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrshiftnsu, Ty), 2083db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqrshrun_n", 1, true); 2084537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshl_v: 2085537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshlq_v: 208661eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Int = usgn ? Intrinsic::arm_neon_vqshiftu : Intrinsic::arm_neon_vqshifts; 20878dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshl"); 2088537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshl_n_v: 2089537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshlq_n_v: 209061eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Int = usgn ? Intrinsic::arm_neon_vqshiftu : Intrinsic::arm_neon_vqshifts; 20918dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshl_n", 209261eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman 1, false); 2093537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshlu_n_v: 2094537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshluq_n_v: 20958dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftsu, Ty), 2096db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqshlu", 1, false); 2097537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshrn_n_v: 209861eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Int = usgn ? Intrinsic::arm_neon_vqshiftnu : Intrinsic::arm_neon_vqshiftns; 20998dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n", 210061eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman 1, true); 2101537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshrun_n_v: 21028dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftnsu, Ty), 2103db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqshrun_n", 1, true); 2104537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqsub_v: 2105537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqsubq_v: 2106464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Int = usgn ? Intrinsic::arm_neon_vqsubu : Intrinsic::arm_neon_vqsubs; 21078dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqsub"); 2108537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vraddhn_v: 21098dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vraddhn, Ty), 2110464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vraddhn"); 2111537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrecpe_v: 2112537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrecpeq_v: 21138dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecpe, Ty), 2114464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vrecpe"); 2115537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrecps_v: 2116537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrecpsq_v: 21178dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecps, Ty), 2118464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vrecps"); 2119537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrhadd_v: 2120537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrhaddq_v: 2121464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Int = usgn ? Intrinsic::arm_neon_vrhaddu : Intrinsic::arm_neon_vrhadds; 21228dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrhadd"); 2123537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrshl_v: 2124537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrshlq_v: 21255af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 21268dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshl"); 2127537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrshrn_n_v: 21288dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrshiftn, Ty), 2129db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vrshrn_n", 1, true); 2130537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrshr_n_v: 2131537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrshrq_n_v: 21325af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 21338dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshr_n", 1, true); 2134537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsqrte_v: 2135537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsqrteq_v: 21368dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsqrte, Ty), 21375af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops, "vrsqrte"); 2138537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsqrts_v: 2139537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsqrtsq_v: 21408dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsqrts, Ty), 21415af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops, "vrsqrts"); 2142537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsra_n_v: 2143537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsraq_n_v: 21445af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 21455af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 21465af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops[2] = EmitNeonShiftVector(Ops[2], Ty, true); 21475af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 21488dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Ops[1] = Builder.CreateCall2(CGM.getIntrinsic(Int, Ty), Ops[1], Ops[2]); 21495af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n"); 2150537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsubhn_v: 21518dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsubhn, Ty), 2152464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vrsubhn"); 2153537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshl_v: 2154537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshlq_v: 2155464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Int = usgn ? Intrinsic::arm_neon_vshiftu : Intrinsic::arm_neon_vshifts; 21568dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vshl"); 2157537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshll_n_v: 2158464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Int = usgn ? Intrinsic::arm_neon_vshiftlu : Intrinsic::arm_neon_vshiftls; 21598dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vshll", 1); 2160537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshl_n_v: 2161537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshlq_n_v: 216261eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false); 216361eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman return Builder.CreateShl(Builder.CreateBitCast(Ops[0],Ty), Ops[1], "vshl_n"); 2164537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshrn_n_v: 21658dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftn, Ty), 2166db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vshrn_n", 1, true); 2167537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshr_n_v: 2168537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshrq_n_v: 2169464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 217061eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false); 2171464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman if (usgn) 2172464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return Builder.CreateLShr(Ops[0], Ops[1], "vshr_n"); 2173464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman else 2174464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return Builder.CreateAShr(Ops[0], Ops[1], "vshr_n"); 2175537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsri_n_v: 2176537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsriq_n_v: 21777965396d8d6ac23ec4c4f9d01d216f2e73d7fc72Bob Wilson rightShift = true; 2178537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsli_n_v: 2179537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsliq_n_v: 21807965396d8d6ac23ec4c4f9d01d216f2e73d7fc72Bob Wilson Ops[2] = EmitNeonShiftVector(Ops[2], Ty, rightShift); 21818dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftins, Ty), 2182464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vsli_n"); 2183537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsra_n_v: 2184537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsraq_n_v: 2185464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2186464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 218761eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[2] = EmitNeonShiftVector(Ops[2], Ty, false); 2188464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman if (usgn) 2189464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateLShr(Ops[1], Ops[2], "vsra_n"); 2190464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman else 2191464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateAShr(Ops[1], Ops[2], "vsra_n"); 2192464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return Builder.CreateAdd(Ops[0], Ops[1]); 2193537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst1_v: 2194537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst1q_v: 2195ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 21968dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, Ty), 2197464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2198550a9d823a939366a9f776b58f18883acd905a93Bob Wilson case ARM::BI__builtin_neon_vst1q_lane_v: 2199550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // Handle 64-bit integer elements as a special case. Use a shuffle to get 2200550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // a one-element vector and avoid poor code for i64 in the backend. 2201550a9d823a939366a9f776b58f18883acd905a93Bob Wilson if (VTy->getElementType()->isIntegerTy(64)) { 2202550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 2203550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Value *SV = llvm::ConstantVector::get(cast<llvm::Constant>(Ops[2])); 2204550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); 2205ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops[2] = Align; 2206550a9d823a939366a9f776b58f18883acd905a93Bob Wilson return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, 2207550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ops[1]->getType()), Ops); 2208550a9d823a939366a9f776b58f18883acd905a93Bob Wilson } 2209550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // fall through 2210550a9d823a939366a9f776b58f18883acd905a93Bob Wilson case ARM::BI__builtin_neon_vst1_lane_v: { 2211464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 2212464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); 2213464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 2214eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson StoreInst *St = Builder.CreateStore(Ops[1], 2215eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson Builder.CreateBitCast(Ops[0], Ty)); 2216eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson St->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); 2217eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson return St; 2218eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson } 2219537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst2_v: 2220537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst2q_v: 2221ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 22228dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst2, Ty), 2223464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2224537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst2_lane_v: 2225537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst2q_lane_v: 2226ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 22278dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst2lane, Ty), 2228464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2229537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst3_v: 2230537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst3q_v: 2231ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 22328dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst3, Ty), 2233464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2234537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst3_lane_v: 2235537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst3q_lane_v: 2236ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 22378dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst3lane, Ty), 2238464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2239537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst4_v: 2240537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst4q_v: 2241ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 22428dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst4, Ty), 2243464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2244537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst4_lane_v: 2245537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst4q_lane_v: 2246ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 22478dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst4lane, Ty), 2248464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2249537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsubhn_v: 22508dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vsubhn, Ty), 2251548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vsubhn"); 2252537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbl1_v: 22531c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl1), 22541c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbl1"); 2255537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbl2_v: 22561c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl2), 22571c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbl2"); 2258537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbl3_v: 22591c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl3), 22601c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbl3"); 2261537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbl4_v: 22621c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl4), 22631c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbl4"); 2264537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbx1_v: 22651c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx1), 22661c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbx1"); 2267537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbx2_v: 22681c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx2), 22691c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbx2"); 2270537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbx3_v: 22711c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx3), 22721c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbx3"); 2273537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbx4_v: 22741c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx4), 22751c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbx4"); 2276537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtst_v: 2277537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtstq_v: { 22781c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 22791c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 22801c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]); 22811c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0], 22821c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman ConstantAggregateZero::get(Ty)); 22831c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return Builder.CreateSExt(Ops[0], Ty, "vtst"); 22841c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 2285537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtrn_v: 2286537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtrnq_v: { 22874be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 22884be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 22894be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 22909577abc63f2c7afe5adf6e4e101ae91d29c3b8a6Ted Kremenek Value *SV = 0; 22914be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 22921c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman for (unsigned vi = 0; vi != 2; ++vi) { 22934be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SmallVector<Constant*, 16> Indices; 22944be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 22952ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner Indices.push_back(Builder.getInt32(i+vi)); 22962ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner Indices.push_back(Builder.getInt32(i+e+vi)); 22971c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 22984be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi); 2299fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner SV = llvm::ConstantVector::get(Indices); 23004be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vtrn"); 23014be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateStore(SV, Addr); 23021c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 23034be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return SV; 23041c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 2305537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vuzp_v: 2306537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vuzpq_v: { 23074be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 23081c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 23094be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 23109577abc63f2c7afe5adf6e4e101ae91d29c3b8a6Ted Kremenek Value *SV = 0; 23114be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 23124be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned vi = 0; vi != 2; ++vi) { 23134be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SmallVector<Constant*, 16> Indices; 23144be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 231577b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Indices.push_back(ConstantInt::get(Int32Ty, 2*i+vi)); 23164be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 23174be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi); 2318fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner SV = llvm::ConstantVector::get(Indices); 23194be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vuzp"); 23204be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateStore(SV, Addr); 23214be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 23224be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return SV; 23231c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 2324537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vzip_v: 2325537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vzipq_v: { 23264be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 23271c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 23284be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 23299577abc63f2c7afe5adf6e4e101ae91d29c3b8a6Ted Kremenek Value *SV = 0; 23304be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 23314be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned vi = 0; vi != 2; ++vi) { 23324be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SmallVector<Constant*, 16> Indices; 23334be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 2334e361cc3daa6c22e4413d48bd8b8934ea9fd5a55fDaniel Dunbar Indices.push_back(ConstantInt::get(Int32Ty, (i + vi*e) >> 1)); 2335e361cc3daa6c22e4413d48bd8b8934ea9fd5a55fDaniel Dunbar Indices.push_back(ConstantInt::get(Int32Ty, ((i + vi*e) >> 1)+e)); 23364be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 23374be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi); 2338fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner SV = llvm::ConstantVector::get(Indices); 23394be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vzip"); 23404be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateStore(SV, Addr); 23414be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 23424be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return SV; 23439eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 23442752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner } 23452752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner} 23462752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner 2347aa51e513850688b7963efc62abf1eface7037602Bill Wendlingllvm::Value *CodeGenFunction:: 2348795b10062c2eaffae9e04241fb1a73cdbcb24a37Bill WendlingBuildVector(ArrayRef<llvm::Value*> Ops) { 2349aa51e513850688b7963efc62abf1eface7037602Bill Wendling assert((Ops.size() & (Ops.size() - 1)) == 0 && 2350aa51e513850688b7963efc62abf1eface7037602Bill Wendling "Not a power-of-two sized vector!"); 2351aa51e513850688b7963efc62abf1eface7037602Bill Wendling bool AllConstants = true; 2352aa51e513850688b7963efc62abf1eface7037602Bill Wendling for (unsigned i = 0, e = Ops.size(); i != e && AllConstants; ++i) 2353aa51e513850688b7963efc62abf1eface7037602Bill Wendling AllConstants &= isa<Constant>(Ops[i]); 2354aa51e513850688b7963efc62abf1eface7037602Bill Wendling 2355aa51e513850688b7963efc62abf1eface7037602Bill Wendling // If this is a constant vector, create a ConstantVector. 2356aa51e513850688b7963efc62abf1eface7037602Bill Wendling if (AllConstants) { 23572ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner SmallVector<llvm::Constant*, 16> CstOps; 2358aa51e513850688b7963efc62abf1eface7037602Bill Wendling for (unsigned i = 0, e = Ops.size(); i != e; ++i) 2359aa51e513850688b7963efc62abf1eface7037602Bill Wendling CstOps.push_back(cast<Constant>(Ops[i])); 2360aa51e513850688b7963efc62abf1eface7037602Bill Wendling return llvm::ConstantVector::get(CstOps); 2361aa51e513850688b7963efc62abf1eface7037602Bill Wendling } 2362aa51e513850688b7963efc62abf1eface7037602Bill Wendling 2363aa51e513850688b7963efc62abf1eface7037602Bill Wendling // Otherwise, insertelement the values to build the vector. 2364aa51e513850688b7963efc62abf1eface7037602Bill Wendling Value *Result = 2365aa51e513850688b7963efc62abf1eface7037602Bill Wendling llvm::UndefValue::get(llvm::VectorType::get(Ops[0]->getType(), Ops.size())); 2366aa51e513850688b7963efc62abf1eface7037602Bill Wendling 2367aa51e513850688b7963efc62abf1eface7037602Bill Wendling for (unsigned i = 0, e = Ops.size(); i != e; ++i) 23682ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner Result = Builder.CreateInsertElement(Result, Ops[i], Builder.getInt32(i)); 2369aa51e513850688b7963efc62abf1eface7037602Bill Wendling 2370aa51e513850688b7963efc62abf1eface7037602Bill Wendling return Result; 2371aa51e513850688b7963efc62abf1eface7037602Bill Wendling} 2372aa51e513850688b7963efc62abf1eface7037602Bill Wendling 23731eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpValue *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, 23741feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner const CallExpr *E) { 23755f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Value*, 4> Ops; 23762929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson 237746c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // Find out if any arguments are required to be integer constant expressions. 237846c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner unsigned ICEArguments = 0; 237946c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner ASTContext::GetBuiltinTypeError Error; 238046c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 238146c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner assert(Error == ASTContext::GE_None && "Should not codegen an error"); 238246c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner 238346c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) { 238446c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // If this is a normal argument, just emit it as a scalar. 238546c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner if ((ICEArguments & (1 << i)) == 0) { 238646c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner Ops.push_back(EmitScalarExpr(E->getArg(i))); 238746c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner continue; 238846c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner } 238946c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner 239046c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // If this is required to be a constant, constant fold it so that we know 239146c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // that the generated intrinsic gets a ConstantInt. 239246c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner llvm::APSInt Result; 239346c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext()); 239446c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst; 2395d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result)); 239646c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner } 23972929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson 2398564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson switch (BuiltinID) { 239946a26b0b0e2ec1557bad9b70e8e20836524ebdfcAnders Carlsson default: return 0; 2400aa51e513850688b7963efc62abf1eface7037602Bill Wendling case X86::BI__builtin_ia32_vec_init_v8qi: 2401aa51e513850688b7963efc62abf1eface7037602Bill Wendling case X86::BI__builtin_ia32_vec_init_v4hi: 2402aa51e513850688b7963efc62abf1eface7037602Bill Wendling case X86::BI__builtin_ia32_vec_init_v2si: 2403aa51e513850688b7963efc62abf1eface7037602Bill Wendling return Builder.CreateBitCast(BuildVector(Ops), 2404d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::Type::getX86_MMXTy(getLLVMContext())); 24051944ec188408aff1931c62c79a069e30f2549ec2Argyrios Kyrtzidis case X86::BI__builtin_ia32_vec_ext_v2si: 24061944ec188408aff1931c62c79a069e30f2549ec2Argyrios Kyrtzidis return Builder.CreateExtractElement(Ops[0], 24071944ec188408aff1931c62c79a069e30f2549ec2Argyrios Kyrtzidis llvm::ConstantInt::get(Ops[1]->getType(), 0)); 2408e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_ldmxcsr: { 24092acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PtrTy = Int8PtrTy; 241077b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Value *One = llvm::ConstantInt::get(Int32Ty, 1); 2411578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Value *Tmp = Builder.CreateAlloca(Int32Ty, One); 2412e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Builder.CreateStore(Ops[0], Tmp); 2413e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr), 24143eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner Builder.CreateBitCast(Tmp, PtrTy)); 2415e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 2416e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_stmxcsr: { 24172acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PtrTy = Int8PtrTy; 241877b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Value *One = llvm::ConstantInt::get(Int32Ty, 1); 2419578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Value *Tmp = Builder.CreateAlloca(Int32Ty, One); 2420012614ecf78442368ec82ee30efb3bc047b413e6Ted Kremenek Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr), 2421012614ecf78442368ec82ee30efb3bc047b413e6Ted Kremenek Builder.CreateBitCast(Tmp, PtrTy)); 2422e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman return Builder.CreateLoad(Tmp, "stmxcsr"); 2423e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 2424e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_storehps: 2425e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_storelps: { 242677b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Type *PtrTy = llvm::PointerType::getUnqual(Int64Ty); 242777b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2); 24281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2429e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman // cast val v2i64 2430e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast"); 24311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2432e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman // extract (0, 1) 2433e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1; 243477b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Value *Idx = llvm::ConstantInt::get(Int32Ty, Index); 2435e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract"); 2436e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman 2437e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman // cast pointer to i64 & store 2438e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy); 2439e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 2440e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 244128cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling case X86::BI__builtin_ia32_palignr: { 244228cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 244328cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling 244428cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // If palignr is shifting the pair of input vectors less than 9 bytes, 244528cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // emit a shuffle instruction. 244628cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling if (shiftVal <= 8) { 24475f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Constant*, 8> Indices; 244828cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling for (unsigned i = 0; i != 8; ++i) 244928cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling Indices.push_back(llvm::ConstantInt::get(Int32Ty, shiftVal + i)); 245028cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling 2451fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner Value* SV = llvm::ConstantVector::get(Indices); 245228cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 245328cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling } 245428cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling 245528cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // If palignr is shifting the pair of input vectors more than 8 but less 245628cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // than 16 bytes, emit a logical right shift of the destination. 245728cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling if (shiftVal < 16) { 245828cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // MMX has these as 1 x i64 vectors for some odd optimization reasons. 24592acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 1); 246028cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling 246128cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 246228cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling Ops[1] = llvm::ConstantInt::get(VecTy, (shiftVal-8) * 8); 246328cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling 246428cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // create i32 constant 246528cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_mmx_psrl_q); 2466e9c0265d6e6b5bf865f4a0c2c00d00ac251e6437Frits van Bommel return Builder.CreateCall(F, makeArrayRef(&Ops[0], 2), "palignr"); 246728cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling } 246828cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling 24695c22ad2ef6bf39da22d5190025e0ddfd4b568b2aEli Friedman // If palignr is shifting the pair of vectors more than 16 bytes, emit zero. 247028cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling return llvm::Constant::getNullValue(ConvertType(E->getType())); 247128cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling } 2472c3420ffb282c6ffc0192013bf8045b6c21eddeceNate Begeman case X86::BI__builtin_ia32_palignr128: { 2473ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 2474ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 2475ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // If palignr is shifting the pair of input vectors less than 17 bytes, 2476ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // emit a shuffle instruction. 2477ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman if (shiftVal <= 16) { 24785f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Constant*, 16> Indices; 2479ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman for (unsigned i = 0; i != 16; ++i) 248077b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Indices.push_back(llvm::ConstantInt::get(Int32Ty, shiftVal + i)); 2481ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 2482fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner Value* SV = llvm::ConstantVector::get(Indices); 2483ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 2484ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman } 2485ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 2486ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // If palignr is shifting the pair of input vectors more than 16 but less 2487ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // than 32 bytes, emit a logical right shift of the destination. 2488ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman if (shiftVal < 32) { 24892acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2); 2490ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 2491ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 249277b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Ops[1] = llvm::ConstantInt::get(Int32Ty, (shiftVal-16) * 8); 2493ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 2494ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // create i32 constant 2495ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_psrl_dq); 2496e9c0265d6e6b5bf865f4a0c2c00d00ac251e6437Frits van Bommel return Builder.CreateCall(F, makeArrayRef(&Ops[0], 2), "palignr"); 2497ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman } 2498ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 2499ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 2500ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman return llvm::Constant::getNullValue(ConvertType(E->getType())); 250191b59274439f776cdd545bd7bf5849fdb1842160Eric Christopher } 25029c2ffd803af03f1728423d0d73ff87d988642633Craig Topper case X86::BI__builtin_ia32_palignr256: { 25039c2ffd803af03f1728423d0d73ff87d988642633Craig Topper unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 25049c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 25059c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // If palignr is shifting the pair of input vectors less than 17 bytes, 25069c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // emit a shuffle instruction. 25079c2ffd803af03f1728423d0d73ff87d988642633Craig Topper if (shiftVal <= 16) { 25089c2ffd803af03f1728423d0d73ff87d988642633Craig Topper SmallVector<llvm::Constant*, 32> Indices; 25099c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // 256-bit palignr operates on 128-bit lanes so we need to handle that 25109c2ffd803af03f1728423d0d73ff87d988642633Craig Topper for (unsigned l = 0; l != 2; ++l) { 25119c2ffd803af03f1728423d0d73ff87d988642633Craig Topper unsigned LaneStart = l * 16; 25129c2ffd803af03f1728423d0d73ff87d988642633Craig Topper unsigned LaneEnd = (l+1) * 16; 25139c2ffd803af03f1728423d0d73ff87d988642633Craig Topper for (unsigned i = 0; i != 16; ++i) { 25149c2ffd803af03f1728423d0d73ff87d988642633Craig Topper unsigned Idx = shiftVal + i + LaneStart; 25159c2ffd803af03f1728423d0d73ff87d988642633Craig Topper if (Idx >= LaneEnd) Idx += 16; // end of lane, switch operand 25169c2ffd803af03f1728423d0d73ff87d988642633Craig Topper Indices.push_back(llvm::ConstantInt::get(Int32Ty, Idx)); 25179c2ffd803af03f1728423d0d73ff87d988642633Craig Topper } 25189c2ffd803af03f1728423d0d73ff87d988642633Craig Topper } 25199c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 25209c2ffd803af03f1728423d0d73ff87d988642633Craig Topper Value* SV = llvm::ConstantVector::get(Indices); 25219c2ffd803af03f1728423d0d73ff87d988642633Craig Topper return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 25229c2ffd803af03f1728423d0d73ff87d988642633Craig Topper } 25239c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 25249c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // If palignr is shifting the pair of input vectors more than 16 but less 25259c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // than 32 bytes, emit a logical right shift of the destination. 25269c2ffd803af03f1728423d0d73ff87d988642633Craig Topper if (shiftVal < 32) { 25279c2ffd803af03f1728423d0d73ff87d988642633Craig Topper llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 4); 25289c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 25299c2ffd803af03f1728423d0d73ff87d988642633Craig Topper Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 25309c2ffd803af03f1728423d0d73ff87d988642633Craig Topper Ops[1] = llvm::ConstantInt::get(Int32Ty, (shiftVal-16) * 8); 25319c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 25329c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // create i32 constant 25339c2ffd803af03f1728423d0d73ff87d988642633Craig Topper llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_avx2_psrl_dq); 25349c2ffd803af03f1728423d0d73ff87d988642633Craig Topper return Builder.CreateCall(F, makeArrayRef(&Ops[0], 2), "palignr"); 25359c2ffd803af03f1728423d0d73ff87d988642633Craig Topper } 25369c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 25379c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 25389c2ffd803af03f1728423d0d73ff87d988642633Craig Topper return llvm::Constant::getNullValue(ConvertType(E->getType())); 25399c2ffd803af03f1728423d0d73ff87d988642633Craig Topper } 2540b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling case X86::BI__builtin_ia32_movntps: 25414a7376d00df98cbfcad29ee709637707a2f3d46cCraig Topper case X86::BI__builtin_ia32_movntps256: 2542b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling case X86::BI__builtin_ia32_movntpd: 25434a7376d00df98cbfcad29ee709637707a2f3d46cCraig Topper case X86::BI__builtin_ia32_movntpd256: 2544b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling case X86::BI__builtin_ia32_movntdq: 25454a7376d00df98cbfcad29ee709637707a2f3d46cCraig Topper case X86::BI__builtin_ia32_movntdq256: 2546b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling case X86::BI__builtin_ia32_movnti: { 2547b107dd02f5e365f60b036b8a27c784f2d0d0a855Bill Wendling llvm::MDNode *Node = llvm::MDNode::get(getLLVMContext(), 2548b107dd02f5e365f60b036b8a27c784f2d0d0a855Bill Wendling Builder.getInt32(1)); 2549b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling 2550b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling // Convert the type of the pointer to a pointer to the stored type. 2551b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling Value *BC = Builder.CreateBitCast(Ops[0], 2552b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling llvm::PointerType::getUnqual(Ops[1]->getType()), 2553b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling "cast"); 2554b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling StoreInst *SI = Builder.CreateStore(Ops[1], BC); 2555b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling SI->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); 2556b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling SI->setAlignment(16); 2557b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling return SI; 2558b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling } 25598b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer // 3DNow! 25608b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer case X86::BI__builtin_ia32_pswapdsf: 25618b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer case X86::BI__builtin_ia32_pswapdsi: { 25628b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer const char *name = 0; 25638b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer Intrinsic::ID ID = Intrinsic::not_intrinsic; 25648b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer switch(BuiltinID) { 2565f8495d67ca4dd2ea15a4dc59e9a2fa32a9bfa475Craig Topper default: llvm_unreachable("Unsupported intrinsic!"); 25668b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer case X86::BI__builtin_ia32_pswapdsf: 25678b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer case X86::BI__builtin_ia32_pswapdsi: 25688b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer name = "pswapd"; 25698b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer ID = Intrinsic::x86_3dnowa_pswapd; 25708b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer break; 25718b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer } 2572345032a7211a6f983d59c30c0b3fa2b96819532aChandler Carruth llvm::Type *MMXTy = llvm::Type::getX86_MMXTy(getLLVMContext()); 2573345032a7211a6f983d59c30c0b3fa2b96819532aChandler Carruth Ops[0] = Builder.CreateBitCast(Ops[0], MMXTy, "cast"); 25748b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer llvm::Function *F = CGM.getIntrinsic(ID); 25754c7d9f1507d0f102bd4133bba63348636facd469Jay Foad return Builder.CreateCall(F, Ops, name); 25768b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer } 25779a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer case X86::BI__builtin_ia32_rdrand16_step: 25789a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer case X86::BI__builtin_ia32_rdrand32_step: 25799a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer case X86::BI__builtin_ia32_rdrand64_step: { 25809a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer Intrinsic::ID ID; 25819a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer switch (BuiltinID) { 25829a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer default: llvm_unreachable("Unsupported intrinsic!"); 25839a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer case X86::BI__builtin_ia32_rdrand16_step: 25849a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer ID = Intrinsic::x86_rdrand_16; 25859a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer break; 25869a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer case X86::BI__builtin_ia32_rdrand32_step: 25879a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer ID = Intrinsic::x86_rdrand_32; 25889a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer break; 25899a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer case X86::BI__builtin_ia32_rdrand64_step: 25909a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer ID = Intrinsic::x86_rdrand_64; 25919a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer break; 25929a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer } 25939a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer 25949a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer Value *Call = Builder.CreateCall(CGM.getIntrinsic(ID)); 25959a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer Builder.CreateStore(Builder.CreateExtractValue(Call, 0), Ops[0]); 25969a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer return Builder.CreateExtractValue(Call, 1); 25979a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer } 2598564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson } 2599564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson} 2600564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson 26019631939f82c0eaa6fb3936a0ce58a41adfbc9011Tony Linthicum 26021eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpValue *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, 26031feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner const CallExpr *E) { 26045f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Value*, 4> Ops; 2605dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 2606dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) 2607dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner Ops.push_back(EmitScalarExpr(E->getArg(i))); 2608dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 2609dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner Intrinsic::ID ID = Intrinsic::not_intrinsic; 2610dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 2611dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner switch (BuiltinID) { 2612dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner default: return 0; 2613dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 26144d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov // vec_ld, vec_lvsl, vec_lvsr 26154d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvx: 26164d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvxl: 26174d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvebx: 26184d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvehx: 26194d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvewx: 26204d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvsl: 26214d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvsr: 26224d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov { 2623d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy); 26244d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov 2625578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Ops[0] = Builder.CreateGEP(Ops[1], Ops[0]); 26264d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov Ops.pop_back(); 26274d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov 26284d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov switch (BuiltinID) { 2629b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("Unsupported ld/lvsl/lvsr intrinsic!"); 26304d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvx: 26314d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvx; 26324d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 26334d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvxl: 26344d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvxl; 26354d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 26364d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvebx: 26374d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvebx; 26384d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 26394d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvehx: 26404d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvehx; 26414d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 26424d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvewx: 26434d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvewx; 26444d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 26454d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvsl: 26464d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvsl; 26474d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 26484d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvsr: 26494d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvsr; 26504d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 26514d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov } 26524d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov llvm::Function *F = CGM.getIntrinsic(ID); 26534c7d9f1507d0f102bd4133bba63348636facd469Jay Foad return Builder.CreateCall(F, Ops, ""); 26544d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov } 26554d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov 2656dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner // vec_st 2657dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvx: 2658dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvxl: 2659dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvebx: 2660dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvehx: 2661dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvewx: 2662dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner { 2663d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Ops[2] = Builder.CreateBitCast(Ops[2], Int8PtrTy); 2664578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Ops[1] = Builder.CreateGEP(Ops[2], Ops[1]); 2665dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner Ops.pop_back(); 2666dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 2667dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner switch (BuiltinID) { 2668b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("Unsupported st intrinsic!"); 2669dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvx: 2670dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvx; 2671dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 2672dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvxl: 2673dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvxl; 2674dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 2675dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvebx: 2676dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvebx; 2677dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 2678dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvehx: 2679dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvehx; 2680dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 2681dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvewx: 2682dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvewx; 2683dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 2684dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner } 2685dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner llvm::Function *F = CGM.getIntrinsic(ID); 26864c7d9f1507d0f102bd4133bba63348636facd469Jay Foad return Builder.CreateCall(F, Ops, ""); 2687dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner } 2688dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner } 26891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 2690