CGBuiltin.cpp revision 1bfc28c48c1b86a05d2e07b403107ef3da5a0f8e
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 14022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson#include "CodeGenFunction.h" 1555bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian#include "CGObjCRuntime.h" 1655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "CodeGenModule.h" 1755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "TargetInfo.h" 18bef20ac367a09555b30d6eb3847a81ec164caf88Chris Lattner#include "clang/AST/ASTContext.h" 19c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbar#include "clang/AST/Decl.h" 206b15cdc1312f8fc45c86ee75e2a85106700e97f6Chris Lattner#include "clang/Basic/TargetBuiltins.h" 2155fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/TargetInfo.h" 223b844ba7d5be205a9b4f5f0b0d1b7978977f4b8cChandler Carruth#include "llvm/IR/DataLayout.h" 233b844ba7d5be205a9b4f5f0b0d1b7978977f4b8cChandler Carruth#include "llvm/IR/Intrinsics.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)); 89956a5a17713deb1b5b27893303c4f308a1bd2a62Micah Villmow unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); 9026815d97c5743481e317f17a8d53a6819d061862John McCall 919cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::IntegerType *IntType = 92db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth llvm::IntegerType::get(CGF.getLLVMContext(), 9326815d97c5743481e317f17a8d53a6819d061862John McCall CGF.getContext().getTypeSize(T)); 949cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 9526815d97c5743481e317f17a8d53a6819d061862John McCall 9626815d97c5743481e317f17a8d53a6819d061862John McCall llvm::Value *Args[2]; 9726815d97c5743481e317f17a8d53a6819d061862John McCall Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType); 9826815d97c5743481e317f17a8d53a6819d061862John McCall Args[1] = CGF.EmitScalarExpr(E->getArg(1)); 992acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ValueType = Args[1]->getType(); 10026815d97c5743481e317f17a8d53a6819d061862John McCall Args[1] = EmitToInt(CGF, Args[1], T, IntType); 10126815d97c5743481e317f17a8d53a6819d061862John McCall 102c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman llvm::Value *Result = 103c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman CGF.Builder.CreateAtomicRMW(Kind, Args[0], Args[1], 104c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman llvm::SequentiallyConsistent); 10526815d97c5743481e317f17a8d53a6819d061862John McCall Result = EmitFromInt(CGF, Result, T, ValueType); 10626815d97c5743481e317f17a8d53a6819d061862John McCall return RValue::get(Result); 1070002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar} 1080002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar 1090002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar/// Utility to insert an atomic instruction based Instrinsic::ID and 11026815d97c5743481e317f17a8d53a6819d061862John McCall/// the expression node, where the return value is the result of the 11126815d97c5743481e317f17a8d53a6819d061862John McCall/// operation. 112420b11850d3f4557421f43f519b59d528329c668Chris Lattnerstatic RValue EmitBinaryAtomicPost(CodeGenFunction &CGF, 113c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman llvm::AtomicRMWInst::BinOp Kind, 114c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman const CallExpr *E, 1150002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Instruction::BinaryOps Op) { 11626815d97c5743481e317f17a8d53a6819d061862John McCall QualType T = E->getType(); 11726815d97c5743481e317f17a8d53a6819d061862John McCall assert(E->getArg(0)->getType()->isPointerType()); 11826815d97c5743481e317f17a8d53a6819d061862John McCall assert(CGF.getContext().hasSameUnqualifiedType(T, 11926815d97c5743481e317f17a8d53a6819d061862John McCall E->getArg(0)->getType()->getPointeeType())); 12026815d97c5743481e317f17a8d53a6819d061862John McCall assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType())); 12126815d97c5743481e317f17a8d53a6819d061862John McCall 1224f209445c06a43283c6f72dda7c925538b1578e9Chris Lattner llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); 123956a5a17713deb1b5b27893303c4f308a1bd2a62Micah Villmow unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); 12426815d97c5743481e317f17a8d53a6819d061862John McCall 1259cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::IntegerType *IntType = 126db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth llvm::IntegerType::get(CGF.getLLVMContext(), 12726815d97c5743481e317f17a8d53a6819d061862John McCall CGF.getContext().getTypeSize(T)); 1289cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 12926815d97c5743481e317f17a8d53a6819d061862John McCall 13026815d97c5743481e317f17a8d53a6819d061862John McCall llvm::Value *Args[2]; 13126815d97c5743481e317f17a8d53a6819d061862John McCall Args[1] = CGF.EmitScalarExpr(E->getArg(1)); 1322acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ValueType = Args[1]->getType(); 13326815d97c5743481e317f17a8d53a6819d061862John McCall Args[1] = EmitToInt(CGF, Args[1], T, IntType); 13426815d97c5743481e317f17a8d53a6819d061862John McCall Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType); 13526815d97c5743481e317f17a8d53a6819d061862John McCall 136c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman llvm::Value *Result = 137c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman CGF.Builder.CreateAtomicRMW(Kind, Args[0], Args[1], 138c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman llvm::SequentiallyConsistent); 13926815d97c5743481e317f17a8d53a6819d061862John McCall Result = CGF.Builder.CreateBinOp(Op, Result, Args[1]); 14026815d97c5743481e317f17a8d53a6819d061862John McCall Result = EmitFromInt(CGF, Result, T, ValueType); 14126815d97c5743481e317f17a8d53a6819d061862John McCall return RValue::get(Result); 1421ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang} 1431ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang 144420b11850d3f4557421f43f519b59d528329c668Chris Lattner/// EmitFAbs - Emit a call to fabs/fabsf/fabsl, depending on the type of ValTy, 145420b11850d3f4557421f43f519b59d528329c668Chris Lattner/// which must be a scalar floating point type. 146420b11850d3f4557421f43f519b59d528329c668Chris Lattnerstatic Value *EmitFAbs(CodeGenFunction &CGF, Value *V, QualType ValTy) { 147420b11850d3f4557421f43f519b59d528329c668Chris Lattner const BuiltinType *ValTyP = ValTy->getAs<BuiltinType>(); 148420b11850d3f4557421f43f519b59d528329c668Chris Lattner assert(ValTyP && "isn't scalar fp type!"); 149258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 150420b11850d3f4557421f43f519b59d528329c668Chris Lattner StringRef FnName; 151420b11850d3f4557421f43f519b59d528329c668Chris Lattner switch (ValTyP->getKind()) { 152b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("Isn't a scalar fp type!"); 153420b11850d3f4557421f43f519b59d528329c668Chris Lattner case BuiltinType::Float: FnName = "fabsf"; break; 154420b11850d3f4557421f43f519b59d528329c668Chris Lattner case BuiltinType::Double: FnName = "fabs"; break; 155420b11850d3f4557421f43f519b59d528329c668Chris Lattner case BuiltinType::LongDouble: FnName = "fabsl"; break; 156420b11850d3f4557421f43f519b59d528329c668Chris Lattner } 157258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 158420b11850d3f4557421f43f519b59d528329c668Chris Lattner // The prototype is something that takes and returns whatever V's type is. 159da549e8995c447542d5631b8b67fcc3a9582797aJay Foad llvm::FunctionType *FT = llvm::FunctionType::get(V->getType(), V->getType(), 16095d318c4c10437db40ca6e15fdf32e04012da58eBenjamin Kramer false); 161420b11850d3f4557421f43f519b59d528329c668Chris Lattner llvm::Value *Fn = CGF.CGM.CreateRuntimeFunction(FT, FnName); 162420b11850d3f4557421f43f519b59d528329c668Chris Lattner 163bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall return CGF.EmitNounwindRuntimeCall(Fn, V, "abs"); 164420b11850d3f4557421f43f519b59d528329c668Chris Lattner} 165420b11850d3f4557421f43f519b59d528329c668Chris Lattner 166a45680b7e7c49ea9893c6cff585984f3e4120366John McCallstatic RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *Fn, 167a45680b7e7c49ea9893c6cff585984f3e4120366John McCall const CallExpr *E, llvm::Value *calleeValue) { 168a45680b7e7c49ea9893c6cff585984f3e4120366John McCall return CGF.EmitCall(E->getCallee()->getType(), calleeValue, 169a45680b7e7c49ea9893c6cff585984f3e4120366John McCall ReturnValueSlot(), E->arg_begin(), E->arg_end(), Fn); 170a45680b7e7c49ea9893c6cff585984f3e4120366John McCall} 171a45680b7e7c49ea9893c6cff585984f3e4120366John McCall 1720cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman/// \brief Emit a call to llvm.{sadd,uadd,ssub,usub,smul,umul}.with.overflow.* 1730cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman/// depending on IntrinsicID. 1740cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman/// 1750cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman/// \arg CGF The current codegen function. 1760cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman/// \arg IntrinsicID The ID for the Intrinsic we wish to generate. 1770cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman/// \arg X The first argument to the llvm.*.with.overflow.*. 1780cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman/// \arg Y The second argument to the llvm.*.with.overflow.*. 1790cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman/// \arg Carry The carry returned by the llvm.*.with.overflow.*. 1800cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman/// \returns The result (i.e. sum/product) returned by the intrinsic. 1810cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesmanstatic llvm::Value *EmitOverflowIntrinsic(CodeGenFunction &CGF, 1820cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman const llvm::Intrinsic::ID IntrinsicID, 1830cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *X, llvm::Value *Y, 1840cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *&Carry) { 1850cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // Make sure we have integers of the same width. 1860cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman assert(X->getType() == Y->getType() && 1870cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman "Arguments must be the same type. (Did you forget to make sure both " 1880cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman "arguments have the same integer width?)"); 1890cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman 190563fb903fab15972e2d9c66b0ae046a94be86a71NAKAMURA Takumi llvm::Value *Callee = CGF.CGM.getIntrinsic(IntrinsicID, X->getType()); 1910cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *Tmp = CGF.Builder.CreateCall2(Callee, X, Y); 1920cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman Carry = CGF.Builder.CreateExtractValue(Tmp, 1); 1930cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman return CGF.Builder.CreateExtractValue(Tmp, 0); 1940cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman} 1950cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman 1961eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpRValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, 197ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar unsigned BuiltinID, const CallExpr *E) { 198564ea2a99b3afeac9ded332730a56db1f6358a58Chris Lattner // See if we can constant fold this builtin. If so, don't emit it at all. 199f35d35a2316dcb65d078844696c2032b71a7f103Anders Carlsson Expr::EvalResult Result; 20052a27f5be98d99fd5339949d8a3d0b2aec655e0bEli Friedman if (E->EvaluateAsRValue(Result, CGM.getContext()) && 201dd697bc8629f0fa6777245610d52ca7ceb3b67f4Fariborz Jahanian !Result.hasSideEffects()) { 202f35d35a2316dcb65d078844696c2032b71a7f103Anders Carlsson if (Result.Val.isInt()) 203d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall return RValue::get(llvm::ConstantInt::get(getLLVMContext(), 2044a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Result.Val.getInt())); 205a1aa9e36e6e21f74c56cf9e72cb5bd9aa2a92fd4Chris Lattner if (Result.Val.isFloat()) 206d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall return RValue::get(llvm::ConstantFP::get(getLLVMContext(), 207d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Result.Val.getFloat())); 2081f32999ec79a980576e100d64d5f3267eb19ea49Chris Lattner } 2091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 210564ea2a99b3afeac9ded332730a56db1f6358a58Chris Lattner switch (BuiltinID) { 211564ea2a99b3afeac9ded332730a56db1f6358a58Chris Lattner default: break; // Handle intrinsics and libm functions below. 212506ff88f44562df267b6a06608ab841b76df2a2bChris Lattner case Builtin::BI__builtin___CFStringMakeConstantString: 2130d13f6fdbdd6f06e2449b8834dda53334abd399aDavid Chisnall case Builtin::BI__builtin___NSStringMakeConstantString: 214e9352cc9818ba59e7cf88500ef048991c90f3821Anders Carlsson return RValue::get(CGM.EmitConstantExpr(E, E->getType(), 0)); 2156a705f0443f8398ece14d80e71d8e8c9e71aa84aChris Lattner case Builtin::BI__builtin_stdarg_start: 216793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson case Builtin::BI__builtin_va_start: 217793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson case Builtin::BI__builtin_va_end: { 2180785570af3ef5f8c5a0377129e41efe6f3f8d770Daniel Dunbar Value *ArgValue = EmitVAListRef(E->getArg(0)); 2192acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *DestType = Int8PtrTy; 220793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson if (ArgValue->getType() != DestType) 2211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ArgValue = Builder.CreateBitCast(ArgValue, DestType, 222b27ffbef8e8aa1e87b63cbc0d9cd630aba30dae5Daniel Dunbar ArgValue->getName().data()); 223793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson 2241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Intrinsic::ID inst = (BuiltinID == Builtin::BI__builtin_va_end) ? 2256a705f0443f8398ece14d80e71d8e8c9e71aa84aChris Lattner Intrinsic::vaend : Intrinsic::vastart; 2267acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner return RValue::get(Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue)); 227793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson } 228a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson case Builtin::BI__builtin_va_copy: { 2294fd0aa5803357d8c72eeac2cae15e12649ea08feEli Friedman Value *DstPtr = EmitVAListRef(E->getArg(0)); 2304fd0aa5803357d8c72eeac2cae15e12649ea08feEli Friedman Value *SrcPtr = EmitVAListRef(E->getArg(1)); 231a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson 2322acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Type = Int8PtrTy; 233a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson 234a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson DstPtr = Builder.CreateBitCast(DstPtr, Type); 235a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson SrcPtr = Builder.CreateBitCast(SrcPtr, Type); 2361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return RValue::get(Builder.CreateCall2(CGM.getIntrinsic(Intrinsic::vacopy), 2373eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner DstPtr, SrcPtr)); 238a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson } 239258f930227c1a102c9c22eee88df65f748863425Jim Grosbach case Builtin::BI__builtin_abs: 240f7b2d8b3b1971e73e2d2f0662520dc7693235a7fEli Friedman case Builtin::BI__builtin_labs: 241f7b2d8b3b1971e73e2d2f0662520dc7693235a7fEli Friedman case Builtin::BI__builtin_llabs: { 2421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *ArgValue = EmitScalarExpr(E->getArg(0)); 2431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2449a847f598c4907a72b8593b364b9e6b94b086e75Chris Lattner Value *NegOp = Builder.CreateNeg(ArgValue, "neg"); 2451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *CmpResult = 2461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Builder.CreateICmpSGE(ArgValue, 247c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson llvm::Constant::getNullValue(ArgValue->getType()), 2489a847f598c4907a72b8593b364b9e6b94b086e75Chris Lattner "abscond"); 2491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *Result = 250c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs"); 2511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 252c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson return RValue::get(Result); 253c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson } 254258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 255ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian case Builtin::BI__builtin_conj: 256ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian case Builtin::BI__builtin_conjf: 257ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian case Builtin::BI__builtin_conjl: { 258ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); 259ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian Value *Real = ComplexVal.first; 260ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian Value *Imag = ComplexVal.second; 261258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Value *Zero = 262258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Imag->getType()->isFPOrFPVectorTy() 263ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian ? llvm::ConstantFP::getZeroValueForNegation(Imag->getType()) 264ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian : llvm::Constant::getNullValue(Imag->getType()); 265258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 266ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian Imag = Builder.CreateFSub(Zero, Imag, "sub"); 267ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian return RValue::getComplex(std::make_pair(Real, Imag)); 268ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian } 269ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian case Builtin::BI__builtin_creal: 270ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian case Builtin::BI__builtin_crealf: 27108cc03fcd97c3886b004d861aadbc28de70092c5Meador Inge case Builtin::BI__builtin_creall: 27208cc03fcd97c3886b004d861aadbc28de70092c5Meador Inge case Builtin::BIcreal: 27308cc03fcd97c3886b004d861aadbc28de70092c5Meador Inge case Builtin::BIcrealf: 27408cc03fcd97c3886b004d861aadbc28de70092c5Meador Inge case Builtin::BIcreall: { 275ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); 276ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian return RValue::get(ComplexVal.first); 277ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian } 278258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 279ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian case Builtin::BI__builtin_cimag: 280ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian case Builtin::BI__builtin_cimagf: 28108cc03fcd97c3886b004d861aadbc28de70092c5Meador Inge case Builtin::BI__builtin_cimagl: 28208cc03fcd97c3886b004d861aadbc28de70092c5Meador Inge case Builtin::BIcimag: 28308cc03fcd97c3886b004d861aadbc28de70092c5Meador Inge case Builtin::BIcimagf: 28408cc03fcd97c3886b004d861aadbc28de70092c5Meador Inge case Builtin::BIcimagl: { 285ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); 286ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian return RValue::get(ComplexVal.second); 287ce23bb7cdc51db26411d75da3b20818ac2cc1db6Fariborz Jahanian } 288258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 289a49a2839266f0bac2b6286e9f49fdc0c292938feBenjamin Kramer case Builtin::BI__builtin_ctzs: 2903a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson case Builtin::BI__builtin_ctz: 2913a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson case Builtin::BI__builtin_ctzl: 2923a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson case Builtin::BI__builtin_ctzll: { 2933a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson Value *ArgValue = EmitScalarExpr(E->getArg(0)); 2941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2959cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ArgType = ArgValue->getType(); 2968dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType); 2973a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson 2982acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ResultType = ConvertType(E->getType()); 2998b30a9379f730875ba8fb2d0fe2d43611e0c20ffBob Wilson Value *ZeroUndef = Builder.getInt1(Target.isCLZForZeroUndef()); 3008b30a9379f730875ba8fb2d0fe2d43611e0c20ffBob Wilson Value *Result = Builder.CreateCall2(F, ArgValue, ZeroUndef); 3013a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson if (Result->getType() != ResultType) 302eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 303eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 3043a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson return RValue::get(Result); 3053a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson } 306a49a2839266f0bac2b6286e9f49fdc0c292938feBenjamin Kramer case Builtin::BI__builtin_clzs: 307f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman case Builtin::BI__builtin_clz: 308f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman case Builtin::BI__builtin_clzl: 309f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman case Builtin::BI__builtin_clzll: { 310f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman Value *ArgValue = EmitScalarExpr(E->getArg(0)); 3111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3129cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ArgType = ArgValue->getType(); 3138dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType); 314f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman 3152acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ResultType = ConvertType(E->getType()); 3168b30a9379f730875ba8fb2d0fe2d43611e0c20ffBob Wilson Value *ZeroUndef = Builder.getInt1(Target.isCLZForZeroUndef()); 3178b30a9379f730875ba8fb2d0fe2d43611e0c20ffBob Wilson Value *Result = Builder.CreateCall2(F, ArgValue, ZeroUndef); 318f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman if (Result->getType() != ResultType) 319eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 320eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 321f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman return RValue::get(Result); 322f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman } 32304b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_ffs: 32404b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_ffsl: 32504b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_ffsll: { 32604b290030eee33295600728450f348989d1a627eDaniel Dunbar // ffs(x) -> x ? cttz(x) + 1 : 0 32704b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *ArgValue = EmitScalarExpr(E->getArg(0)); 3281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3299cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ArgType = ArgValue->getType(); 3308dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType); 3311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3322acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ResultType = ConvertType(E->getType()); 33350058ec63f38eabeb94391a61d2e7fb18a062173Chandler Carruth Value *Tmp = Builder.CreateAdd(Builder.CreateCall2(F, ArgValue, 33450058ec63f38eabeb94391a61d2e7fb18a062173Chandler Carruth Builder.getTrue()), 335578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer llvm::ConstantInt::get(ArgType, 1)); 336c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Value *Zero = llvm::Constant::getNullValue(ArgType); 33704b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero"); 33804b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp, "ffs"); 33904b290030eee33295600728450f348989d1a627eDaniel Dunbar if (Result->getType() != ResultType) 340eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 341eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 34204b290030eee33295600728450f348989d1a627eDaniel Dunbar return RValue::get(Result); 34304b290030eee33295600728450f348989d1a627eDaniel Dunbar } 34404b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_parity: 34504b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_parityl: 34604b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_parityll: { 34704b290030eee33295600728450f348989d1a627eDaniel Dunbar // parity(x) -> ctpop(x) & 1 34804b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *ArgValue = EmitScalarExpr(E->getArg(0)); 3491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3509cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ArgType = ArgValue->getType(); 3518dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType); 3521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3532acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ResultType = ConvertType(E->getType()); 354578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Value *Tmp = Builder.CreateCall(F, ArgValue); 355578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Value *Result = Builder.CreateAnd(Tmp, llvm::ConstantInt::get(ArgType, 1)); 35604b290030eee33295600728450f348989d1a627eDaniel Dunbar if (Result->getType() != ResultType) 357eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 358eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 35904b290030eee33295600728450f348989d1a627eDaniel Dunbar return RValue::get(Result); 36004b290030eee33295600728450f348989d1a627eDaniel Dunbar } 36104b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_popcount: 36204b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_popcountl: 36304b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_popcountll: { 36404b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *ArgValue = EmitScalarExpr(E->getArg(0)); 3651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3669cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ArgType = ArgValue->getType(); 3678dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType); 3681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3692acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ResultType = ConvertType(E->getType()); 370578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Value *Result = Builder.CreateCall(F, ArgValue); 37104b290030eee33295600728450f348989d1a627eDaniel Dunbar if (Result->getType() != ResultType) 372eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 373eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 37404b290030eee33295600728450f348989d1a627eDaniel Dunbar return RValue::get(Result); 37504b290030eee33295600728450f348989d1a627eDaniel Dunbar } 376e42b8a596886fc98e367c73e54d761446700029eFariborz Jahanian case Builtin::BI__builtin_expect: { 377dd697bc8629f0fa6777245610d52ca7ceb3b67f4Fariborz Jahanian Value *ArgValue = EmitScalarExpr(E->getArg(0)); 3789cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ArgType = ArgValue->getType(); 379558229f267d2cdee69639df04382082e7c7ad54cJakub Staszak 3808dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *FnExpect = CGM.getIntrinsic(Intrinsic::expect, ArgType); 381558229f267d2cdee69639df04382082e7c7ad54cJakub Staszak Value *ExpectedValue = EmitScalarExpr(E->getArg(1)); 382558229f267d2cdee69639df04382082e7c7ad54cJakub Staszak 383558229f267d2cdee69639df04382082e7c7ad54cJakub Staszak Value *Result = Builder.CreateCall2(FnExpect, ArgValue, ExpectedValue, 384558229f267d2cdee69639df04382082e7c7ad54cJakub Staszak "expval"); 385558229f267d2cdee69639df04382082e7c7ad54cJakub Staszak return RValue::get(Result); 386e42b8a596886fc98e367c73e54d761446700029eFariborz Jahanian } 387d190057934331390ff67ebf51d66186dd5e392f0Benjamin Kramer case Builtin::BI__builtin_bswap16: 388df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson case Builtin::BI__builtin_bswap32: 389df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson case Builtin::BI__builtin_bswap64: { 3901feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner Value *ArgValue = EmitScalarExpr(E->getArg(0)); 3919cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ArgType = ArgValue->getType(); 3928dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::bswap, ArgType); 393578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return RValue::get(Builder.CreateCall(F, ArgValue)); 3941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 395d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar case Builtin::BI__builtin_object_size: { 396c6794850a570a91c5f224b6f0293db9f560f4213Richard Smith // We rely on constant folding to deal with expressions with side effects. 397c6794850a570a91c5f224b6f0293db9f560f4213Richard Smith assert(!E->getArg(0)->HasSideEffects(getContext()) && 398c6794850a570a91c5f224b6f0293db9f560f4213Richard Smith "should have been constant folded"); 399c6794850a570a91c5f224b6f0293db9f560f4213Richard Smith 400b16d32f74ffc467a5604934a1f844906be20cf7dMike Stump // We pass this builtin onto the optimizer so that it can 401b16d32f74ffc467a5604934a1f844906be20cf7dMike Stump // figure out the object size in more complex cases. 4028dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer llvm::Type *ResType = ConvertType(E->getType()); 403258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 404fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher // LLVM only supports 0 and 2, make sure that we pass along that 405fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher // as a boolean. 406fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher Value *Ty = EmitScalarExpr(E->getArg(1)); 407fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher ConstantInt *CI = dyn_cast<ConstantInt>(Ty); 408fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher assert(CI); 409fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher uint64_t val = CI->getZExtValue(); 410258f930227c1a102c9c22eee88df65f748863425Jim Grosbach CI = ConstantInt::get(Builder.getInt1Ty(), (val & 0x2) >> 1); 411258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 4128dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::objectsize, ResType); 4133e86a0433db4c664d29f2b19eb977138e071a68aNuno Lopes return RValue::get(Builder.CreateCall2(F, EmitScalarExpr(E->getArg(0)),CI)); 414d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar } 4154493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar case Builtin::BI__builtin_prefetch: { 4164493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0)); 4174493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar // FIXME: Technically these constants should of type 'int', yes? 4181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump RW = (E->getNumArgs() > 1) ? EmitScalarExpr(E->getArg(1)) : 41977b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::ConstantInt::get(Int32Ty, 0); 4201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : 42177b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::ConstantInt::get(Int32Ty, 3); 4222eccb672799d19fb535ce349566fea6729cbb891Bruno Cardoso Lopes Value *Data = llvm::ConstantInt::get(Int32Ty, 1); 4238dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 4242eccb672799d19fb535ce349566fea6729cbb891Bruno Cardoso Lopes return RValue::get(Builder.CreateCall4(F, Address, RW, Locality, Data)); 4254493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar } 426a841c19f7860393d6319bf40e9d662284462771dHal Finkel case Builtin::BI__builtin_readcyclecounter: { 427a841c19f7860393d6319bf40e9d662284462771dHal Finkel Value *F = CGM.getIntrinsic(Intrinsic::readcyclecounter); 428a841c19f7860393d6319bf40e9d662284462771dHal Finkel return RValue::get(Builder.CreateCall(F)); 429a841c19f7860393d6319bf40e9d662284462771dHal Finkel } 4304493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar case Builtin::BI__builtin_trap: { 4318dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::trap); 4324493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar return RValue::get(Builder.CreateCall(F)); 433df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson } 434385cc5f01b59af0183a825351d93695ca7185091Nico Weber case Builtin::BI__debugbreak: { 435385cc5f01b59af0183a825351d93695ca7185091Nico Weber Value *F = CGM.getIntrinsic(Intrinsic::debugtrap); 436385cc5f01b59af0183a825351d93695ca7185091Nico Weber return RValue::get(Builder.CreateCall(F)); 437385cc5f01b59af0183a825351d93695ca7185091Nico Weber } 43821190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner case Builtin::BI__builtin_unreachable: { 4394f45bc099f2665bc6e4bcbb169aa452390dbf3feWill Dietz if (SanOpts->Unreachable) 4404def70d3040e73707c738f7c366737a986135edfRichard Smith EmitCheck(Builder.getFalse(), "builtin_unreachable", 4414def70d3040e73707c738f7c366737a986135edfRichard Smith EmitCheckSourceLocation(E->getExprLoc()), 442cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko ArrayRef<llvm::Value *>(), CRK_Unrecoverable); 443cd5b22e12b6513163dd131589746c194090f14e6John McCall else 444cd5b22e12b6513163dd131589746c194090f14e6John McCall Builder.CreateUnreachable(); 445cd5b22e12b6513163dd131589746c194090f14e6John McCall 446cd5b22e12b6513163dd131589746c194090f14e6John McCall // We do need to preserve an insertion point. 447d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall EmitBlock(createBasicBlock("unreachable.cont")); 448cd5b22e12b6513163dd131589746c194090f14e6John McCall 449cd5b22e12b6513163dd131589746c194090f14e6John McCall return RValue::get(0); 45021190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner } 451258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 452a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar case Builtin::BI__builtin_powi: 453a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar case Builtin::BI__builtin_powif: 454a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar case Builtin::BI__builtin_powil: { 455a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar Value *Base = EmitScalarExpr(E->getArg(0)); 456a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar Value *Exponent = EmitScalarExpr(E->getArg(1)); 4579cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ArgType = Base->getType(); 4588dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::powi, ArgType); 459578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return RValue::get(Builder.CreateCall2(F, Base, Exponent)); 460a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar } 461a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar 462fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isgreater: 463fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isgreaterequal: 464fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isless: 465fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_islessequal: 466fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_islessgreater: 467fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isunordered: { 468fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner // Ordered comparisons: we know the arguments to these are matching scalar 469fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner // floating point values. 4701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *LHS = EmitScalarExpr(E->getArg(0)); 471fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner Value *RHS = EmitScalarExpr(E->getArg(1)); 4721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 473fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner switch (BuiltinID) { 474b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("Unknown ordered comparison"); 475fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isgreater: 476fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp"); 477fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 478fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isgreaterequal: 479fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp"); 480fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 481fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isless: 482fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp"); 483fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 484fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_islessequal: 485fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp"); 486fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 487fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_islessgreater: 488fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp"); 489fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 4901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case Builtin::BI__builtin_isunordered: 491fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp"); 492fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 493fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner } 494fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner // ZExt bool to int type. 495578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType()))); 496fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner } 497d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman case Builtin::BI__builtin_isnan: { 498d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman Value *V = EmitScalarExpr(E->getArg(0)); 499d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman V = Builder.CreateFCmpUNO(V, V, "cmp"); 500578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 501d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman } 502258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 503420b11850d3f4557421f43f519b59d528329c668Chris Lattner case Builtin::BI__builtin_isinf: { 504420b11850d3f4557421f43f519b59d528329c668Chris Lattner // isinf(x) --> fabs(x) == infinity 505420b11850d3f4557421f43f519b59d528329c668Chris Lattner Value *V = EmitScalarExpr(E->getArg(0)); 506420b11850d3f4557421f43f519b59d528329c668Chris Lattner V = EmitFAbs(*this, V, E->getArg(0)->getType()); 507258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 508420b11850d3f4557421f43f519b59d528329c668Chris Lattner V = Builder.CreateFCmpOEQ(V, ConstantFP::getInfinity(V->getType()),"isinf"); 509578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 510420b11850d3f4557421f43f519b59d528329c668Chris Lattner } 511258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 51258ae5b4b1e2fc02b95d6650af5755a59639aa153Chris Lattner // TODO: BI__builtin_isinf_sign 51358ae5b4b1e2fc02b95d6650af5755a59639aa153Chris Lattner // isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0 5146349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer 5156349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer case Builtin::BI__builtin_isnormal: { 5166349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer // isnormal(x) --> x == x && fabsf(x) < infinity && fabsf(x) >= float_min 5176349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer Value *V = EmitScalarExpr(E->getArg(0)); 5186349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq"); 5196349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer 5206349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer Value *Abs = EmitFAbs(*this, V, E->getArg(0)->getType()); 5216349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer Value *IsLessThanInf = 5226349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer Builder.CreateFCmpULT(Abs, ConstantFP::getInfinity(V->getType()),"isinf"); 5236349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer APFloat Smallest = APFloat::getSmallestNormalized( 5246349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer getContext().getFloatTypeSemantics(E->getArg(0)->getType())); 5256349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer Value *IsNormal = 5266349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer Builder.CreateFCmpUGE(Abs, ConstantFP::get(V->getContext(), Smallest), 5276349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer "isnormal"); 5286349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer V = Builder.CreateAnd(Eq, IsLessThanInf, "and"); 5296349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer V = Builder.CreateAnd(V, IsNormal, "and"); 5306349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 5316349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer } 5326349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer 533ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner case Builtin::BI__builtin_isfinite: { 534ef004ec5adb0e11815cef3435fa5ac7366d783a9Julien Lerouge // isfinite(x) --> x == x && fabs(x) != infinity; 535ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner Value *V = EmitScalarExpr(E->getArg(0)); 536ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq"); 537258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 538ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner Value *Abs = EmitFAbs(*this, V, E->getArg(0)->getType()); 539ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner Value *IsNotInf = 540ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner Builder.CreateFCmpUNE(Abs, ConstantFP::getInfinity(V->getType()),"isinf"); 541258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 542ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner V = Builder.CreateAnd(Eq, IsNotInf, "and"); 543ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 544ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner } 5457867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer 5467867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer case Builtin::BI__builtin_fpclassify: { 5477867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *V = EmitScalarExpr(E->getArg(5)); 5482acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Ty = ConvertType(E->getArg(5)->getType()); 5497867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer 5507867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer // Create Result 5517867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer BasicBlock *Begin = Builder.GetInsertBlock(); 5527867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer BasicBlock *End = createBasicBlock("fpclassify_end", this->CurFn); 5537867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.SetInsertPoint(End); 5547867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer PHINode *Result = 555bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad Builder.CreatePHI(ConvertType(E->getArg(0)->getType()), 4, 5567867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer "fpclassify_result"); 5577867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer 5587867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer // if (V==0) return FP_ZERO 5597867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.SetInsertPoint(Begin); 5607867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *IsZero = Builder.CreateFCmpOEQ(V, Constant::getNullValue(Ty), 5617867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer "iszero"); 5627867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *ZeroLiteral = EmitScalarExpr(E->getArg(4)); 5637867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer BasicBlock *NotZero = createBasicBlock("fpclassify_not_zero", this->CurFn); 5647867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.CreateCondBr(IsZero, End, NotZero); 5657867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Result->addIncoming(ZeroLiteral, Begin); 5667867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer 5677867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer // if (V != V) return FP_NAN 5687867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.SetInsertPoint(NotZero); 5697867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *IsNan = Builder.CreateFCmpUNO(V, V, "cmp"); 5707867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *NanLiteral = EmitScalarExpr(E->getArg(0)); 5717867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer BasicBlock *NotNan = createBasicBlock("fpclassify_not_nan", this->CurFn); 5727867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.CreateCondBr(IsNan, End, NotNan); 5737867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Result->addIncoming(NanLiteral, NotZero); 5747867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer 5757867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer // if (fabs(V) == infinity) return FP_INFINITY 5767867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.SetInsertPoint(NotNan); 5777867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *VAbs = EmitFAbs(*this, V, E->getArg(5)->getType()); 5787867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *IsInf = 5797867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.CreateFCmpOEQ(VAbs, ConstantFP::getInfinity(V->getType()), 5807867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer "isinf"); 5817867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *InfLiteral = EmitScalarExpr(E->getArg(1)); 5827867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer BasicBlock *NotInf = createBasicBlock("fpclassify_not_inf", this->CurFn); 5837867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.CreateCondBr(IsInf, End, NotInf); 5847867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Result->addIncoming(InfLiteral, NotNan); 5857867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer 5867867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer // if (fabs(V) >= MIN_NORMAL) return FP_NORMAL else FP_SUBNORMAL 5877867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.SetInsertPoint(NotInf); 5887867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer APFloat Smallest = APFloat::getSmallestNormalized( 5897867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer getContext().getFloatTypeSemantics(E->getArg(5)->getType())); 5907867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *IsNormal = 5917867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.CreateFCmpUGE(VAbs, ConstantFP::get(V->getContext(), Smallest), 5927867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer "isnormal"); 5937867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *NormalResult = 5947867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.CreateSelect(IsNormal, EmitScalarExpr(E->getArg(2)), 5957867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer EmitScalarExpr(E->getArg(3))); 5967867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.CreateBr(End); 5977867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Result->addIncoming(NormalResult, NotInf); 5987867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer 5997867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer // return Result 6007867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.SetInsertPoint(End); 6017867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer return RValue::get(Result); 6027867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer } 603258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 604b52fe9ce99970955a5f581f5c66fcd89be9a268bEli Friedman case Builtin::BIalloca: 6059e800e3dd80d77f6c47054738177bf824089f55aChris Lattner case Builtin::BI__builtin_alloca: { 6069e800e3dd80d77f6c47054738177bf824089f55aChris Lattner Value *Size = EmitScalarExpr(E->getArg(0)); 607578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return RValue::get(Builder.CreateAlloca(Builder.getInt8Ty(), Size)); 6081caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar } 609e6dddfd907f6ea58daed5e26eeaacd893d98db9bEli Friedman case Builtin::BIbzero: 6101caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar case Builtin::BI__builtin_bzero: { 611ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Dest = 612ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(0)); 6133ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Value *SizeVal = EmitScalarExpr(E->getArg(1)); 614ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Builder.CreateMemSet(Dest.first, Builder.getInt8(0), SizeVal, 615ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Dest.second, false); 616ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return RValue::get(Dest.first); 6179e800e3dd80d77f6c47054738177bf824089f55aChris Lattner } 618e6ec205d6d0f4aec27bf49ca1e8fbb139acc2f2bEli Friedman case Builtin::BImemcpy: 619d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman case Builtin::BI__builtin_memcpy: { 620ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Dest = 621ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(0)); 622ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Src = 623ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(1)); 6243ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Value *SizeVal = EmitScalarExpr(E->getArg(2)); 625ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman unsigned Align = std::min(Dest.second, Src.second); 626ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Builder.CreateMemCpy(Dest.first, Src.first, SizeVal, Align, false); 627ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return RValue::get(Dest.first); 6281caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar } 629258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 630a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner case Builtin::BI__builtin___memcpy_chk: { 631f3477c13eeaf11b32a41f181398fb5deffd0dd73Sylvestre Ledru // fold __builtin_memcpy_chk(x, y, cst1, cst2) to memcpy iff cst1<=cst2. 632a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith llvm::APSInt Size, DstSize; 633a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || 634a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) 635a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner break; 636a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner if (Size.ugt(DstSize)) 637a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner break; 638ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Dest = 639ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(0)); 640ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Src = 641ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(1)); 642a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); 643ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman unsigned Align = std::min(Dest.second, Src.second); 644ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Builder.CreateMemCpy(Dest.first, Src.first, SizeVal, Align, false); 645ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return RValue::get(Dest.first); 646a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner } 647258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 6488e2eab27056a78bf1db50ee09929438ed5ea9d93Fariborz Jahanian case Builtin::BI__builtin_objc_memmove_collectable: { 64955bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian Value *Address = EmitScalarExpr(E->getArg(0)); 65055bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian Value *SrcAddr = EmitScalarExpr(E->getArg(1)); 65155bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian Value *SizeVal = EmitScalarExpr(E->getArg(2)); 652258f930227c1a102c9c22eee88df65f748863425Jim Grosbach CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, 65355bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian Address, SrcAddr, SizeVal); 65455bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian return RValue::get(Address); 65555bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian } 656a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner 657a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner case Builtin::BI__builtin___memmove_chk: { 658f3477c13eeaf11b32a41f181398fb5deffd0dd73Sylvestre Ledru // fold __builtin_memmove_chk(x, y, cst1, cst2) to memmove iff cst1<=cst2. 659a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith llvm::APSInt Size, DstSize; 660a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || 661a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) 662a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner break; 663a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner if (Size.ugt(DstSize)) 664a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner break; 665ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Dest = 666ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(0)); 667ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Src = 668ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(1)); 669a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); 670ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman unsigned Align = std::min(Dest.second, Src.second); 671ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Builder.CreateMemMove(Dest.first, Src.first, SizeVal, Align, false); 672ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return RValue::get(Dest.first); 673a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner } 674a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner 675e6ec205d6d0f4aec27bf49ca1e8fbb139acc2f2bEli Friedman case Builtin::BImemmove: 6761caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar case Builtin::BI__builtin_memmove: { 677ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Dest = 678ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(0)); 679ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Src = 680ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(1)); 6813ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Value *SizeVal = EmitScalarExpr(E->getArg(2)); 682ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman unsigned Align = std::min(Dest.second, Src.second); 683ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Builder.CreateMemMove(Dest.first, Src.first, SizeVal, Align, false); 684ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return RValue::get(Dest.first); 6851caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar } 686e6ec205d6d0f4aec27bf49ca1e8fbb139acc2f2bEli Friedman case Builtin::BImemset: 6871caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar case Builtin::BI__builtin_memset: { 688ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Dest = 689ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(0)); 6909f0c7cc36d29cf591c33962931f5862847145f3eBenjamin Kramer Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), 6919f0c7cc36d29cf591c33962931f5862847145f3eBenjamin Kramer Builder.getInt8Ty()); 6923ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Value *SizeVal = EmitScalarExpr(E->getArg(2)); 693ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Builder.CreateMemSet(Dest.first, ByteVal, SizeVal, Dest.second, false); 694ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return RValue::get(Dest.first); 695d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman } 696a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner case Builtin::BI__builtin___memset_chk: { 697f3477c13eeaf11b32a41f181398fb5deffd0dd73Sylvestre Ledru // fold __builtin_memset_chk(x, y, cst1, cst2) to memset iff cst1<=cst2. 698a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith llvm::APSInt Size, DstSize; 699a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || 700a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) 701a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner break; 702a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner if (Size.ugt(DstSize)) 703a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner break; 704ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Dest = 705ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(0)); 706a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), 707a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner Builder.getInt8Ty()); 708a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); 709ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Builder.CreateMemSet(Dest.first, ByteVal, SizeVal, Dest.second, false); 710ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return RValue::get(Dest.first); 711a5e5e0f41e1dcee4603244ccea3d3956c55c23acChris Lattner } 712fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall case Builtin::BI__builtin_dwarf_cfa: { 713fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // The offset in bytes from the first argument to the CFA. 714fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // 715fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // Why on earth is this in the frontend? Is there any reason at 716fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // all that the backend can't reasonably determine this while 717fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // lowering llvm.eh.dwarf.cfa()? 718fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // 719fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // TODO: If there's a satisfactory reason, add a target hook for 720fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // this instead of hard-coding 0, which is correct for most targets. 721fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall int32_t Offset = 0; 722fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall 7238dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::eh_dwarf_cfa); 724258f930227c1a102c9c22eee88df65f748863425Jim Grosbach return RValue::get(Builder.CreateCall(F, 72577b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::ConstantInt::get(Int32Ty, Offset))); 726fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall } 727256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman case Builtin::BI__builtin_return_address: { 72883c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov Value *Depth = EmitScalarExpr(E->getArg(0)); 729578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Depth = Builder.CreateIntCast(Depth, Int32Ty, false); 7308dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::returnaddress); 73183c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov return RValue::get(Builder.CreateCall(F, Depth)); 732256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman } 733256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman case Builtin::BI__builtin_frame_address: { 73483c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov Value *Depth = EmitScalarExpr(E->getArg(0)); 735578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Depth = Builder.CreateIntCast(Depth, Int32Ty, false); 7368dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::frameaddress); 73783c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov return RValue::get(Builder.CreateCall(F, Depth)); 738256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman } 7393b660efb9f9fa3e87096f4a96a2093cd17c43c2eEli Friedman case Builtin::BI__builtin_extract_return_addr: { 740492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall Value *Address = EmitScalarExpr(E->getArg(0)); 741492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall Value *Result = getTargetHooks().decodeReturnAddress(*this, Address); 742492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall return RValue::get(Result); 743492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall } 744492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall case Builtin::BI__builtin_frob_return_addr: { 745492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall Value *Address = EmitScalarExpr(E->getArg(0)); 746492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall Value *Result = getTargetHooks().encodeReturnAddress(*this, Address); 747492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall return RValue::get(Result); 7483b660efb9f9fa3e87096f4a96a2093cd17c43c2eEli Friedman } 7496374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall case Builtin::BI__builtin_dwarf_sp_column: { 7502acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::IntegerType *Ty 7516374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall = cast<llvm::IntegerType>(ConvertType(E->getType())); 7526374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall int Column = getTargetHooks().getDwarfEHStackPointer(CGM); 7536374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall if (Column == -1) { 7546374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall CGM.ErrorUnsupported(E, "__builtin_dwarf_sp_column"); 7556374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall return RValue::get(llvm::UndefValue::get(Ty)); 7566374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall } 7576374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall return RValue::get(llvm::ConstantInt::get(Ty, Column, true)); 7586374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall } 7596374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall case Builtin::BI__builtin_init_dwarf_reg_size_table: { 7606374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall Value *Address = EmitScalarExpr(E->getArg(0)); 7616374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall if (getTargetHooks().initDwarfEHRegSizeTable(*this, Address)) 7626374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall CGM.ErrorUnsupported(E, "__builtin_init_dwarf_reg_size_table"); 7636374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall return RValue::get(llvm::UndefValue::get(ConvertType(E->getType()))); 7646374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall } 7657ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall case Builtin::BI__builtin_eh_return: { 7667ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall Value *Int = EmitScalarExpr(E->getArg(0)); 7677ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall Value *Ptr = EmitScalarExpr(E->getArg(1)); 7687ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall 7692acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::IntegerType *IntTy = cast<llvm::IntegerType>(Int->getType()); 7707ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall assert((IntTy->getBitWidth() == 32 || IntTy->getBitWidth() == 64) && 7717ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall "LLVM's __builtin_eh_return only supports 32- and 64-bit variants"); 7727ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall Value *F = CGM.getIntrinsic(IntTy->getBitWidth() == 32 7737ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall ? Intrinsic::eh_return_i32 7748dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer : Intrinsic::eh_return_i64); 7757ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall Builder.CreateCall2(F, Int, Ptr); 776cd5b22e12b6513163dd131589746c194090f14e6John McCall Builder.CreateUnreachable(); 777cd5b22e12b6513163dd131589746c194090f14e6John McCall 778cd5b22e12b6513163dd131589746c194090f14e6John McCall // We do need to preserve an insertion point. 779d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall EmitBlock(createBasicBlock("builtin_eh_return.cont")); 780cd5b22e12b6513163dd131589746c194090f14e6John McCall 781cd5b22e12b6513163dd131589746c194090f14e6John McCall return RValue::get(0); 7827ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall } 783a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman case Builtin::BI__builtin_unwind_init: { 7848dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init); 785a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman return RValue::get(Builder.CreateCall(F)); 786a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman } 7875e11085830d4d4c53ff75575ab75889ee5126854John McCall case Builtin::BI__builtin_extend_pointer: { 7885e11085830d4d4c53ff75575ab75889ee5126854John McCall // Extends a pointer to the size of an _Unwind_Word, which is 789d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // uint64_t on all platforms. Generally this gets poked into a 790d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // register and eventually used as an address, so if the 791d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // addressing registers are wider than pointers and the platform 792d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // doesn't implicitly ignore high-order bits when doing 793d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // addressing, we need to make sure we zext / sext based on 794d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // the platform's expectations. 7955e11085830d4d4c53ff75575ab75889ee5126854John McCall // 7965e11085830d4d4c53ff75575ab75889ee5126854John McCall // See: http://gcc.gnu.org/ml/gcc-bugs/2002-02/msg00237.html 797d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall 798d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // Cast the pointer to intptr_t. 7995e11085830d4d4c53ff75575ab75889ee5126854John McCall Value *Ptr = EmitScalarExpr(E->getArg(0)); 800d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall Value *Result = Builder.CreatePtrToInt(Ptr, IntPtrTy, "extend.cast"); 801d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall 802d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // If that's 64 bits, we're done. 803d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall if (IntPtrTy->getBitWidth() == 64) 804d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall return RValue::get(Result); 805d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall 806d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // Otherwise, ask the codegen data what to do. 807492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall if (getTargetHooks().extendPointerWithSExt()) 808d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall return RValue::get(Builder.CreateSExt(Result, Int64Ty, "extend.sext")); 809d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall else 810d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall return RValue::get(Builder.CreateZExt(Result, Int64Ty, "extend.zext")); 8115e11085830d4d4c53ff75575ab75889ee5126854John McCall } 812a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman case Builtin::BI__builtin_setjmp: { 81378673d9f910e8dfe13248c2426c51d8f9fb28572John McCall // Buffer is a void**. 814a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *Buf = EmitScalarExpr(E->getArg(0)); 81578673d9f910e8dfe13248c2426c51d8f9fb28572John McCall 81678673d9f910e8dfe13248c2426c51d8f9fb28572John McCall // Store the frame pointer to the setjmp buffer. 817a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *FrameAddr = 81878673d9f910e8dfe13248c2426c51d8f9fb28572John McCall Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress), 81977b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner ConstantInt::get(Int32Ty, 0)); 820a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Builder.CreateStore(FrameAddr, Buf); 82178673d9f910e8dfe13248c2426c51d8f9fb28572John McCall 8226d172e2985346e55095c75f456901ea5d40fddaaJim Grosbach // Store the stack pointer to the setjmp buffer. 8236d172e2985346e55095c75f456901ea5d40fddaaJim Grosbach Value *StackAddr = 8246d172e2985346e55095c75f456901ea5d40fddaaJim Grosbach Builder.CreateCall(CGM.getIntrinsic(Intrinsic::stacksave)); 8256d172e2985346e55095c75f456901ea5d40fddaaJim Grosbach Value *StackSaveSlot = 82677b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Builder.CreateGEP(Buf, ConstantInt::get(Int32Ty, 2)); 8276d172e2985346e55095c75f456901ea5d40fddaaJim Grosbach Builder.CreateStore(StackAddr, StackSaveSlot); 8286d172e2985346e55095c75f456901ea5d40fddaaJim Grosbach 82978673d9f910e8dfe13248c2426c51d8f9fb28572John McCall // Call LLVM's EH setjmp, which is lightweight. 83078673d9f910e8dfe13248c2426c51d8f9fb28572John McCall Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp); 831d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Buf = Builder.CreateBitCast(Buf, Int8PtrTy); 832a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman return RValue::get(Builder.CreateCall(F, Buf)); 833a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman } 834a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman case Builtin::BI__builtin_longjmp: { 835a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *Buf = EmitScalarExpr(E->getArg(0)); 836d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Buf = Builder.CreateBitCast(Buf, Int8PtrTy); 83778673d9f910e8dfe13248c2426c51d8f9fb28572John McCall 83878673d9f910e8dfe13248c2426c51d8f9fb28572John McCall // Call LLVM's EH longjmp, which is lightweight. 83978673d9f910e8dfe13248c2426c51d8f9fb28572John McCall Builder.CreateCall(CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp), Buf); 84078673d9f910e8dfe13248c2426c51d8f9fb28572John McCall 841cd5b22e12b6513163dd131589746c194090f14e6John McCall // longjmp doesn't return; mark this as unreachable. 842cd5b22e12b6513163dd131589746c194090f14e6John McCall Builder.CreateUnreachable(); 843cd5b22e12b6513163dd131589746c194090f14e6John McCall 844cd5b22e12b6513163dd131589746c194090f14e6John McCall // We do need to preserve an insertion point. 845d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall EmitBlock(createBasicBlock("longjmp.cont")); 846cd5b22e12b6513163dd131589746c194090f14e6John McCall 847cd5b22e12b6513163dd131589746c194090f14e6John McCall return RValue::get(0); 848a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman } 8491ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_add: 8501ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_sub: 8515caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or: 8525caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and: 8535caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor: 8545caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch: 8555caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch: 8565caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch: 8575caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch: 8585caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch: 8595caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap: 8605caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap: 8615caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set: 8625caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release: 86323aa9c8ca0bc441aab2a38a4c9fc7a1c9e9ac16aChris Lattner case Builtin::BI__sync_swap: 864b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Shouldn't make it through sema"); 8655caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_1: 8665caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_2: 8675caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_4: 8685caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_8: 8695caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_16: 870c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Add, E); 8715caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_1: 8725caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_2: 8735caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_4: 8745caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_8: 8755caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_16: 876c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Sub, E); 8775caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_1: 8785caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_2: 8795caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_4: 8805caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_8: 8815caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_16: 882c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Or, E); 8835caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_1: 8845caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_2: 8855caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_4: 8865caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_8: 8875caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_16: 888c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::And, E); 8895caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_1: 8905caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_2: 8915caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_4: 8925caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_8: 8935caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_16: 894c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xor, E); 8951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8965caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // Clang extensions: not overloaded yet. 8971ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_min: 898c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Min, E); 8991ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_max: 900c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Max, E); 9011ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_umin: 902c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::UMin, E); 9031ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_umax: 904c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::UMax, E); 9050002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar 9065caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_1: 9075caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_2: 9085caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_4: 9095caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_8: 9105caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_16: 911c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Add, E, 9120002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::Add); 9135caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_1: 9145caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_2: 9155caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_4: 9165caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_8: 9175caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_16: 918c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Sub, E, 9190002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::Sub); 9205caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_1: 9215caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_2: 9225caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_4: 9235caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_8: 9245caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_16: 925c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::And, E, 9260002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::And); 9275caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_1: 9285caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_2: 9295caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_4: 9305caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_8: 9315caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_16: 932c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Or, E, 9330002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::Or); 9345caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_1: 9355caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_2: 9365caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_4: 9375caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_8: 9385caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_16: 939c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Xor, E, 9400002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::Xor); 9411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9425caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap_1: 9435caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap_2: 9445caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap_4: 9455caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap_8: 946cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar case Builtin::BI__sync_val_compare_and_swap_16: { 94726815d97c5743481e317f17a8d53a6819d061862John McCall QualType T = E->getType(); 948d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::Value *DestPtr = EmitScalarExpr(E->getArg(0)); 949956a5a17713deb1b5b27893303c4f308a1bd2a62Micah Villmow unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); 950258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 9519cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::IntegerType *IntType = 952d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::IntegerType::get(getLLVMContext(), 953d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall getContext().getTypeSize(T)); 9549cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 955db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth 95626815d97c5743481e317f17a8d53a6819d061862John McCall Value *Args[3]; 95726815d97c5743481e317f17a8d53a6819d061862John McCall Args[0] = Builder.CreateBitCast(DestPtr, IntPtrType); 958d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Args[1] = EmitScalarExpr(E->getArg(1)); 9592acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ValueType = Args[1]->getType(); 960d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Args[1] = EmitToInt(*this, Args[1], T, IntType); 961d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Args[2] = EmitToInt(*this, EmitScalarExpr(E->getArg(2)), T, IntType); 96226815d97c5743481e317f17a8d53a6819d061862John McCall 963c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman Value *Result = Builder.CreateAtomicCmpXchg(Args[0], Args[1], Args[2], 964c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman llvm::SequentiallyConsistent); 965d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Result = EmitFromInt(*this, Result, T, ValueType); 96626815d97c5743481e317f17a8d53a6819d061862John McCall return RValue::get(Result); 967022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson } 9680002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar 9695caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap_1: 9705caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap_2: 9715caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap_4: 9725caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap_8: 973cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar case Builtin::BI__sync_bool_compare_and_swap_16: { 97426815d97c5743481e317f17a8d53a6819d061862John McCall QualType T = E->getArg(1)->getType(); 975d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::Value *DestPtr = EmitScalarExpr(E->getArg(0)); 976956a5a17713deb1b5b27893303c4f308a1bd2a62Micah Villmow unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); 977258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 9789cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::IntegerType *IntType = 979d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::IntegerType::get(getLLVMContext(), 980d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall getContext().getTypeSize(T)); 9819cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 982db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth 98326815d97c5743481e317f17a8d53a6819d061862John McCall Value *Args[3]; 98426815d97c5743481e317f17a8d53a6819d061862John McCall Args[0] = Builder.CreateBitCast(DestPtr, IntPtrType); 985d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Args[1] = EmitToInt(*this, EmitScalarExpr(E->getArg(1)), T, IntType); 986d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Args[2] = EmitToInt(*this, EmitScalarExpr(E->getArg(2)), T, IntType); 98726815d97c5743481e317f17a8d53a6819d061862John McCall 988db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth Value *OldVal = Args[1]; 989c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman Value *PrevVal = Builder.CreateAtomicCmpXchg(Args[0], Args[1], Args[2], 990c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman llvm::SequentiallyConsistent); 9910002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Value *Result = Builder.CreateICmpEQ(PrevVal, OldVal); 9920002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar // zext bool to int. 99326815d97c5743481e317f17a8d53a6819d061862John McCall Result = Builder.CreateZExt(Result, ConvertType(E->getType())); 99426815d97c5743481e317f17a8d53a6819d061862John McCall return RValue::get(Result); 9950002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar } 9960002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar 99723aa9c8ca0bc441aab2a38a4c9fc7a1c9e9ac16aChris Lattner case Builtin::BI__sync_swap_1: 99823aa9c8ca0bc441aab2a38a4c9fc7a1c9e9ac16aChris Lattner case Builtin::BI__sync_swap_2: 99923aa9c8ca0bc441aab2a38a4c9fc7a1c9e9ac16aChris Lattner case Builtin::BI__sync_swap_4: 100023aa9c8ca0bc441aab2a38a4c9fc7a1c9e9ac16aChris Lattner case Builtin::BI__sync_swap_8: 100123aa9c8ca0bc441aab2a38a4c9fc7a1c9e9ac16aChris Lattner case Builtin::BI__sync_swap_16: 1002c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E); 100323aa9c8ca0bc441aab2a38a4c9fc7a1c9e9ac16aChris Lattner 10045caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_1: 10055caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_2: 10065caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_4: 10075caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_8: 10085caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_16: 1009c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E); 1010cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar 10115caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release_1: 10125caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release_2: 10135caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release_4: 10145caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release_8: 1015f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner case Builtin::BI__sync_lock_release_16: { 1016f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner Value *Ptr = EmitScalarExpr(E->getArg(0)); 1017eb43f4a8f133c2bc510ae136a556e92b68a6ff44Eli Friedman QualType ElTy = E->getArg(0)->getType()->getPointeeType(); 1018eb43f4a8f133c2bc510ae136a556e92b68a6ff44Eli Friedman CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy); 1019ff993202abf6f5dc41c584c7103f5d39f248b3ddEli Friedman llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), 1020ff993202abf6f5dc41c584c7103f5d39f248b3ddEli Friedman StoreSize.getQuantity() * 8); 1021ff993202abf6f5dc41c584c7103f5d39f248b3ddEli Friedman Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); 1022258f930227c1a102c9c22eee88df65f748863425Jim Grosbach llvm::StoreInst *Store = 1023ff993202abf6f5dc41c584c7103f5d39f248b3ddEli Friedman Builder.CreateStore(llvm::Constant::getNullValue(ITy), Ptr); 1024eb43f4a8f133c2bc510ae136a556e92b68a6ff44Eli Friedman Store->setAlignment(StoreSize.getQuantity()); 1025eb43f4a8f133c2bc510ae136a556e92b68a6ff44Eli Friedman Store->setAtomic(llvm::Release); 1026eb4f81e174b11633f7b85f555ea5d2834d6dae8aDaniel Dunbar return RValue::get(0); 1027f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner } 1028ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar 1029f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner case Builtin::BI__sync_synchronize: { 1030c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman // We assume this is supposed to correspond to a C++0x-style 1031c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman // sequentially-consistent fence (i.e. this is only usable for 1032c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman // synchonization, not device I/O or anything like that). This intrinsic 1033258f930227c1a102c9c22eee88df65f748863425Jim Grosbach // is really badly designed in the sense that in theory, there isn't 1034c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman // any way to safely use it... but in practice, it mostly works 1035c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman // to use it with non-atomic loads and stores to get acquire/release 1036c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman // semantics. 1037c83b975f1fb9d11e10b5aa25029ae9bb5fa80e07Eli Friedman Builder.CreateFence(llvm::SequentiallyConsistent); 1038eb4f81e174b11633f7b85f555ea5d2834d6dae8aDaniel Dunbar return RValue::get(0); 1039f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner } 10401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10412c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case Builtin::BI__c11_atomic_is_lock_free: 10422c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case Builtin::BI__atomic_is_lock_free: { 10432c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith // Call "bool __atomic_is_lock_free(size_t size, void *ptr)". For the 10442c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith // __c11 builtin, ptr is 0 (indicating a properly-aligned object), since 10452c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith // _Atomic(T) is always properly-aligned. 10462c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith const char *LibCallName = "__atomic_is_lock_free"; 10472c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith CallArgList Args; 10482c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Args.add(RValue::get(EmitScalarExpr(E->getArg(0))), 10492c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith getContext().getSizeType()); 10502c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith if (BuiltinID == Builtin::BI__atomic_is_lock_free) 10512c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Args.add(RValue::get(EmitScalarExpr(E->getArg(1))), 10522c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith getContext().VoidPtrTy); 10532c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith else 10542c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Args.add(RValue::get(llvm::Constant::getNullValue(VoidPtrTy)), 10552c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith getContext().VoidPtrTy); 10562c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith const CGFunctionInfo &FuncInfo = 10570f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall CGM.getTypes().arrangeFreeFunctionCall(E->getType(), Args, 10580f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall FunctionType::ExtInfo(), 10590f3d0970dcdf6cf17550b86838dff12813968dbcJohn McCall RequiredArgs::All); 10602c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo); 10612c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName); 10622c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith return EmitCall(FuncInfo, Func, ReturnValueSlot(), Args); 10632c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith } 10642c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 10652c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case Builtin::BI__atomic_test_and_set: { 10662c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith // Look at the argument type to determine whether this is a volatile 10672c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith // operation. The parameter type is always volatile. 10682c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType(); 10692c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith bool Volatile = 10702c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified(); 10712c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 10722c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Value *Ptr = EmitScalarExpr(E->getArg(0)); 1073956a5a17713deb1b5b27893303c4f308a1bd2a62Micah Villmow unsigned AddrSpace = Ptr->getType()->getPointerAddressSpace(); 10742c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Ptr = Builder.CreateBitCast(Ptr, Int8Ty->getPointerTo(AddrSpace)); 10752c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Value *NewVal = Builder.getInt8(1); 10762c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Value *Order = EmitScalarExpr(E->getArg(1)); 10772c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith if (isa<llvm::ConstantInt>(Order)) { 10782c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 10792c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith AtomicRMWInst *Result = 0; 10802c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith switch (ord) { 10812c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case 0: // memory_order_relaxed 10822c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith default: // invalid order 10832c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, 10842c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Ptr, NewVal, 10852c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::Monotonic); 10862c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith break; 10872c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case 1: // memory_order_consume 10882c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case 2: // memory_order_acquire 10892c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, 10902c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Ptr, NewVal, 10912c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::Acquire); 10922c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith break; 10932c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case 3: // memory_order_release 10942c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, 10952c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Ptr, NewVal, 10962c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::Release); 10972c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith break; 10982c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case 4: // memory_order_acq_rel 10992c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, 11002c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Ptr, NewVal, 11012c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::AcquireRelease); 11022c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith break; 11032c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case 5: // memory_order_seq_cst 11042c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, 11052c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Ptr, NewVal, 11062c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::SequentiallyConsistent); 11072c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith break; 11082c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith } 11092c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Result->setVolatile(Volatile); 11102c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith return RValue::get(Builder.CreateIsNotNull(Result, "tobool")); 11112c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith } 11122c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11132c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 11142c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11152c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::BasicBlock *BBs[5] = { 11162c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith createBasicBlock("monotonic", CurFn), 11172c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith createBasicBlock("acquire", CurFn), 11182c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith createBasicBlock("release", CurFn), 11192c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith createBasicBlock("acqrel", CurFn), 11202c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith createBasicBlock("seqcst", CurFn) 11212c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith }; 11222c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::AtomicOrdering Orders[5] = { 11232c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::Monotonic, llvm::Acquire, llvm::Release, 11242c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::AcquireRelease, llvm::SequentiallyConsistent 11252c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith }; 11262c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11272c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 11282c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::SwitchInst *SI = Builder.CreateSwitch(Order, BBs[0]); 11292c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11302c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Builder.SetInsertPoint(ContBB); 11312c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith PHINode *Result = Builder.CreatePHI(Int8Ty, 5, "was_set"); 11322c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11332c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith for (unsigned i = 0; i < 5; ++i) { 11342c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Builder.SetInsertPoint(BBs[i]); 11352c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith AtomicRMWInst *RMW = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, 11362c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Ptr, NewVal, Orders[i]); 11372c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith RMW->setVolatile(Volatile); 11382c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Result->addIncoming(RMW, BBs[i]); 11392c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Builder.CreateBr(ContBB); 11402c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith } 11412c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11422c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith SI->addCase(Builder.getInt32(0), BBs[0]); 11432c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith SI->addCase(Builder.getInt32(1), BBs[1]); 11442c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith SI->addCase(Builder.getInt32(2), BBs[1]); 11452c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith SI->addCase(Builder.getInt32(3), BBs[2]); 11462c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith SI->addCase(Builder.getInt32(4), BBs[3]); 11472c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith SI->addCase(Builder.getInt32(5), BBs[4]); 11482c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11492c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Builder.SetInsertPoint(ContBB); 11502c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith return RValue::get(Builder.CreateIsNotNull(Result, "tobool")); 11512c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith } 11522c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11532c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case Builtin::BI__atomic_clear: { 11542c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType(); 11552c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith bool Volatile = 11562c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified(); 11572c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11582c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Value *Ptr = EmitScalarExpr(E->getArg(0)); 1159956a5a17713deb1b5b27893303c4f308a1bd2a62Micah Villmow unsigned AddrSpace = Ptr->getType()->getPointerAddressSpace(); 11602c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Ptr = Builder.CreateBitCast(Ptr, Int8Ty->getPointerTo(AddrSpace)); 11612c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Value *NewVal = Builder.getInt8(0); 11622c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Value *Order = EmitScalarExpr(E->getArg(1)); 11632c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith if (isa<llvm::ConstantInt>(Order)) { 11642c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 11652c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith StoreInst *Store = Builder.CreateStore(NewVal, Ptr, Volatile); 11662c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Store->setAlignment(1); 11672c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith switch (ord) { 11682c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case 0: // memory_order_relaxed 11692c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith default: // invalid order 11702c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Store->setOrdering(llvm::Monotonic); 11712c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith break; 11722c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case 3: // memory_order_release 11732c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Store->setOrdering(llvm::Release); 11742c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith break; 11752c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith case 5: // memory_order_seq_cst 11762c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Store->setOrdering(llvm::SequentiallyConsistent); 11772c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith break; 11782c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith } 11792c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith return RValue::get(0); 11802c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith } 11812c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11822c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 11832c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11842c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::BasicBlock *BBs[3] = { 11852c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith createBasicBlock("monotonic", CurFn), 11862c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith createBasicBlock("release", CurFn), 11872c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith createBasicBlock("seqcst", CurFn) 11882c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith }; 11892c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::AtomicOrdering Orders[3] = { 11902c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::Monotonic, llvm::Release, llvm::SequentiallyConsistent 11912c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith }; 11922c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11932c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 11942c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith llvm::SwitchInst *SI = Builder.CreateSwitch(Order, BBs[0]); 11952c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 11962c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith for (unsigned i = 0; i < 3; ++i) { 11972c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Builder.SetInsertPoint(BBs[i]); 11982c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith StoreInst *Store = Builder.CreateStore(NewVal, Ptr, Volatile); 11992c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Store->setAlignment(1); 12002c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Store->setOrdering(Orders[i]); 12012c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Builder.CreateBr(ContBB); 12022c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith } 12032c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 12042c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith SI->addCase(Builder.getInt32(0), BBs[0]); 12052c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith SI->addCase(Builder.getInt32(3), BBs[1]); 12062c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith SI->addCase(Builder.getInt32(5), BBs[2]); 12072c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 12082c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith Builder.SetInsertPoint(ContBB); 12092c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith return RValue::get(0); 12102c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith } 12112c39d71bb7cefdfe6116fa52454f3b3dc5abd517Richard Smith 1212276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman case Builtin::BI__atomic_thread_fence: 1213fafbf06732746f3ceca21d452d77b144ba8652aeRichard Smith case Builtin::BI__atomic_signal_fence: 1214fafbf06732746f3ceca21d452d77b144ba8652aeRichard Smith case Builtin::BI__c11_atomic_thread_fence: 1215fafbf06732746f3ceca21d452d77b144ba8652aeRichard Smith case Builtin::BI__c11_atomic_signal_fence: { 1216276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman llvm::SynchronizationScope Scope; 1217fafbf06732746f3ceca21d452d77b144ba8652aeRichard Smith if (BuiltinID == Builtin::BI__atomic_signal_fence || 1218fafbf06732746f3ceca21d452d77b144ba8652aeRichard Smith BuiltinID == Builtin::BI__c11_atomic_signal_fence) 1219276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Scope = llvm::SingleThread; 1220276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman else 1221276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Scope = llvm::CrossThread; 1222276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Value *Order = EmitScalarExpr(E->getArg(0)); 1223276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman if (isa<llvm::ConstantInt>(Order)) { 1224276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 1225276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman switch (ord) { 1226276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman case 0: // memory_order_relaxed 1227276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman default: // invalid order 1228276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman break; 1229276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman case 1: // memory_order_consume 1230276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman case 2: // memory_order_acquire 1231276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateFence(llvm::Acquire, Scope); 1232276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman break; 1233276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman case 3: // memory_order_release 1234276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateFence(llvm::Release, Scope); 1235276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman break; 1236276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman case 4: // memory_order_acq_rel 1237276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateFence(llvm::AcquireRelease, Scope); 1238276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman break; 1239276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman case 5: // memory_order_seq_cst 1240276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateFence(llvm::SequentiallyConsistent, Scope); 1241276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman break; 1242276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman } 1243276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman return RValue::get(0); 1244276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman } 1245276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman 1246276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman llvm::BasicBlock *AcquireBB, *ReleaseBB, *AcqRelBB, *SeqCstBB; 1247276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman AcquireBB = createBasicBlock("acquire", CurFn); 1248276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman ReleaseBB = createBasicBlock("release", CurFn); 1249276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman AcqRelBB = createBasicBlock("acqrel", CurFn); 1250276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman SeqCstBB = createBasicBlock("seqcst", CurFn); 1251276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 1252276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman 1253276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 1254276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman llvm::SwitchInst *SI = Builder.CreateSwitch(Order, ContBB); 1255276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman 1256276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.SetInsertPoint(AcquireBB); 1257276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateFence(llvm::Acquire, Scope); 1258276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateBr(ContBB); 1259276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman SI->addCase(Builder.getInt32(1), AcquireBB); 1260276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman SI->addCase(Builder.getInt32(2), AcquireBB); 1261276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman 1262276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.SetInsertPoint(ReleaseBB); 1263276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateFence(llvm::Release, Scope); 1264276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateBr(ContBB); 1265276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman SI->addCase(Builder.getInt32(3), ReleaseBB); 1266276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman 1267276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.SetInsertPoint(AcqRelBB); 1268276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateFence(llvm::AcquireRelease, Scope); 1269276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateBr(ContBB); 1270276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman SI->addCase(Builder.getInt32(4), AcqRelBB); 1271276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman 1272276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.SetInsertPoint(SeqCstBB); 1273276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateFence(llvm::SequentiallyConsistent, Scope); 1274276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.CreateBr(ContBB); 1275276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman SI->addCase(Builder.getInt32(5), SeqCstBB); 1276276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman 1277276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman Builder.SetInsertPoint(ContBB); 1278276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman return RValue::get(0); 1279276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman } 1280276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman 1281ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar // Library functions with special handling. 1282ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIsqrt: 1283ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIsqrtf: 1284ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIsqrtl: { 1285beb41281f8355caa05700d0a77539defbdf428f8John McCall // TODO: there is currently no set of optimizer flags 1286beb41281f8355caa05700d0a77539defbdf428f8John McCall // sufficient for us to rewrite sqrt to @llvm.sqrt. 1287beb41281f8355caa05700d0a77539defbdf428f8John McCall // -fmath-errno=0 is not good enough; we need finiteness. 1288beb41281f8355caa05700d0a77539defbdf428f8John McCall // We could probably precondition the call with an ult 1289beb41281f8355caa05700d0a77539defbdf428f8John McCall // against 0, but is that worth the complexity? 1290beb41281f8355caa05700d0a77539defbdf428f8John McCall break; 1291ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar } 1292ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar 1293ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIpow: 1294ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIpowf: 1295ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIpowl: { 1296ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar // Rewrite sqrt to intrinsic if allowed. 129740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis if (!FD->hasAttr<ConstAttr>()) 1298ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar break; 1299ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar Value *Base = EmitScalarExpr(E->getArg(0)); 1300ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar Value *Exponent = EmitScalarExpr(E->getArg(1)); 13019cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ArgType = Base->getType(); 13028dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::pow, ArgType); 1303578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer return RValue::get(Builder.CreateCall2(F, Base, Exponent)); 1304ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar } 1305ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman 1306094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BIfma: 1307094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BIfmaf: 1308094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BIfmal: 1309094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BI__builtin_fma: 1310094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BI__builtin_fmaf: 1311094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BI__builtin_fmal: { 1312094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich // Rewrite fma to intrinsic. 1313094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich Value *FirstArg = EmitScalarExpr(E->getArg(0)); 13149cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ArgType = FirstArg->getType(); 13158dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::fma, ArgType); 1316094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich return RValue::get(Builder.CreateCall3(F, FirstArg, 1317094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich EmitScalarExpr(E->getArg(1)), 1318578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer EmitScalarExpr(E->getArg(2)))); 1319094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich } 1320094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich 1321ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman case Builtin::BI__builtin_signbit: 1322ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman case Builtin::BI__builtin_signbitf: 1323ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman case Builtin::BI__builtin_signbitl: { 1324ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman LLVMContext &C = CGM.getLLVMContext(); 1325ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman 1326ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *Arg = EmitScalarExpr(E->getArg(0)); 13272acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ArgTy = Arg->getType(); 1328ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman if (ArgTy->isPPC_FP128Ty()) 1329ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman break; // FIXME: I'm not sure what the right implementation is here. 1330ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman int ArgWidth = ArgTy->getPrimitiveSizeInBits(); 13312acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ArgIntTy = llvm::IntegerType::get(C, ArgWidth); 1332ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *BCArg = Builder.CreateBitCast(Arg, ArgIntTy); 1333ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *ZeroCmp = llvm::Constant::getNullValue(ArgIntTy); 1334ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *Result = Builder.CreateICmpSLT(BCArg, ZeroCmp); 1335ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman return RValue::get(Builder.CreateZExt(Result, ConvertType(E->getType()))); 1336ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman } 133777f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge case Builtin::BI__builtin_annotation: { 133877f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge llvm::Value *AnnVal = EmitScalarExpr(E->getArg(0)); 133977f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::annotation, 134077f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge AnnVal->getType()); 134177f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge 134277f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge // Get the annotation string, go through casts. Sema requires this to be a 134377f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge // non-wide string literal, potentially casted, so the cast<> is safe. 134477f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge const Expr *AnnotationStrExpr = E->getArg(1)->IgnoreParenCasts(); 1345cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko StringRef Str = cast<StringLiteral>(AnnotationStrExpr)->getString(); 134677f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge return RValue::get(EmitAnnotationCall(F, AnnVal, Str, E->getExprLoc())); 134777f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge } 13480cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman case Builtin::BI__builtin_addcs: 13490cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman case Builtin::BI__builtin_addc: 13500cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman case Builtin::BI__builtin_addcl: 13517c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_addcll: 13527c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subcs: 13537c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subc: 13547c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subcl: 13557c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subcll: { 13560cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman 13570cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // We translate all of these builtins from expressions of the form: 13580cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // int x = ..., y = ..., carryin = ..., carryout, result; 13590cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // result = __builtin_addc(x, y, carryin, &carryout); 13600cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // 13610cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // to LLVM IR of the form: 13620cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // 13630cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %tmp1 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x, i32 %y) 13640cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %tmpsum1 = extractvalue {i32, i1} %tmp1, 0 13650cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %carry1 = extractvalue {i32, i1} %tmp1, 1 13660cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %tmp2 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %tmpsum1, 13670cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // i32 %carryin) 13680cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %result = extractvalue {i32, i1} %tmp2, 0 13690cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %carry2 = extractvalue {i32, i1} %tmp2, 1 13700cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %tmp3 = or i1 %carry1, %carry2 13710cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %tmp4 = zext i1 %tmp3 to i32 13720cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // store i32 %tmp4, i32* %carryout 13730cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman 13740cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // Scalarize our inputs. 13750cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *X = EmitScalarExpr(E->getArg(0)); 13760cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *Y = EmitScalarExpr(E->getArg(1)); 13770cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *Carryin = EmitScalarExpr(E->getArg(2)); 13780cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman std::pair<llvm::Value*, unsigned> CarryOutPtr = 13790cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman EmitPointerWithAlignment(E->getArg(3)); 13800cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman 13817c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman // Decide if we are lowering to a uadd.with.overflow or usub.with.overflow. 13827c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman llvm::Intrinsic::ID IntrinsicId; 13837c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman switch (BuiltinID) { 13847c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman default: llvm_unreachable("Unknown multiprecision builtin id."); 13857c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_addcs: 13867c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_addc: 13877c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_addcl: 13887c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_addcll: 13897c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman IntrinsicId = llvm::Intrinsic::uadd_with_overflow; 13907c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman break; 13917c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subcs: 13927c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subc: 13937c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subcl: 13947c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subcll: 13957c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman IntrinsicId = llvm::Intrinsic::usub_with_overflow; 13967c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman break; 13977c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman } 13980cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman 13990cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // Construct our resulting LLVM IR expression. 14000cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *Carry1; 14010cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *Sum1 = EmitOverflowIntrinsic(*this, IntrinsicId, 14020cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman X, Y, Carry1); 14030cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *Carry2; 14040cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *Sum2 = EmitOverflowIntrinsic(*this, IntrinsicId, 14050cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman Sum1, Carryin, Carry2); 14060cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *CarryOut = Builder.CreateZExt(Builder.CreateOr(Carry1, Carry2), 14070cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman X->getType()); 14080cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::StoreInst *CarryOutStore = Builder.CreateStore(CarryOut, 14090cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman CarryOutPtr.first); 14100cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman CarryOutStore->setAlignment(CarryOutPtr.second); 14110cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman return RValue::get(Sum2); 14120cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman } 141327844533aad5c165523a5926424097699610d3f0Nico Weber case Builtin::BI__noop: 141427844533aad5c165523a5926424097699610d3f0Nico Weber return RValue::get(0); 14157ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman } 14161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1417a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // If this is an alias for a lib function (e.g. __builtin_sin), emit 1418a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // the call using the normal call path, but using the unmangled 1419a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // version of the function name. 1420a45680b7e7c49ea9893c6cff585984f3e4120366John McCall if (getContext().BuiltinInfo.isLibFunction(BuiltinID)) 1421a45680b7e7c49ea9893c6cff585984f3e4120366John McCall return emitLibraryCall(*this, FD, E, 1422a45680b7e7c49ea9893c6cff585984f3e4120366John McCall CGM.getBuiltinLibFunction(FD, BuiltinID)); 1423258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 1424a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // If this is a predefined lib function (e.g. malloc), emit the call 1425a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // using exactly the normal call path. 1426a45680b7e7c49ea9893c6cff585984f3e4120366John McCall if (getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID)) 1427a45680b7e7c49ea9893c6cff585984f3e4120366John McCall return emitLibraryCall(*this, FD, E, EmitScalarExpr(E->getCallee())); 14281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1429b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // See if we have a target specific intrinsic. 1430a6f80ef997f0363386749087b325607eaa5adcfcDale Johannesen const char *Name = getContext().BuiltinInfo.GetName(BuiltinID); 143155cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic; 143255cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar if (const char *Prefix = 14331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Triple::getArchTypePrefix(Target.getTriple().getArch())) 143455cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix, Name); 14351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1436b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (IntrinsicID != Intrinsic::not_intrinsic) { 1437b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner SmallVector<Value*, 16> Args; 14381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 143946c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // Find out if any arguments are required to be integer constant 144046c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // expressions. 144146c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner unsigned ICEArguments = 0; 144246c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner ASTContext::GetBuiltinTypeError Error; 144346c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 144446c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner assert(Error == ASTContext::GE_None && "Should not codegen an error"); 144546c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner 1446b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner Function *F = CGM.getIntrinsic(IntrinsicID); 14472acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = F->getFunctionType(); 14481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1449b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 145046c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner Value *ArgValue; 145146c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // If this is a normal argument, just emit it as a scalar. 145246c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner if ((ICEArguments & (1 << i)) == 0) { 145346c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner ArgValue = EmitScalarExpr(E->getArg(i)); 145446c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner } else { 1455258f930227c1a102c9c22eee88df65f748863425Jim Grosbach // If this is required to be a constant, constant fold it so that we 145646c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // know that the generated intrinsic gets a ConstantInt. 145746c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner llvm::APSInt Result; 145846c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result,getContext()); 145946c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner assert(IsConst && "Constant arg isn't actually constant?"); 146046c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner (void)IsConst; 1461d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall ArgValue = llvm::ConstantInt::get(getLLVMContext(), Result); 146246c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner } 14631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1464b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // If the intrinsic arg type is different from the builtin arg type 1465b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // we need to do a bit cast. 14662acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PTy = FTy->getParamType(i); 1467b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (PTy != ArgValue->getType()) { 1468b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) && 1469b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner "Must be able to losslessly bit cast to param"); 1470b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner ArgValue = Builder.CreateBitCast(ArgValue, PTy); 1471b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 14721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1473b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner Args.push_back(ArgValue); 1474b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 14751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14764c7d9f1507d0f102bd4133bba63348636facd469Jay Foad Value *V = Builder.CreateCall(F, Args); 1477b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner QualType BuiltinRetType = E->getType(); 14781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14798b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner llvm::Type *RetTy = VoidTy; 1480258f930227c1a102c9c22eee88df65f748863425Jim Grosbach if (!BuiltinRetType->isVoidType()) 14818b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner RetTy = ConvertType(BuiltinRetType); 14821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1483b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (RetTy != V->getType()) { 1484b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner assert(V->getType()->canLosslesslyBitCastTo(RetTy) && 1485b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner "Must be able to losslessly bit cast result type"); 1486b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner V = Builder.CreateBitCast(V, RetTy); 1487b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 14881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1489b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner return RValue::get(V); 1490b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 14911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1492b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // See if we have a target specific builtin that needs to be lowered. 1493f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E)) 1494b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner return RValue::get(V); 14951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1496488e993a135ce700b982bf099c3d6b856301d642Daniel Dunbar ErrorUnsupported(E, "builtin function"); 14971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1498b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // Unknown builtin, for now just dump it out and return undef. 14999d232c884ea9872d6555df0fd7359699819bc1f1John McCall return GetUndefRValue(E->getType()); 15001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 1501564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson 1502f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel DunbarValue *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, 1503f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar const CallExpr *E) { 150455cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar switch (Target.getTriple().getArch()) { 15052752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner case llvm::Triple::arm: 15062752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner case llvm::Triple::thumb: 15072752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner return EmitARMBuiltinExpr(BuiltinID, E); 150855cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::x86: 150955cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::x86_64: 1510f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar return EmitX86BuiltinExpr(BuiltinID, E); 151155cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::ppc: 151255cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::ppc64: 1513f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar return EmitPPCBuiltinExpr(BuiltinID, E); 151455cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar default: 151555cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar return 0; 151655cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar } 1517f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar} 1518f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar 15198b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattnerstatic llvm::VectorType *GetNeonType(CodeGenFunction *CGF, 15208b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner NeonTypeFlags TypeFlags) { 152183084c863572b48579767a4dd5dc686e1a8d669dNAKAMURA Takumi int IsQuad = TypeFlags.isQuad(); 152283084c863572b48579767a4dd5dc686e1a8d669dNAKAMURA Takumi switch (TypeFlags.getEltType()) { 1523da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Int8: 1524da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Poly8: 15258b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner return llvm::VectorType::get(CGF->Int8Ty, 8 << IsQuad); 1526da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Int16: 1527da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Poly16: 1528da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Float16: 15298b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner return llvm::VectorType::get(CGF->Int16Ty, 4 << IsQuad); 1530da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Int32: 15318b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner return llvm::VectorType::get(CGF->Int32Ty, 2 << IsQuad); 1532da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Int64: 15338b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner return llvm::VectorType::get(CGF->Int64Ty, 1 << IsQuad); 1534da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Float32: 15358b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner return llvm::VectorType::get(CGF->FloatTy, 2 << IsQuad); 1536561d3abc881033776ece385a01a510e1cbc1fa92David Blaikie } 1537561d3abc881033776ece385a01a510e1cbc1fa92David Blaikie llvm_unreachable("Invalid NeonTypeFlags element type!"); 1538998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman} 1539998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman 1540cf55652cf668c1402eee0b12edd2e5a1bc34d7a1Bob WilsonValue *CodeGenFunction::EmitNeonSplat(Value *V, Constant *C) { 1541d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman unsigned nElts = cast<llvm::VectorType>(V->getType())->getNumElements(); 15422ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner Value* SV = llvm::ConstantVector::getSplat(nElts, C); 1543d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman return Builder.CreateShuffleVector(V, V, SV, "lane"); 1544d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman} 1545d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman 154630d91718a676177f0d0d0210ce4fdb4f616df6e5Nate BegemanValue *CodeGenFunction::EmitNeonCall(Function *F, SmallVectorImpl<Value*> &Ops, 1547db3d4d036037f379f12643e067b229862d61e932Bob Wilson const char *name, 154861eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman unsigned shift, bool rightshift) { 154930d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman unsigned j = 0; 155030d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end(); 155130d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman ai != ae; ++ai, ++j) 155261eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman if (shift > 0 && shift == j) 155361eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[j] = EmitNeonShiftVector(Ops[j], ai->getType(), rightshift); 155461eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman else 155561eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[j] = Builder.CreateBitCast(Ops[j], ai->getType(), name); 155630d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman 15574c7d9f1507d0f102bd4133bba63348636facd469Jay Foad return Builder.CreateCall(F, Ops, name); 155830d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman} 155930d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman 1560258f930227c1a102c9c22eee88df65f748863425Jim GrosbachValue *CodeGenFunction::EmitNeonShiftVector(Value *V, llvm::Type *Ty, 1561464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman bool neg) { 15622ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner int SV = cast<ConstantInt>(V)->getSExtValue(); 1563258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 15642acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 1565464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman llvm::Constant *C = ConstantInt::get(VTy->getElementType(), neg ? -SV : SV); 15662ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner return llvm::ConstantVector::getSplat(VTy->getNumElements(), C); 1567464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman} 1568464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman 156906b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson/// GetPointeeAlignment - Given an expression with a pointer type, find the 157006b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson/// alignment of the type referenced by the pointer. Skip over implicit 157106b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson/// casts. 1572ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedmanstd::pair<llvm::Value*, unsigned> 1573ea93e40785ffeadfac66b948c95f9490ec26207aEli FriedmanCodeGenFunction::EmitPointerWithAlignment(const Expr *Addr) { 1574ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman assert(Addr->getType()->isPointerType()); 1575ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Addr = Addr->IgnoreParens(); 1576ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Addr)) { 1577a484fc73ec6331bcaad092270b4ab9c8d1df23c3Eli Friedman if ((ICE->getCastKind() == CK_BitCast || ICE->getCastKind() == CK_NoOp) && 1578a484fc73ec6331bcaad092270b4ab9c8d1df23c3Eli Friedman ICE->getSubExpr()->getType()->isPointerType()) { 1579258f930227c1a102c9c22eee88df65f748863425Jim Grosbach std::pair<llvm::Value*, unsigned> Ptr = 1580ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(ICE->getSubExpr()); 1581ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ptr.first = Builder.CreateBitCast(Ptr.first, 1582ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman ConvertType(Addr->getType())); 1583ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return Ptr; 1584ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } else if (ICE->getCastKind() == CK_ArrayToPointerDecay) { 1585ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman LValue LV = EmitLValue(ICE->getSubExpr()); 15868e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman unsigned Align = LV.getAlignment().getQuantity(); 15878e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman if (!Align) { 15888e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman // FIXME: Once LValues are fixed to always set alignment, 15898e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman // zap this code. 15908e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman QualType PtTy = ICE->getSubExpr()->getType(); 15918e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman if (!PtTy->isIncompleteType()) 15928e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman Align = getContext().getTypeAlignInChars(PtTy).getQuantity(); 15938e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman else 15948e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman Align = 1; 15958e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman } 15968e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman return std::make_pair(LV.getAddress(), Align); 1597d6e73569ccf09369f9bd2021d53c88e7bded06e3Chris Lattner } 1598ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 1599ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(Addr)) { 1600ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (UO->getOpcode() == UO_AddrOf) { 1601ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman LValue LV = EmitLValue(UO->getSubExpr()); 16028e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman unsigned Align = LV.getAlignment().getQuantity(); 16038e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman if (!Align) { 16048e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman // FIXME: Once LValues are fixed to always set alignment, 16058e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman // zap this code. 16068e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman QualType PtTy = UO->getSubExpr()->getType(); 16078e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman if (!PtTy->isIncompleteType()) 16088e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman Align = getContext().getTypeAlignInChars(PtTy).getQuantity(); 16098e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman else 16108e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman Align = 1; 16118e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman } 16128e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman return std::make_pair(LV.getAddress(), Align); 161306b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson } 161406b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson } 1615f4c3db175101cbf94dad59419c3ed7aed51bf606Jay Foad 1616ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman unsigned Align = 1; 1617ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman QualType PtTy = Addr->getType()->getPointeeType(); 1618ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (!PtTy->isIncompleteType()) 1619ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Align = getContext().getTypeAlignInChars(PtTy).getQuantity(); 1620ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman 1621ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return std::make_pair(EmitScalarExpr(Addr), Align); 162206b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson} 162306b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson 16242752c0137d95aa2f4ee1cdff4b564bac842e041bChris LattnerValue *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, 16252752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner const CallExpr *E) { 1626e140af3e27016f902146023fba7680b43043ec07Rafael Espindola if (BuiltinID == ARM::BI__clear_cache) { 162779ba509b0106fd0a1ff832baeb1fdb5430527efeRafael Espindola const FunctionDecl *FD = E->getDirectCallee(); 16288a37c79f03e62aecfa2c58b9179f90dd1fcdb253Eric Christopher // Oddly people write this call without args on occasion and gcc accepts 16298a37c79f03e62aecfa2c58b9179f90dd1fcdb253Eric Christopher // it - it's also marked as varargs in the description file. 16305f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Value*, 2> Ops; 16318a37c79f03e62aecfa2c58b9179f90dd1fcdb253Eric Christopher for (unsigned i = 0; i < E->getNumArgs(); i++) 16328a37c79f03e62aecfa2c58b9179f90dd1fcdb253Eric Christopher Ops.push_back(EmitScalarExpr(E->getArg(i))); 16332acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); 16342acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); 16355f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Name = FD->getName(); 1636bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); 16372752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner } 1638e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 163926c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes if (BuiltinID == ARM::BI__builtin_arm_ldrexd) { 164026c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Function *F = CGM.getIntrinsic(Intrinsic::arm_ldrexd); 164126c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 164226c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *LdPtr = EmitScalarExpr(E->getArg(0)); 164326c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *Val = Builder.CreateCall(F, LdPtr, "ldrexd"); 164426c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 164526c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *Val0 = Builder.CreateExtractValue(Val, 1); 164626c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *Val1 = Builder.CreateExtractValue(Val, 0); 164726c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Val0 = Builder.CreateZExt(Val0, Int64Ty); 164826c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Val1 = Builder.CreateZExt(Val1, Int64Ty); 164926c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 165026c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *ShiftCst = llvm::ConstantInt::get(Int64Ty, 32); 165126c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */); 165226c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes return Builder.CreateOr(Val, Val1); 165326c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes } 165426c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 165526c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes if (BuiltinID == ARM::BI__builtin_arm_strexd) { 165626c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Function *F = CGM.getIntrinsic(Intrinsic::arm_strexd); 16577650d95a1a616ea300f37126a8dfc93dc19a662aChris Lattner llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, NULL); 165826c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 165926c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *One = llvm::ConstantInt::get(Int32Ty, 1); 1660578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Value *Tmp = Builder.CreateAlloca(Int64Ty, One); 166126c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *Val = EmitScalarExpr(E->getArg(0)); 166226c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Builder.CreateStore(Val, Tmp); 166326c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 166426c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *LdPtr = Builder.CreateBitCast(Tmp,llvm::PointerType::getUnqual(STy)); 166526c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Val = Builder.CreateLoad(LdPtr); 166626c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 166726c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *Arg0 = Builder.CreateExtractValue(Val, 0); 166826c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *Arg1 = Builder.CreateExtractValue(Val, 1); 166926c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *StPtr = EmitScalarExpr(E->getArg(1)); 167026c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes return Builder.CreateCall3(F, Arg0, Arg1, StPtr, "strexd"); 167126c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes } 167226c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 16735f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Value*, 4> Ops; 1674ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman llvm::Value *Align = 0; 1675ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) { 1676ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (i == 0) { 1677ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman switch (BuiltinID) { 1678ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1_v: 1679ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1q_v: 1680ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1q_lane_v: 1681ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1_lane_v: 1682ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1_dup_v: 1683ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1q_dup_v: 1684ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst1_v: 1685ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst1q_v: 1686ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst1q_lane_v: 1687ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst1_lane_v: 1688ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst2_v: 1689ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst2q_v: 1690ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst2_lane_v: 1691ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst2q_lane_v: 1692ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst3_v: 1693ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst3q_v: 1694ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst3_lane_v: 1695ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst3q_lane_v: 1696ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst4_v: 1697ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst4q_v: 1698ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst4_lane_v: 1699ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst4q_lane_v: 1700ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman // Get the alignment for the argument in addition to the value; 1701ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman // we'll use it later. 1702ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Src = 1703ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(0)); 1704ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Src.first); 1705ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Align = Builder.getInt32(Src.second); 1706ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman continue; 1707ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 1708ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 1709ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (i == 1) { 1710ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman switch (BuiltinID) { 1711ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld2_v: 1712ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld2q_v: 1713ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld3_v: 1714ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld3q_v: 1715ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld4_v: 1716ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld4q_v: 1717ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld2_lane_v: 1718ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld2q_lane_v: 1719ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld3_lane_v: 1720ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld3q_lane_v: 1721ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld4_lane_v: 1722ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld4q_lane_v: 1723ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld2_dup_v: 1724ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld3_dup_v: 1725ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld4_dup_v: 1726ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman // Get the alignment for the argument in addition to the value; 1727ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman // we'll use it later. 1728ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Src = 1729ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(1)); 1730ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Src.first); 1731ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Align = Builder.getInt32(Src.second); 1732ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman continue; 1733ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 1734ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 1735e140af3e27016f902146023fba7680b43043ec07Rafael Espindola Ops.push_back(EmitScalarExpr(E->getArg(i))); 1736ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 1737e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 173883bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson // vget_lane and vset_lane are not overloaded and do not have an extra 173983bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson // argument that specifies the vector type. 174083bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson switch (BuiltinID) { 174183bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson default: break; 174283bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vget_lane_i8: 174383bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vget_lane_i16: 174483bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vget_lane_i32: 174583bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vget_lane_i64: 174683bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vget_lane_f32: 174783bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vgetq_lane_i8: 174883bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vgetq_lane_i16: 174983bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vgetq_lane_i32: 175083bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vgetq_lane_i64: 175183bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vgetq_lane_f32: 175283bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 175383bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson "vget_lane"); 175483bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vset_lane_i8: 175583bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vset_lane_i16: 175683bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vset_lane_i32: 175783bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vset_lane_i64: 175883bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vset_lane_f32: 175983bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vsetq_lane_i8: 176083bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vsetq_lane_i16: 176183bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vsetq_lane_i32: 176283bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vsetq_lane_i64: 176383bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vsetq_lane_f32: 176483bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson Ops.push_back(EmitScalarExpr(E->getArg(2))); 176583bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 176683bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson } 176783bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson 176883bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson // Get the last argument, which specifies the vector type. 1769e140af3e27016f902146023fba7680b43043ec07Rafael Espindola llvm::APSInt Result; 1770e140af3e27016f902146023fba7680b43043ec07Rafael Espindola const Expr *Arg = E->getArg(E->getNumArgs()-1); 1771e140af3e27016f902146023fba7680b43043ec07Rafael Espindola if (!Arg->isIntegerConstantExpr(Result, getContext())) 1772e140af3e27016f902146023fba7680b43043ec07Rafael Espindola return 0; 1773e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 177499c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f || 177599c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman BuiltinID == ARM::BI__builtin_arm_vcvtr_d) { 177699c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman // Determine the overloaded type of this builtin. 17779cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *Ty; 177899c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f) 17798b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner Ty = FloatTy; 178099c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman else 17818b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner Ty = DoubleTy; 1782258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 178399c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman // Determine whether this is an unsigned conversion or not. 178499c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman bool usgn = Result.getZExtValue() == 1; 178599c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman unsigned Int = usgn ? Intrinsic::arm_vcvtru : Intrinsic::arm_vcvtr; 178699c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman 178799c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman // Call the appropriate intrinsic. 17888dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Int, Ty); 17894c7d9f1507d0f102bd4133bba63348636facd469Jay Foad return Builder.CreateCall(F, Ops, "vcvtr"); 179099c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman } 1791258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 179299c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman // Determine the type of this overloaded NEON intrinsic. 1793da95f73b59f9af964e33725c515139d34c90c863Bob Wilson NeonTypeFlags Type(Result.getZExtValue()); 1794da95f73b59f9af964e33725c515139d34c90c863Bob Wilson bool usgn = Type.isUnsigned(); 1795da95f73b59f9af964e33725c515139d34c90c863Bob Wilson bool quad = Type.isQuad(); 17967965396d8d6ac23ec4c4f9d01d216f2e73d7fc72Bob Wilson bool rightShift = false; 1797e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 17988b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner llvm::VectorType *VTy = GetNeonType(this, Type); 17999cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *Ty = VTy; 1800e140af3e27016f902146023fba7680b43043ec07Rafael Espindola if (!Ty) 1801e140af3e27016f902146023fba7680b43043ec07Rafael Espindola return 0; 1802e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 1803e140af3e27016f902146023fba7680b43043ec07Rafael Espindola unsigned Int; 1804e140af3e27016f902146023fba7680b43043ec07Rafael Espindola switch (BuiltinID) { 1805e140af3e27016f902146023fba7680b43043ec07Rafael Espindola default: return 0; 18064c919eb0c022be30d6130446cb8d50a7e8da9f46Jim Grosbach case ARM::BI__builtin_neon_vbsl_v: 18074c919eb0c022be30d6130446cb8d50a7e8da9f46Jim Grosbach case ARM::BI__builtin_neon_vbslq_v: 18084c919eb0c022be30d6130446cb8d50a7e8da9f46Jim Grosbach return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vbsl, Ty), 18094c919eb0c022be30d6130446cb8d50a7e8da9f46Jim Grosbach Ops, "vbsl"); 1810537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vabd_v: 1811537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vabdq_v: 1812998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman Int = usgn ? Intrinsic::arm_neon_vabdu : Intrinsic::arm_neon_vabds; 18138dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vabd"); 1814537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vabs_v: 1815537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vabsq_v: 18168dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vabs, Ty), 1817548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vabs"); 1818537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vaddhn_v: 18198dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vaddhn, Ty), 1820548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vaddhn"); 1821537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcale_v: 18229eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman std::swap(Ops[0], Ops[1]); 1823537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcage_v: { 1824d185035263b98cdde75a869b26b5e5e2e6b13fdfBob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacged); 182530d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcage"); 182630d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 1827537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcaleq_v: 18289eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman std::swap(Ops[0], Ops[1]); 1829537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcageq_v: { 1830d185035263b98cdde75a869b26b5e5e2e6b13fdfBob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgeq); 183130d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcage"); 183230d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 1833537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcalt_v: 18349eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman std::swap(Ops[0], Ops[1]); 1835537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcagt_v: { 1836d185035263b98cdde75a869b26b5e5e2e6b13fdfBob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgtd); 183730d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcagt"); 183830d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 1839537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcaltq_v: 18409eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman std::swap(Ops[0], Ops[1]); 1841537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcagtq_v: { 1842d185035263b98cdde75a869b26b5e5e2e6b13fdfBob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgtq); 184330d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcagt"); 184430d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 1845537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcls_v: 1846537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vclsq_v: { 18478dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcls, Ty); 184830d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcls"); 18499eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 1850537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vclz_v: 1851537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vclzq_v: { 185271bcc68ba44a87a516d84461bc68475e43134338Eric Christopher // Generate target-independent intrinsic; also need to add second argument 185387d747b1fbf89aa0ba08cfc0e26655aa7739c77dJoel Jones // for whether or not clz of zero is undefined; on ARM it isn't. 185487d747b1fbf89aa0ba08cfc0e26655aa7739c77dJoel Jones Function *F = CGM.getIntrinsic(Intrinsic::ctlz, Ty); 185587d747b1fbf89aa0ba08cfc0e26655aa7739c77dJoel Jones Ops.push_back(Builder.getInt1(Target.isCLZForZeroUndef())); 185630d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vclz"); 18579eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 1858537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcnt_v: 1859537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcntq_v: { 18601638f2e8263df93b9fa055a12cc3f0968b9682d8Joel Jones // generate target-independent intrinsic 18611638f2e8263df93b9fa055a12cc3f0968b9682d8Joel Jones Function *F = CGM.getIntrinsic(Intrinsic::ctpop, Ty); 18621638f2e8263df93b9fa055a12cc3f0968b9682d8Joel Jones return EmitNeonCall(F, Ops, "vctpop"); 18639eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 1864537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_f16_v: { 1865da95f73b59f9af964e33725c515139d34c90c863Bob Wilson assert(Type.getEltType() == NeonTypeFlags::Float16 && !quad && 1866da95f73b59f9af964e33725c515139d34c90c863Bob Wilson "unexpected vcvt_f16_v builtin"); 186746e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcvtfp2hf); 186846e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson return EmitNeonCall(F, Ops, "vcvt"); 186946e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson } 1870537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_f32_f16: { 1871da95f73b59f9af964e33725c515139d34c90c863Bob Wilson assert(Type.getEltType() == NeonTypeFlags::Float16 && !quad && 1872da95f73b59f9af964e33725c515139d34c90c863Bob Wilson "unexpected vcvt_f32_f16 builtin"); 187346e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcvthf2fp); 187446e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson return EmitNeonCall(F, Ops, "vcvt"); 187546e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson } 1876537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_f32_v: 1877da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case ARM::BI__builtin_neon_vcvtq_f32_v: 187830d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 18798b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, quad)); 1880258f930227c1a102c9c22eee88df65f748863425Jim Grosbach return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") 18819eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); 1882537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_s32_v: 1883537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_u32_v: 1884537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvtq_s32_v: 1885537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvtq_u32_v: { 1886da95f73b59f9af964e33725c515139d34c90c863Bob Wilson llvm::Type *FloatTy = 18878b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, quad)); 1888da95f73b59f9af964e33725c515139d34c90c863Bob Wilson Ops[0] = Builder.CreateBitCast(Ops[0], FloatTy); 1889258f930227c1a102c9c22eee88df65f748863425Jim Grosbach return usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt") 18909eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman : Builder.CreateFPToSI(Ops[0], Ty, "vcvt"); 18919eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 1892537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_n_f32_v: 1893537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvtq_n_f32_v: { 1894da95f73b59f9af964e33725c515139d34c90c863Bob Wilson llvm::Type *FloatTy = 18958b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, quad)); 1896da95f73b59f9af964e33725c515139d34c90c863Bob Wilson llvm::Type *Tys[2] = { FloatTy, Ty }; 1897da95f73b59f9af964e33725c515139d34c90c863Bob Wilson Int = usgn ? Intrinsic::arm_neon_vcvtfxu2fp 1898da95f73b59f9af964e33725c515139d34c90c863Bob Wilson : Intrinsic::arm_neon_vcvtfxs2fp; 18998dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Int, Tys); 190030d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcvt_n"); 19019eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 1902537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_n_s32_v: 1903537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_n_u32_v: 1904537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvtq_n_s32_v: 1905537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvtq_n_u32_v: { 1906da95f73b59f9af964e33725c515139d34c90c863Bob Wilson llvm::Type *FloatTy = 19078b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, quad)); 1908da95f73b59f9af964e33725c515139d34c90c863Bob Wilson llvm::Type *Tys[2] = { Ty, FloatTy }; 1909da95f73b59f9af964e33725c515139d34c90c863Bob Wilson Int = usgn ? Intrinsic::arm_neon_vcvtfp2fxu 1910da95f73b59f9af964e33725c515139d34c90c863Bob Wilson : Intrinsic::arm_neon_vcvtfp2fxs; 19118dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Int, Tys); 191230d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcvt_n"); 191330d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 1914537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vext_v: 1915537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vextq_v: { 1916fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner int CV = cast<ConstantInt>(Ops[2])->getSExtValue(); 19171c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman SmallVector<Constant*, 16> Indices; 19184be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 191977b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Indices.push_back(ConstantInt::get(Int32Ty, i+CV)); 1920258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 192130d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 192230d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 1923fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner Value *SV = llvm::ConstantVector::get(Indices); 19241c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return Builder.CreateShuffleVector(Ops[0], Ops[1], SV, "vext"); 19251c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 1926537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vhadd_v: 1927537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vhaddq_v: 1928df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vhaddu : Intrinsic::arm_neon_vhadds; 19298dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vhadd"); 1930537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vhsub_v: 1931537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vhsubq_v: 1932df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vhsubu : Intrinsic::arm_neon_vhsubs; 19338dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vhsub"); 1934537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld1_v: 1935537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld1q_v: 1936ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 19378dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Ty), 19384be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops, "vld1"); 1939550a9d823a939366a9f776b58f18883acd905a93Bob Wilson case ARM::BI__builtin_neon_vld1q_lane_v: 1940550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // Handle 64-bit integer elements as a special case. Use shuffles of 1941550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // one-element vectors to avoid poor code for i64 in the backend. 1942550a9d823a939366a9f776b58f18883acd905a93Bob Wilson if (VTy->getElementType()->isIntegerTy(64)) { 1943550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // Extract the other lane. 1944550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 1945550a9d823a939366a9f776b58f18883acd905a93Bob Wilson int Lane = cast<ConstantInt>(Ops[2])->getZExtValue(); 1946550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Value *SV = llvm::ConstantVector::get(ConstantInt::get(Int32Ty, 1-Lane)); 1947550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); 1948550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // Load the value as a one-element vector. 1949550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ty = llvm::VectorType::get(VTy->getElementType(), 1); 1950550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Ty); 1951ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Value *Ld = Builder.CreateCall2(F, Ops[0], Align); 1952550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // Combine them. 1953550a9d823a939366a9f776b58f18883acd905a93Bob Wilson SmallVector<Constant*, 2> Indices; 1954550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Indices.push_back(ConstantInt::get(Int32Ty, 1-Lane)); 1955550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Indices.push_back(ConstantInt::get(Int32Ty, Lane)); 1956550a9d823a939366a9f776b58f18883acd905a93Bob Wilson SV = llvm::ConstantVector::get(Indices); 1957550a9d823a939366a9f776b58f18883acd905a93Bob Wilson return Builder.CreateShuffleVector(Ops[1], Ld, SV, "vld1q_lane"); 1958550a9d823a939366a9f776b58f18883acd905a93Bob Wilson } 1959550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // fall through 1960550a9d823a939366a9f776b58f18883acd905a93Bob Wilson case ARM::BI__builtin_neon_vld1_lane_v: { 19614be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 19624be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 19634be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 1964eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson LoadInst *Ld = Builder.CreateLoad(Ops[0]); 1965eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); 1966eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson return Builder.CreateInsertElement(Ops[1], Ld, Ops[2], "vld1_lane"); 1967eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson } 1968537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld1_dup_v: 1969537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld1q_dup_v: { 19704be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *V = UndefValue::get(Ty); 19714be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 19724be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 1973eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson LoadInst *Ld = Builder.CreateLoad(Ops[0]); 1974eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); 197577b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 1976eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson Ops[0] = Builder.CreateInsertElement(V, Ld, CI); 19774be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return EmitNeonSplat(Ops[0], CI); 19784be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 1979537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld2_v: 1980537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld2q_v: { 19818dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld2, Ty); 198206b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld2"); 19834be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 19844be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 19854be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 19864be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 1987537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3_v: 1988537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3q_v: { 19898dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld3, Ty); 199006b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld3"); 19914be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 19924be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 19934be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 19944be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 1995537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4_v: 1996537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4q_v: { 19978dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld4, Ty); 199806b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld4"); 19994be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 20004be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 20014be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 20024be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 2003537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld2_lane_v: 2004537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld2q_lane_v: { 20058dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld2lane, Ty); 20064be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 20074be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 2008ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 20091cbac8ac446cf513dbc7486dd50abd55bcfc62c6Frits van Bommel Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld2_lane"); 20104be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 20114be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 20124be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 20134be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 2014537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3_lane_v: 2015537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3q_lane_v: { 20168dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld3lane, Ty); 20174be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 20184be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 20194be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[4] = Builder.CreateBitCast(Ops[4], Ty); 2020ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 20211cbac8ac446cf513dbc7486dd50abd55bcfc62c6Frits van Bommel Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld3_lane"); 20224be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 20234be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 20244be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 20254be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 2026537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4_lane_v: 2027537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4q_lane_v: { 20288dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld4lane, Ty); 20294be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 20304be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 20314be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[4] = Builder.CreateBitCast(Ops[4], Ty); 20324be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[5] = Builder.CreateBitCast(Ops[5], Ty); 2033ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 20341cbac8ac446cf513dbc7486dd50abd55bcfc62c6Frits van Bommel Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld3_lane"); 20354be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 20364be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 20374be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 20384be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 2039537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld2_dup_v: 2040537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3_dup_v: 2041537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4_dup_v: { 2042a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson // Handle 64-bit elements as a special-case. There is no "dup" needed. 2043a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson if (VTy->getElementType()->getPrimitiveSizeInBits() == 64) { 2044a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson switch (BuiltinID) { 2045258f930227c1a102c9c22eee88df65f748863425Jim Grosbach case ARM::BI__builtin_neon_vld2_dup_v: 2046258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Int = Intrinsic::arm_neon_vld2; 2047a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson break; 2048537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3_dup_v: 2049258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Int = Intrinsic::arm_neon_vld3; 2050a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson break; 2051537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4_dup_v: 2052258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Int = Intrinsic::arm_neon_vld4; 2053a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson break; 2054b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("unknown vld_dup intrinsic?"); 2055a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson } 20568dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Int, Ty); 2057a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld_dup"); 2058a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 2059a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2060a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson return Builder.CreateStore(Ops[1], Ops[0]); 2061a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson } 20624be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman switch (BuiltinID) { 2063258f930227c1a102c9c22eee88df65f748863425Jim Grosbach case ARM::BI__builtin_neon_vld2_dup_v: 2064258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Int = Intrinsic::arm_neon_vld2lane; 20654be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman break; 2066537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3_dup_v: 2067258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Int = Intrinsic::arm_neon_vld3lane; 20684be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman break; 2069537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4_dup_v: 2070258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Int = Intrinsic::arm_neon_vld4lane; 20714be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman break; 2072b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("unknown vld_dup intrinsic?"); 20734be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 20748dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Int, Ty); 20752acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::StructType *STy = cast<llvm::StructType>(F->getReturnType()); 2076258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 20774be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SmallVector<Value*, 6> Args; 20784be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Args.push_back(Ops[1]); 20794be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Args.append(STy->getNumElements(), UndefValue::get(Ty)); 20804be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 208177b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 20824be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Args.push_back(CI); 2083ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Args.push_back(Align); 2084258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 20854c7d9f1507d0f102bd4133bba63348636facd469Jay Foad Ops[1] = Builder.CreateCall(F, Args, "vld_dup"); 20864be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman // splat lane 0 to all elts in each vector of the result. 20874be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { 20884be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Val = Builder.CreateExtractValue(Ops[1], i); 20894be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Elt = Builder.CreateBitCast(Val, Ty); 20904be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Elt = EmitNeonSplat(Elt, CI); 20914be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Elt = Builder.CreateBitCast(Elt, Val->getType()); 20924be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[1] = Builder.CreateInsertValue(Ops[1], Elt, i); 20934be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 20944be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 20954be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 20964be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 20974be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 2098537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmax_v: 2099537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmaxq_v: 2100df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vmaxu : Intrinsic::arm_neon_vmaxs; 21018dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmax"); 2102537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmin_v: 2103537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vminq_v: 2104df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vminu : Intrinsic::arm_neon_vmins; 21058dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmin"); 2106537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmovl_v: { 21072acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *DTy =llvm::VectorType::getTruncatedElementVectorType(VTy); 21082235941293353325835d182da4470f61828fe789Bob Wilson Ops[0] = Builder.CreateBitCast(Ops[0], DTy); 21097cea322bf019b0d38867a27e20e3771d84dbb1afBob Wilson if (usgn) 21107cea322bf019b0d38867a27e20e3771d84dbb1afBob Wilson return Builder.CreateZExt(Ops[0], Ty, "vmovl"); 21117cea322bf019b0d38867a27e20e3771d84dbb1afBob Wilson return Builder.CreateSExt(Ops[0], Ty, "vmovl"); 21122235941293353325835d182da4470f61828fe789Bob Wilson } 2113537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmovn_v: { 21142acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *QTy = llvm::VectorType::getExtendedElementVectorType(VTy); 21152235941293353325835d182da4470f61828fe789Bob Wilson Ops[0] = Builder.CreateBitCast(Ops[0], QTy); 21163b6081bf49b7506cb96131247f209d1e03610df8Bob Wilson return Builder.CreateTrunc(Ops[0], Ty, "vmovn"); 21172235941293353325835d182da4470f61828fe789Bob Wilson } 2118537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmul_v: 2119537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmulq_v: 2120da95f73b59f9af964e33725c515139d34c90c863Bob Wilson assert(Type.isPoly() && "vmul builtin only supported for polynomial types"); 21218dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vmulp, Ty), 2122953d513c7ee79b3d9e37597e64317e75c0fbf7f6Bob Wilson Ops, "vmul"); 2123537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmull_v: 21242d33e423d5091b7d2cb8618952752abd55bba965Bob Wilson Int = usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls; 2125da95f73b59f9af964e33725c515139d34c90c863Bob Wilson Int = Type.isPoly() ? (unsigned)Intrinsic::arm_neon_vmullp : Int; 21268dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull"); 212702262662b4550d0227038470f2d7b3db7ada2b87Bob Wilson case ARM::BI__builtin_neon_vfma_v: 212802262662b4550d0227038470f2d7b3db7ada2b87Bob Wilson case ARM::BI__builtin_neon_vfmaq_v: { 212902262662b4550d0227038470f2d7b3db7ada2b87Bob Wilson Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 213002262662b4550d0227038470f2d7b3db7ada2b87Bob Wilson Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 213102262662b4550d0227038470f2d7b3db7ada2b87Bob Wilson Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 213202262662b4550d0227038470f2d7b3db7ada2b87Bob Wilson Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 2133c4a04010f676ce9ff0049b0fc5d1f96a2dbe81beTim Northover 2134c4a04010f676ce9ff0049b0fc5d1f96a2dbe81beTim Northover // NEON intrinsic puts accumulator first, unlike the LLVM fma. 2135c4a04010f676ce9ff0049b0fc5d1f96a2dbe81beTim Northover return Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]); 213602262662b4550d0227038470f2d7b3db7ada2b87Bob Wilson } 2137537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpadal_v: 2138537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpadalq_v: { 2139df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vpadalu : Intrinsic::arm_neon_vpadals; 2140c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson // The source operand type has twice as many elements of half the size. 2141c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 21422acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *EltTy = 2143d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::IntegerType::get(getLLVMContext(), EltBits / 2); 21449cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *NarrowTy = 2145c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); 21469cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *Tys[2] = { Ty, NarrowTy }; 21478dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vpadal"); 2148c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson } 2149537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpadd_v: 21508dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vpadd, Ty), 2151548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vpadd"); 2152537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpaddl_v: 2153537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpaddlq_v: { 2154548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vpaddlu : Intrinsic::arm_neon_vpaddls; 2155c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson // The source operand type has twice as many elements of half the size. 2156c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 21572acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *EltTy = llvm::IntegerType::get(getLLVMContext(), EltBits / 2); 21589cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *NarrowTy = 2159c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); 21609cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *Tys[2] = { Ty, NarrowTy }; 21618dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vpaddl"); 2162c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson } 2163537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpmax_v: 2164548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vpmaxu : Intrinsic::arm_neon_vpmaxs; 21658dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmax"); 2166537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpmin_v: 2167548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vpminu : Intrinsic::arm_neon_vpmins; 21688dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmin"); 2169537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqabs_v: 2170537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqabsq_v: 21718dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqabs, Ty), 2172548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vqabs"); 2173537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqadd_v: 2174537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqaddq_v: 2175548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vqaddu : Intrinsic::arm_neon_vqadds; 21768dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqadd"); 2177537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqdmlal_v: 21788dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmlal, Ty), 2179db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqdmlal"); 2180537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqdmlsl_v: 21818dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmlsl, Ty), 2182db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqdmlsl"); 2183537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqdmulh_v: 2184537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqdmulhq_v: 21858dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmulh, Ty), 2186db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqdmulh"); 2187537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqdmull_v: 21888dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmull, Ty), 2189db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqdmull"); 2190537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqmovn_v: 2191548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vqmovnu : Intrinsic::arm_neon_vqmovns; 21928dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqmovn"); 2193537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqmovun_v: 21948dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqmovnsu, Ty), 2195548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vqdmull"); 2196537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqneg_v: 2197537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqnegq_v: 21988dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqneg, Ty), 219961eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops, "vqneg"); 2200537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrdmulh_v: 2201537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrdmulhq_v: 22028dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrdmulh, Ty), 2203db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqrdmulh"); 2204537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrshl_v: 2205537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrshlq_v: 2206548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vqrshiftu : Intrinsic::arm_neon_vqrshifts; 22078dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshl"); 2208537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrshrn_n_v: 2209258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Int = 2210258f930227c1a102c9c22eee88df65f748863425Jim Grosbach usgn ? Intrinsic::arm_neon_vqrshiftnu : Intrinsic::arm_neon_vqrshiftns; 22118dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n", 221261eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman 1, true); 2213537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrshrun_n_v: 22148dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrshiftnsu, Ty), 2215db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqrshrun_n", 1, true); 2216537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshl_v: 2217537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshlq_v: 221861eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Int = usgn ? Intrinsic::arm_neon_vqshiftu : Intrinsic::arm_neon_vqshifts; 22198dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshl"); 2220537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshl_n_v: 2221537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshlq_n_v: 222261eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Int = usgn ? Intrinsic::arm_neon_vqshiftu : Intrinsic::arm_neon_vqshifts; 22238dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshl_n", 222461eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman 1, false); 2225537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshlu_n_v: 2226537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshluq_n_v: 22278dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftsu, Ty), 2228db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqshlu", 1, false); 2229537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshrn_n_v: 223061eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Int = usgn ? Intrinsic::arm_neon_vqshiftnu : Intrinsic::arm_neon_vqshiftns; 22318dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n", 223261eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman 1, true); 2233537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshrun_n_v: 22348dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftnsu, Ty), 2235db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqshrun_n", 1, true); 2236537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqsub_v: 2237537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqsubq_v: 2238464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Int = usgn ? Intrinsic::arm_neon_vqsubu : Intrinsic::arm_neon_vqsubs; 22398dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqsub"); 2240537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vraddhn_v: 22418dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vraddhn, Ty), 2242464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vraddhn"); 2243537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrecpe_v: 2244537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrecpeq_v: 22458dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecpe, Ty), 2246464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vrecpe"); 2247537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrecps_v: 2248537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrecpsq_v: 22498dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecps, Ty), 2250464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vrecps"); 2251537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrhadd_v: 2252537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrhaddq_v: 2253464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Int = usgn ? Intrinsic::arm_neon_vrhaddu : Intrinsic::arm_neon_vrhadds; 22548dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrhadd"); 2255537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrshl_v: 2256537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrshlq_v: 22575af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 22588dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshl"); 2259537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrshrn_n_v: 22608dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrshiftn, Ty), 2261db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vrshrn_n", 1, true); 2262537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrshr_n_v: 2263537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrshrq_n_v: 22645af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 22658dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshr_n", 1, true); 2266537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsqrte_v: 2267537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsqrteq_v: 22688dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsqrte, Ty), 22695af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops, "vrsqrte"); 2270537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsqrts_v: 2271537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsqrtsq_v: 22728dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsqrts, Ty), 22735af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops, "vrsqrts"); 2274537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsra_n_v: 2275537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsraq_n_v: 22765af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 22775af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 22785af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops[2] = EmitNeonShiftVector(Ops[2], Ty, true); 22795af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 2280258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Ops[1] = Builder.CreateCall2(CGM.getIntrinsic(Int, Ty), Ops[1], Ops[2]); 22815af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n"); 2282537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsubhn_v: 22838dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsubhn, Ty), 2284464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vrsubhn"); 2285537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshl_v: 2286537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshlq_v: 2287464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Int = usgn ? Intrinsic::arm_neon_vshiftu : Intrinsic::arm_neon_vshifts; 22888dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vshl"); 2289537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshll_n_v: 2290464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Int = usgn ? Intrinsic::arm_neon_vshiftlu : Intrinsic::arm_neon_vshiftls; 22918dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vshll", 1); 2292537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshl_n_v: 2293537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshlq_n_v: 229461eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false); 2295258f930227c1a102c9c22eee88df65f748863425Jim Grosbach return Builder.CreateShl(Builder.CreateBitCast(Ops[0],Ty), Ops[1], 2296258f930227c1a102c9c22eee88df65f748863425Jim Grosbach "vshl_n"); 2297537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshrn_n_v: 22988dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftn, Ty), 2299db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vshrn_n", 1, true); 2300537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshr_n_v: 2301537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshrq_n_v: 2302464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 230361eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false); 2304464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman if (usgn) 2305464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return Builder.CreateLShr(Ops[0], Ops[1], "vshr_n"); 2306464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman else 2307464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return Builder.CreateAShr(Ops[0], Ops[1], "vshr_n"); 2308537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsri_n_v: 2309537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsriq_n_v: 23107965396d8d6ac23ec4c4f9d01d216f2e73d7fc72Bob Wilson rightShift = true; 2311537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsli_n_v: 2312537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsliq_n_v: 23137965396d8d6ac23ec4c4f9d01d216f2e73d7fc72Bob Wilson Ops[2] = EmitNeonShiftVector(Ops[2], Ty, rightShift); 23148dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftins, Ty), 2315464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vsli_n"); 2316537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsra_n_v: 2317537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsraq_n_v: 2318464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2319464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 232061eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[2] = EmitNeonShiftVector(Ops[2], Ty, false); 2321464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman if (usgn) 2322464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateLShr(Ops[1], Ops[2], "vsra_n"); 2323464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman else 2324464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateAShr(Ops[1], Ops[2], "vsra_n"); 2325464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return Builder.CreateAdd(Ops[0], Ops[1]); 2326537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst1_v: 2327537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst1q_v: 2328ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 23298dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, Ty), 2330464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2331550a9d823a939366a9f776b58f18883acd905a93Bob Wilson case ARM::BI__builtin_neon_vst1q_lane_v: 2332550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // Handle 64-bit integer elements as a special case. Use a shuffle to get 2333550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // a one-element vector and avoid poor code for i64 in the backend. 2334550a9d823a939366a9f776b58f18883acd905a93Bob Wilson if (VTy->getElementType()->isIntegerTy(64)) { 2335550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 2336550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Value *SV = llvm::ConstantVector::get(cast<llvm::Constant>(Ops[2])); 2337550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); 2338ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops[2] = Align; 2339550a9d823a939366a9f776b58f18883acd905a93Bob Wilson return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, 2340550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ops[1]->getType()), Ops); 2341550a9d823a939366a9f776b58f18883acd905a93Bob Wilson } 2342550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // fall through 2343550a9d823a939366a9f776b58f18883acd905a93Bob Wilson case ARM::BI__builtin_neon_vst1_lane_v: { 2344464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 2345464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); 2346464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 2347eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson StoreInst *St = Builder.CreateStore(Ops[1], 2348eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson Builder.CreateBitCast(Ops[0], Ty)); 2349eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson St->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); 2350eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson return St; 2351eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson } 2352537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst2_v: 2353537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst2q_v: 2354ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 23558dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst2, Ty), 2356464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2357537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst2_lane_v: 2358537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst2q_lane_v: 2359ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 23608dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst2lane, Ty), 2361464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2362537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst3_v: 2363537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst3q_v: 2364ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 23658dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst3, Ty), 2366464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2367537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst3_lane_v: 2368537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst3q_lane_v: 2369ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 23708dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst3lane, Ty), 2371464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2372537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst4_v: 2373537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst4q_v: 2374ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 23758dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst4, Ty), 2376464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2377537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst4_lane_v: 2378537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst4q_lane_v: 2379ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 23808dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst4lane, Ty), 2381464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2382537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsubhn_v: 23838dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vsubhn, Ty), 2384548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vsubhn"); 2385537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbl1_v: 23861c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl1), 23871c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbl1"); 2388537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbl2_v: 23891c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl2), 23901c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbl2"); 2391537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbl3_v: 23921c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl3), 23931c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbl3"); 2394537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbl4_v: 23951c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl4), 23961c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbl4"); 2397537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbx1_v: 23981c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx1), 23991c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbx1"); 2400537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbx2_v: 24011c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx2), 24021c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbx2"); 2403537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbx3_v: 24041c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx3), 24051c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbx3"); 2406537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbx4_v: 24071c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx4), 24081c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbx4"); 2409537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtst_v: 2410537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtstq_v: { 24111c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 24121c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 24131c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]); 2414258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0], 24151c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman ConstantAggregateZero::get(Ty)); 24161c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return Builder.CreateSExt(Ops[0], Ty, "vtst"); 24171c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 2418537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtrn_v: 2419537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtrnq_v: { 24204be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 24214be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 24224be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 24239577abc63f2c7afe5adf6e4e101ae91d29c3b8a6Ted Kremenek Value *SV = 0; 24244be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 24251c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman for (unsigned vi = 0; vi != 2; ++vi) { 24264be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SmallVector<Constant*, 16> Indices; 24274be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 24282ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner Indices.push_back(Builder.getInt32(i+vi)); 24292ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner Indices.push_back(Builder.getInt32(i+e+vi)); 24301c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 24314be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi); 2432fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner SV = llvm::ConstantVector::get(Indices); 24334be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vtrn"); 24344be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateStore(SV, Addr); 24351c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 24364be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return SV; 24371c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 2438537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vuzp_v: 2439537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vuzpq_v: { 24404be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 24411c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 24424be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 24439577abc63f2c7afe5adf6e4e101ae91d29c3b8a6Ted Kremenek Value *SV = 0; 2444258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 24454be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned vi = 0; vi != 2; ++vi) { 24464be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SmallVector<Constant*, 16> Indices; 24474be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 244877b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Indices.push_back(ConstantInt::get(Int32Ty, 2*i+vi)); 24494be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 24504be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi); 2451fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner SV = llvm::ConstantVector::get(Indices); 24524be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vuzp"); 24534be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateStore(SV, Addr); 24544be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 24554be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return SV; 24561c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 2457258f930227c1a102c9c22eee88df65f748863425Jim Grosbach case ARM::BI__builtin_neon_vzip_v: 2458537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vzipq_v: { 24594be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 24601c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 24614be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 24629577abc63f2c7afe5adf6e4e101ae91d29c3b8a6Ted Kremenek Value *SV = 0; 2463258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 24644be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned vi = 0; vi != 2; ++vi) { 24654be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SmallVector<Constant*, 16> Indices; 24664be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 2467e361cc3daa6c22e4413d48bd8b8934ea9fd5a55fDaniel Dunbar Indices.push_back(ConstantInt::get(Int32Ty, (i + vi*e) >> 1)); 2468e361cc3daa6c22e4413d48bd8b8934ea9fd5a55fDaniel Dunbar Indices.push_back(ConstantInt::get(Int32Ty, ((i + vi*e) >> 1)+e)); 24694be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 24704be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi); 2471fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner SV = llvm::ConstantVector::get(Indices); 24724be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vzip"); 24734be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateStore(SV, Addr); 24744be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 24754be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return SV; 24769eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 24772752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner } 24782752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner} 24792752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner 2480aa51e513850688b7963efc62abf1eface7037602Bill Wendlingllvm::Value *CodeGenFunction:: 2481795b10062c2eaffae9e04241fb1a73cdbcb24a37Bill WendlingBuildVector(ArrayRef<llvm::Value*> Ops) { 2482aa51e513850688b7963efc62abf1eface7037602Bill Wendling assert((Ops.size() & (Ops.size() - 1)) == 0 && 2483aa51e513850688b7963efc62abf1eface7037602Bill Wendling "Not a power-of-two sized vector!"); 2484aa51e513850688b7963efc62abf1eface7037602Bill Wendling bool AllConstants = true; 2485aa51e513850688b7963efc62abf1eface7037602Bill Wendling for (unsigned i = 0, e = Ops.size(); i != e && AllConstants; ++i) 2486aa51e513850688b7963efc62abf1eface7037602Bill Wendling AllConstants &= isa<Constant>(Ops[i]); 2487aa51e513850688b7963efc62abf1eface7037602Bill Wendling 2488aa51e513850688b7963efc62abf1eface7037602Bill Wendling // If this is a constant vector, create a ConstantVector. 2489aa51e513850688b7963efc62abf1eface7037602Bill Wendling if (AllConstants) { 24902ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner SmallVector<llvm::Constant*, 16> CstOps; 2491aa51e513850688b7963efc62abf1eface7037602Bill Wendling for (unsigned i = 0, e = Ops.size(); i != e; ++i) 2492aa51e513850688b7963efc62abf1eface7037602Bill Wendling CstOps.push_back(cast<Constant>(Ops[i])); 2493aa51e513850688b7963efc62abf1eface7037602Bill Wendling return llvm::ConstantVector::get(CstOps); 2494aa51e513850688b7963efc62abf1eface7037602Bill Wendling } 2495aa51e513850688b7963efc62abf1eface7037602Bill Wendling 2496aa51e513850688b7963efc62abf1eface7037602Bill Wendling // Otherwise, insertelement the values to build the vector. 2497aa51e513850688b7963efc62abf1eface7037602Bill Wendling Value *Result = 2498aa51e513850688b7963efc62abf1eface7037602Bill Wendling llvm::UndefValue::get(llvm::VectorType::get(Ops[0]->getType(), Ops.size())); 2499aa51e513850688b7963efc62abf1eface7037602Bill Wendling 2500aa51e513850688b7963efc62abf1eface7037602Bill Wendling for (unsigned i = 0, e = Ops.size(); i != e; ++i) 25012ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner Result = Builder.CreateInsertElement(Result, Ops[i], Builder.getInt32(i)); 2502aa51e513850688b7963efc62abf1eface7037602Bill Wendling 2503aa51e513850688b7963efc62abf1eface7037602Bill Wendling return Result; 2504aa51e513850688b7963efc62abf1eface7037602Bill Wendling} 2505aa51e513850688b7963efc62abf1eface7037602Bill Wendling 25061eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpValue *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, 25071feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner const CallExpr *E) { 25085f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Value*, 4> Ops; 25092929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson 251046c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // Find out if any arguments are required to be integer constant expressions. 251146c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner unsigned ICEArguments = 0; 251246c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner ASTContext::GetBuiltinTypeError Error; 251346c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 251446c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner assert(Error == ASTContext::GE_None && "Should not codegen an error"); 251546c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner 251646c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) { 251746c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // If this is a normal argument, just emit it as a scalar. 251846c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner if ((ICEArguments & (1 << i)) == 0) { 251946c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner Ops.push_back(EmitScalarExpr(E->getArg(i))); 252046c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner continue; 252146c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner } 252246c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner 252346c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // If this is required to be a constant, constant fold it so that we know 252446c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // that the generated intrinsic gets a ConstantInt. 252546c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner llvm::APSInt Result; 252646c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext()); 252746c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst; 2528d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result)); 252946c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner } 25302929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson 2531564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson switch (BuiltinID) { 253246a26b0b0e2ec1557bad9b70e8e20836524ebdfcAnders Carlsson default: return 0; 2533aa51e513850688b7963efc62abf1eface7037602Bill Wendling case X86::BI__builtin_ia32_vec_init_v8qi: 2534aa51e513850688b7963efc62abf1eface7037602Bill Wendling case X86::BI__builtin_ia32_vec_init_v4hi: 2535aa51e513850688b7963efc62abf1eface7037602Bill Wendling case X86::BI__builtin_ia32_vec_init_v2si: 2536aa51e513850688b7963efc62abf1eface7037602Bill Wendling return Builder.CreateBitCast(BuildVector(Ops), 2537d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::Type::getX86_MMXTy(getLLVMContext())); 25381944ec188408aff1931c62c79a069e30f2549ec2Argyrios Kyrtzidis case X86::BI__builtin_ia32_vec_ext_v2si: 25391944ec188408aff1931c62c79a069e30f2549ec2Argyrios Kyrtzidis return Builder.CreateExtractElement(Ops[0], 25401944ec188408aff1931c62c79a069e30f2549ec2Argyrios Kyrtzidis llvm::ConstantInt::get(Ops[1]->getType(), 0)); 2541e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_ldmxcsr: { 25422acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PtrTy = Int8PtrTy; 254377b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Value *One = llvm::ConstantInt::get(Int32Ty, 1); 2544578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Value *Tmp = Builder.CreateAlloca(Int32Ty, One); 2545e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Builder.CreateStore(Ops[0], Tmp); 2546e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr), 25473eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner Builder.CreateBitCast(Tmp, PtrTy)); 2548e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 2549e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_stmxcsr: { 25502acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PtrTy = Int8PtrTy; 255177b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Value *One = llvm::ConstantInt::get(Int32Ty, 1); 2552578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Value *Tmp = Builder.CreateAlloca(Int32Ty, One); 2553012614ecf78442368ec82ee30efb3bc047b413e6Ted Kremenek Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr), 2554012614ecf78442368ec82ee30efb3bc047b413e6Ted Kremenek Builder.CreateBitCast(Tmp, PtrTy)); 2555e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman return Builder.CreateLoad(Tmp, "stmxcsr"); 2556e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 2557e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_storehps: 2558e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_storelps: { 255977b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Type *PtrTy = llvm::PointerType::getUnqual(Int64Ty); 256077b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2); 25611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2562e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman // cast val v2i64 2563e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast"); 25641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2565e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman // extract (0, 1) 2566e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1; 256777b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Value *Idx = llvm::ConstantInt::get(Int32Ty, Index); 2568e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract"); 2569e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman 2570e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman // cast pointer to i64 & store 2571e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy); 2572e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 2573e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 257428cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling case X86::BI__builtin_ia32_palignr: { 257528cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 2576258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 257728cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // If palignr is shifting the pair of input vectors less than 9 bytes, 257828cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // emit a shuffle instruction. 257928cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling if (shiftVal <= 8) { 25805f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Constant*, 8> Indices; 258128cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling for (unsigned i = 0; i != 8; ++i) 258228cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling Indices.push_back(llvm::ConstantInt::get(Int32Ty, shiftVal + i)); 2583258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 2584fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner Value* SV = llvm::ConstantVector::get(Indices); 258528cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 258628cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling } 2587258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 258828cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // If palignr is shifting the pair of input vectors more than 8 but less 258928cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // than 16 bytes, emit a logical right shift of the destination. 259028cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling if (shiftVal < 16) { 259128cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // MMX has these as 1 x i64 vectors for some odd optimization reasons. 25922acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 1); 2593258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 259428cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 259528cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling Ops[1] = llvm::ConstantInt::get(VecTy, (shiftVal-8) * 8); 2596258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 259728cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // create i32 constant 259828cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_mmx_psrl_q); 2599e9c0265d6e6b5bf865f4a0c2c00d00ac251e6437Frits van Bommel return Builder.CreateCall(F, makeArrayRef(&Ops[0], 2), "palignr"); 260028cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling } 2601258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 26025c22ad2ef6bf39da22d5190025e0ddfd4b568b2aEli Friedman // If palignr is shifting the pair of vectors more than 16 bytes, emit zero. 260328cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling return llvm::Constant::getNullValue(ConvertType(E->getType())); 260428cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling } 2605c3420ffb282c6ffc0192013bf8045b6c21eddeceNate Begeman case X86::BI__builtin_ia32_palignr128: { 2606ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 2607258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 2608ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // If palignr is shifting the pair of input vectors less than 17 bytes, 2609ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // emit a shuffle instruction. 2610ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman if (shiftVal <= 16) { 26115f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Constant*, 16> Indices; 2612ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman for (unsigned i = 0; i != 16; ++i) 261377b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Indices.push_back(llvm::ConstantInt::get(Int32Ty, shiftVal + i)); 2614258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 2615fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner Value* SV = llvm::ConstantVector::get(Indices); 2616ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 2617ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman } 2618258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 2619ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // If palignr is shifting the pair of input vectors more than 16 but less 2620ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // than 32 bytes, emit a logical right shift of the destination. 2621ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman if (shiftVal < 32) { 26222acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2); 2623258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 2624ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 262577b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Ops[1] = llvm::ConstantInt::get(Int32Ty, (shiftVal-16) * 8); 2626258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 2627ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // create i32 constant 2628ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_psrl_dq); 2629e9c0265d6e6b5bf865f4a0c2c00d00ac251e6437Frits van Bommel return Builder.CreateCall(F, makeArrayRef(&Ops[0], 2), "palignr"); 2630ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman } 2631258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 2632ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 2633ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman return llvm::Constant::getNullValue(ConvertType(E->getType())); 263491b59274439f776cdd545bd7bf5849fdb1842160Eric Christopher } 26359c2ffd803af03f1728423d0d73ff87d988642633Craig Topper case X86::BI__builtin_ia32_palignr256: { 26369c2ffd803af03f1728423d0d73ff87d988642633Craig Topper unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 26379c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 26389c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // If palignr is shifting the pair of input vectors less than 17 bytes, 26399c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // emit a shuffle instruction. 26409c2ffd803af03f1728423d0d73ff87d988642633Craig Topper if (shiftVal <= 16) { 26419c2ffd803af03f1728423d0d73ff87d988642633Craig Topper SmallVector<llvm::Constant*, 32> Indices; 26429c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // 256-bit palignr operates on 128-bit lanes so we need to handle that 26439c2ffd803af03f1728423d0d73ff87d988642633Craig Topper for (unsigned l = 0; l != 2; ++l) { 26449c2ffd803af03f1728423d0d73ff87d988642633Craig Topper unsigned LaneStart = l * 16; 26459c2ffd803af03f1728423d0d73ff87d988642633Craig Topper unsigned LaneEnd = (l+1) * 16; 26469c2ffd803af03f1728423d0d73ff87d988642633Craig Topper for (unsigned i = 0; i != 16; ++i) { 26479c2ffd803af03f1728423d0d73ff87d988642633Craig Topper unsigned Idx = shiftVal + i + LaneStart; 26489c2ffd803af03f1728423d0d73ff87d988642633Craig Topper if (Idx >= LaneEnd) Idx += 16; // end of lane, switch operand 26499c2ffd803af03f1728423d0d73ff87d988642633Craig Topper Indices.push_back(llvm::ConstantInt::get(Int32Ty, Idx)); 26509c2ffd803af03f1728423d0d73ff87d988642633Craig Topper } 26519c2ffd803af03f1728423d0d73ff87d988642633Craig Topper } 26529c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 26539c2ffd803af03f1728423d0d73ff87d988642633Craig Topper Value* SV = llvm::ConstantVector::get(Indices); 26549c2ffd803af03f1728423d0d73ff87d988642633Craig Topper return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 26559c2ffd803af03f1728423d0d73ff87d988642633Craig Topper } 26569c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 26579c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // If palignr is shifting the pair of input vectors more than 16 but less 26589c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // than 32 bytes, emit a logical right shift of the destination. 26599c2ffd803af03f1728423d0d73ff87d988642633Craig Topper if (shiftVal < 32) { 26609c2ffd803af03f1728423d0d73ff87d988642633Craig Topper llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 4); 26619c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 26629c2ffd803af03f1728423d0d73ff87d988642633Craig Topper Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 26639c2ffd803af03f1728423d0d73ff87d988642633Craig Topper Ops[1] = llvm::ConstantInt::get(Int32Ty, (shiftVal-16) * 8); 26649c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 26659c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // create i32 constant 26669c2ffd803af03f1728423d0d73ff87d988642633Craig Topper llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_avx2_psrl_dq); 26679c2ffd803af03f1728423d0d73ff87d988642633Craig Topper return Builder.CreateCall(F, makeArrayRef(&Ops[0], 2), "palignr"); 26689c2ffd803af03f1728423d0d73ff87d988642633Craig Topper } 26699c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 26709c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 26719c2ffd803af03f1728423d0d73ff87d988642633Craig Topper return llvm::Constant::getNullValue(ConvertType(E->getType())); 26729c2ffd803af03f1728423d0d73ff87d988642633Craig Topper } 2673b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling case X86::BI__builtin_ia32_movntps: 26744a7376d00df98cbfcad29ee709637707a2f3d46cCraig Topper case X86::BI__builtin_ia32_movntps256: 2675b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling case X86::BI__builtin_ia32_movntpd: 26764a7376d00df98cbfcad29ee709637707a2f3d46cCraig Topper case X86::BI__builtin_ia32_movntpd256: 2677b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling case X86::BI__builtin_ia32_movntdq: 26784a7376d00df98cbfcad29ee709637707a2f3d46cCraig Topper case X86::BI__builtin_ia32_movntdq256: 2679b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling case X86::BI__builtin_ia32_movnti: { 2680b107dd02f5e365f60b036b8a27c784f2d0d0a855Bill Wendling llvm::MDNode *Node = llvm::MDNode::get(getLLVMContext(), 2681b107dd02f5e365f60b036b8a27c784f2d0d0a855Bill Wendling Builder.getInt32(1)); 2682b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling 2683b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling // Convert the type of the pointer to a pointer to the stored type. 2684b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling Value *BC = Builder.CreateBitCast(Ops[0], 2685b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling llvm::PointerType::getUnqual(Ops[1]->getType()), 2686b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling "cast"); 2687b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling StoreInst *SI = Builder.CreateStore(Ops[1], BC); 2688b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling SI->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); 2689b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling SI->setAlignment(16); 2690b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling return SI; 2691b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling } 26928b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer // 3DNow! 26938b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer case X86::BI__builtin_ia32_pswapdsf: 26948b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer case X86::BI__builtin_ia32_pswapdsi: { 26958b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer const char *name = 0; 26968b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer Intrinsic::ID ID = Intrinsic::not_intrinsic; 26978b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer switch(BuiltinID) { 2698f8495d67ca4dd2ea15a4dc59e9a2fa32a9bfa475Craig Topper default: llvm_unreachable("Unsupported intrinsic!"); 26998b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer case X86::BI__builtin_ia32_pswapdsf: 27008b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer case X86::BI__builtin_ia32_pswapdsi: 27018b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer name = "pswapd"; 27028b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer ID = Intrinsic::x86_3dnowa_pswapd; 27038b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer break; 27048b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer } 2705345032a7211a6f983d59c30c0b3fa2b96819532aChandler Carruth llvm::Type *MMXTy = llvm::Type::getX86_MMXTy(getLLVMContext()); 2706345032a7211a6f983d59c30c0b3fa2b96819532aChandler Carruth Ops[0] = Builder.CreateBitCast(Ops[0], MMXTy, "cast"); 27078b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer llvm::Function *F = CGM.getIntrinsic(ID); 27084c7d9f1507d0f102bd4133bba63348636facd469Jay Foad return Builder.CreateCall(F, Ops, name); 27098b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer } 27109a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer case X86::BI__builtin_ia32_rdrand16_step: 27119a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer case X86::BI__builtin_ia32_rdrand32_step: 27121bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao case X86::BI__builtin_ia32_rdrand64_step: 27131bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao case X86::BI__builtin_ia32_rdseed16_step: 27141bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao case X86::BI__builtin_ia32_rdseed32_step: 27151bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao case X86::BI__builtin_ia32_rdseed64_step: { 27169a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer Intrinsic::ID ID; 27179a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer switch (BuiltinID) { 27189a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer default: llvm_unreachable("Unsupported intrinsic!"); 27199a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer case X86::BI__builtin_ia32_rdrand16_step: 27209a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer ID = Intrinsic::x86_rdrand_16; 27219a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer break; 27229a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer case X86::BI__builtin_ia32_rdrand32_step: 27239a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer ID = Intrinsic::x86_rdrand_32; 27249a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer break; 27259a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer case X86::BI__builtin_ia32_rdrand64_step: 27269a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer ID = Intrinsic::x86_rdrand_64; 27279a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer break; 27281bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao case X86::BI__builtin_ia32_rdseed16_step: 27291bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao ID = Intrinsic::x86_rdseed_16; 27301bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao break; 27311bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao case X86::BI__builtin_ia32_rdseed32_step: 27321bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao ID = Intrinsic::x86_rdseed_32; 27331bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao break; 27341bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao case X86::BI__builtin_ia32_rdseed64_step: 27351bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao ID = Intrinsic::x86_rdseed_64; 27361bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao break; 27379a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer } 27389a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer 27399a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer Value *Call = Builder.CreateCall(CGM.getIntrinsic(ID)); 27409a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer Builder.CreateStore(Builder.CreateExtractValue(Call, 0), Ops[0]); 27419a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer return Builder.CreateExtractValue(Call, 1); 27429a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer } 2743564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson } 2744564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson} 2745564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson 27469631939f82c0eaa6fb3936a0ce58a41adfbc9011Tony Linthicum 27471eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpValue *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, 27481feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner const CallExpr *E) { 27495f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Value*, 4> Ops; 2750dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 2751dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) 2752dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner Ops.push_back(EmitScalarExpr(E->getArg(i))); 2753dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 2754dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner Intrinsic::ID ID = Intrinsic::not_intrinsic; 2755dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 2756dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner switch (BuiltinID) { 2757dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner default: return 0; 2758dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 27594d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov // vec_ld, vec_lvsl, vec_lvsr 27604d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvx: 27614d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvxl: 27624d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvebx: 27634d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvehx: 27644d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvewx: 27654d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvsl: 27664d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvsr: 27674d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov { 2768d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy); 27694d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov 2770578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Ops[0] = Builder.CreateGEP(Ops[1], Ops[0]); 27714d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov Ops.pop_back(); 27724d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov 27734d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov switch (BuiltinID) { 2774b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("Unsupported ld/lvsl/lvsr intrinsic!"); 27754d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvx: 27764d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvx; 27774d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 27784d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvxl: 27794d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvxl; 27804d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 27814d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvebx: 27824d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvebx; 27834d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 27844d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvehx: 27854d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvehx; 27864d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 27874d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvewx: 27884d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvewx; 27894d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 27904d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvsl: 27914d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvsl; 27924d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 27934d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvsr: 27944d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvsr; 27954d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 27964d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov } 27974d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov llvm::Function *F = CGM.getIntrinsic(ID); 27984c7d9f1507d0f102bd4133bba63348636facd469Jay Foad return Builder.CreateCall(F, Ops, ""); 27994d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov } 28004d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov 2801dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner // vec_st 2802dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvx: 2803dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvxl: 2804dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvebx: 2805dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvehx: 2806dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvewx: 2807dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner { 2808d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Ops[2] = Builder.CreateBitCast(Ops[2], Int8PtrTy); 2809578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Ops[1] = Builder.CreateGEP(Ops[2], Ops[1]); 2810dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner Ops.pop_back(); 2811dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 2812dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner switch (BuiltinID) { 2813b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("Unsupported st intrinsic!"); 2814dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvx: 2815dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvx; 2816dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 2817dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvxl: 2818dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvxl; 2819dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 2820dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvebx: 2821dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvebx; 2822dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 2823dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvehx: 2824dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvehx; 2825dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 2826dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvewx: 2827dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvewx; 2828dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 2829dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner } 2830dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner llvm::Function *F = CGM.getIntrinsic(ID); 28314c7d9f1507d0f102bd4133bba63348636facd469Jay Foad return Builder.CreateCall(F, Ops, ""); 2832dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner } 2833dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner } 28341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 2835