CGBuiltin.cpp revision 440a5f49133307745de7cc92a44d53088cf47c26
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 163b71757b2e02b83c18b736729a747016f0b1e1353Benjamin Kramer 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()); 29964aa4b3ec7e62288e2e66c1935487ece995ca94bJohn McCall Value *ZeroUndef = Builder.getInt1(getTarget().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()); 31664aa4b3ec7e62288e2e66c1935487ece995ca94bJohn McCall Value *ZeroUndef = Builder.getInt1(getTarget().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: { 1285ce4ad40100573008d013d2b9d3104c218ea34c2aHal Finkel // Transform a call to sqrt* into a @llvm.sqrt.* intrinsic call, but only 1286ce4ad40100573008d013d2b9d3104c218ea34c2aHal Finkel // in finite- or unsafe-math mode (the intrinsic has different semantics 1287ce4ad40100573008d013d2b9d3104c218ea34c2aHal Finkel // for handling negative numbers compared to the library function, so 1288ce4ad40100573008d013d2b9d3104c218ea34c2aHal Finkel // -fmath-errno=0 is not enough). 1289ce4ad40100573008d013d2b9d3104c218ea34c2aHal Finkel if (!FD->hasAttr<ConstAttr>()) 1290ce4ad40100573008d013d2b9d3104c218ea34c2aHal Finkel break; 1291ce4ad40100573008d013d2b9d3104c218ea34c2aHal Finkel if (!(CGM.getCodeGenOpts().UnsafeFPMath || 1292ce4ad40100573008d013d2b9d3104c218ea34c2aHal Finkel CGM.getCodeGenOpts().NoNaNsFPMath)) 1293ce4ad40100573008d013d2b9d3104c218ea34c2aHal Finkel break; 1294ce4ad40100573008d013d2b9d3104c218ea34c2aHal Finkel Value *Arg0 = EmitScalarExpr(E->getArg(0)); 1295ce4ad40100573008d013d2b9d3104c218ea34c2aHal Finkel llvm::Type *ArgType = Arg0->getType(); 1296ce4ad40100573008d013d2b9d3104c218ea34c2aHal Finkel Value *F = CGM.getIntrinsic(Intrinsic::sqrt, ArgType); 1297ce4ad40100573008d013d2b9d3104c218ea34c2aHal Finkel return RValue::get(Builder.CreateCall(F, Arg0)); 1298ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar } 1299ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar 1300ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIpow: 1301ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIpowf: 1302ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIpowl: { 13030323a7887b26f727080d2aa38f1a325dd23a1ee9Eli Bendersky // Transform a call to pow* into a @llvm.pow.* intrinsic call. 13040323a7887b26f727080d2aa38f1a325dd23a1ee9Eli Bendersky if (!FD->hasAttr<ConstAttr>()) 13050323a7887b26f727080d2aa38f1a325dd23a1ee9Eli Bendersky break; 13060323a7887b26f727080d2aa38f1a325dd23a1ee9Eli Bendersky Value *Base = EmitScalarExpr(E->getArg(0)); 13070323a7887b26f727080d2aa38f1a325dd23a1ee9Eli Bendersky Value *Exponent = EmitScalarExpr(E->getArg(1)); 13080323a7887b26f727080d2aa38f1a325dd23a1ee9Eli Bendersky llvm::Type *ArgType = Base->getType(); 13090323a7887b26f727080d2aa38f1a325dd23a1ee9Eli Bendersky Value *F = CGM.getIntrinsic(Intrinsic::pow, ArgType); 13100323a7887b26f727080d2aa38f1a325dd23a1ee9Eli Bendersky return RValue::get(Builder.CreateCall2(F, Base, Exponent)); 131164b22d8351a83593220803ed702e036c73bb8710Eli Bendersky break; 1312ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar } 1313ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman 1314094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BIfma: 1315094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BIfmaf: 1316094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BIfmal: 1317094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BI__builtin_fma: 1318094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BI__builtin_fmaf: 1319094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BI__builtin_fmal: { 1320094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich // Rewrite fma to intrinsic. 1321094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich Value *FirstArg = EmitScalarExpr(E->getArg(0)); 13229cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ArgType = FirstArg->getType(); 13238dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::fma, ArgType); 1324094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich return RValue::get(Builder.CreateCall3(F, FirstArg, 1325094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich EmitScalarExpr(E->getArg(1)), 1326578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer EmitScalarExpr(E->getArg(2)))); 1327094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich } 1328094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich 1329ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman case Builtin::BI__builtin_signbit: 1330ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman case Builtin::BI__builtin_signbitf: 1331ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman case Builtin::BI__builtin_signbitl: { 1332ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman LLVMContext &C = CGM.getLLVMContext(); 1333ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman 1334ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *Arg = EmitScalarExpr(E->getArg(0)); 13352acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ArgTy = Arg->getType(); 1336ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman if (ArgTy->isPPC_FP128Ty()) 1337ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman break; // FIXME: I'm not sure what the right implementation is here. 1338ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman int ArgWidth = ArgTy->getPrimitiveSizeInBits(); 13392acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ArgIntTy = llvm::IntegerType::get(C, ArgWidth); 1340ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *BCArg = Builder.CreateBitCast(Arg, ArgIntTy); 1341ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *ZeroCmp = llvm::Constant::getNullValue(ArgIntTy); 1342ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *Result = Builder.CreateICmpSLT(BCArg, ZeroCmp); 1343ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman return RValue::get(Builder.CreateZExt(Result, ConvertType(E->getType()))); 1344ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman } 134577f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge case Builtin::BI__builtin_annotation: { 134677f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge llvm::Value *AnnVal = EmitScalarExpr(E->getArg(0)); 134777f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::annotation, 134877f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge AnnVal->getType()); 134977f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge 135077f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge // Get the annotation string, go through casts. Sema requires this to be a 135177f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge // non-wide string literal, potentially casted, so the cast<> is safe. 135277f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge const Expr *AnnotationStrExpr = E->getArg(1)->IgnoreParenCasts(); 1353cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko StringRef Str = cast<StringLiteral>(AnnotationStrExpr)->getString(); 135477f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge return RValue::get(EmitAnnotationCall(F, AnnVal, Str, E->getExprLoc())); 135577f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge } 1356ee76e7215d27c25bb053b71ae0a59119c08ccef9Michael Gottesman case Builtin::BI__builtin_addcb: 13570cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman case Builtin::BI__builtin_addcs: 13580cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman case Builtin::BI__builtin_addc: 13590cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman case Builtin::BI__builtin_addcl: 13607c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_addcll: 1361ee76e7215d27c25bb053b71ae0a59119c08ccef9Michael Gottesman case Builtin::BI__builtin_subcb: 13627c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subcs: 13637c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subc: 13647c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subcl: 13657c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subcll: { 13660cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman 13670cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // We translate all of these builtins from expressions of the form: 13680cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // int x = ..., y = ..., carryin = ..., carryout, result; 13690cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // result = __builtin_addc(x, y, carryin, &carryout); 13700cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // 13710cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // to LLVM IR of the form: 13720cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // 13730cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %tmp1 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x, i32 %y) 13740cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %tmpsum1 = extractvalue {i32, i1} %tmp1, 0 13750cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %carry1 = extractvalue {i32, i1} %tmp1, 1 13760cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %tmp2 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %tmpsum1, 13770cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // i32 %carryin) 13780cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %result = extractvalue {i32, i1} %tmp2, 0 13790cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %carry2 = extractvalue {i32, i1} %tmp2, 1 13800cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %tmp3 = or i1 %carry1, %carry2 13810cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %tmp4 = zext i1 %tmp3 to i32 13820cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // store i32 %tmp4, i32* %carryout 13830cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman 13840cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // Scalarize our inputs. 13850cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *X = EmitScalarExpr(E->getArg(0)); 13860cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *Y = EmitScalarExpr(E->getArg(1)); 13870cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *Carryin = EmitScalarExpr(E->getArg(2)); 13880cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman std::pair<llvm::Value*, unsigned> CarryOutPtr = 13890cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman EmitPointerWithAlignment(E->getArg(3)); 13900cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman 13917c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman // Decide if we are lowering to a uadd.with.overflow or usub.with.overflow. 13927c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman llvm::Intrinsic::ID IntrinsicId; 13937c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman switch (BuiltinID) { 13947c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman default: llvm_unreachable("Unknown multiprecision builtin id."); 1395ee76e7215d27c25bb053b71ae0a59119c08ccef9Michael Gottesman case Builtin::BI__builtin_addcb: 13967c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_addcs: 13977c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_addc: 13987c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_addcl: 13997c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_addcll: 14007c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman IntrinsicId = llvm::Intrinsic::uadd_with_overflow; 14017c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman break; 1402ee76e7215d27c25bb053b71ae0a59119c08ccef9Michael Gottesman case Builtin::BI__builtin_subcb: 14037c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subcs: 14047c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subc: 14057c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subcl: 14067c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subcll: 14077c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman IntrinsicId = llvm::Intrinsic::usub_with_overflow; 14087c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman break; 14097c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman } 14100cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman 14110cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // Construct our resulting LLVM IR expression. 14120cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *Carry1; 14130cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *Sum1 = EmitOverflowIntrinsic(*this, IntrinsicId, 14140cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman X, Y, Carry1); 14150cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *Carry2; 14160cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *Sum2 = EmitOverflowIntrinsic(*this, IntrinsicId, 14170cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman Sum1, Carryin, Carry2); 14180cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *CarryOut = Builder.CreateZExt(Builder.CreateOr(Carry1, Carry2), 14190cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman X->getType()); 14200cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::StoreInst *CarryOutStore = Builder.CreateStore(CarryOut, 14210cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman CarryOutPtr.first); 14220cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman CarryOutStore->setAlignment(CarryOutPtr.second); 14230cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman return RValue::get(Sum2); 14240cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman } 142598d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_uadd_overflow: 142698d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_uaddl_overflow: 142798d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_uaddll_overflow: 142898d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_usub_overflow: 142998d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_usubl_overflow: 143098d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_usubll_overflow: 143198d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_umul_overflow: 143298d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_umull_overflow: 143398d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_umulll_overflow: 143498d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_sadd_overflow: 143598d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_saddl_overflow: 143698d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_saddll_overflow: 143798d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_ssub_overflow: 143898d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_ssubl_overflow: 143998d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_ssubll_overflow: 144098d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_smul_overflow: 144198d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_smull_overflow: 144298d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_smulll_overflow: { 144398d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman 144498d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman // We translate all of these builtins directly to the relevant llvm IR node. 144598d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman 144698d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman // Scalarize our inputs. 144798d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman llvm::Value *X = EmitScalarExpr(E->getArg(0)); 144898d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman llvm::Value *Y = EmitScalarExpr(E->getArg(1)); 144998d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman std::pair<llvm::Value *, unsigned> SumOutPtr = 145098d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman EmitPointerWithAlignment(E->getArg(2)); 145198d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman 145298d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman // Decide which of the overflow intrinsics we are lowering to: 145398d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman llvm::Intrinsic::ID IntrinsicId; 145498d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman switch (BuiltinID) { 145598d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman default: llvm_unreachable("Unknown security overflow builtin id."); 145698d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_uadd_overflow: 145798d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_uaddl_overflow: 145898d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_uaddll_overflow: 145998d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman IntrinsicId = llvm::Intrinsic::uadd_with_overflow; 146098d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman break; 146198d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_usub_overflow: 146298d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_usubl_overflow: 146398d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_usubll_overflow: 146498d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman IntrinsicId = llvm::Intrinsic::usub_with_overflow; 146598d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman break; 146698d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_umul_overflow: 146798d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_umull_overflow: 146898d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_umulll_overflow: 146998d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman IntrinsicId = llvm::Intrinsic::umul_with_overflow; 147098d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman break; 147198d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_sadd_overflow: 147298d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_saddl_overflow: 147398d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_saddll_overflow: 147498d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman IntrinsicId = llvm::Intrinsic::sadd_with_overflow; 147598d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman break; 147698d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_ssub_overflow: 147798d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_ssubl_overflow: 147898d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_ssubll_overflow: 147998d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman IntrinsicId = llvm::Intrinsic::ssub_with_overflow; 148098d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman break; 148198d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_smul_overflow: 148298d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_smull_overflow: 148398d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_smulll_overflow: 148498d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman IntrinsicId = llvm::Intrinsic::smul_with_overflow; 148598d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman break; 148698d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman } 148798d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman 148898d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman 148998d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman llvm::Value *Carry; 149098d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman llvm::Value *Sum = EmitOverflowIntrinsic(*this, IntrinsicId, X, Y, Carry); 149198d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman llvm::StoreInst *SumOutStore = Builder.CreateStore(Sum, SumOutPtr.first); 149298d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman SumOutStore->setAlignment(SumOutPtr.second); 149398d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman 149498d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman return RValue::get(Carry); 149598d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman } 14965154dce6388e3aaa445467030df7a45ed1211abeRichard Smith case Builtin::BI__builtin_addressof: 14975154dce6388e3aaa445467030df7a45ed1211abeRichard Smith return RValue::get(EmitLValue(E->getArg(0)).getAddress()); 149827844533aad5c165523a5926424097699610d3f0Nico Weber case Builtin::BI__noop: 149927844533aad5c165523a5926424097699610d3f0Nico Weber return RValue::get(0); 15007ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman } 15011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1502a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // If this is an alias for a lib function (e.g. __builtin_sin), emit 1503a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // the call using the normal call path, but using the unmangled 1504a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // version of the function name. 1505a45680b7e7c49ea9893c6cff585984f3e4120366John McCall if (getContext().BuiltinInfo.isLibFunction(BuiltinID)) 1506a45680b7e7c49ea9893c6cff585984f3e4120366John McCall return emitLibraryCall(*this, FD, E, 1507a45680b7e7c49ea9893c6cff585984f3e4120366John McCall CGM.getBuiltinLibFunction(FD, BuiltinID)); 1508258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 1509a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // If this is a predefined lib function (e.g. malloc), emit the call 1510a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // using exactly the normal call path. 1511a45680b7e7c49ea9893c6cff585984f3e4120366John McCall if (getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID)) 1512a45680b7e7c49ea9893c6cff585984f3e4120366John McCall return emitLibraryCall(*this, FD, E, EmitScalarExpr(E->getCallee())); 15131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1514b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // See if we have a target specific intrinsic. 1515a6f80ef997f0363386749087b325607eaa5adcfcDale Johannesen const char *Name = getContext().BuiltinInfo.GetName(BuiltinID); 151655cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic; 151755cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar if (const char *Prefix = 151864aa4b3ec7e62288e2e66c1935487ece995ca94bJohn McCall llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch())) 151955cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix, Name); 15201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1521b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (IntrinsicID != Intrinsic::not_intrinsic) { 1522b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner SmallVector<Value*, 16> Args; 15231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 152446c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // Find out if any arguments are required to be integer constant 152546c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // expressions. 152646c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner unsigned ICEArguments = 0; 152746c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner ASTContext::GetBuiltinTypeError Error; 152846c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 152946c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner assert(Error == ASTContext::GE_None && "Should not codegen an error"); 153046c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner 1531b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner Function *F = CGM.getIntrinsic(IntrinsicID); 15322acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = F->getFunctionType(); 15331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1534b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 153546c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner Value *ArgValue; 153646c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // If this is a normal argument, just emit it as a scalar. 153746c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner if ((ICEArguments & (1 << i)) == 0) { 153846c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner ArgValue = EmitScalarExpr(E->getArg(i)); 153946c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner } else { 1540258f930227c1a102c9c22eee88df65f748863425Jim Grosbach // If this is required to be a constant, constant fold it so that we 154146c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // know that the generated intrinsic gets a ConstantInt. 154246c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner llvm::APSInt Result; 154346c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result,getContext()); 154446c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner assert(IsConst && "Constant arg isn't actually constant?"); 154546c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner (void)IsConst; 1546d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall ArgValue = llvm::ConstantInt::get(getLLVMContext(), Result); 154746c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner } 15481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1549b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // If the intrinsic arg type is different from the builtin arg type 1550b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // we need to do a bit cast. 15512acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PTy = FTy->getParamType(i); 1552b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (PTy != ArgValue->getType()) { 1553b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) && 1554b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner "Must be able to losslessly bit cast to param"); 1555b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner ArgValue = Builder.CreateBitCast(ArgValue, PTy); 1556b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 15571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1558b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner Args.push_back(ArgValue); 1559b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 15601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15614c7d9f1507d0f102bd4133bba63348636facd469Jay Foad Value *V = Builder.CreateCall(F, Args); 1562b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner QualType BuiltinRetType = E->getType(); 15631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15648b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner llvm::Type *RetTy = VoidTy; 1565258f930227c1a102c9c22eee88df65f748863425Jim Grosbach if (!BuiltinRetType->isVoidType()) 15668b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner RetTy = ConvertType(BuiltinRetType); 15671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1568b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (RetTy != V->getType()) { 1569b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner assert(V->getType()->canLosslesslyBitCastTo(RetTy) && 1570b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner "Must be able to losslessly bit cast result type"); 1571b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner V = Builder.CreateBitCast(V, RetTy); 1572b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 15731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1574b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner return RValue::get(V); 1575b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 15761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1577b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // See if we have a target specific builtin that needs to be lowered. 1578f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E)) 1579b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner return RValue::get(V); 15801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1581488e993a135ce700b982bf099c3d6b856301d642Daniel Dunbar ErrorUnsupported(E, "builtin function"); 15821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1583b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // Unknown builtin, for now just dump it out and return undef. 15849d232c884ea9872d6555df0fd7359699819bc1f1John McCall return GetUndefRValue(E->getType()); 15851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 1586564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson 1587f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel DunbarValue *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, 1588f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar const CallExpr *E) { 158964aa4b3ec7e62288e2e66c1935487ece995ca94bJohn McCall switch (getTarget().getTriple().getArch()) { 1590ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover case llvm::Triple::aarch64: 1591ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover return EmitAArch64BuiltinExpr(BuiltinID, E); 15922752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner case llvm::Triple::arm: 15932752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner case llvm::Triple::thumb: 15942752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner return EmitARMBuiltinExpr(BuiltinID, E); 159555cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::x86: 159655cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::x86_64: 1597f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar return EmitX86BuiltinExpr(BuiltinID, E); 159855cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::ppc: 159955cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::ppc64: 1600ea7fb0ce25acc04664a2e7c2b24af03cef2c0d1fBill Schmidt case llvm::Triple::ppc64le: 1601f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar return EmitPPCBuiltinExpr(BuiltinID, E); 160255cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar default: 160355cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar return 0; 160455cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar } 1605f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar} 1606f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar 16078b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattnerstatic llvm::VectorType *GetNeonType(CodeGenFunction *CGF, 16088b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner NeonTypeFlags TypeFlags) { 160983084c863572b48579767a4dd5dc686e1a8d669dNAKAMURA Takumi int IsQuad = TypeFlags.isQuad(); 161083084c863572b48579767a4dd5dc686e1a8d669dNAKAMURA Takumi switch (TypeFlags.getEltType()) { 1611da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Int8: 1612da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Poly8: 16138b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner return llvm::VectorType::get(CGF->Int8Ty, 8 << IsQuad); 1614da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Int16: 1615da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Poly16: 1616da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Float16: 16178b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner return llvm::VectorType::get(CGF->Int16Ty, 4 << IsQuad); 1618da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Int32: 16198b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner return llvm::VectorType::get(CGF->Int32Ty, 2 << IsQuad); 1620da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Int64: 16218b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner return llvm::VectorType::get(CGF->Int64Ty, 1 << IsQuad); 1622da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Float32: 16238b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner return llvm::VectorType::get(CGF->FloatTy, 2 << IsQuad); 1624b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case NeonTypeFlags::Float64: 1625b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return llvm::VectorType::get(CGF->DoubleTy, 1 << IsQuad); 1626561d3abc881033776ece385a01a510e1cbc1fa92David Blaikie } 1627561d3abc881033776ece385a01a510e1cbc1fa92David Blaikie llvm_unreachable("Invalid NeonTypeFlags element type!"); 1628998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman} 1629998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman 1630cf55652cf668c1402eee0b12edd2e5a1bc34d7a1Bob WilsonValue *CodeGenFunction::EmitNeonSplat(Value *V, Constant *C) { 1631d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman unsigned nElts = cast<llvm::VectorType>(V->getType())->getNumElements(); 16322ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner Value* SV = llvm::ConstantVector::getSplat(nElts, C); 1633d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman return Builder.CreateShuffleVector(V, V, SV, "lane"); 1634d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman} 1635d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman 163630d91718a676177f0d0d0210ce4fdb4f616df6e5Nate BegemanValue *CodeGenFunction::EmitNeonCall(Function *F, SmallVectorImpl<Value*> &Ops, 1637db3d4d036037f379f12643e067b229862d61e932Bob Wilson const char *name, 163861eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman unsigned shift, bool rightshift) { 163930d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman unsigned j = 0; 164030d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end(); 164130d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman ai != ae; ++ai, ++j) 164261eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman if (shift > 0 && shift == j) 164361eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[j] = EmitNeonShiftVector(Ops[j], ai->getType(), rightshift); 164461eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman else 164561eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[j] = Builder.CreateBitCast(Ops[j], ai->getType(), name); 164630d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman 16474c7d9f1507d0f102bd4133bba63348636facd469Jay Foad return Builder.CreateCall(F, Ops, name); 164830d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman} 164930d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman 1650258f930227c1a102c9c22eee88df65f748863425Jim GrosbachValue *CodeGenFunction::EmitNeonShiftVector(Value *V, llvm::Type *Ty, 1651464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman bool neg) { 16522ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner int SV = cast<ConstantInt>(V)->getSExtValue(); 1653258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 16542acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 1655464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman llvm::Constant *C = ConstantInt::get(VTy->getElementType(), neg ? -SV : SV); 16562ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner return llvm::ConstantVector::getSplat(VTy->getNumElements(), C); 1657464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman} 1658464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman 165906b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson/// GetPointeeAlignment - Given an expression with a pointer type, find the 166006b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson/// alignment of the type referenced by the pointer. Skip over implicit 166106b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson/// casts. 1662ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedmanstd::pair<llvm::Value*, unsigned> 1663ea93e40785ffeadfac66b948c95f9490ec26207aEli FriedmanCodeGenFunction::EmitPointerWithAlignment(const Expr *Addr) { 1664ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman assert(Addr->getType()->isPointerType()); 1665ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Addr = Addr->IgnoreParens(); 1666ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Addr)) { 1667a484fc73ec6331bcaad092270b4ab9c8d1df23c3Eli Friedman if ((ICE->getCastKind() == CK_BitCast || ICE->getCastKind() == CK_NoOp) && 1668a484fc73ec6331bcaad092270b4ab9c8d1df23c3Eli Friedman ICE->getSubExpr()->getType()->isPointerType()) { 1669258f930227c1a102c9c22eee88df65f748863425Jim Grosbach std::pair<llvm::Value*, unsigned> Ptr = 1670ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(ICE->getSubExpr()); 1671ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ptr.first = Builder.CreateBitCast(Ptr.first, 1672ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman ConvertType(Addr->getType())); 1673ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return Ptr; 1674ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } else if (ICE->getCastKind() == CK_ArrayToPointerDecay) { 1675ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman LValue LV = EmitLValue(ICE->getSubExpr()); 16768e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman unsigned Align = LV.getAlignment().getQuantity(); 16778e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman if (!Align) { 16788e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman // FIXME: Once LValues are fixed to always set alignment, 16798e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman // zap this code. 16808e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman QualType PtTy = ICE->getSubExpr()->getType(); 16818e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman if (!PtTy->isIncompleteType()) 16828e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman Align = getContext().getTypeAlignInChars(PtTy).getQuantity(); 16838e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman else 16848e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman Align = 1; 16858e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman } 16868e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman return std::make_pair(LV.getAddress(), Align); 1687d6e73569ccf09369f9bd2021d53c88e7bded06e3Chris Lattner } 1688ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 1689ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(Addr)) { 1690ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (UO->getOpcode() == UO_AddrOf) { 1691ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman LValue LV = EmitLValue(UO->getSubExpr()); 16928e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman unsigned Align = LV.getAlignment().getQuantity(); 16938e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman if (!Align) { 16948e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman // FIXME: Once LValues are fixed to always set alignment, 16958e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman // zap this code. 16968e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman QualType PtTy = UO->getSubExpr()->getType(); 16978e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman if (!PtTy->isIncompleteType()) 16988e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman Align = getContext().getTypeAlignInChars(PtTy).getQuantity(); 16998e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman else 17008e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman Align = 1; 17018e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman } 17028e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman return std::make_pair(LV.getAddress(), Align); 170306b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson } 170406b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson } 1705f4c3db175101cbf94dad59419c3ed7aed51bf606Jay Foad 1706ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman unsigned Align = 1; 1707ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman QualType PtTy = Addr->getType()->getPointeeType(); 1708ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (!PtTy->isIncompleteType()) 1709ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Align = getContext().getTypeAlignInChars(PtTy).getQuantity(); 1710ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman 1711ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return std::make_pair(EmitScalarExpr(Addr), Align); 171206b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson} 171306b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson 1714ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim NorthoverValue *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, 1715ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover const CallExpr *E) { 1716ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover if (BuiltinID == AArch64::BI__clear_cache) { 1717ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover assert(E->getNumArgs() == 2 && 1718ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover "Variadic __clear_cache slipped through on AArch64"); 1719ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover 1720ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover const FunctionDecl *FD = E->getDirectCallee(); 1721ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover SmallVector<Value *, 2> Ops; 1722ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover for (unsigned i = 0; i < E->getNumArgs(); i++) 1723ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover Ops.push_back(EmitScalarExpr(E->getArg(i))); 1724ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); 1725ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); 1726ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover StringRef Name = FD->getName(); 1727ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); 1728ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover } 1729ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover 1730b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover SmallVector<Value *, 4> Ops; 1731b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) { 1732b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Ops.push_back(EmitScalarExpr(E->getArg(i))); 1733b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 1734b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 1735b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Get the last argument, which specifies the vector type. 1736b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover llvm::APSInt Result; 1737b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover const Expr *Arg = E->getArg(E->getNumArgs() - 1); 1738b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (!Arg->isIntegerConstantExpr(Result, getContext())) 1739b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return 0; 1740b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 1741b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Determine the type of this overloaded NEON intrinsic. 1742b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover NeonTypeFlags Type(Result.getZExtValue()); 1743b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover bool usgn = Type.isUnsigned(); 1744b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 1745b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover llvm::VectorType *VTy = GetNeonType(this, Type); 1746b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover llvm::Type *Ty = VTy; 1747b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (!Ty) 1748b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return 0; 1749b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 1750b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover unsigned Int; 1751b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover switch (BuiltinID) { 1752b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover default: 1753b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return 0; 1754b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 1755b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // AArch64 builtins mapping to legacy ARM v7 builtins. 1756b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // FIXME: the mapped builtins listed correspond to what has been tested 1757b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // in aarch64-neon-intrinsics.c so far. 1758b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vmul_v: 1759b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmul_v, E); 1760b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vmulq_v: 1761b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmulq_v, E); 1762b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vabd_v: 1763b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vabd_v, E); 1764b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vabdq_v: 1765b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vabdq_v, E); 1766b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vfma_v: 1767b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vfma_v, E); 1768b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vfmaq_v: 1769b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vfmaq_v, E); 1770b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vbsl_v: 1771b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vbsl_v, E); 1772b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vbslq_v: 1773b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vbslq_v, E); 1774b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vrsqrts_v: 1775b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrsqrts_v, E); 1776b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vrsqrtsq_v: 1777b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrsqrtsq_v, E); 1778b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vrecps_v: 1779b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrecps_v, E); 1780b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vrecpsq_v: 1781b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrecpsq_v, E); 1782b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vcage_v: 1783b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcage_v, E); 1784b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vcale_v: 1785b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcale_v, E); 1786b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vcaleq_v: 1787b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::swap(Ops[0], Ops[1]); 1788b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vcageq_v: { 1789b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Function *F; 1790b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (VTy->getElementType()->isIntegerTy(64)) 1791b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover F = CGM.getIntrinsic(Intrinsic::aarch64_neon_vacgeq); 1792b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover else 1793b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgeq); 1794b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitNeonCall(F, Ops, "vcage"); 1795b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 1796b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vcalt_v: 1797b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcalt_v, E); 1798b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vcagt_v: 1799b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcagt_v, E); 1800b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vcaltq_v: 1801b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::swap(Ops[0], Ops[1]); 1802b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vcagtq_v: { 1803b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Function *F; 1804b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (VTy->getElementType()->isIntegerTy(64)) 1805b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover F = CGM.getIntrinsic(Intrinsic::aarch64_neon_vacgtq); 1806b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover else 1807b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgtq); 1808b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitNeonCall(F, Ops, "vcagt"); 1809b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 1810b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vtst_v: 1811b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vtst_v, E); 1812b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vtstq_v: 1813b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vtstq_v, E); 1814b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vhadd_v: 1815b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vhadd_v, E); 1816b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vhaddq_v: 1817b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vhaddq_v, E); 1818b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vhsub_v: 1819b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vhsub_v, E); 1820b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vhsubq_v: 1821b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vhsubq_v, E); 1822b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vrhadd_v: 1823b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrhadd_v, E); 1824b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vrhaddq_v: 1825b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrhaddq_v, E); 1826b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqadd_v: 1827b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqadd_v, E); 1828b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqaddq_v: 1829b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqaddq_v, E); 1830b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqsub_v: 1831b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqsub_v, E); 1832b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqsubq_v: 1833b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqsubq_v, E); 1834b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vshl_v: 1835b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshl_v, E); 1836b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vshlq_v: 1837b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshlq_v, E); 1838b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqshl_v: 1839b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqshl_v, E); 1840b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqshlq_v: 1841b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqshlq_v, E); 1842b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vrshl_v: 1843b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrshl_v, E); 1844b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vrshlq_v: 1845b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrshlq_v, E); 1846b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqrshl_v: 1847b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqrshl_v, E); 1848b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqrshlq_v: 1849b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqrshlq_v, E); 1850097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case AArch64::BI__builtin_neon_vaddhn_v: 1851097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vaddhn_v, E); 1852097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case AArch64::BI__builtin_neon_vraddhn_v: 1853097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vraddhn_v, E); 1854097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case AArch64::BI__builtin_neon_vsubhn_v: 1855097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vsubhn_v, E); 1856097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case AArch64::BI__builtin_neon_vrsubhn_v: 1857097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrsubhn_v, E); 1858097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case AArch64::BI__builtin_neon_vmull_v: 1859097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmull_v, E); 1860097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case AArch64::BI__builtin_neon_vqdmull_v: 1861097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqdmull_v, E); 1862097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case AArch64::BI__builtin_neon_vqdmlal_v: 1863097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqdmlal_v, E); 1864097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case AArch64::BI__builtin_neon_vqdmlsl_v: 1865097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqdmlsl_v, E); 1866b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vmax_v: 1867b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmax_v, E); 1868b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vmaxq_v: 1869b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmaxq_v, E); 1870b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vmin_v: 1871b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmin_v, E); 1872b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vminq_v: 1873b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vminq_v, E); 1874b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vpmax_v: 1875b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vpmax_v, E); 1876b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vpmin_v: 1877b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vpmin_v, E); 1878b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vpadd_v: 1879b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vpadd_v, E); 1880b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqdmulh_v: 1881b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqdmulh_v, E); 1882b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqdmulhq_v: 1883b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqdmulhq_v, E); 1884b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqrdmulh_v: 1885b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqrdmulh_v, E); 1886b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqrdmulhq_v: 1887b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqrdmulhq_v, E); 1888912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu 1889912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu // Shift by immediate 1890912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vshr_n_v: 1891912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshr_n_v, E); 1892912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vshrq_n_v: 1893912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshrq_n_v, E); 1894912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vrshr_n_v: 1895912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vrshrq_n_v: 1896912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Int = usgn ? Intrinsic::aarch64_neon_vurshr 1897912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu : Intrinsic::aarch64_neon_vsrshr; 1898912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshr_n"); 1899912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vsra_n_v: 1900912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vsra_n_v, E); 1901912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vsraq_n_v: 1902912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vsraq_n_v, E); 1903912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vrsra_n_v: 1904912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vrsraq_n_v: { 1905912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 1906912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 1907912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Int = usgn ? Intrinsic::aarch64_neon_vurshr 1908912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu : Intrinsic::aarch64_neon_vsrshr; 1909912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Ops[1] = Builder.CreateCall2(CGM.getIntrinsic(Int, Ty), Ops[1], Ops[2]); 1910912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n"); 1911912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu } 191212cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu case AArch64::BI__builtin_neon_vshl_n_v: 191312cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshl_n_v, E); 191412cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu case AArch64::BI__builtin_neon_vshlq_n_v: 191512cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshlq_n_v, E); 1916912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vqshl_n_v: 1917912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqshl_n_v, E); 1918912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vqshlq_n_v: 1919912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqshlq_n_v, E); 1920912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vqshlu_n_v: 1921912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vqshluq_n_v: 1922912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Int = Intrinsic::aarch64_neon_vsqshlu; 1923912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshlu_n"); 1924912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vsri_n_v: 1925912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vsriq_n_v: 1926912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Int = Intrinsic::aarch64_neon_vsri; 1927912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsri_n"); 1928912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vsli_n_v: 1929912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vsliq_n_v: 1930912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Int = Intrinsic::aarch64_neon_vsli; 1931912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsli_n"); 1932912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vshll_n_v: { 1933912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu llvm::Type *SrcTy = llvm::VectorType::getTruncatedElementVectorType(VTy); 1934912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 1935912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu if (usgn) 1936912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Ops[0] = Builder.CreateZExt(Ops[0], VTy); 1937912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu else 1938912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Ops[0] = Builder.CreateSExt(Ops[0], VTy); 1939912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Ops[1] = EmitNeonShiftVector(Ops[1], VTy, false); 1940912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return Builder.CreateShl(Ops[0], Ops[1], "vshll_n"); 1941912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu } 1942912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vshrn_n_v: { 1943912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu llvm::Type *SrcTy = llvm::VectorType::getExtendedElementVectorType(VTy); 1944912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 1945912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Ops[1] = EmitNeonShiftVector(Ops[1], SrcTy, false); 1946912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu if (usgn) 1947912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Ops[0] = Builder.CreateLShr(Ops[0], Ops[1]); 1948912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu else 1949912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Ops[0] = Builder.CreateAShr(Ops[0], Ops[1]); 1950912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return Builder.CreateTrunc(Ops[0], Ty, "vshrn_n"); 1951912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu } 1952912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vqshrun_n_v: 1953912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Int = Intrinsic::aarch64_neon_vsqshrun; 1954912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrun_n"); 1955912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vrshrn_n_v: 1956912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Int = Intrinsic::aarch64_neon_vrshrn; 1957912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshrn_n"); 1958912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vqrshrun_n_v: 1959912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Int = Intrinsic::aarch64_neon_vsqrshrun; 1960912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrun_n"); 1961912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vqshrn_n_v: 1962912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Int = usgn ? Intrinsic::aarch64_neon_vuqshrn 1963912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu : Intrinsic::aarch64_neon_vsqshrn; 1964912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n"); 1965912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vqrshrn_n_v: 1966912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Int = usgn ? Intrinsic::aarch64_neon_vuqrshrn 1967912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu : Intrinsic::aarch64_neon_vsqrshrn; 1968912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n"); 1969912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu 1970912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu // Convert 197112cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu case AArch64::BI__builtin_neon_vmovl_v: 197212cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmovl_v, E); 1973912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vcvt_n_f32_v: 1974912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvt_n_f32_v, E); 1975912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vcvtq_n_f32_v: 1976912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvtq_n_f32_v, E); 1977912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vcvtq_n_f64_v: { 1978912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu llvm::Type *FloatTy = 1979912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, true)); 1980912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu llvm::Type *Tys[2] = { FloatTy, Ty }; 1981912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Int = usgn ? Intrinsic::arm_neon_vcvtfxu2fp 1982912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu : Intrinsic::arm_neon_vcvtfxs2fp; 1983912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Function *F = CGM.getIntrinsic(Int, Tys); 1984912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitNeonCall(F, Ops, "vcvt_n"); 1985912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu } 1986912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vcvt_n_s32_v: 1987912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvt_n_s32_v, E); 1988912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vcvtq_n_s32_v: 1989912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvtq_n_s32_v, E); 1990912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vcvt_n_u32_v: 1991912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvt_n_u32_v, E); 1992912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vcvtq_n_u32_v: 1993912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvtq_n_u32_v, E); 1994912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vcvtq_n_s64_v: 1995912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case AArch64::BI__builtin_neon_vcvtq_n_u64_v: { 1996912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu llvm::Type *FloatTy = 1997912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, true)); 1998912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu llvm::Type *Tys[2] = { Ty, FloatTy }; 1999912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Int = usgn ? Intrinsic::arm_neon_vcvtfp2fxu 2000912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu : Intrinsic::arm_neon_vcvtfp2fxs; 2001912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu Function *F = CGM.getIntrinsic(Int, Tys); 2002912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return EmitNeonCall(F, Ops, "vcvt_n"); 2003912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu } 2004b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 2005b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // AArch64-only builtins 2006b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vfms_v: 2007b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vfmsq_v: { 2008b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 2009b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2010b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 2011b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Ops[1] = Builder.CreateFNeg(Ops[1]); 2012b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 2013b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 2014b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // LLVM's fma intrinsic puts the accumulator in the last position, but the 2015b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // AArch64 intrinsic has it first. 2016b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]); 2017b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 2018b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vmaxnm_v: 2019b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vmaxnmq_v: { 2020b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Int = Intrinsic::aarch64_neon_vmaxnm; 2021b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmaxnm"); 2022b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 2023b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vminnm_v: 2024b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vminnmq_v: { 2025b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Int = Intrinsic::aarch64_neon_vminnm; 2026b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vminnm"); 2027b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 2028b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vpmaxnm_v: 2029b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vpmaxnmq_v: { 2030b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Int = Intrinsic::aarch64_neon_vpmaxnm; 2031b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmaxnm"); 2032b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 2033b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vpminnm_v: 2034b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vpminnmq_v: { 2035b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Int = Intrinsic::aarch64_neon_vpminnm; 2036b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpminnm"); 2037b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 2038b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vpmaxq_v: { 2039b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Int = usgn ? Intrinsic::arm_neon_vpmaxu : Intrinsic::arm_neon_vpmaxs; 2040b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmax"); 2041b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 2042b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vpminq_v: { 2043b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Int = usgn ? Intrinsic::arm_neon_vpminu : Intrinsic::arm_neon_vpmins; 2044b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmin"); 2045b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 2046b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vpaddq_v: { 2047b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Int = Intrinsic::arm_neon_vpadd; 2048b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpadd"); 2049b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 2050b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vmulx_v: 2051b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vmulxq_v: { 2052b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Int = Intrinsic::aarch64_neon_vmulx; 2053b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmulx"); 2054b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 2055b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 2056ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover} 2057ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover 20582752c0137d95aa2f4ee1cdff4b564bac842e041bChris LattnerValue *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, 20592752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner const CallExpr *E) { 2060e140af3e27016f902146023fba7680b43043ec07Rafael Espindola if (BuiltinID == ARM::BI__clear_cache) { 20614537d6e0f9baf2e011a4260e0d7872789b01c3f2Rafael Espindola assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments"); 206279ba509b0106fd0a1ff832baeb1fdb5430527efeRafael Espindola const FunctionDecl *FD = E->getDirectCallee(); 20635f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Value*, 2> Ops; 20644537d6e0f9baf2e011a4260e0d7872789b01c3f2Rafael Espindola for (unsigned i = 0; i < 2; i++) 20658a37c79f03e62aecfa2c58b9179f90dd1fcdb253Eric Christopher Ops.push_back(EmitScalarExpr(E->getArg(i))); 20662acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); 20672acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); 20685f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Name = FD->getName(); 2069bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); 20702752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner } 2071e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 207209df2b066221d869f17f4b5762405f111a65f983Tim Northover if (BuiltinID == ARM::BI__builtin_arm_ldrexd || 207309df2b066221d869f17f4b5762405f111a65f983Tim Northover (BuiltinID == ARM::BI__builtin_arm_ldrex && 207409df2b066221d869f17f4b5762405f111a65f983Tim Northover getContext().getTypeSize(E->getType()) == 64)) { 207526c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Function *F = CGM.getIntrinsic(Intrinsic::arm_ldrexd); 207626c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 207726c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *LdPtr = EmitScalarExpr(E->getArg(0)); 207809df2b066221d869f17f4b5762405f111a65f983Tim Northover Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy), 207909df2b066221d869f17f4b5762405f111a65f983Tim Northover "ldrexd"); 208026c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 208126c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *Val0 = Builder.CreateExtractValue(Val, 1); 208226c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *Val1 = Builder.CreateExtractValue(Val, 0); 208326c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Val0 = Builder.CreateZExt(Val0, Int64Ty); 208426c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Val1 = Builder.CreateZExt(Val1, Int64Ty); 208526c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 208626c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *ShiftCst = llvm::ConstantInt::get(Int64Ty, 32); 208726c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */); 208809df2b066221d869f17f4b5762405f111a65f983Tim Northover Val = Builder.CreateOr(Val, Val1); 208909df2b066221d869f17f4b5762405f111a65f983Tim Northover return Builder.CreateBitCast(Val, ConvertType(E->getType())); 209026c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes } 209126c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 209209df2b066221d869f17f4b5762405f111a65f983Tim Northover if (BuiltinID == ARM::BI__builtin_arm_ldrex) { 209309df2b066221d869f17f4b5762405f111a65f983Tim Northover Value *LoadAddr = EmitScalarExpr(E->getArg(0)); 209409df2b066221d869f17f4b5762405f111a65f983Tim Northover 209509df2b066221d869f17f4b5762405f111a65f983Tim Northover QualType Ty = E->getType(); 209609df2b066221d869f17f4b5762405f111a65f983Tim Northover llvm::Type *RealResTy = ConvertType(Ty); 209709df2b066221d869f17f4b5762405f111a65f983Tim Northover llvm::Type *IntResTy = llvm::IntegerType::get(getLLVMContext(), 209809df2b066221d869f17f4b5762405f111a65f983Tim Northover getContext().getTypeSize(Ty)); 209909df2b066221d869f17f4b5762405f111a65f983Tim Northover LoadAddr = Builder.CreateBitCast(LoadAddr, IntResTy->getPointerTo()); 210009df2b066221d869f17f4b5762405f111a65f983Tim Northover 210109df2b066221d869f17f4b5762405f111a65f983Tim Northover Function *F = CGM.getIntrinsic(Intrinsic::arm_ldrex, LoadAddr->getType()); 210209df2b066221d869f17f4b5762405f111a65f983Tim Northover Value *Val = Builder.CreateCall(F, LoadAddr, "ldrex"); 210309df2b066221d869f17f4b5762405f111a65f983Tim Northover 210409df2b066221d869f17f4b5762405f111a65f983Tim Northover if (RealResTy->isPointerTy()) 210509df2b066221d869f17f4b5762405f111a65f983Tim Northover return Builder.CreateIntToPtr(Val, RealResTy); 210609df2b066221d869f17f4b5762405f111a65f983Tim Northover else { 210709df2b066221d869f17f4b5762405f111a65f983Tim Northover Val = Builder.CreateTruncOrBitCast(Val, IntResTy); 210809df2b066221d869f17f4b5762405f111a65f983Tim Northover return Builder.CreateBitCast(Val, RealResTy); 210909df2b066221d869f17f4b5762405f111a65f983Tim Northover } 211009df2b066221d869f17f4b5762405f111a65f983Tim Northover } 211109df2b066221d869f17f4b5762405f111a65f983Tim Northover 211209df2b066221d869f17f4b5762405f111a65f983Tim Northover if (BuiltinID == ARM::BI__builtin_arm_strexd || 211309df2b066221d869f17f4b5762405f111a65f983Tim Northover (BuiltinID == ARM::BI__builtin_arm_strex && 211409df2b066221d869f17f4b5762405f111a65f983Tim Northover getContext().getTypeSize(E->getArg(0)->getType()) == 64)) { 211526c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Function *F = CGM.getIntrinsic(Intrinsic::arm_strexd); 21167650d95a1a616ea300f37126a8dfc93dc19a662aChris Lattner llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, NULL); 211726c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 21183fc779191ce87cddf603e0c5bdbd225611201ff4Juergen Ributzka Value *Tmp = CreateMemTemp(E->getArg(0)->getType()); 211926c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *Val = EmitScalarExpr(E->getArg(0)); 212026c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Builder.CreateStore(Val, Tmp); 212126c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 212226c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *LdPtr = Builder.CreateBitCast(Tmp,llvm::PointerType::getUnqual(STy)); 212326c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Val = Builder.CreateLoad(LdPtr); 212426c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 212526c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *Arg0 = Builder.CreateExtractValue(Val, 0); 212626c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *Arg1 = Builder.CreateExtractValue(Val, 1); 212709df2b066221d869f17f4b5762405f111a65f983Tim Northover Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), Int8PtrTy); 212826c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes return Builder.CreateCall3(F, Arg0, Arg1, StPtr, "strexd"); 212926c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes } 213026c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 213109df2b066221d869f17f4b5762405f111a65f983Tim Northover if (BuiltinID == ARM::BI__builtin_arm_strex) { 213209df2b066221d869f17f4b5762405f111a65f983Tim Northover Value *StoreVal = EmitScalarExpr(E->getArg(0)); 213309df2b066221d869f17f4b5762405f111a65f983Tim Northover Value *StoreAddr = EmitScalarExpr(E->getArg(1)); 213409df2b066221d869f17f4b5762405f111a65f983Tim Northover 213509df2b066221d869f17f4b5762405f111a65f983Tim Northover QualType Ty = E->getArg(0)->getType(); 213609df2b066221d869f17f4b5762405f111a65f983Tim Northover llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(), 213709df2b066221d869f17f4b5762405f111a65f983Tim Northover getContext().getTypeSize(Ty)); 213809df2b066221d869f17f4b5762405f111a65f983Tim Northover StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo()); 213909df2b066221d869f17f4b5762405f111a65f983Tim Northover 214009df2b066221d869f17f4b5762405f111a65f983Tim Northover if (StoreVal->getType()->isPointerTy()) 214109df2b066221d869f17f4b5762405f111a65f983Tim Northover StoreVal = Builder.CreatePtrToInt(StoreVal, Int32Ty); 214209df2b066221d869f17f4b5762405f111a65f983Tim Northover else { 214309df2b066221d869f17f4b5762405f111a65f983Tim Northover StoreVal = Builder.CreateBitCast(StoreVal, StoreTy); 214409df2b066221d869f17f4b5762405f111a65f983Tim Northover StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int32Ty); 214509df2b066221d869f17f4b5762405f111a65f983Tim Northover } 214609df2b066221d869f17f4b5762405f111a65f983Tim Northover 214709df2b066221d869f17f4b5762405f111a65f983Tim Northover Function *F = CGM.getIntrinsic(Intrinsic::arm_strex, StoreAddr->getType()); 214809df2b066221d869f17f4b5762405f111a65f983Tim Northover return Builder.CreateCall2(F, StoreVal, StoreAddr, "strex"); 214909df2b066221d869f17f4b5762405f111a65f983Tim Northover } 215009df2b066221d869f17f4b5762405f111a65f983Tim Northover 215109df2b066221d869f17f4b5762405f111a65f983Tim Northover if (BuiltinID == ARM::BI__builtin_arm_clrex) { 215209df2b066221d869f17f4b5762405f111a65f983Tim Northover Function *F = CGM.getIntrinsic(Intrinsic::arm_clrex); 215309df2b066221d869f17f4b5762405f111a65f983Tim Northover return Builder.CreateCall(F); 215409df2b066221d869f17f4b5762405f111a65f983Tim Northover } 215509df2b066221d869f17f4b5762405f111a65f983Tim Northover 2156520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly // CRC32 2157520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic; 2158520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly switch (BuiltinID) { 2159520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly case ARM::BI__builtin_arm_crc32b: 2160520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly CRCIntrinsicID = Intrinsic::arm_crc32b; break; 2161520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly case ARM::BI__builtin_arm_crc32cb: 2162520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly CRCIntrinsicID = Intrinsic::arm_crc32cb; break; 2163520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly case ARM::BI__builtin_arm_crc32h: 2164520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly CRCIntrinsicID = Intrinsic::arm_crc32h; break; 2165520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly case ARM::BI__builtin_arm_crc32ch: 2166520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly CRCIntrinsicID = Intrinsic::arm_crc32ch; break; 2167520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly case ARM::BI__builtin_arm_crc32w: 2168520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly case ARM::BI__builtin_arm_crc32d: 2169520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly CRCIntrinsicID = Intrinsic::arm_crc32w; break; 2170520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly case ARM::BI__builtin_arm_crc32cw: 2171520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly case ARM::BI__builtin_arm_crc32cd: 2172520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly CRCIntrinsicID = Intrinsic::arm_crc32cw; break; 2173520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly } 2174520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly 2175520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly if (CRCIntrinsicID != Intrinsic::not_intrinsic) { 2176520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly Value *Arg0 = EmitScalarExpr(E->getArg(0)); 2177520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly Value *Arg1 = EmitScalarExpr(E->getArg(1)); 2178520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly 2179520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly // crc32{c,}d intrinsics are implemnted as two calls to crc32{c,}w 2180520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly // intrinsics, hence we need different codegen for these cases. 2181520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly if (BuiltinID == ARM::BI__builtin_arm_crc32d || 2182520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly BuiltinID == ARM::BI__builtin_arm_crc32cd) { 2183520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly Value *C1 = llvm::ConstantInt::get(Int64Ty, 32); 2184520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly Value *Arg1a = Builder.CreateTruncOrBitCast(Arg1, Int32Ty); 2185520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly Value *Arg1b = Builder.CreateLShr(Arg1, C1); 2186520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly Arg1b = Builder.CreateTruncOrBitCast(Arg1b, Int32Ty); 2187520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly 2188520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly Function *F = CGM.getIntrinsic(CRCIntrinsicID); 2189520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly Value *Res = Builder.CreateCall2(F, Arg0, Arg1a); 2190520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly return Builder.CreateCall2(F, Res, Arg1b); 2191520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly } else { 2192520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly Arg1 = Builder.CreateZExtOrBitCast(Arg1, Int32Ty); 2193520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly 2194520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly Function *F = CGM.getIntrinsic(CRCIntrinsicID); 2195520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly return Builder.CreateCall2(F, Arg0, Arg1); 2196520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly } 2197520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly } 2198520ec1e553ffa955276462e4230c1b128fa433afJoey Gouly 21995f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Value*, 4> Ops; 2200ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman llvm::Value *Align = 0; 2201ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) { 2202ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (i == 0) { 2203ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman switch (BuiltinID) { 2204ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1_v: 2205ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1q_v: 2206ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1q_lane_v: 2207ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1_lane_v: 2208ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1_dup_v: 2209ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1q_dup_v: 2210ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst1_v: 2211ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst1q_v: 2212ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst1q_lane_v: 2213ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst1_lane_v: 2214ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst2_v: 2215ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst2q_v: 2216ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst2_lane_v: 2217ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst2q_lane_v: 2218ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst3_v: 2219ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst3q_v: 2220ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst3_lane_v: 2221ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst3q_lane_v: 2222ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst4_v: 2223ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst4q_v: 2224ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst4_lane_v: 2225ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst4q_lane_v: 2226ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman // Get the alignment for the argument in addition to the value; 2227ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman // we'll use it later. 2228ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Src = 2229ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(0)); 2230ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Src.first); 2231ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Align = Builder.getInt32(Src.second); 2232ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman continue; 2233ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 2234ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 2235ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (i == 1) { 2236ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman switch (BuiltinID) { 2237ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld2_v: 2238ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld2q_v: 2239ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld3_v: 2240ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld3q_v: 2241ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld4_v: 2242ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld4q_v: 2243ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld2_lane_v: 2244ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld2q_lane_v: 2245ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld3_lane_v: 2246ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld3q_lane_v: 2247ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld4_lane_v: 2248ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld4q_lane_v: 2249ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld2_dup_v: 2250ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld3_dup_v: 2251ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld4_dup_v: 2252ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman // Get the alignment for the argument in addition to the value; 2253ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman // we'll use it later. 2254ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Src = 2255ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(1)); 2256ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Src.first); 2257ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Align = Builder.getInt32(Src.second); 2258ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman continue; 2259ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 2260ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 2261e140af3e27016f902146023fba7680b43043ec07Rafael Espindola Ops.push_back(EmitScalarExpr(E->getArg(i))); 2262ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 2263e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 226483bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson // vget_lane and vset_lane are not overloaded and do not have an extra 226583bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson // argument that specifies the vector type. 226683bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson switch (BuiltinID) { 226783bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson default: break; 226883bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vget_lane_i8: 226983bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vget_lane_i16: 227083bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vget_lane_i32: 227183bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vget_lane_i64: 227283bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vget_lane_f32: 227383bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vgetq_lane_i8: 227483bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vgetq_lane_i16: 227583bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vgetq_lane_i32: 227683bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vgetq_lane_i64: 227783bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vgetq_lane_f32: 227883bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 227983bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson "vget_lane"); 228083bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vset_lane_i8: 228183bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vset_lane_i16: 228283bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vset_lane_i32: 228383bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vset_lane_i64: 228483bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vset_lane_f32: 228583bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vsetq_lane_i8: 228683bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vsetq_lane_i16: 228783bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vsetq_lane_i32: 228883bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vsetq_lane_i64: 228983bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vsetq_lane_f32: 229083bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson Ops.push_back(EmitScalarExpr(E->getArg(2))); 229183bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 229283bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson } 229383bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson 229483bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson // Get the last argument, which specifies the vector type. 2295e140af3e27016f902146023fba7680b43043ec07Rafael Espindola llvm::APSInt Result; 2296e140af3e27016f902146023fba7680b43043ec07Rafael Espindola const Expr *Arg = E->getArg(E->getNumArgs()-1); 2297e140af3e27016f902146023fba7680b43043ec07Rafael Espindola if (!Arg->isIntegerConstantExpr(Result, getContext())) 2298e140af3e27016f902146023fba7680b43043ec07Rafael Espindola return 0; 2299e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 230099c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f || 230199c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman BuiltinID == ARM::BI__builtin_arm_vcvtr_d) { 230299c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman // Determine the overloaded type of this builtin. 23039cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *Ty; 230499c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f) 23058b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner Ty = FloatTy; 230699c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman else 23078b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner Ty = DoubleTy; 2308258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 230999c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman // Determine whether this is an unsigned conversion or not. 231099c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman bool usgn = Result.getZExtValue() == 1; 231199c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman unsigned Int = usgn ? Intrinsic::arm_vcvtru : Intrinsic::arm_vcvtr; 231299c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman 231399c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman // Call the appropriate intrinsic. 23148dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Int, Ty); 23154c7d9f1507d0f102bd4133bba63348636facd469Jay Foad return Builder.CreateCall(F, Ops, "vcvtr"); 231699c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman } 2317258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 231899c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman // Determine the type of this overloaded NEON intrinsic. 2319da95f73b59f9af964e33725c515139d34c90c863Bob Wilson NeonTypeFlags Type(Result.getZExtValue()); 2320da95f73b59f9af964e33725c515139d34c90c863Bob Wilson bool usgn = Type.isUnsigned(); 2321da95f73b59f9af964e33725c515139d34c90c863Bob Wilson bool quad = Type.isQuad(); 23227965396d8d6ac23ec4c4f9d01d216f2e73d7fc72Bob Wilson bool rightShift = false; 2323e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 23248b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner llvm::VectorType *VTy = GetNeonType(this, Type); 23259cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *Ty = VTy; 2326e140af3e27016f902146023fba7680b43043ec07Rafael Espindola if (!Ty) 2327e140af3e27016f902146023fba7680b43043ec07Rafael Espindola return 0; 2328e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 2329e140af3e27016f902146023fba7680b43043ec07Rafael Espindola unsigned Int; 2330e140af3e27016f902146023fba7680b43043ec07Rafael Espindola switch (BuiltinID) { 2331e140af3e27016f902146023fba7680b43043ec07Rafael Espindola default: return 0; 23324c919eb0c022be30d6130446cb8d50a7e8da9f46Jim Grosbach case ARM::BI__builtin_neon_vbsl_v: 23334c919eb0c022be30d6130446cb8d50a7e8da9f46Jim Grosbach case ARM::BI__builtin_neon_vbslq_v: 23344c919eb0c022be30d6130446cb8d50a7e8da9f46Jim Grosbach return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vbsl, Ty), 23354c919eb0c022be30d6130446cb8d50a7e8da9f46Jim Grosbach Ops, "vbsl"); 2336537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vabd_v: 2337537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vabdq_v: 2338998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman Int = usgn ? Intrinsic::arm_neon_vabdu : Intrinsic::arm_neon_vabds; 23398dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vabd"); 2340537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vabs_v: 2341537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vabsq_v: 23428dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vabs, Ty), 2343548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vabs"); 23446bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover case ARM::BI__builtin_neon_vaddhn_v: { 23456bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover llvm::VectorType *SrcTy = 23466bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover llvm::VectorType::getExtendedElementVectorType(VTy); 23476bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover 23486bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover // %sum = add <4 x i32> %lhs, %rhs 23496bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 23506bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy); 23516bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover Ops[0] = Builder.CreateAdd(Ops[0], Ops[1], "vaddhn"); 23526bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover 23536bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16> 23546bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover Constant *ShiftAmt = ConstantInt::get(SrcTy->getElementType(), 23556bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover SrcTy->getScalarSizeInBits() / 2); 23566bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover ShiftAmt = ConstantVector::getSplat(VTy->getNumElements(), ShiftAmt); 23576bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vaddhn"); 23586bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover 23596bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover // %res = trunc <4 x i32> %high to <4 x i16> 23606bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover return Builder.CreateTrunc(Ops[0], VTy, "vaddhn"); 23616bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover } 2362537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcale_v: 23639eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman std::swap(Ops[0], Ops[1]); 2364537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcage_v: { 2365d185035263b98cdde75a869b26b5e5e2e6b13fdfBob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacged); 236630d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcage"); 236730d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 2368537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcaleq_v: 23699eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman std::swap(Ops[0], Ops[1]); 2370537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcageq_v: { 2371d185035263b98cdde75a869b26b5e5e2e6b13fdfBob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgeq); 237230d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcage"); 237330d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 2374537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcalt_v: 23759eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman std::swap(Ops[0], Ops[1]); 2376537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcagt_v: { 2377d185035263b98cdde75a869b26b5e5e2e6b13fdfBob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgtd); 237830d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcagt"); 237930d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 2380537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcaltq_v: 23819eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman std::swap(Ops[0], Ops[1]); 2382537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcagtq_v: { 2383d185035263b98cdde75a869b26b5e5e2e6b13fdfBob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgtq); 238430d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcagt"); 238530d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 2386537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcls_v: 2387537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vclsq_v: { 23888dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcls, Ty); 238930d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcls"); 23909eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 2391537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vclz_v: 2392537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vclzq_v: { 239371bcc68ba44a87a516d84461bc68475e43134338Eric Christopher // Generate target-independent intrinsic; also need to add second argument 239487d747b1fbf89aa0ba08cfc0e26655aa7739c77dJoel Jones // for whether or not clz of zero is undefined; on ARM it isn't. 239587d747b1fbf89aa0ba08cfc0e26655aa7739c77dJoel Jones Function *F = CGM.getIntrinsic(Intrinsic::ctlz, Ty); 239664aa4b3ec7e62288e2e66c1935487ece995ca94bJohn McCall Ops.push_back(Builder.getInt1(getTarget().isCLZForZeroUndef())); 239730d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vclz"); 23989eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 2399537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcnt_v: 2400537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcntq_v: { 24011638f2e8263df93b9fa055a12cc3f0968b9682d8Joel Jones // generate target-independent intrinsic 24021638f2e8263df93b9fa055a12cc3f0968b9682d8Joel Jones Function *F = CGM.getIntrinsic(Intrinsic::ctpop, Ty); 24031638f2e8263df93b9fa055a12cc3f0968b9682d8Joel Jones return EmitNeonCall(F, Ops, "vctpop"); 24049eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 2405537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_f16_v: { 2406da95f73b59f9af964e33725c515139d34c90c863Bob Wilson assert(Type.getEltType() == NeonTypeFlags::Float16 && !quad && 2407da95f73b59f9af964e33725c515139d34c90c863Bob Wilson "unexpected vcvt_f16_v builtin"); 240846e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcvtfp2hf); 240946e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson return EmitNeonCall(F, Ops, "vcvt"); 241046e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson } 2411537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_f32_f16: { 2412da95f73b59f9af964e33725c515139d34c90c863Bob Wilson assert(Type.getEltType() == NeonTypeFlags::Float16 && !quad && 2413da95f73b59f9af964e33725c515139d34c90c863Bob Wilson "unexpected vcvt_f32_f16 builtin"); 241446e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcvthf2fp); 241546e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson return EmitNeonCall(F, Ops, "vcvt"); 241646e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson } 2417537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_f32_v: 2418da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case ARM::BI__builtin_neon_vcvtq_f32_v: 241930d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 24208b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, quad)); 2421258f930227c1a102c9c22eee88df65f748863425Jim Grosbach return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") 24229eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); 2423537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_s32_v: 2424537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_u32_v: 2425537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvtq_s32_v: 2426537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvtq_u32_v: { 2427da95f73b59f9af964e33725c515139d34c90c863Bob Wilson llvm::Type *FloatTy = 24288b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, quad)); 2429da95f73b59f9af964e33725c515139d34c90c863Bob Wilson Ops[0] = Builder.CreateBitCast(Ops[0], FloatTy); 2430258f930227c1a102c9c22eee88df65f748863425Jim Grosbach return usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt") 24319eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman : Builder.CreateFPToSI(Ops[0], Ty, "vcvt"); 24329eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 2433537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_n_f32_v: 2434537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvtq_n_f32_v: { 2435da95f73b59f9af964e33725c515139d34c90c863Bob Wilson llvm::Type *FloatTy = 24368b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, quad)); 2437da95f73b59f9af964e33725c515139d34c90c863Bob Wilson llvm::Type *Tys[2] = { FloatTy, Ty }; 2438da95f73b59f9af964e33725c515139d34c90c863Bob Wilson Int = usgn ? Intrinsic::arm_neon_vcvtfxu2fp 2439da95f73b59f9af964e33725c515139d34c90c863Bob Wilson : Intrinsic::arm_neon_vcvtfxs2fp; 24408dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Int, Tys); 244130d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcvt_n"); 24429eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 2443537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_n_s32_v: 2444537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_n_u32_v: 2445537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvtq_n_s32_v: 2446537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvtq_n_u32_v: { 2447da95f73b59f9af964e33725c515139d34c90c863Bob Wilson llvm::Type *FloatTy = 24488b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, quad)); 2449da95f73b59f9af964e33725c515139d34c90c863Bob Wilson llvm::Type *Tys[2] = { Ty, FloatTy }; 2450da95f73b59f9af964e33725c515139d34c90c863Bob Wilson Int = usgn ? Intrinsic::arm_neon_vcvtfp2fxu 2451da95f73b59f9af964e33725c515139d34c90c863Bob Wilson : Intrinsic::arm_neon_vcvtfp2fxs; 24528dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Int, Tys); 245330d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcvt_n"); 245430d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 2455537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vext_v: 2456537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vextq_v: { 2457fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner int CV = cast<ConstantInt>(Ops[2])->getSExtValue(); 24581c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman SmallVector<Constant*, 16> Indices; 24594be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 246077b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Indices.push_back(ConstantInt::get(Int32Ty, i+CV)); 2461258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 246230d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 246330d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 2464fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner Value *SV = llvm::ConstantVector::get(Indices); 24651c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return Builder.CreateShuffleVector(Ops[0], Ops[1], SV, "vext"); 24661c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 2467537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vhadd_v: 2468537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vhaddq_v: 2469df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vhaddu : Intrinsic::arm_neon_vhadds; 24708dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vhadd"); 2471537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vhsub_v: 2472537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vhsubq_v: 2473df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vhsubu : Intrinsic::arm_neon_vhsubs; 24748dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vhsub"); 2475537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld1_v: 2476537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld1q_v: 2477ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 24788dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Ty), 24794be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops, "vld1"); 2480550a9d823a939366a9f776b58f18883acd905a93Bob Wilson case ARM::BI__builtin_neon_vld1q_lane_v: 2481550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // Handle 64-bit integer elements as a special case. Use shuffles of 2482550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // one-element vectors to avoid poor code for i64 in the backend. 2483550a9d823a939366a9f776b58f18883acd905a93Bob Wilson if (VTy->getElementType()->isIntegerTy(64)) { 2484550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // Extract the other lane. 2485550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 2486550a9d823a939366a9f776b58f18883acd905a93Bob Wilson int Lane = cast<ConstantInt>(Ops[2])->getZExtValue(); 2487550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Value *SV = llvm::ConstantVector::get(ConstantInt::get(Int32Ty, 1-Lane)); 2488550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); 2489550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // Load the value as a one-element vector. 2490550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ty = llvm::VectorType::get(VTy->getElementType(), 1); 2491550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Ty); 2492ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Value *Ld = Builder.CreateCall2(F, Ops[0], Align); 2493550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // Combine them. 2494550a9d823a939366a9f776b58f18883acd905a93Bob Wilson SmallVector<Constant*, 2> Indices; 2495550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Indices.push_back(ConstantInt::get(Int32Ty, 1-Lane)); 2496550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Indices.push_back(ConstantInt::get(Int32Ty, Lane)); 2497550a9d823a939366a9f776b58f18883acd905a93Bob Wilson SV = llvm::ConstantVector::get(Indices); 2498550a9d823a939366a9f776b58f18883acd905a93Bob Wilson return Builder.CreateShuffleVector(Ops[1], Ld, SV, "vld1q_lane"); 2499550a9d823a939366a9f776b58f18883acd905a93Bob Wilson } 2500550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // fall through 2501550a9d823a939366a9f776b58f18883acd905a93Bob Wilson case ARM::BI__builtin_neon_vld1_lane_v: { 25024be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 25034be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 25044be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2505eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson LoadInst *Ld = Builder.CreateLoad(Ops[0]); 2506eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); 2507eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson return Builder.CreateInsertElement(Ops[1], Ld, Ops[2], "vld1_lane"); 2508eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson } 2509537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld1_dup_v: 2510537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld1q_dup_v: { 25114be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *V = UndefValue::get(Ty); 25124be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 25134be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2514eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson LoadInst *Ld = Builder.CreateLoad(Ops[0]); 2515eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); 251677b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 2517eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson Ops[0] = Builder.CreateInsertElement(V, Ld, CI); 25184be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return EmitNeonSplat(Ops[0], CI); 25194be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 2520537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld2_v: 2521537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld2q_v: { 25228dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld2, Ty); 252306b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld2"); 25244be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 25254be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 25264be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 25274be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 2528537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3_v: 2529537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3q_v: { 25308dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld3, Ty); 253106b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld3"); 25324be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 25334be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 25344be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 25354be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 2536537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4_v: 2537537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4q_v: { 25388dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld4, Ty); 253906b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld4"); 25404be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 25414be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 25424be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 25434be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 2544537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld2_lane_v: 2545537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld2q_lane_v: { 25468dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld2lane, Ty); 25474be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 25484be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 2549ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 25501cbac8ac446cf513dbc7486dd50abd55bcfc62c6Frits van Bommel Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld2_lane"); 25514be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 25524be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 25534be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 25544be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 2555537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3_lane_v: 2556537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3q_lane_v: { 25578dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld3lane, Ty); 25584be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 25594be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 25604be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[4] = Builder.CreateBitCast(Ops[4], Ty); 2561ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 25621cbac8ac446cf513dbc7486dd50abd55bcfc62c6Frits van Bommel Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld3_lane"); 25634be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 25644be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 25654be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 25664be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 2567537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4_lane_v: 2568537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4q_lane_v: { 25698dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld4lane, Ty); 25704be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 25714be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 25724be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[4] = Builder.CreateBitCast(Ops[4], Ty); 25734be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[5] = Builder.CreateBitCast(Ops[5], Ty); 2574ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 25751cbac8ac446cf513dbc7486dd50abd55bcfc62c6Frits van Bommel Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld3_lane"); 25764be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 25774be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 25784be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 25794be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 2580537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld2_dup_v: 2581537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3_dup_v: 2582537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4_dup_v: { 2583a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson // Handle 64-bit elements as a special-case. There is no "dup" needed. 2584a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson if (VTy->getElementType()->getPrimitiveSizeInBits() == 64) { 2585a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson switch (BuiltinID) { 2586258f930227c1a102c9c22eee88df65f748863425Jim Grosbach case ARM::BI__builtin_neon_vld2_dup_v: 2587258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Int = Intrinsic::arm_neon_vld2; 2588a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson break; 2589537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3_dup_v: 2590258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Int = Intrinsic::arm_neon_vld3; 2591a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson break; 2592537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4_dup_v: 2593258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Int = Intrinsic::arm_neon_vld4; 2594a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson break; 2595b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("unknown vld_dup intrinsic?"); 2596a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson } 25978dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Int, Ty); 2598a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld_dup"); 2599a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 2600a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2601a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson return Builder.CreateStore(Ops[1], Ops[0]); 2602a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson } 26034be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman switch (BuiltinID) { 2604258f930227c1a102c9c22eee88df65f748863425Jim Grosbach case ARM::BI__builtin_neon_vld2_dup_v: 2605258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Int = Intrinsic::arm_neon_vld2lane; 26064be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman break; 2607537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3_dup_v: 2608258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Int = Intrinsic::arm_neon_vld3lane; 26094be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman break; 2610537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4_dup_v: 2611258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Int = Intrinsic::arm_neon_vld4lane; 26124be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman break; 2613b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("unknown vld_dup intrinsic?"); 26144be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 26158dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Int, Ty); 26162acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::StructType *STy = cast<llvm::StructType>(F->getReturnType()); 2617258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 26184be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SmallVector<Value*, 6> Args; 26194be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Args.push_back(Ops[1]); 26204be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Args.append(STy->getNumElements(), UndefValue::get(Ty)); 26214be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 262277b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 26234be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Args.push_back(CI); 2624ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Args.push_back(Align); 2625258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 26264c7d9f1507d0f102bd4133bba63348636facd469Jay Foad Ops[1] = Builder.CreateCall(F, Args, "vld_dup"); 26274be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman // splat lane 0 to all elts in each vector of the result. 26284be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { 26294be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Val = Builder.CreateExtractValue(Ops[1], i); 26304be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Elt = Builder.CreateBitCast(Val, Ty); 26314be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Elt = EmitNeonSplat(Elt, CI); 26324be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Elt = Builder.CreateBitCast(Elt, Val->getType()); 26334be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[1] = Builder.CreateInsertValue(Ops[1], Elt, i); 26344be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 26354be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 26364be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 26374be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 26384be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 2639537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmax_v: 2640537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmaxq_v: 2641df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vmaxu : Intrinsic::arm_neon_vmaxs; 26428dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmax"); 2643537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmin_v: 2644537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vminq_v: 2645df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vminu : Intrinsic::arm_neon_vmins; 26468dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmin"); 2647537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmovl_v: { 26482acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *DTy =llvm::VectorType::getTruncatedElementVectorType(VTy); 26492235941293353325835d182da4470f61828fe789Bob Wilson Ops[0] = Builder.CreateBitCast(Ops[0], DTy); 26507cea322bf019b0d38867a27e20e3771d84dbb1afBob Wilson if (usgn) 26517cea322bf019b0d38867a27e20e3771d84dbb1afBob Wilson return Builder.CreateZExt(Ops[0], Ty, "vmovl"); 26527cea322bf019b0d38867a27e20e3771d84dbb1afBob Wilson return Builder.CreateSExt(Ops[0], Ty, "vmovl"); 26532235941293353325835d182da4470f61828fe789Bob Wilson } 2654537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmovn_v: { 26552acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *QTy = llvm::VectorType::getExtendedElementVectorType(VTy); 26562235941293353325835d182da4470f61828fe789Bob Wilson Ops[0] = Builder.CreateBitCast(Ops[0], QTy); 26573b6081bf49b7506cb96131247f209d1e03610df8Bob Wilson return Builder.CreateTrunc(Ops[0], Ty, "vmovn"); 26582235941293353325835d182da4470f61828fe789Bob Wilson } 2659537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmul_v: 2660537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmulq_v: 2661da95f73b59f9af964e33725c515139d34c90c863Bob Wilson assert(Type.isPoly() && "vmul builtin only supported for polynomial types"); 26628dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vmulp, Ty), 2663953d513c7ee79b3d9e37597e64317e75c0fbf7f6Bob Wilson Ops, "vmul"); 2664537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmull_v: 26653b6b5dad09d314cb8055ed7500a03c3cf3daad0fTim Northover // FIXME: the integer vmull operations could be emitted in terms of pure 26663b6b5dad09d314cb8055ed7500a03c3cf3daad0fTim Northover // LLVM IR (2 exts followed by a mul). Unfortunately LLVM has a habit of 26673b6b5dad09d314cb8055ed7500a03c3cf3daad0fTim Northover // hoisting the exts outside loops. Until global ISel comes along that can 26683b6b5dad09d314cb8055ed7500a03c3cf3daad0fTim Northover // see through such movement this leads to bad CodeGen. So we need an 26693b6b5dad09d314cb8055ed7500a03c3cf3daad0fTim Northover // intrinsic for now. 26702d33e423d5091b7d2cb8618952752abd55bba965Bob Wilson Int = usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls; 2671da95f73b59f9af964e33725c515139d34c90c863Bob Wilson Int = Type.isPoly() ? (unsigned)Intrinsic::arm_neon_vmullp : Int; 26728dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull"); 267302262662b4550d0227038470f2d7b3db7ada2b87Bob Wilson case ARM::BI__builtin_neon_vfma_v: 267402262662b4550d0227038470f2d7b3db7ada2b87Bob Wilson case ARM::BI__builtin_neon_vfmaq_v: { 267502262662b4550d0227038470f2d7b3db7ada2b87Bob Wilson Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 267602262662b4550d0227038470f2d7b3db7ada2b87Bob Wilson Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 267702262662b4550d0227038470f2d7b3db7ada2b87Bob Wilson Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 267802262662b4550d0227038470f2d7b3db7ada2b87Bob Wilson Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 2679c4a04010f676ce9ff0049b0fc5d1f96a2dbe81beTim Northover 2680c4a04010f676ce9ff0049b0fc5d1f96a2dbe81beTim Northover // NEON intrinsic puts accumulator first, unlike the LLVM fma. 2681c4a04010f676ce9ff0049b0fc5d1f96a2dbe81beTim Northover return Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]); 268202262662b4550d0227038470f2d7b3db7ada2b87Bob Wilson } 2683537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpadal_v: 2684537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpadalq_v: { 2685df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vpadalu : Intrinsic::arm_neon_vpadals; 2686c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson // The source operand type has twice as many elements of half the size. 2687c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 26882acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *EltTy = 2689d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::IntegerType::get(getLLVMContext(), EltBits / 2); 26909cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *NarrowTy = 2691c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); 26929cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *Tys[2] = { Ty, NarrowTy }; 26938dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vpadal"); 2694c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson } 2695537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpadd_v: 26968dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vpadd, Ty), 2697548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vpadd"); 2698537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpaddl_v: 2699537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpaddlq_v: { 2700548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vpaddlu : Intrinsic::arm_neon_vpaddls; 2701c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson // The source operand type has twice as many elements of half the size. 2702c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 27032acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *EltTy = llvm::IntegerType::get(getLLVMContext(), EltBits / 2); 27049cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *NarrowTy = 2705c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); 27069cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *Tys[2] = { Ty, NarrowTy }; 27078dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vpaddl"); 2708c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson } 2709537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpmax_v: 2710548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vpmaxu : Intrinsic::arm_neon_vpmaxs; 27118dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmax"); 2712537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpmin_v: 2713548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vpminu : Intrinsic::arm_neon_vpmins; 27148dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmin"); 2715537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqabs_v: 2716537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqabsq_v: 27178dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqabs, Ty), 2718548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vqabs"); 2719537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqadd_v: 2720537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqaddq_v: 2721548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vqaddu : Intrinsic::arm_neon_vqadds; 27228dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqadd"); 2723b1c09b913e331824da29f8017452b6171f7eccbcTim Northover case ARM::BI__builtin_neon_vqdmlal_v: { 2724b1c09b913e331824da29f8017452b6171f7eccbcTim Northover SmallVector<Value *, 2> MulOps(Ops.begin() + 1, Ops.end()); 2725b1c09b913e331824da29f8017452b6171f7eccbcTim Northover Value *Mul = EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmull, Ty), 2726b1c09b913e331824da29f8017452b6171f7eccbcTim Northover MulOps, "vqdmlal"); 2727b1c09b913e331824da29f8017452b6171f7eccbcTim Northover 2728b1c09b913e331824da29f8017452b6171f7eccbcTim Northover SmallVector<Value *, 2> AddOps; 2729b1c09b913e331824da29f8017452b6171f7eccbcTim Northover AddOps.push_back(Ops[0]); 2730b1c09b913e331824da29f8017452b6171f7eccbcTim Northover AddOps.push_back(Mul); 2731b1c09b913e331824da29f8017452b6171f7eccbcTim Northover return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqadds, Ty), 2732b1c09b913e331824da29f8017452b6171f7eccbcTim Northover AddOps, "vqdmlal"); 2733b1c09b913e331824da29f8017452b6171f7eccbcTim Northover } 2734b1c09b913e331824da29f8017452b6171f7eccbcTim Northover case ARM::BI__builtin_neon_vqdmlsl_v: { 2735b1c09b913e331824da29f8017452b6171f7eccbcTim Northover SmallVector<Value *, 2> MulOps(Ops.begin() + 1, Ops.end()); 2736b1c09b913e331824da29f8017452b6171f7eccbcTim Northover Value *Mul = EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmull, Ty), 2737b1c09b913e331824da29f8017452b6171f7eccbcTim Northover MulOps, "vqdmlsl"); 2738b1c09b913e331824da29f8017452b6171f7eccbcTim Northover 2739b1c09b913e331824da29f8017452b6171f7eccbcTim Northover SmallVector<Value *, 2> SubOps; 2740b1c09b913e331824da29f8017452b6171f7eccbcTim Northover SubOps.push_back(Ops[0]); 2741b1c09b913e331824da29f8017452b6171f7eccbcTim Northover SubOps.push_back(Mul); 2742b1c09b913e331824da29f8017452b6171f7eccbcTim Northover return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqsubs, Ty), 2743b1c09b913e331824da29f8017452b6171f7eccbcTim Northover SubOps, "vqdmlsl"); 2744b1c09b913e331824da29f8017452b6171f7eccbcTim Northover } 2745537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqdmulh_v: 2746537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqdmulhq_v: 27478dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmulh, Ty), 2748db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqdmulh"); 2749537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqdmull_v: 27508dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmull, Ty), 2751db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqdmull"); 2752537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqmovn_v: 2753548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vqmovnu : Intrinsic::arm_neon_vqmovns; 27548dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqmovn"); 2755537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqmovun_v: 27568dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqmovnsu, Ty), 2757548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vqdmull"); 2758537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqneg_v: 2759537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqnegq_v: 27608dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqneg, Ty), 276161eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops, "vqneg"); 2762537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrdmulh_v: 2763537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrdmulhq_v: 27648dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrdmulh, Ty), 2765db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqrdmulh"); 2766537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrshl_v: 2767537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrshlq_v: 2768548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vqrshiftu : Intrinsic::arm_neon_vqrshifts; 27698dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshl"); 2770537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrshrn_n_v: 2771258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Int = 2772258f930227c1a102c9c22eee88df65f748863425Jim Grosbach usgn ? Intrinsic::arm_neon_vqrshiftnu : Intrinsic::arm_neon_vqrshiftns; 27738dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n", 277461eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman 1, true); 2775537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrshrun_n_v: 27768dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrshiftnsu, Ty), 2777db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqrshrun_n", 1, true); 2778537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshl_v: 2779537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshlq_v: 278061eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Int = usgn ? Intrinsic::arm_neon_vqshiftu : Intrinsic::arm_neon_vqshifts; 27818dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshl"); 2782537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshl_n_v: 2783537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshlq_n_v: 278461eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Int = usgn ? Intrinsic::arm_neon_vqshiftu : Intrinsic::arm_neon_vqshifts; 27858dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshl_n", 278661eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman 1, false); 2787537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshlu_n_v: 2788537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshluq_n_v: 27898dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftsu, Ty), 2790db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqshlu", 1, false); 2791537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshrn_n_v: 279261eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Int = usgn ? Intrinsic::arm_neon_vqshiftnu : Intrinsic::arm_neon_vqshiftns; 27938dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n", 279461eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman 1, true); 2795537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshrun_n_v: 27968dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftnsu, Ty), 2797db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqshrun_n", 1, true); 2798537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqsub_v: 2799537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqsubq_v: 2800464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Int = usgn ? Intrinsic::arm_neon_vqsubu : Intrinsic::arm_neon_vqsubs; 28018dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqsub"); 2802537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vraddhn_v: 28038dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vraddhn, Ty), 2804464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vraddhn"); 2805537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrecpe_v: 2806537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrecpeq_v: 28078dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecpe, Ty), 2808464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vrecpe"); 2809537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrecps_v: 2810537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrecpsq_v: 28118dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecps, Ty), 2812464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vrecps"); 2813537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrhadd_v: 2814537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrhaddq_v: 2815464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Int = usgn ? Intrinsic::arm_neon_vrhaddu : Intrinsic::arm_neon_vrhadds; 28168dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrhadd"); 2817537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrshl_v: 2818537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrshlq_v: 28195af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 28208dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshl"); 2821537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrshrn_n_v: 28228dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrshiftn, Ty), 2823db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vrshrn_n", 1, true); 2824537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrshr_n_v: 2825537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrshrq_n_v: 28265af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 28278dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshr_n", 1, true); 2828537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsqrte_v: 2829537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsqrteq_v: 28308dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsqrte, Ty), 28315af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops, "vrsqrte"); 2832537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsqrts_v: 2833537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsqrtsq_v: 28348dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsqrts, Ty), 28355af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops, "vrsqrts"); 2836537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsra_n_v: 2837537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsraq_n_v: 28385af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 28395af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 28405af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops[2] = EmitNeonShiftVector(Ops[2], Ty, true); 28415af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 2842258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Ops[1] = Builder.CreateCall2(CGM.getIntrinsic(Int, Ty), Ops[1], Ops[2]); 28435af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n"); 2844537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsubhn_v: 28458dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsubhn, Ty), 2846464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vrsubhn"); 2847537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshl_v: 2848537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshlq_v: 2849464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Int = usgn ? Intrinsic::arm_neon_vshiftu : Intrinsic::arm_neon_vshifts; 28508dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vshl"); 2851537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshll_n_v: 2852464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Int = usgn ? Intrinsic::arm_neon_vshiftlu : Intrinsic::arm_neon_vshiftls; 28538dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vshll", 1); 2854537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshl_n_v: 2855537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshlq_n_v: 285661eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false); 2857258f930227c1a102c9c22eee88df65f748863425Jim Grosbach return Builder.CreateShl(Builder.CreateBitCast(Ops[0],Ty), Ops[1], 2858258f930227c1a102c9c22eee88df65f748863425Jim Grosbach "vshl_n"); 2859537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshrn_n_v: 28608dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftn, Ty), 2861db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vshrn_n", 1, true); 2862537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshr_n_v: 2863537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshrq_n_v: 2864464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 286561eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false); 2866464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman if (usgn) 2867464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return Builder.CreateLShr(Ops[0], Ops[1], "vshr_n"); 2868464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman else 2869464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return Builder.CreateAShr(Ops[0], Ops[1], "vshr_n"); 2870537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsri_n_v: 2871537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsriq_n_v: 28727965396d8d6ac23ec4c4f9d01d216f2e73d7fc72Bob Wilson rightShift = true; 2873537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsli_n_v: 2874537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsliq_n_v: 28757965396d8d6ac23ec4c4f9d01d216f2e73d7fc72Bob Wilson Ops[2] = EmitNeonShiftVector(Ops[2], Ty, rightShift); 28768dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftins, Ty), 2877464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vsli_n"); 2878537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsra_n_v: 2879537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsraq_n_v: 2880464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2881464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 288261eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[2] = EmitNeonShiftVector(Ops[2], Ty, false); 2883464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman if (usgn) 2884464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateLShr(Ops[1], Ops[2], "vsra_n"); 2885464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman else 2886464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateAShr(Ops[1], Ops[2], "vsra_n"); 2887464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return Builder.CreateAdd(Ops[0], Ops[1]); 2888537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst1_v: 2889537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst1q_v: 2890ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 28918dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, Ty), 2892464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2893550a9d823a939366a9f776b58f18883acd905a93Bob Wilson case ARM::BI__builtin_neon_vst1q_lane_v: 2894550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // Handle 64-bit integer elements as a special case. Use a shuffle to get 2895550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // a one-element vector and avoid poor code for i64 in the backend. 2896550a9d823a939366a9f776b58f18883acd905a93Bob Wilson if (VTy->getElementType()->isIntegerTy(64)) { 2897550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 2898550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Value *SV = llvm::ConstantVector::get(cast<llvm::Constant>(Ops[2])); 2899550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); 2900ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops[2] = Align; 2901550a9d823a939366a9f776b58f18883acd905a93Bob Wilson return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, 2902550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ops[1]->getType()), Ops); 2903550a9d823a939366a9f776b58f18883acd905a93Bob Wilson } 2904550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // fall through 2905550a9d823a939366a9f776b58f18883acd905a93Bob Wilson case ARM::BI__builtin_neon_vst1_lane_v: { 2906464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 2907464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); 2908464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 2909eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson StoreInst *St = Builder.CreateStore(Ops[1], 2910eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson Builder.CreateBitCast(Ops[0], Ty)); 2911eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson St->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); 2912eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson return St; 2913eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson } 2914537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst2_v: 2915537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst2q_v: 2916ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 29178dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst2, Ty), 2918464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2919537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst2_lane_v: 2920537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst2q_lane_v: 2921ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 29228dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst2lane, Ty), 2923464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2924537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst3_v: 2925537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst3q_v: 2926ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 29278dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst3, Ty), 2928464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2929537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst3_lane_v: 2930537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst3q_lane_v: 2931ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 29328dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst3lane, Ty), 2933464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2934537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst4_v: 2935537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst4q_v: 2936ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 29378dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst4, Ty), 2938464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2939537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst4_lane_v: 2940537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst4q_lane_v: 2941ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 29428dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst4lane, Ty), 2943464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 29446bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover case ARM::BI__builtin_neon_vsubhn_v: { 29456bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover llvm::VectorType *SrcTy = 29466bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover llvm::VectorType::getExtendedElementVectorType(VTy); 29476bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover 29486bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover // %sum = add <4 x i32> %lhs, %rhs 29496bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 29506bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy); 29516bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover Ops[0] = Builder.CreateSub(Ops[0], Ops[1], "vsubhn"); 29526bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover 29536bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16> 29546bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover Constant *ShiftAmt = ConstantInt::get(SrcTy->getElementType(), 29556bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover SrcTy->getScalarSizeInBits() / 2); 29566bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover ShiftAmt = ConstantVector::getSplat(VTy->getNumElements(), ShiftAmt); 29576bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vsubhn"); 29586bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover 29596bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover // %res = trunc <4 x i32> %high to <4 x i16> 29606bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover return Builder.CreateTrunc(Ops[0], VTy, "vsubhn"); 29616bf1e8eadd36f077cf5403d23c664129d98eaf79Tim Northover } 2962537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbl1_v: 29631c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl1), 29641c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbl1"); 2965537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbl2_v: 29661c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl2), 29671c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbl2"); 2968537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbl3_v: 29691c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl3), 29701c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbl3"); 2971537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbl4_v: 29721c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl4), 29731c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbl4"); 2974537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbx1_v: 29751c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx1), 29761c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbx1"); 2977537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbx2_v: 29781c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx2), 29791c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbx2"); 2980537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbx3_v: 29811c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx3), 29821c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbx3"); 2983537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbx4_v: 29841c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx4), 29851c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbx4"); 2986537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtst_v: 2987537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtstq_v: { 29881c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 29891c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 29901c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]); 2991258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0], 29921c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman ConstantAggregateZero::get(Ty)); 29931c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return Builder.CreateSExt(Ops[0], Ty, "vtst"); 29941c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 2995537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtrn_v: 2996537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtrnq_v: { 29974be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 29984be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 29994be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 30009577abc63f2c7afe5adf6e4e101ae91d29c3b8a6Ted Kremenek Value *SV = 0; 30014be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 30021c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman for (unsigned vi = 0; vi != 2; ++vi) { 30034be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SmallVector<Constant*, 16> Indices; 30044be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 30052ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner Indices.push_back(Builder.getInt32(i+vi)); 30062ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner Indices.push_back(Builder.getInt32(i+e+vi)); 30071c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 30084be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi); 3009fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner SV = llvm::ConstantVector::get(Indices); 30104be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vtrn"); 30114be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateStore(SV, Addr); 30121c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 30134be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return SV; 30141c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 3015537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vuzp_v: 3016537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vuzpq_v: { 30174be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 30181c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 30194be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 30209577abc63f2c7afe5adf6e4e101ae91d29c3b8a6Ted Kremenek Value *SV = 0; 3021258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 30224be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned vi = 0; vi != 2; ++vi) { 30234be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SmallVector<Constant*, 16> Indices; 30244be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 302577b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Indices.push_back(ConstantInt::get(Int32Ty, 2*i+vi)); 30264be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 30274be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi); 3028fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner SV = llvm::ConstantVector::get(Indices); 30294be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vuzp"); 30304be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateStore(SV, Addr); 30314be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 30324be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return SV; 30331c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 3034258f930227c1a102c9c22eee88df65f748863425Jim Grosbach case ARM::BI__builtin_neon_vzip_v: 3035537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vzipq_v: { 30364be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 30371c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 30384be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 30399577abc63f2c7afe5adf6e4e101ae91d29c3b8a6Ted Kremenek Value *SV = 0; 3040258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 30414be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned vi = 0; vi != 2; ++vi) { 30424be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SmallVector<Constant*, 16> Indices; 30434be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 3044e361cc3daa6c22e4413d48bd8b8934ea9fd5a55fDaniel Dunbar Indices.push_back(ConstantInt::get(Int32Ty, (i + vi*e) >> 1)); 3045e361cc3daa6c22e4413d48bd8b8934ea9fd5a55fDaniel Dunbar Indices.push_back(ConstantInt::get(Int32Ty, ((i + vi*e) >> 1)+e)); 30464be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 30474be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi); 3048fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner SV = llvm::ConstantVector::get(Indices); 30494be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vzip"); 30504be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateStore(SV, Addr); 30514be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 30524be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return SV; 30539eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 30542752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner } 30552752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner} 30562752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner 3057aa51e513850688b7963efc62abf1eface7037602Bill Wendlingllvm::Value *CodeGenFunction:: 3058795b10062c2eaffae9e04241fb1a73cdbcb24a37Bill WendlingBuildVector(ArrayRef<llvm::Value*> Ops) { 3059aa51e513850688b7963efc62abf1eface7037602Bill Wendling assert((Ops.size() & (Ops.size() - 1)) == 0 && 3060aa51e513850688b7963efc62abf1eface7037602Bill Wendling "Not a power-of-two sized vector!"); 3061aa51e513850688b7963efc62abf1eface7037602Bill Wendling bool AllConstants = true; 3062aa51e513850688b7963efc62abf1eface7037602Bill Wendling for (unsigned i = 0, e = Ops.size(); i != e && AllConstants; ++i) 3063aa51e513850688b7963efc62abf1eface7037602Bill Wendling AllConstants &= isa<Constant>(Ops[i]); 3064aa51e513850688b7963efc62abf1eface7037602Bill Wendling 3065aa51e513850688b7963efc62abf1eface7037602Bill Wendling // If this is a constant vector, create a ConstantVector. 3066aa51e513850688b7963efc62abf1eface7037602Bill Wendling if (AllConstants) { 30672ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner SmallVector<llvm::Constant*, 16> CstOps; 3068aa51e513850688b7963efc62abf1eface7037602Bill Wendling for (unsigned i = 0, e = Ops.size(); i != e; ++i) 3069aa51e513850688b7963efc62abf1eface7037602Bill Wendling CstOps.push_back(cast<Constant>(Ops[i])); 3070aa51e513850688b7963efc62abf1eface7037602Bill Wendling return llvm::ConstantVector::get(CstOps); 3071aa51e513850688b7963efc62abf1eface7037602Bill Wendling } 3072aa51e513850688b7963efc62abf1eface7037602Bill Wendling 3073aa51e513850688b7963efc62abf1eface7037602Bill Wendling // Otherwise, insertelement the values to build the vector. 3074aa51e513850688b7963efc62abf1eface7037602Bill Wendling Value *Result = 3075aa51e513850688b7963efc62abf1eface7037602Bill Wendling llvm::UndefValue::get(llvm::VectorType::get(Ops[0]->getType(), Ops.size())); 3076aa51e513850688b7963efc62abf1eface7037602Bill Wendling 3077aa51e513850688b7963efc62abf1eface7037602Bill Wendling for (unsigned i = 0, e = Ops.size(); i != e; ++i) 30782ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner Result = Builder.CreateInsertElement(Result, Ops[i], Builder.getInt32(i)); 3079aa51e513850688b7963efc62abf1eface7037602Bill Wendling 3080aa51e513850688b7963efc62abf1eface7037602Bill Wendling return Result; 3081aa51e513850688b7963efc62abf1eface7037602Bill Wendling} 3082aa51e513850688b7963efc62abf1eface7037602Bill Wendling 30831eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpValue *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, 30841feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner const CallExpr *E) { 30855f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Value*, 4> Ops; 30862929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson 308746c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // Find out if any arguments are required to be integer constant expressions. 308846c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner unsigned ICEArguments = 0; 308946c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner ASTContext::GetBuiltinTypeError Error; 309046c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 309146c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner assert(Error == ASTContext::GE_None && "Should not codegen an error"); 309246c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner 309346c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) { 309446c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // If this is a normal argument, just emit it as a scalar. 309546c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner if ((ICEArguments & (1 << i)) == 0) { 309646c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner Ops.push_back(EmitScalarExpr(E->getArg(i))); 309746c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner continue; 309846c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner } 309946c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner 310046c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // If this is required to be a constant, constant fold it so that we know 310146c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // that the generated intrinsic gets a ConstantInt. 310246c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner llvm::APSInt Result; 310346c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext()); 310446c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst; 3105d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result)); 310646c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner } 31072929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson 3108564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson switch (BuiltinID) { 310946a26b0b0e2ec1557bad9b70e8e20836524ebdfcAnders Carlsson default: return 0; 3110aa51e513850688b7963efc62abf1eface7037602Bill Wendling case X86::BI__builtin_ia32_vec_init_v8qi: 3111aa51e513850688b7963efc62abf1eface7037602Bill Wendling case X86::BI__builtin_ia32_vec_init_v4hi: 3112aa51e513850688b7963efc62abf1eface7037602Bill Wendling case X86::BI__builtin_ia32_vec_init_v2si: 3113aa51e513850688b7963efc62abf1eface7037602Bill Wendling return Builder.CreateBitCast(BuildVector(Ops), 3114d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::Type::getX86_MMXTy(getLLVMContext())); 31151944ec188408aff1931c62c79a069e30f2549ec2Argyrios Kyrtzidis case X86::BI__builtin_ia32_vec_ext_v2si: 31161944ec188408aff1931c62c79a069e30f2549ec2Argyrios Kyrtzidis return Builder.CreateExtractElement(Ops[0], 31171944ec188408aff1931c62c79a069e30f2549ec2Argyrios Kyrtzidis llvm::ConstantInt::get(Ops[1]->getType(), 0)); 3118e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_ldmxcsr: { 31193fc779191ce87cddf603e0c5bdbd225611201ff4Juergen Ributzka Value *Tmp = CreateMemTemp(E->getArg(0)->getType()); 3120e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Builder.CreateStore(Ops[0], Tmp); 3121e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr), 31223fc779191ce87cddf603e0c5bdbd225611201ff4Juergen Ributzka Builder.CreateBitCast(Tmp, Int8PtrTy)); 3123e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 3124e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_stmxcsr: { 3125fe0af454943374758309a1066e3304b3a56af04eJuergen Ributzka Value *Tmp = CreateMemTemp(E->getType()); 3126012614ecf78442368ec82ee30efb3bc047b413e6Ted Kremenek Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr), 31273fc779191ce87cddf603e0c5bdbd225611201ff4Juergen Ributzka Builder.CreateBitCast(Tmp, Int8PtrTy)); 3128e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman return Builder.CreateLoad(Tmp, "stmxcsr"); 3129e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 3130e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_storehps: 3131e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_storelps: { 313277b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Type *PtrTy = llvm::PointerType::getUnqual(Int64Ty); 313377b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2); 31341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3135e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman // cast val v2i64 3136e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast"); 31371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3138e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman // extract (0, 1) 3139e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1; 314077b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Value *Idx = llvm::ConstantInt::get(Int32Ty, Index); 3141e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract"); 3142e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman 3143e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman // cast pointer to i64 & store 3144e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy); 3145e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 3146e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 314728cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling case X86::BI__builtin_ia32_palignr: { 314828cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 3149258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 315028cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // If palignr is shifting the pair of input vectors less than 9 bytes, 315128cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // emit a shuffle instruction. 315228cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling if (shiftVal <= 8) { 31535f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Constant*, 8> Indices; 315428cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling for (unsigned i = 0; i != 8; ++i) 315528cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling Indices.push_back(llvm::ConstantInt::get(Int32Ty, shiftVal + i)); 3156258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 3157fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner Value* SV = llvm::ConstantVector::get(Indices); 315828cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 315928cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling } 3160258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 316128cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // If palignr is shifting the pair of input vectors more than 8 but less 316228cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // than 16 bytes, emit a logical right shift of the destination. 316328cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling if (shiftVal < 16) { 316428cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // MMX has these as 1 x i64 vectors for some odd optimization reasons. 31652acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 1); 3166258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 316728cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 316828cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling Ops[1] = llvm::ConstantInt::get(VecTy, (shiftVal-8) * 8); 3169258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 317028cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // create i32 constant 317128cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_mmx_psrl_q); 3172e9c0265d6e6b5bf865f4a0c2c00d00ac251e6437Frits van Bommel return Builder.CreateCall(F, makeArrayRef(&Ops[0], 2), "palignr"); 317328cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling } 3174258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 31755c22ad2ef6bf39da22d5190025e0ddfd4b568b2aEli Friedman // If palignr is shifting the pair of vectors more than 16 bytes, emit zero. 317628cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling return llvm::Constant::getNullValue(ConvertType(E->getType())); 317728cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling } 3178c3420ffb282c6ffc0192013bf8045b6c21eddeceNate Begeman case X86::BI__builtin_ia32_palignr128: { 3179ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 3180258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 3181ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // If palignr is shifting the pair of input vectors less than 17 bytes, 3182ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // emit a shuffle instruction. 3183ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman if (shiftVal <= 16) { 31845f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Constant*, 16> Indices; 3185ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman for (unsigned i = 0; i != 16; ++i) 318677b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Indices.push_back(llvm::ConstantInt::get(Int32Ty, shiftVal + i)); 3187258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 3188fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner Value* SV = llvm::ConstantVector::get(Indices); 3189ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 3190ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman } 3191258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 3192ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // If palignr is shifting the pair of input vectors more than 16 but less 3193ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // than 32 bytes, emit a logical right shift of the destination. 3194ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman if (shiftVal < 32) { 31952acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2); 3196258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 3197ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 319877b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Ops[1] = llvm::ConstantInt::get(Int32Ty, (shiftVal-16) * 8); 3199258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 3200ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // create i32 constant 3201ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_psrl_dq); 3202e9c0265d6e6b5bf865f4a0c2c00d00ac251e6437Frits van Bommel return Builder.CreateCall(F, makeArrayRef(&Ops[0], 2), "palignr"); 3203ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman } 3204258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 3205ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 3206ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman return llvm::Constant::getNullValue(ConvertType(E->getType())); 320791b59274439f776cdd545bd7bf5849fdb1842160Eric Christopher } 32089c2ffd803af03f1728423d0d73ff87d988642633Craig Topper case X86::BI__builtin_ia32_palignr256: { 32099c2ffd803af03f1728423d0d73ff87d988642633Craig Topper unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 32109c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 32119c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // If palignr is shifting the pair of input vectors less than 17 bytes, 32129c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // emit a shuffle instruction. 32139c2ffd803af03f1728423d0d73ff87d988642633Craig Topper if (shiftVal <= 16) { 32149c2ffd803af03f1728423d0d73ff87d988642633Craig Topper SmallVector<llvm::Constant*, 32> Indices; 32159c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // 256-bit palignr operates on 128-bit lanes so we need to handle that 32169c2ffd803af03f1728423d0d73ff87d988642633Craig Topper for (unsigned l = 0; l != 2; ++l) { 32179c2ffd803af03f1728423d0d73ff87d988642633Craig Topper unsigned LaneStart = l * 16; 32189c2ffd803af03f1728423d0d73ff87d988642633Craig Topper unsigned LaneEnd = (l+1) * 16; 32199c2ffd803af03f1728423d0d73ff87d988642633Craig Topper for (unsigned i = 0; i != 16; ++i) { 32209c2ffd803af03f1728423d0d73ff87d988642633Craig Topper unsigned Idx = shiftVal + i + LaneStart; 32219c2ffd803af03f1728423d0d73ff87d988642633Craig Topper if (Idx >= LaneEnd) Idx += 16; // end of lane, switch operand 32229c2ffd803af03f1728423d0d73ff87d988642633Craig Topper Indices.push_back(llvm::ConstantInt::get(Int32Ty, Idx)); 32239c2ffd803af03f1728423d0d73ff87d988642633Craig Topper } 32249c2ffd803af03f1728423d0d73ff87d988642633Craig Topper } 32259c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 32269c2ffd803af03f1728423d0d73ff87d988642633Craig Topper Value* SV = llvm::ConstantVector::get(Indices); 32279c2ffd803af03f1728423d0d73ff87d988642633Craig Topper return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 32289c2ffd803af03f1728423d0d73ff87d988642633Craig Topper } 32299c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 32309c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // If palignr is shifting the pair of input vectors more than 16 but less 32319c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // than 32 bytes, emit a logical right shift of the destination. 32329c2ffd803af03f1728423d0d73ff87d988642633Craig Topper if (shiftVal < 32) { 32339c2ffd803af03f1728423d0d73ff87d988642633Craig Topper llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 4); 32349c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 32359c2ffd803af03f1728423d0d73ff87d988642633Craig Topper Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 32369c2ffd803af03f1728423d0d73ff87d988642633Craig Topper Ops[1] = llvm::ConstantInt::get(Int32Ty, (shiftVal-16) * 8); 32379c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 32389c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // create i32 constant 32399c2ffd803af03f1728423d0d73ff87d988642633Craig Topper llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_avx2_psrl_dq); 32409c2ffd803af03f1728423d0d73ff87d988642633Craig Topper return Builder.CreateCall(F, makeArrayRef(&Ops[0], 2), "palignr"); 32419c2ffd803af03f1728423d0d73ff87d988642633Craig Topper } 32429c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 32439c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 32449c2ffd803af03f1728423d0d73ff87d988642633Craig Topper return llvm::Constant::getNullValue(ConvertType(E->getType())); 32459c2ffd803af03f1728423d0d73ff87d988642633Craig Topper } 3246b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling case X86::BI__builtin_ia32_movntps: 32474a7376d00df98cbfcad29ee709637707a2f3d46cCraig Topper case X86::BI__builtin_ia32_movntps256: 3248b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling case X86::BI__builtin_ia32_movntpd: 32494a7376d00df98cbfcad29ee709637707a2f3d46cCraig Topper case X86::BI__builtin_ia32_movntpd256: 3250b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling case X86::BI__builtin_ia32_movntdq: 32514a7376d00df98cbfcad29ee709637707a2f3d46cCraig Topper case X86::BI__builtin_ia32_movntdq256: 3252440a5f49133307745de7cc92a44d53088cf47c26Eli Friedman case X86::BI__builtin_ia32_movnti: 3253440a5f49133307745de7cc92a44d53088cf47c26Eli Friedman case X86::BI__builtin_ia32_movnti64: { 3254b107dd02f5e365f60b036b8a27c784f2d0d0a855Bill Wendling llvm::MDNode *Node = llvm::MDNode::get(getLLVMContext(), 3255b107dd02f5e365f60b036b8a27c784f2d0d0a855Bill Wendling Builder.getInt32(1)); 3256b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling 3257b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling // Convert the type of the pointer to a pointer to the stored type. 3258b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling Value *BC = Builder.CreateBitCast(Ops[0], 3259b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling llvm::PointerType::getUnqual(Ops[1]->getType()), 3260b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling "cast"); 3261b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling StoreInst *SI = Builder.CreateStore(Ops[1], BC); 3262b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling SI->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); 3263440a5f49133307745de7cc92a44d53088cf47c26Eli Friedman 3264440a5f49133307745de7cc92a44d53088cf47c26Eli Friedman // If the operand is an integer, we can't assume alignment. Otherwise, 3265440a5f49133307745de7cc92a44d53088cf47c26Eli Friedman // assume natural alignment. 3266440a5f49133307745de7cc92a44d53088cf47c26Eli Friedman QualType ArgTy = E->getArg(1)->getType(); 3267440a5f49133307745de7cc92a44d53088cf47c26Eli Friedman unsigned Align; 3268440a5f49133307745de7cc92a44d53088cf47c26Eli Friedman if (ArgTy->isIntegerType()) 3269440a5f49133307745de7cc92a44d53088cf47c26Eli Friedman Align = 1; 3270440a5f49133307745de7cc92a44d53088cf47c26Eli Friedman else 3271440a5f49133307745de7cc92a44d53088cf47c26Eli Friedman Align = getContext().getTypeSizeInChars(ArgTy).getQuantity(); 3272440a5f49133307745de7cc92a44d53088cf47c26Eli Friedman SI->setAlignment(Align); 3273b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling return SI; 3274b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling } 32758b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer // 3DNow! 32768b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer case X86::BI__builtin_ia32_pswapdsf: 32778b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer case X86::BI__builtin_ia32_pswapdsi: { 32788b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer const char *name = 0; 32798b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer Intrinsic::ID ID = Intrinsic::not_intrinsic; 32808b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer switch(BuiltinID) { 3281f8495d67ca4dd2ea15a4dc59e9a2fa32a9bfa475Craig Topper default: llvm_unreachable("Unsupported intrinsic!"); 32828b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer case X86::BI__builtin_ia32_pswapdsf: 32838b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer case X86::BI__builtin_ia32_pswapdsi: 32848b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer name = "pswapd"; 32858b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer ID = Intrinsic::x86_3dnowa_pswapd; 32868b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer break; 32878b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer } 3288345032a7211a6f983d59c30c0b3fa2b96819532aChandler Carruth llvm::Type *MMXTy = llvm::Type::getX86_MMXTy(getLLVMContext()); 3289345032a7211a6f983d59c30c0b3fa2b96819532aChandler Carruth Ops[0] = Builder.CreateBitCast(Ops[0], MMXTy, "cast"); 32908b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer llvm::Function *F = CGM.getIntrinsic(ID); 32914c7d9f1507d0f102bd4133bba63348636facd469Jay Foad return Builder.CreateCall(F, Ops, name); 32928b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer } 32939a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer case X86::BI__builtin_ia32_rdrand16_step: 32949a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer case X86::BI__builtin_ia32_rdrand32_step: 32951bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao case X86::BI__builtin_ia32_rdrand64_step: 32961bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao case X86::BI__builtin_ia32_rdseed16_step: 32971bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao case X86::BI__builtin_ia32_rdseed32_step: 32981bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao case X86::BI__builtin_ia32_rdseed64_step: { 32999a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer Intrinsic::ID ID; 33009a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer switch (BuiltinID) { 33019a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer default: llvm_unreachable("Unsupported intrinsic!"); 33029a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer case X86::BI__builtin_ia32_rdrand16_step: 33039a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer ID = Intrinsic::x86_rdrand_16; 33049a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer break; 33059a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer case X86::BI__builtin_ia32_rdrand32_step: 33069a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer ID = Intrinsic::x86_rdrand_32; 33079a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer break; 33089a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer case X86::BI__builtin_ia32_rdrand64_step: 33099a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer ID = Intrinsic::x86_rdrand_64; 33109a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer break; 33111bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao case X86::BI__builtin_ia32_rdseed16_step: 33121bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao ID = Intrinsic::x86_rdseed_16; 33131bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao break; 33141bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao case X86::BI__builtin_ia32_rdseed32_step: 33151bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao ID = Intrinsic::x86_rdseed_32; 33161bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao break; 33171bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao case X86::BI__builtin_ia32_rdseed64_step: 33181bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao ID = Intrinsic::x86_rdseed_64; 33191bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao break; 33209a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer } 33219a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer 33229a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer Value *Call = Builder.CreateCall(CGM.getIntrinsic(ID)); 33239a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer Builder.CreateStore(Builder.CreateExtractValue(Call, 0), Ops[0]); 33249a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer return Builder.CreateExtractValue(Call, 1); 33259a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer } 33262766deb114cc5d3420027764438cf683dda8a9f0Juergen Ributzka // AVX2 broadcast 33272766deb114cc5d3420027764438cf683dda8a9f0Juergen Ributzka case X86::BI__builtin_ia32_vbroadcastsi256: { 33283fc779191ce87cddf603e0c5bdbd225611201ff4Juergen Ributzka Value *VecTmp = CreateMemTemp(E->getArg(0)->getType()); 33293fc779191ce87cddf603e0c5bdbd225611201ff4Juergen Ributzka Builder.CreateStore(Ops[0], VecTmp); 33303fc779191ce87cddf603e0c5bdbd225611201ff4Juergen Ributzka Value *F = CGM.getIntrinsic(Intrinsic::x86_avx2_vbroadcasti128); 33313fc779191ce87cddf603e0c5bdbd225611201ff4Juergen Ributzka return Builder.CreateCall(F, Builder.CreateBitCast(VecTmp, Int8PtrTy)); 33322766deb114cc5d3420027764438cf683dda8a9f0Juergen Ributzka } 3333564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson } 3334564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson} 3335564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson 33369631939f82c0eaa6fb3936a0ce58a41adfbc9011Tony Linthicum 33371eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpValue *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, 33381feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner const CallExpr *E) { 33395f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Value*, 4> Ops; 3340dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 3341dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) 3342dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner Ops.push_back(EmitScalarExpr(E->getArg(i))); 3343dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 3344dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner Intrinsic::ID ID = Intrinsic::not_intrinsic; 3345dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 3346dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner switch (BuiltinID) { 3347dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner default: return 0; 3348dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 33494d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov // vec_ld, vec_lvsl, vec_lvsr 33504d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvx: 33514d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvxl: 33524d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvebx: 33534d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvehx: 33544d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvewx: 33554d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvsl: 33564d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvsr: 33574d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov { 3358d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy); 33594d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov 3360578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Ops[0] = Builder.CreateGEP(Ops[1], Ops[0]); 33614d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov Ops.pop_back(); 33624d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov 33634d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov switch (BuiltinID) { 3364b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("Unsupported ld/lvsl/lvsr intrinsic!"); 33654d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvx: 33664d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvx; 33674d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 33684d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvxl: 33694d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvxl; 33704d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 33714d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvebx: 33724d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvebx; 33734d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 33744d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvehx: 33754d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvehx; 33764d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 33774d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvewx: 33784d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvewx; 33794d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 33804d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvsl: 33814d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvsl; 33824d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 33834d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvsr: 33844d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvsr; 33854d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 33864d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov } 33874d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov llvm::Function *F = CGM.getIntrinsic(ID); 33884c7d9f1507d0f102bd4133bba63348636facd469Jay Foad return Builder.CreateCall(F, Ops, ""); 33894d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov } 33904d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov 3391dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner // vec_st 3392dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvx: 3393dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvxl: 3394dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvebx: 3395dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvehx: 3396dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvewx: 3397dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner { 3398d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Ops[2] = Builder.CreateBitCast(Ops[2], Int8PtrTy); 3399578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Ops[1] = Builder.CreateGEP(Ops[2], Ops[1]); 3400dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner Ops.pop_back(); 3401dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 3402dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner switch (BuiltinID) { 3403b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("Unsupported st intrinsic!"); 3404dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvx: 3405dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvx; 3406dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 3407dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvxl: 3408dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvxl; 3409dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 3410dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvebx: 3411dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvebx; 3412dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 3413dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvehx: 3414dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvehx; 3415dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 3416dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvewx: 3417dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvewx; 3418dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 3419dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner } 3420dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner llvm::Function *F = CGM.getIntrinsic(ID); 34214c7d9f1507d0f102bd4133bba63348636facd469Jay Foad return Builder.CreateCall(F, Ops, ""); 3422dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner } 3423dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner } 34241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 3425