CGBuiltin.cpp revision fe0af454943374758309a1066e3304b3a56af04e
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: { 1285beb41281f8355caa05700d0a77539defbdf428f8John McCall // TODO: there is currently no set of optimizer flags 1286beb41281f8355caa05700d0a77539defbdf428f8John McCall // sufficient for us to rewrite sqrt to @llvm.sqrt. 1287beb41281f8355caa05700d0a77539defbdf428f8John McCall // -fmath-errno=0 is not good enough; we need finiteness. 1288beb41281f8355caa05700d0a77539defbdf428f8John McCall // We could probably precondition the call with an ult 1289beb41281f8355caa05700d0a77539defbdf428f8John McCall // against 0, but is that worth the complexity? 1290beb41281f8355caa05700d0a77539defbdf428f8John McCall break; 1291ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar } 1292ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar 1293ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIpow: 1294ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIpowf: 1295ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIpowl: { 12960323a7887b26f727080d2aa38f1a325dd23a1ee9Eli Bendersky // Transform a call to pow* into a @llvm.pow.* intrinsic call. 12970323a7887b26f727080d2aa38f1a325dd23a1ee9Eli Bendersky if (!FD->hasAttr<ConstAttr>()) 12980323a7887b26f727080d2aa38f1a325dd23a1ee9Eli Bendersky break; 12990323a7887b26f727080d2aa38f1a325dd23a1ee9Eli Bendersky Value *Base = EmitScalarExpr(E->getArg(0)); 13000323a7887b26f727080d2aa38f1a325dd23a1ee9Eli Bendersky Value *Exponent = EmitScalarExpr(E->getArg(1)); 13010323a7887b26f727080d2aa38f1a325dd23a1ee9Eli Bendersky llvm::Type *ArgType = Base->getType(); 13020323a7887b26f727080d2aa38f1a325dd23a1ee9Eli Bendersky Value *F = CGM.getIntrinsic(Intrinsic::pow, ArgType); 13030323a7887b26f727080d2aa38f1a325dd23a1ee9Eli Bendersky return RValue::get(Builder.CreateCall2(F, Base, Exponent)); 130464b22d8351a83593220803ed702e036c73bb8710Eli Bendersky break; 1305ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar } 1306ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman 1307094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BIfma: 1308094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BIfmaf: 1309094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BIfmal: 1310094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BI__builtin_fma: 1311094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BI__builtin_fmaf: 1312094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich case Builtin::BI__builtin_fmal: { 1313094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich // Rewrite fma to intrinsic. 1314094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich Value *FirstArg = EmitScalarExpr(E->getArg(0)); 13159cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *ArgType = FirstArg->getType(); 13168dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Value *F = CGM.getIntrinsic(Intrinsic::fma, ArgType); 1317094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich return RValue::get(Builder.CreateCall3(F, FirstArg, 1318094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich EmitScalarExpr(E->getArg(1)), 1319578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer EmitScalarExpr(E->getArg(2)))); 1320094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich } 1321094240ab184c3ca4b94e9d7eac80fcd34d8dd30cCameron Zwarich 1322ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman case Builtin::BI__builtin_signbit: 1323ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman case Builtin::BI__builtin_signbitf: 1324ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman case Builtin::BI__builtin_signbitl: { 1325ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman LLVMContext &C = CGM.getLLVMContext(); 1326ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman 1327ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *Arg = EmitScalarExpr(E->getArg(0)); 13282acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ArgTy = Arg->getType(); 1329ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman if (ArgTy->isPPC_FP128Ty()) 1330ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman break; // FIXME: I'm not sure what the right implementation is here. 1331ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman int ArgWidth = ArgTy->getPrimitiveSizeInBits(); 13322acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ArgIntTy = llvm::IntegerType::get(C, ArgWidth); 1333ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *BCArg = Builder.CreateBitCast(Arg, ArgIntTy); 1334ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *ZeroCmp = llvm::Constant::getNullValue(ArgIntTy); 1335ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *Result = Builder.CreateICmpSLT(BCArg, ZeroCmp); 1336ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman return RValue::get(Builder.CreateZExt(Result, ConvertType(E->getType()))); 1337ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman } 133877f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge case Builtin::BI__builtin_annotation: { 133977f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge llvm::Value *AnnVal = EmitScalarExpr(E->getArg(0)); 134077f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::annotation, 134177f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge AnnVal->getType()); 134277f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge 134377f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge // Get the annotation string, go through casts. Sema requires this to be a 134477f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge // non-wide string literal, potentially casted, so the cast<> is safe. 134577f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge const Expr *AnnotationStrExpr = E->getArg(1)->IgnoreParenCasts(); 1346cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko StringRef Str = cast<StringLiteral>(AnnotationStrExpr)->getString(); 134777f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge return RValue::get(EmitAnnotationCall(F, AnnVal, Str, E->getExprLoc())); 134877f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge } 1349ee76e7215d27c25bb053b71ae0a59119c08ccef9Michael Gottesman case Builtin::BI__builtin_addcb: 13500cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman case Builtin::BI__builtin_addcs: 13510cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman case Builtin::BI__builtin_addc: 13520cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman case Builtin::BI__builtin_addcl: 13537c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_addcll: 1354ee76e7215d27c25bb053b71ae0a59119c08ccef9Michael Gottesman case Builtin::BI__builtin_subcb: 13557c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subcs: 13567c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subc: 13577c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subcl: 13587c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subcll: { 13590cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman 13600cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // We translate all of these builtins from expressions of the form: 13610cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // int x = ..., y = ..., carryin = ..., carryout, result; 13620cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // result = __builtin_addc(x, y, carryin, &carryout); 13630cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // 13640cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // to LLVM IR of the form: 13650cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // 13660cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %tmp1 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x, i32 %y) 13670cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %tmpsum1 = extractvalue {i32, i1} %tmp1, 0 13680cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %carry1 = extractvalue {i32, i1} %tmp1, 1 13690cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %tmp2 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %tmpsum1, 13700cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // i32 %carryin) 13710cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %result = extractvalue {i32, i1} %tmp2, 0 13720cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %carry2 = extractvalue {i32, i1} %tmp2, 1 13730cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %tmp3 = or i1 %carry1, %carry2 13740cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // %tmp4 = zext i1 %tmp3 to i32 13750cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // store i32 %tmp4, i32* %carryout 13760cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman 13770cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // Scalarize our inputs. 13780cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *X = EmitScalarExpr(E->getArg(0)); 13790cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *Y = EmitScalarExpr(E->getArg(1)); 13800cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *Carryin = EmitScalarExpr(E->getArg(2)); 13810cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman std::pair<llvm::Value*, unsigned> CarryOutPtr = 13820cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman EmitPointerWithAlignment(E->getArg(3)); 13830cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman 13847c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman // Decide if we are lowering to a uadd.with.overflow or usub.with.overflow. 13857c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman llvm::Intrinsic::ID IntrinsicId; 13867c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman switch (BuiltinID) { 13877c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman default: llvm_unreachable("Unknown multiprecision builtin id."); 1388ee76e7215d27c25bb053b71ae0a59119c08ccef9Michael Gottesman case Builtin::BI__builtin_addcb: 13897c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_addcs: 13907c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_addc: 13917c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_addcl: 13927c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_addcll: 13937c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman IntrinsicId = llvm::Intrinsic::uadd_with_overflow; 13947c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman break; 1395ee76e7215d27c25bb053b71ae0a59119c08ccef9Michael Gottesman case Builtin::BI__builtin_subcb: 13967c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subcs: 13977c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subc: 13987c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subcl: 13997c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman case Builtin::BI__builtin_subcll: 14007c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman IntrinsicId = llvm::Intrinsic::usub_with_overflow; 14017c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman break; 14027c9dbb76f6847fb30527c8e74ef9a25a3d4eb731Michael Gottesman } 14030cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman 14040cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman // Construct our resulting LLVM IR expression. 14050cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *Carry1; 14060cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *Sum1 = EmitOverflowIntrinsic(*this, IntrinsicId, 14070cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman X, Y, Carry1); 14080cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *Carry2; 14090cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *Sum2 = EmitOverflowIntrinsic(*this, IntrinsicId, 14100cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman Sum1, Carryin, Carry2); 14110cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::Value *CarryOut = Builder.CreateZExt(Builder.CreateOr(Carry1, Carry2), 14120cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman X->getType()); 14130cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman llvm::StoreInst *CarryOutStore = Builder.CreateStore(CarryOut, 14140cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman CarryOutPtr.first); 14150cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman CarryOutStore->setAlignment(CarryOutPtr.second); 14160cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman return RValue::get(Sum2); 14170cf07bcc6c53f1df421d4c40ce52d43e8d8adcd3Michael Gottesman } 141898d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_uadd_overflow: 141998d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_uaddl_overflow: 142098d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_uaddll_overflow: 142198d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_usub_overflow: 142298d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_usubl_overflow: 142398d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_usubll_overflow: 142498d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_umul_overflow: 142598d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_umull_overflow: 142698d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_umulll_overflow: 142798d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_sadd_overflow: 142898d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_saddl_overflow: 142998d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_saddll_overflow: 143098d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_ssub_overflow: 143198d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_ssubl_overflow: 143298d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_ssubll_overflow: 143398d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_smul_overflow: 143498d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_smull_overflow: 143598d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_smulll_overflow: { 143698d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman 143798d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman // We translate all of these builtins directly to the relevant llvm IR node. 143898d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman 143998d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman // Scalarize our inputs. 144098d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman llvm::Value *X = EmitScalarExpr(E->getArg(0)); 144198d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman llvm::Value *Y = EmitScalarExpr(E->getArg(1)); 144298d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman std::pair<llvm::Value *, unsigned> SumOutPtr = 144398d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman EmitPointerWithAlignment(E->getArg(2)); 144498d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman 144598d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman // Decide which of the overflow intrinsics we are lowering to: 144698d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman llvm::Intrinsic::ID IntrinsicId; 144798d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman switch (BuiltinID) { 144898d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman default: llvm_unreachable("Unknown security overflow builtin id."); 144998d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_uadd_overflow: 145098d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_uaddl_overflow: 145198d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_uaddll_overflow: 145298d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman IntrinsicId = llvm::Intrinsic::uadd_with_overflow; 145398d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman break; 145498d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_usub_overflow: 145598d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_usubl_overflow: 145698d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_usubll_overflow: 145798d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman IntrinsicId = llvm::Intrinsic::usub_with_overflow; 145898d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman break; 145998d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_umul_overflow: 146098d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_umull_overflow: 146198d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_umulll_overflow: 146298d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman IntrinsicId = llvm::Intrinsic::umul_with_overflow; 146398d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman break; 146498d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_sadd_overflow: 146598d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_saddl_overflow: 146698d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_saddll_overflow: 146798d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman IntrinsicId = llvm::Intrinsic::sadd_with_overflow; 146898d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman break; 146998d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_ssub_overflow: 147098d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_ssubl_overflow: 147198d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_ssubll_overflow: 147298d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman IntrinsicId = llvm::Intrinsic::ssub_with_overflow; 147398d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman break; 147498d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_smul_overflow: 147598d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_smull_overflow: 147698d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman case Builtin::BI__builtin_smulll_overflow: 147798d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman IntrinsicId = llvm::Intrinsic::smul_with_overflow; 147898d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman break; 147998d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman } 148098d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman 148198d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman 148298d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman llvm::Value *Carry; 148398d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman llvm::Value *Sum = EmitOverflowIntrinsic(*this, IntrinsicId, X, Y, Carry); 148498d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman llvm::StoreInst *SumOutStore = Builder.CreateStore(Sum, SumOutPtr.first); 148598d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman SumOutStore->setAlignment(SumOutPtr.second); 148698d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman 148798d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman return RValue::get(Carry); 148898d1ec1e99625176626b0bcd44cef7df6e89b289Michael Gottesman } 14895154dce6388e3aaa445467030df7a45ed1211abeRichard Smith case Builtin::BI__builtin_addressof: 14905154dce6388e3aaa445467030df7a45ed1211abeRichard Smith return RValue::get(EmitLValue(E->getArg(0)).getAddress()); 149127844533aad5c165523a5926424097699610d3f0Nico Weber case Builtin::BI__noop: 149227844533aad5c165523a5926424097699610d3f0Nico Weber return RValue::get(0); 14937ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman } 14941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1495a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // If this is an alias for a lib function (e.g. __builtin_sin), emit 1496a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // the call using the normal call path, but using the unmangled 1497a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // version of the function name. 1498a45680b7e7c49ea9893c6cff585984f3e4120366John McCall if (getContext().BuiltinInfo.isLibFunction(BuiltinID)) 1499a45680b7e7c49ea9893c6cff585984f3e4120366John McCall return emitLibraryCall(*this, FD, E, 1500a45680b7e7c49ea9893c6cff585984f3e4120366John McCall CGM.getBuiltinLibFunction(FD, BuiltinID)); 1501258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 1502a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // If this is a predefined lib function (e.g. malloc), emit the call 1503a45680b7e7c49ea9893c6cff585984f3e4120366John McCall // using exactly the normal call path. 1504a45680b7e7c49ea9893c6cff585984f3e4120366John McCall if (getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID)) 1505a45680b7e7c49ea9893c6cff585984f3e4120366John McCall return emitLibraryCall(*this, FD, E, EmitScalarExpr(E->getCallee())); 15061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1507b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // See if we have a target specific intrinsic. 1508a6f80ef997f0363386749087b325607eaa5adcfcDale Johannesen const char *Name = getContext().BuiltinInfo.GetName(BuiltinID); 150955cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic; 151055cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar if (const char *Prefix = 151164aa4b3ec7e62288e2e66c1935487ece995ca94bJohn McCall llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch())) 151255cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix, Name); 15131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1514b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (IntrinsicID != Intrinsic::not_intrinsic) { 1515b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner SmallVector<Value*, 16> Args; 15161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 151746c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // Find out if any arguments are required to be integer constant 151846c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // expressions. 151946c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner unsigned ICEArguments = 0; 152046c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner ASTContext::GetBuiltinTypeError Error; 152146c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 152246c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner assert(Error == ASTContext::GE_None && "Should not codegen an error"); 152346c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner 1524b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner Function *F = CGM.getIntrinsic(IntrinsicID); 15252acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = F->getFunctionType(); 15261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1527b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 152846c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner Value *ArgValue; 152946c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // If this is a normal argument, just emit it as a scalar. 153046c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner if ((ICEArguments & (1 << i)) == 0) { 153146c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner ArgValue = EmitScalarExpr(E->getArg(i)); 153246c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner } else { 1533258f930227c1a102c9c22eee88df65f748863425Jim Grosbach // If this is required to be a constant, constant fold it so that we 153446c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // know that the generated intrinsic gets a ConstantInt. 153546c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner llvm::APSInt Result; 153646c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result,getContext()); 153746c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner assert(IsConst && "Constant arg isn't actually constant?"); 153846c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner (void)IsConst; 1539d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall ArgValue = llvm::ConstantInt::get(getLLVMContext(), Result); 154046c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner } 15411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1542b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // If the intrinsic arg type is different from the builtin arg type 1543b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // we need to do a bit cast. 15442acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *PTy = FTy->getParamType(i); 1545b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (PTy != ArgValue->getType()) { 1546b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) && 1547b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner "Must be able to losslessly bit cast to param"); 1548b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner ArgValue = Builder.CreateBitCast(ArgValue, PTy); 1549b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 15501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1551b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner Args.push_back(ArgValue); 1552b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 15531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15544c7d9f1507d0f102bd4133bba63348636facd469Jay Foad Value *V = Builder.CreateCall(F, Args); 1555b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner QualType BuiltinRetType = E->getType(); 15561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15578b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner llvm::Type *RetTy = VoidTy; 1558258f930227c1a102c9c22eee88df65f748863425Jim Grosbach if (!BuiltinRetType->isVoidType()) 15598b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner RetTy = ConvertType(BuiltinRetType); 15601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1561b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (RetTy != V->getType()) { 1562b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner assert(V->getType()->canLosslesslyBitCastTo(RetTy) && 1563b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner "Must be able to losslessly bit cast result type"); 1564b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner V = Builder.CreateBitCast(V, RetTy); 1565b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 15661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1567b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner return RValue::get(V); 1568b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 15691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1570b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // See if we have a target specific builtin that needs to be lowered. 1571f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E)) 1572b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner return RValue::get(V); 15731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1574488e993a135ce700b982bf099c3d6b856301d642Daniel Dunbar ErrorUnsupported(E, "builtin function"); 15751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1576b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // Unknown builtin, for now just dump it out and return undef. 15779d232c884ea9872d6555df0fd7359699819bc1f1John McCall return GetUndefRValue(E->getType()); 15781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 1579564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson 1580f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel DunbarValue *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, 1581f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar const CallExpr *E) { 158264aa4b3ec7e62288e2e66c1935487ece995ca94bJohn McCall switch (getTarget().getTriple().getArch()) { 1583ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover case llvm::Triple::aarch64: 1584ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover return EmitAArch64BuiltinExpr(BuiltinID, E); 15852752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner case llvm::Triple::arm: 15862752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner case llvm::Triple::thumb: 15872752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner return EmitARMBuiltinExpr(BuiltinID, E); 158855cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::x86: 158955cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::x86_64: 1590f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar return EmitX86BuiltinExpr(BuiltinID, E); 159155cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::ppc: 159255cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::ppc64: 1593ea7fb0ce25acc04664a2e7c2b24af03cef2c0d1fBill Schmidt case llvm::Triple::ppc64le: 1594f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar return EmitPPCBuiltinExpr(BuiltinID, E); 159555cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar default: 159655cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar return 0; 159755cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar } 1598f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar} 1599f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar 16008b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattnerstatic llvm::VectorType *GetNeonType(CodeGenFunction *CGF, 16018b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner NeonTypeFlags TypeFlags) { 160283084c863572b48579767a4dd5dc686e1a8d669dNAKAMURA Takumi int IsQuad = TypeFlags.isQuad(); 160383084c863572b48579767a4dd5dc686e1a8d669dNAKAMURA Takumi switch (TypeFlags.getEltType()) { 1604da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Int8: 1605da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Poly8: 16068b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner return llvm::VectorType::get(CGF->Int8Ty, 8 << IsQuad); 1607da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Int16: 1608da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Poly16: 1609da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Float16: 16108b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner return llvm::VectorType::get(CGF->Int16Ty, 4 << IsQuad); 1611da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Int32: 16128b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner return llvm::VectorType::get(CGF->Int32Ty, 2 << IsQuad); 1613da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Int64: 16148b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner return llvm::VectorType::get(CGF->Int64Ty, 1 << IsQuad); 1615da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case NeonTypeFlags::Float32: 16168b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner return llvm::VectorType::get(CGF->FloatTy, 2 << IsQuad); 1617b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case NeonTypeFlags::Float64: 1618b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return llvm::VectorType::get(CGF->DoubleTy, 1 << IsQuad); 1619561d3abc881033776ece385a01a510e1cbc1fa92David Blaikie } 1620561d3abc881033776ece385a01a510e1cbc1fa92David Blaikie llvm_unreachable("Invalid NeonTypeFlags element type!"); 1621998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman} 1622998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman 162312cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liustatic Value *EmitExtendedSHL(CodeGenFunction &CGF, 162412cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu SmallVectorImpl<Value*> &Ops, 162512cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu llvm::VectorType *VTy, bool usgn, bool isHigh) { 162679690a0c488bab19dc778e43a6845b2652fe4f79Hao Liu CGBuilderTy Builder = CGF.Builder; 162712cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu if (isHigh){ 162812cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu unsigned NumElts = VTy->getNumElements(); 162912cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 163012cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu llvm::Type *EltTy = 163112cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu llvm::IntegerType::get(VTy->getContext(), EltBits / 2); 163212cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu // The source operand type has twice as many elements of half the size. 163312cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu llvm::Type *SrcTy = llvm::VectorType::get(EltTy, NumElts * 2); 163412cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu SmallVector<Constant*, 8> Indices; 163512cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu for (unsigned i = 0; i != NumElts; i++) 163612cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu Indices.push_back(Builder.getInt32(i + NumElts)); 163712cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu Value *SV = llvm::ConstantVector::get(Indices); 163812cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu Value *Undef = llvm::UndefValue::get(SrcTy); 163912cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 164012cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu Ops[0] = Builder.CreateShuffleVector(Ops[0], Undef, SV); 164112cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu } else { 164212cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu llvm::Type *SrcTy = llvm::VectorType::getTruncatedElementVectorType(VTy); 164312cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 164412cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu } 164512cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu 164612cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu if (usgn) 164712cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu Ops[0] = Builder.CreateZExt(Ops[0], VTy); 164812cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu else 164912cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu Ops[0] = Builder.CreateSExt(Ops[0], VTy); 165012cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu Ops[1] = CGF.EmitNeonShiftVector(Ops[1], VTy, false); 165112cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu return Builder.CreateShl(Ops[0], Ops[1], "vshl_n"); 165212cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu} 165312cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu 1654cf55652cf668c1402eee0b12edd2e5a1bc34d7a1Bob WilsonValue *CodeGenFunction::EmitNeonSplat(Value *V, Constant *C) { 1655d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman unsigned nElts = cast<llvm::VectorType>(V->getType())->getNumElements(); 16562ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner Value* SV = llvm::ConstantVector::getSplat(nElts, C); 1657d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman return Builder.CreateShuffleVector(V, V, SV, "lane"); 1658d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman} 1659d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman 166030d91718a676177f0d0d0210ce4fdb4f616df6e5Nate BegemanValue *CodeGenFunction::EmitNeonCall(Function *F, SmallVectorImpl<Value*> &Ops, 1661db3d4d036037f379f12643e067b229862d61e932Bob Wilson const char *name, 166261eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman unsigned shift, bool rightshift) { 166330d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman unsigned j = 0; 166430d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end(); 166530d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman ai != ae; ++ai, ++j) 166661eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman if (shift > 0 && shift == j) 166761eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[j] = EmitNeonShiftVector(Ops[j], ai->getType(), rightshift); 166861eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman else 166961eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[j] = Builder.CreateBitCast(Ops[j], ai->getType(), name); 167030d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman 16714c7d9f1507d0f102bd4133bba63348636facd469Jay Foad return Builder.CreateCall(F, Ops, name); 167230d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman} 167330d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman 1674258f930227c1a102c9c22eee88df65f748863425Jim GrosbachValue *CodeGenFunction::EmitNeonShiftVector(Value *V, llvm::Type *Ty, 1675464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman bool neg) { 16762ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner int SV = cast<ConstantInt>(V)->getSExtValue(); 1677258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 16782acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 1679464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman llvm::Constant *C = ConstantInt::get(VTy->getElementType(), neg ? -SV : SV); 16802ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner return llvm::ConstantVector::getSplat(VTy->getNumElements(), C); 1681464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman} 1682464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman 168306b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson/// GetPointeeAlignment - Given an expression with a pointer type, find the 168406b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson/// alignment of the type referenced by the pointer. Skip over implicit 168506b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson/// casts. 1686ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedmanstd::pair<llvm::Value*, unsigned> 1687ea93e40785ffeadfac66b948c95f9490ec26207aEli FriedmanCodeGenFunction::EmitPointerWithAlignment(const Expr *Addr) { 1688ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman assert(Addr->getType()->isPointerType()); 1689ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Addr = Addr->IgnoreParens(); 1690ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Addr)) { 1691a484fc73ec6331bcaad092270b4ab9c8d1df23c3Eli Friedman if ((ICE->getCastKind() == CK_BitCast || ICE->getCastKind() == CK_NoOp) && 1692a484fc73ec6331bcaad092270b4ab9c8d1df23c3Eli Friedman ICE->getSubExpr()->getType()->isPointerType()) { 1693258f930227c1a102c9c22eee88df65f748863425Jim Grosbach std::pair<llvm::Value*, unsigned> Ptr = 1694ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(ICE->getSubExpr()); 1695ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ptr.first = Builder.CreateBitCast(Ptr.first, 1696ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman ConvertType(Addr->getType())); 1697ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return Ptr; 1698ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } else if (ICE->getCastKind() == CK_ArrayToPointerDecay) { 1699ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman LValue LV = EmitLValue(ICE->getSubExpr()); 17008e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman unsigned Align = LV.getAlignment().getQuantity(); 17018e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman if (!Align) { 17028e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman // FIXME: Once LValues are fixed to always set alignment, 17038e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman // zap this code. 17048e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman QualType PtTy = ICE->getSubExpr()->getType(); 17058e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman if (!PtTy->isIncompleteType()) 17068e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman Align = getContext().getTypeAlignInChars(PtTy).getQuantity(); 17078e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman else 17088e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman Align = 1; 17098e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman } 17108e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman return std::make_pair(LV.getAddress(), Align); 1711d6e73569ccf09369f9bd2021d53c88e7bded06e3Chris Lattner } 1712ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 1713ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(Addr)) { 1714ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (UO->getOpcode() == UO_AddrOf) { 1715ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman LValue LV = EmitLValue(UO->getSubExpr()); 17168e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman unsigned Align = LV.getAlignment().getQuantity(); 17178e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman if (!Align) { 17188e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman // FIXME: Once LValues are fixed to always set alignment, 17198e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman // zap this code. 17208e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman QualType PtTy = UO->getSubExpr()->getType(); 17218e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman if (!PtTy->isIncompleteType()) 17228e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman Align = getContext().getTypeAlignInChars(PtTy).getQuantity(); 17238e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman else 17248e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman Align = 1; 17258e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman } 17268e4c189e6502cffb760b33f092e65effb1d10092Eli Friedman return std::make_pair(LV.getAddress(), Align); 172706b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson } 172806b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson } 1729f4c3db175101cbf94dad59419c3ed7aed51bf606Jay Foad 1730ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman unsigned Align = 1; 1731ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman QualType PtTy = Addr->getType()->getPointeeType(); 1732ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (!PtTy->isIncompleteType()) 1733ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Align = getContext().getTypeAlignInChars(PtTy).getQuantity(); 1734ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman 1735ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman return std::make_pair(EmitScalarExpr(Addr), Align); 173606b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson} 173706b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson 1738ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim NorthoverValue *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, 1739ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover const CallExpr *E) { 1740ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover if (BuiltinID == AArch64::BI__clear_cache) { 1741ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover assert(E->getNumArgs() == 2 && 1742ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover "Variadic __clear_cache slipped through on AArch64"); 1743ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover 1744ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover const FunctionDecl *FD = E->getDirectCallee(); 1745ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover SmallVector<Value *, 2> Ops; 1746ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover for (unsigned i = 0; i < E->getNumArgs(); i++) 1747ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover Ops.push_back(EmitScalarExpr(E->getArg(i))); 1748ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); 1749ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); 1750ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover StringRef Name = FD->getName(); 1751ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); 1752ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover } 1753ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover 1754b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover SmallVector<Value *, 4> Ops; 1755b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) { 1756b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Ops.push_back(EmitScalarExpr(E->getArg(i))); 1757b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 1758b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 1759b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Get the last argument, which specifies the vector type. 1760b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover llvm::APSInt Result; 1761b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover const Expr *Arg = E->getArg(E->getNumArgs() - 1); 1762b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (!Arg->isIntegerConstantExpr(Result, getContext())) 1763b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return 0; 1764b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 1765b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Determine the type of this overloaded NEON intrinsic. 1766b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover NeonTypeFlags Type(Result.getZExtValue()); 1767b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover bool usgn = Type.isUnsigned(); 1768b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 1769b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover llvm::VectorType *VTy = GetNeonType(this, Type); 1770b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover llvm::Type *Ty = VTy; 1771b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (!Ty) 1772b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return 0; 1773b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 1774b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover unsigned Int; 1775b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover switch (BuiltinID) { 1776b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover default: 1777b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return 0; 1778b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 1779b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // AArch64 builtins mapping to legacy ARM v7 builtins. 1780b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // FIXME: the mapped builtins listed correspond to what has been tested 1781b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // in aarch64-neon-intrinsics.c so far. 1782b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vmul_v: 1783b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmul_v, E); 1784b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vmulq_v: 1785b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmulq_v, E); 1786b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vabd_v: 1787b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vabd_v, E); 1788b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vabdq_v: 1789b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vabdq_v, E); 1790b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vfma_v: 1791b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vfma_v, E); 1792b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vfmaq_v: 1793b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vfmaq_v, E); 1794b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vbsl_v: 1795b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vbsl_v, E); 1796b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vbslq_v: 1797b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vbslq_v, E); 1798b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vrsqrts_v: 1799b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrsqrts_v, E); 1800b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vrsqrtsq_v: 1801b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrsqrtsq_v, E); 1802b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vrecps_v: 1803b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrecps_v, E); 1804b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vrecpsq_v: 1805b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrecpsq_v, E); 1806b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vcage_v: 1807b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcage_v, E); 1808b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vcale_v: 1809b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcale_v, E); 1810b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vcaleq_v: 1811b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::swap(Ops[0], Ops[1]); 1812b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vcageq_v: { 1813b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Function *F; 1814b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (VTy->getElementType()->isIntegerTy(64)) 1815b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover F = CGM.getIntrinsic(Intrinsic::aarch64_neon_vacgeq); 1816b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover else 1817b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgeq); 1818b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitNeonCall(F, Ops, "vcage"); 1819b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 1820b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vcalt_v: 1821b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcalt_v, E); 1822b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vcagt_v: 1823b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcagt_v, E); 1824b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vcaltq_v: 1825b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::swap(Ops[0], Ops[1]); 1826b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vcagtq_v: { 1827b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Function *F; 1828b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (VTy->getElementType()->isIntegerTy(64)) 1829b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover F = CGM.getIntrinsic(Intrinsic::aarch64_neon_vacgtq); 1830b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover else 1831b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgtq); 1832b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitNeonCall(F, Ops, "vcagt"); 1833b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 1834b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vtst_v: 1835b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vtst_v, E); 1836b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vtstq_v: 1837b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vtstq_v, E); 1838b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vhadd_v: 1839b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vhadd_v, E); 1840b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vhaddq_v: 1841b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vhaddq_v, E); 1842b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vhsub_v: 1843b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vhsub_v, E); 1844b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vhsubq_v: 1845b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vhsubq_v, E); 1846b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vrhadd_v: 1847b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrhadd_v, E); 1848b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vrhaddq_v: 1849b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrhaddq_v, E); 1850b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqadd_v: 1851b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqadd_v, E); 1852b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqaddq_v: 1853b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqaddq_v, E); 1854b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqsub_v: 1855b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqsub_v, E); 1856b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqsubq_v: 1857b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqsubq_v, E); 1858b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vshl_v: 1859b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshl_v, E); 1860b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vshlq_v: 1861b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshlq_v, E); 1862b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqshl_v: 1863b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqshl_v, E); 1864b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqshlq_v: 1865b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqshlq_v, E); 1866b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vrshl_v: 1867b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrshl_v, E); 1868b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vrshlq_v: 1869b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrshlq_v, E); 1870b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqrshl_v: 1871b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqrshl_v, E); 1872b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqrshlq_v: 1873b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqrshlq_v, E); 1874b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vmax_v: 1875b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmax_v, E); 1876b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vmaxq_v: 1877b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmaxq_v, E); 1878b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vmin_v: 1879b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmin_v, E); 1880b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vminq_v: 1881b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vminq_v, E); 1882b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vpmax_v: 1883b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vpmax_v, E); 1884b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vpmin_v: 1885b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vpmin_v, E); 1886b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vpadd_v: 1887b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vpadd_v, E); 1888b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqdmulh_v: 1889b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqdmulh_v, E); 1890b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqdmulhq_v: 1891b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqdmulhq_v, E); 1892b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqrdmulh_v: 1893b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqrdmulh_v, E); 1894b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vqrdmulhq_v: 1895b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqrdmulhq_v, E); 189612cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu case AArch64::BI__builtin_neon_vshl_n_v: 189712cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshl_n_v, E); 189812cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu case AArch64::BI__builtin_neon_vshlq_n_v: 189912cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshlq_n_v, E); 190012cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu case AArch64::BI__builtin_neon_vmovl_v: 190112cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmovl_v, E); 190212cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu case AArch64::BI__builtin_neon_vshll_n_v: 190312cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu return EmitExtendedSHL(*this, Ops, VTy, usgn, false); 190412cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu case AArch64::BI__builtin_neon_vmovl_high_v: 190512cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu Ops.push_back(ConstantInt::get(Int32Ty, 0)); 190612cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu case AArch64::BI__builtin_neon_vshll_high_n_v: 190712cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu return EmitExtendedSHL(*this, Ops, VTy, usgn, true); 1908b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 1909b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // AArch64-only builtins 1910b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vfms_v: 1911b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vfmsq_v: { 1912b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 1913b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 1914b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 1915b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Ops[1] = Builder.CreateFNeg(Ops[1]); 1916b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 1917b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 1918b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // LLVM's fma intrinsic puts the accumulator in the last position, but the 1919b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // AArch64 intrinsic has it first. 1920b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]); 1921b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 1922b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vmaxnm_v: 1923b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vmaxnmq_v: { 1924b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Int = Intrinsic::aarch64_neon_vmaxnm; 1925b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmaxnm"); 1926b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 1927b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vminnm_v: 1928b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vminnmq_v: { 1929b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Int = Intrinsic::aarch64_neon_vminnm; 1930b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vminnm"); 1931b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 1932b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vpmaxnm_v: 1933b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vpmaxnmq_v: { 1934b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Int = Intrinsic::aarch64_neon_vpmaxnm; 1935b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmaxnm"); 1936b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 1937b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vpminnm_v: 1938b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vpminnmq_v: { 1939b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Int = Intrinsic::aarch64_neon_vpminnm; 1940b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpminnm"); 1941b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 1942b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vpmaxq_v: { 1943b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Int = usgn ? Intrinsic::arm_neon_vpmaxu : Intrinsic::arm_neon_vpmaxs; 1944b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmax"); 1945b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 1946b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vpminq_v: { 1947b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Int = usgn ? Intrinsic::arm_neon_vpminu : Intrinsic::arm_neon_vpmins; 1948b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmin"); 1949b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 1950b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vpaddq_v: { 1951b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Int = Intrinsic::arm_neon_vpadd; 1952b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpadd"); 1953b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 1954b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vmulx_v: 1955b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case AArch64::BI__builtin_neon_vmulxq_v: { 1956b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Int = Intrinsic::aarch64_neon_vmulx; 1957b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmulx"); 1958b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 1959b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 1960ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover} 1961ff920eec4d449bee560d8d99636ad0eb50cd9d8dTim Northover 19622752c0137d95aa2f4ee1cdff4b564bac842e041bChris LattnerValue *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, 19632752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner const CallExpr *E) { 1964e140af3e27016f902146023fba7680b43043ec07Rafael Espindola if (BuiltinID == ARM::BI__clear_cache) { 19654537d6e0f9baf2e011a4260e0d7872789b01c3f2Rafael Espindola assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments"); 196679ba509b0106fd0a1ff832baeb1fdb5430527efeRafael Espindola const FunctionDecl *FD = E->getDirectCallee(); 19675f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Value*, 2> Ops; 19684537d6e0f9baf2e011a4260e0d7872789b01c3f2Rafael Espindola for (unsigned i = 0; i < 2; i++) 19698a37c79f03e62aecfa2c58b9179f90dd1fcdb253Eric Christopher Ops.push_back(EmitScalarExpr(E->getArg(i))); 19702acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); 19712acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); 19725f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Name = FD->getName(); 1973bd7370a78604e9a20d698bfe328c1e43f12a0613John McCall return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); 19742752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner } 1975e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 197609df2b066221d869f17f4b5762405f111a65f983Tim Northover if (BuiltinID == ARM::BI__builtin_arm_ldrexd || 197709df2b066221d869f17f4b5762405f111a65f983Tim Northover (BuiltinID == ARM::BI__builtin_arm_ldrex && 197809df2b066221d869f17f4b5762405f111a65f983Tim Northover getContext().getTypeSize(E->getType()) == 64)) { 197926c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Function *F = CGM.getIntrinsic(Intrinsic::arm_ldrexd); 198026c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 198126c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *LdPtr = EmitScalarExpr(E->getArg(0)); 198209df2b066221d869f17f4b5762405f111a65f983Tim Northover Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy), 198309df2b066221d869f17f4b5762405f111a65f983Tim Northover "ldrexd"); 198426c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 198526c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *Val0 = Builder.CreateExtractValue(Val, 1); 198626c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *Val1 = Builder.CreateExtractValue(Val, 0); 198726c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Val0 = Builder.CreateZExt(Val0, Int64Ty); 198826c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Val1 = Builder.CreateZExt(Val1, Int64Ty); 198926c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 199026c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *ShiftCst = llvm::ConstantInt::get(Int64Ty, 32); 199126c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */); 199209df2b066221d869f17f4b5762405f111a65f983Tim Northover Val = Builder.CreateOr(Val, Val1); 199309df2b066221d869f17f4b5762405f111a65f983Tim Northover return Builder.CreateBitCast(Val, ConvertType(E->getType())); 199426c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes } 199526c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 199609df2b066221d869f17f4b5762405f111a65f983Tim Northover if (BuiltinID == ARM::BI__builtin_arm_ldrex) { 199709df2b066221d869f17f4b5762405f111a65f983Tim Northover Value *LoadAddr = EmitScalarExpr(E->getArg(0)); 199809df2b066221d869f17f4b5762405f111a65f983Tim Northover 199909df2b066221d869f17f4b5762405f111a65f983Tim Northover QualType Ty = E->getType(); 200009df2b066221d869f17f4b5762405f111a65f983Tim Northover llvm::Type *RealResTy = ConvertType(Ty); 200109df2b066221d869f17f4b5762405f111a65f983Tim Northover llvm::Type *IntResTy = llvm::IntegerType::get(getLLVMContext(), 200209df2b066221d869f17f4b5762405f111a65f983Tim Northover getContext().getTypeSize(Ty)); 200309df2b066221d869f17f4b5762405f111a65f983Tim Northover LoadAddr = Builder.CreateBitCast(LoadAddr, IntResTy->getPointerTo()); 200409df2b066221d869f17f4b5762405f111a65f983Tim Northover 200509df2b066221d869f17f4b5762405f111a65f983Tim Northover Function *F = CGM.getIntrinsic(Intrinsic::arm_ldrex, LoadAddr->getType()); 200609df2b066221d869f17f4b5762405f111a65f983Tim Northover Value *Val = Builder.CreateCall(F, LoadAddr, "ldrex"); 200709df2b066221d869f17f4b5762405f111a65f983Tim Northover 200809df2b066221d869f17f4b5762405f111a65f983Tim Northover if (RealResTy->isPointerTy()) 200909df2b066221d869f17f4b5762405f111a65f983Tim Northover return Builder.CreateIntToPtr(Val, RealResTy); 201009df2b066221d869f17f4b5762405f111a65f983Tim Northover else { 201109df2b066221d869f17f4b5762405f111a65f983Tim Northover Val = Builder.CreateTruncOrBitCast(Val, IntResTy); 201209df2b066221d869f17f4b5762405f111a65f983Tim Northover return Builder.CreateBitCast(Val, RealResTy); 201309df2b066221d869f17f4b5762405f111a65f983Tim Northover } 201409df2b066221d869f17f4b5762405f111a65f983Tim Northover } 201509df2b066221d869f17f4b5762405f111a65f983Tim Northover 201609df2b066221d869f17f4b5762405f111a65f983Tim Northover if (BuiltinID == ARM::BI__builtin_arm_strexd || 201709df2b066221d869f17f4b5762405f111a65f983Tim Northover (BuiltinID == ARM::BI__builtin_arm_strex && 201809df2b066221d869f17f4b5762405f111a65f983Tim Northover getContext().getTypeSize(E->getArg(0)->getType()) == 64)) { 201926c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Function *F = CGM.getIntrinsic(Intrinsic::arm_strexd); 20207650d95a1a616ea300f37126a8dfc93dc19a662aChris Lattner llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, NULL); 202126c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 20223fc779191ce87cddf603e0c5bdbd225611201ff4Juergen Ributzka Value *Tmp = CreateMemTemp(E->getArg(0)->getType()); 202326c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *Val = EmitScalarExpr(E->getArg(0)); 202426c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Builder.CreateStore(Val, Tmp); 202526c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 202626c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *LdPtr = Builder.CreateBitCast(Tmp,llvm::PointerType::getUnqual(STy)); 202726c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Val = Builder.CreateLoad(LdPtr); 202826c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 202926c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *Arg0 = Builder.CreateExtractValue(Val, 0); 203026c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes Value *Arg1 = Builder.CreateExtractValue(Val, 1); 203109df2b066221d869f17f4b5762405f111a65f983Tim Northover Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), Int8PtrTy); 203226c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes return Builder.CreateCall3(F, Arg0, Arg1, StPtr, "strexd"); 203326c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes } 203426c1b8df8d1af0d8ef7f6c726fe1a8a9ddc60267Bruno Cardoso Lopes 203509df2b066221d869f17f4b5762405f111a65f983Tim Northover if (BuiltinID == ARM::BI__builtin_arm_strex) { 203609df2b066221d869f17f4b5762405f111a65f983Tim Northover Value *StoreVal = EmitScalarExpr(E->getArg(0)); 203709df2b066221d869f17f4b5762405f111a65f983Tim Northover Value *StoreAddr = EmitScalarExpr(E->getArg(1)); 203809df2b066221d869f17f4b5762405f111a65f983Tim Northover 203909df2b066221d869f17f4b5762405f111a65f983Tim Northover QualType Ty = E->getArg(0)->getType(); 204009df2b066221d869f17f4b5762405f111a65f983Tim Northover llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(), 204109df2b066221d869f17f4b5762405f111a65f983Tim Northover getContext().getTypeSize(Ty)); 204209df2b066221d869f17f4b5762405f111a65f983Tim Northover StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo()); 204309df2b066221d869f17f4b5762405f111a65f983Tim Northover 204409df2b066221d869f17f4b5762405f111a65f983Tim Northover if (StoreVal->getType()->isPointerTy()) 204509df2b066221d869f17f4b5762405f111a65f983Tim Northover StoreVal = Builder.CreatePtrToInt(StoreVal, Int32Ty); 204609df2b066221d869f17f4b5762405f111a65f983Tim Northover else { 204709df2b066221d869f17f4b5762405f111a65f983Tim Northover StoreVal = Builder.CreateBitCast(StoreVal, StoreTy); 204809df2b066221d869f17f4b5762405f111a65f983Tim Northover StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int32Ty); 204909df2b066221d869f17f4b5762405f111a65f983Tim Northover } 205009df2b066221d869f17f4b5762405f111a65f983Tim Northover 205109df2b066221d869f17f4b5762405f111a65f983Tim Northover Function *F = CGM.getIntrinsic(Intrinsic::arm_strex, StoreAddr->getType()); 205209df2b066221d869f17f4b5762405f111a65f983Tim Northover return Builder.CreateCall2(F, StoreVal, StoreAddr, "strex"); 205309df2b066221d869f17f4b5762405f111a65f983Tim Northover } 205409df2b066221d869f17f4b5762405f111a65f983Tim Northover 205509df2b066221d869f17f4b5762405f111a65f983Tim Northover if (BuiltinID == ARM::BI__builtin_arm_clrex) { 205609df2b066221d869f17f4b5762405f111a65f983Tim Northover Function *F = CGM.getIntrinsic(Intrinsic::arm_clrex); 205709df2b066221d869f17f4b5762405f111a65f983Tim Northover return Builder.CreateCall(F); 205809df2b066221d869f17f4b5762405f111a65f983Tim Northover } 205909df2b066221d869f17f4b5762405f111a65f983Tim Northover 20605f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Value*, 4> Ops; 2061ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman llvm::Value *Align = 0; 2062ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) { 2063ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (i == 0) { 2064ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman switch (BuiltinID) { 2065ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1_v: 2066ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1q_v: 2067ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1q_lane_v: 2068ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1_lane_v: 2069ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1_dup_v: 2070ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld1q_dup_v: 2071ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst1_v: 2072ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst1q_v: 2073ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst1q_lane_v: 2074ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst1_lane_v: 2075ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst2_v: 2076ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst2q_v: 2077ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst2_lane_v: 2078ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst2q_lane_v: 2079ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst3_v: 2080ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst3q_v: 2081ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst3_lane_v: 2082ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst3q_lane_v: 2083ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst4_v: 2084ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst4q_v: 2085ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst4_lane_v: 2086ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vst4q_lane_v: 2087ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman // Get the alignment for the argument in addition to the value; 2088ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman // we'll use it later. 2089ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Src = 2090ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(0)); 2091ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Src.first); 2092ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Align = Builder.getInt32(Src.second); 2093ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman continue; 2094ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 2095ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 2096ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman if (i == 1) { 2097ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman switch (BuiltinID) { 2098ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld2_v: 2099ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld2q_v: 2100ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld3_v: 2101ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld3q_v: 2102ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld4_v: 2103ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld4q_v: 2104ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld2_lane_v: 2105ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld2q_lane_v: 2106ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld3_lane_v: 2107ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld3q_lane_v: 2108ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld4_lane_v: 2109ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld4q_lane_v: 2110ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld2_dup_v: 2111ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld3_dup_v: 2112ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman case ARM::BI__builtin_neon_vld4_dup_v: 2113ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman // Get the alignment for the argument in addition to the value; 2114ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman // we'll use it later. 2115ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman std::pair<llvm::Value*, unsigned> Src = 2116ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman EmitPointerWithAlignment(E->getArg(1)); 2117ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Src.first); 2118ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Align = Builder.getInt32(Src.second); 2119ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman continue; 2120ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 2121ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 2122e140af3e27016f902146023fba7680b43043ec07Rafael Espindola Ops.push_back(EmitScalarExpr(E->getArg(i))); 2123ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman } 2124e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 212583bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson // vget_lane and vset_lane are not overloaded and do not have an extra 212683bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson // argument that specifies the vector type. 212783bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson switch (BuiltinID) { 212883bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson default: break; 212983bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vget_lane_i8: 213083bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vget_lane_i16: 213183bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vget_lane_i32: 213283bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vget_lane_i64: 213383bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vget_lane_f32: 213483bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vgetq_lane_i8: 213583bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vgetq_lane_i16: 213683bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vgetq_lane_i32: 213783bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vgetq_lane_i64: 213883bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vgetq_lane_f32: 213983bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 214083bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson "vget_lane"); 214183bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vset_lane_i8: 214283bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vset_lane_i16: 214383bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vset_lane_i32: 214483bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vset_lane_i64: 214583bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vset_lane_f32: 214683bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vsetq_lane_i8: 214783bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vsetq_lane_i16: 214883bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vsetq_lane_i32: 214983bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vsetq_lane_i64: 215083bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson case ARM::BI__builtin_neon_vsetq_lane_f32: 215183bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson Ops.push_back(EmitScalarExpr(E->getArg(2))); 215283bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 215383bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson } 215483bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson 215583bbba1fc98dd3b2a351013a40808e995e648f40Bob Wilson // Get the last argument, which specifies the vector type. 2156e140af3e27016f902146023fba7680b43043ec07Rafael Espindola llvm::APSInt Result; 2157e140af3e27016f902146023fba7680b43043ec07Rafael Espindola const Expr *Arg = E->getArg(E->getNumArgs()-1); 2158e140af3e27016f902146023fba7680b43043ec07Rafael Espindola if (!Arg->isIntegerConstantExpr(Result, getContext())) 2159e140af3e27016f902146023fba7680b43043ec07Rafael Espindola return 0; 2160e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 216199c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f || 216299c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman BuiltinID == ARM::BI__builtin_arm_vcvtr_d) { 216399c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman // Determine the overloaded type of this builtin. 21649cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *Ty; 216599c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f) 21668b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner Ty = FloatTy; 216799c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman else 21688b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner Ty = DoubleTy; 2169258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 217099c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman // Determine whether this is an unsigned conversion or not. 217199c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman bool usgn = Result.getZExtValue() == 1; 217299c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman unsigned Int = usgn ? Intrinsic::arm_vcvtru : Intrinsic::arm_vcvtr; 217399c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman 217499c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman // Call the appropriate intrinsic. 21758dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Int, Ty); 21764c7d9f1507d0f102bd4133bba63348636facd469Jay Foad return Builder.CreateCall(F, Ops, "vcvtr"); 217799c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman } 2178258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 217999c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman // Determine the type of this overloaded NEON intrinsic. 2180da95f73b59f9af964e33725c515139d34c90c863Bob Wilson NeonTypeFlags Type(Result.getZExtValue()); 2181da95f73b59f9af964e33725c515139d34c90c863Bob Wilson bool usgn = Type.isUnsigned(); 2182da95f73b59f9af964e33725c515139d34c90c863Bob Wilson bool quad = Type.isQuad(); 21837965396d8d6ac23ec4c4f9d01d216f2e73d7fc72Bob Wilson bool rightShift = false; 2184e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 21858b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner llvm::VectorType *VTy = GetNeonType(this, Type); 21869cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *Ty = VTy; 2187e140af3e27016f902146023fba7680b43043ec07Rafael Espindola if (!Ty) 2188e140af3e27016f902146023fba7680b43043ec07Rafael Espindola return 0; 2189e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 2190e140af3e27016f902146023fba7680b43043ec07Rafael Espindola unsigned Int; 2191e140af3e27016f902146023fba7680b43043ec07Rafael Espindola switch (BuiltinID) { 2192e140af3e27016f902146023fba7680b43043ec07Rafael Espindola default: return 0; 21934c919eb0c022be30d6130446cb8d50a7e8da9f46Jim Grosbach case ARM::BI__builtin_neon_vbsl_v: 21944c919eb0c022be30d6130446cb8d50a7e8da9f46Jim Grosbach case ARM::BI__builtin_neon_vbslq_v: 21954c919eb0c022be30d6130446cb8d50a7e8da9f46Jim Grosbach return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vbsl, Ty), 21964c919eb0c022be30d6130446cb8d50a7e8da9f46Jim Grosbach Ops, "vbsl"); 2197537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vabd_v: 2198537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vabdq_v: 2199998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman Int = usgn ? Intrinsic::arm_neon_vabdu : Intrinsic::arm_neon_vabds; 22008dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vabd"); 2201537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vabs_v: 2202537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vabsq_v: 22038dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vabs, Ty), 2204548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vabs"); 2205537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vaddhn_v: 22068dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vaddhn, Ty), 2207548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vaddhn"); 2208537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcale_v: 22099eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman std::swap(Ops[0], Ops[1]); 2210537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcage_v: { 2211d185035263b98cdde75a869b26b5e5e2e6b13fdfBob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacged); 221230d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcage"); 221330d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 2214537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcaleq_v: 22159eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman std::swap(Ops[0], Ops[1]); 2216537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcageq_v: { 2217d185035263b98cdde75a869b26b5e5e2e6b13fdfBob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgeq); 221830d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcage"); 221930d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 2220537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcalt_v: 22219eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman std::swap(Ops[0], Ops[1]); 2222537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcagt_v: { 2223d185035263b98cdde75a869b26b5e5e2e6b13fdfBob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgtd); 222430d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcagt"); 222530d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 2226537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcaltq_v: 22279eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman std::swap(Ops[0], Ops[1]); 2228537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcagtq_v: { 2229d185035263b98cdde75a869b26b5e5e2e6b13fdfBob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgtq); 223030d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcagt"); 223130d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 2232537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcls_v: 2233537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vclsq_v: { 22348dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcls, Ty); 223530d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcls"); 22369eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 2237537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vclz_v: 2238537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vclzq_v: { 223971bcc68ba44a87a516d84461bc68475e43134338Eric Christopher // Generate target-independent intrinsic; also need to add second argument 224087d747b1fbf89aa0ba08cfc0e26655aa7739c77dJoel Jones // for whether or not clz of zero is undefined; on ARM it isn't. 224187d747b1fbf89aa0ba08cfc0e26655aa7739c77dJoel Jones Function *F = CGM.getIntrinsic(Intrinsic::ctlz, Ty); 224264aa4b3ec7e62288e2e66c1935487ece995ca94bJohn McCall Ops.push_back(Builder.getInt1(getTarget().isCLZForZeroUndef())); 224330d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vclz"); 22449eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 2245537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcnt_v: 2246537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcntq_v: { 22471638f2e8263df93b9fa055a12cc3f0968b9682d8Joel Jones // generate target-independent intrinsic 22481638f2e8263df93b9fa055a12cc3f0968b9682d8Joel Jones Function *F = CGM.getIntrinsic(Intrinsic::ctpop, Ty); 22491638f2e8263df93b9fa055a12cc3f0968b9682d8Joel Jones return EmitNeonCall(F, Ops, "vctpop"); 22509eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 2251537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_f16_v: { 2252da95f73b59f9af964e33725c515139d34c90c863Bob Wilson assert(Type.getEltType() == NeonTypeFlags::Float16 && !quad && 2253da95f73b59f9af964e33725c515139d34c90c863Bob Wilson "unexpected vcvt_f16_v builtin"); 225446e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcvtfp2hf); 225546e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson return EmitNeonCall(F, Ops, "vcvt"); 225646e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson } 2257537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_f32_f16: { 2258da95f73b59f9af964e33725c515139d34c90c863Bob Wilson assert(Type.getEltType() == NeonTypeFlags::Float16 && !quad && 2259da95f73b59f9af964e33725c515139d34c90c863Bob Wilson "unexpected vcvt_f32_f16 builtin"); 226046e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcvthf2fp); 226146e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson return EmitNeonCall(F, Ops, "vcvt"); 226246e392ae6d09979b087d7b1aca3b816ba4199b89Bob Wilson } 2263537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_f32_v: 2264da95f73b59f9af964e33725c515139d34c90c863Bob Wilson case ARM::BI__builtin_neon_vcvtq_f32_v: 226530d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 22668b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, quad)); 2267258f930227c1a102c9c22eee88df65f748863425Jim Grosbach return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") 22689eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); 2269537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_s32_v: 2270537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_u32_v: 2271537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvtq_s32_v: 2272537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvtq_u32_v: { 2273da95f73b59f9af964e33725c515139d34c90c863Bob Wilson llvm::Type *FloatTy = 22748b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, quad)); 2275da95f73b59f9af964e33725c515139d34c90c863Bob Wilson Ops[0] = Builder.CreateBitCast(Ops[0], FloatTy); 2276258f930227c1a102c9c22eee88df65f748863425Jim Grosbach return usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt") 22779eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman : Builder.CreateFPToSI(Ops[0], Ty, "vcvt"); 22789eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 2279537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_n_f32_v: 2280537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvtq_n_f32_v: { 2281da95f73b59f9af964e33725c515139d34c90c863Bob Wilson llvm::Type *FloatTy = 22828b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, quad)); 2283da95f73b59f9af964e33725c515139d34c90c863Bob Wilson llvm::Type *Tys[2] = { FloatTy, Ty }; 2284da95f73b59f9af964e33725c515139d34c90c863Bob Wilson Int = usgn ? Intrinsic::arm_neon_vcvtfxu2fp 2285da95f73b59f9af964e33725c515139d34c90c863Bob Wilson : Intrinsic::arm_neon_vcvtfxs2fp; 22868dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Int, Tys); 228730d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcvt_n"); 22889eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 2289537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_n_s32_v: 2290537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvt_n_u32_v: 2291537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvtq_n_s32_v: 2292537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vcvtq_n_u32_v: { 2293da95f73b59f9af964e33725c515139d34c90c863Bob Wilson llvm::Type *FloatTy = 22948b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, quad)); 2295da95f73b59f9af964e33725c515139d34c90c863Bob Wilson llvm::Type *Tys[2] = { Ty, FloatTy }; 2296da95f73b59f9af964e33725c515139d34c90c863Bob Wilson Int = usgn ? Intrinsic::arm_neon_vcvtfp2fxu 2297da95f73b59f9af964e33725c515139d34c90c863Bob Wilson : Intrinsic::arm_neon_vcvtfp2fxs; 22988dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Int, Tys); 229930d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcvt_n"); 230030d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 2301537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vext_v: 2302537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vextq_v: { 2303fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner int CV = cast<ConstantInt>(Ops[2])->getSExtValue(); 23041c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman SmallVector<Constant*, 16> Indices; 23054be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 230677b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Indices.push_back(ConstantInt::get(Int32Ty, i+CV)); 2307258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 230830d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 230930d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 2310fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner Value *SV = llvm::ConstantVector::get(Indices); 23111c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return Builder.CreateShuffleVector(Ops[0], Ops[1], SV, "vext"); 23121c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 2313537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vhadd_v: 2314537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vhaddq_v: 2315df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vhaddu : Intrinsic::arm_neon_vhadds; 23168dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vhadd"); 2317537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vhsub_v: 2318537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vhsubq_v: 2319df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vhsubu : Intrinsic::arm_neon_vhsubs; 23208dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vhsub"); 2321537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld1_v: 2322537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld1q_v: 2323ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 23248dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Ty), 23254be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops, "vld1"); 2326550a9d823a939366a9f776b58f18883acd905a93Bob Wilson case ARM::BI__builtin_neon_vld1q_lane_v: 2327550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // Handle 64-bit integer elements as a special case. Use shuffles of 2328550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // one-element vectors to avoid poor code for i64 in the backend. 2329550a9d823a939366a9f776b58f18883acd905a93Bob Wilson if (VTy->getElementType()->isIntegerTy(64)) { 2330550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // Extract the other lane. 2331550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 2332550a9d823a939366a9f776b58f18883acd905a93Bob Wilson int Lane = cast<ConstantInt>(Ops[2])->getZExtValue(); 2333550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Value *SV = llvm::ConstantVector::get(ConstantInt::get(Int32Ty, 1-Lane)); 2334550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); 2335550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // Load the value as a one-element vector. 2336550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ty = llvm::VectorType::get(VTy->getElementType(), 1); 2337550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Ty); 2338ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Value *Ld = Builder.CreateCall2(F, Ops[0], Align); 2339550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // Combine them. 2340550a9d823a939366a9f776b58f18883acd905a93Bob Wilson SmallVector<Constant*, 2> Indices; 2341550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Indices.push_back(ConstantInt::get(Int32Ty, 1-Lane)); 2342550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Indices.push_back(ConstantInt::get(Int32Ty, Lane)); 2343550a9d823a939366a9f776b58f18883acd905a93Bob Wilson SV = llvm::ConstantVector::get(Indices); 2344550a9d823a939366a9f776b58f18883acd905a93Bob Wilson return Builder.CreateShuffleVector(Ops[1], Ld, SV, "vld1q_lane"); 2345550a9d823a939366a9f776b58f18883acd905a93Bob Wilson } 2346550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // fall through 2347550a9d823a939366a9f776b58f18883acd905a93Bob Wilson case ARM::BI__builtin_neon_vld1_lane_v: { 23484be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 23494be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 23504be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2351eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson LoadInst *Ld = Builder.CreateLoad(Ops[0]); 2352eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); 2353eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson return Builder.CreateInsertElement(Ops[1], Ld, Ops[2], "vld1_lane"); 2354eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson } 2355537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld1_dup_v: 2356537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld1q_dup_v: { 23574be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *V = UndefValue::get(Ty); 23584be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 23594be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2360eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson LoadInst *Ld = Builder.CreateLoad(Ops[0]); 2361eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); 236277b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 2363eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson Ops[0] = Builder.CreateInsertElement(V, Ld, CI); 23644be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return EmitNeonSplat(Ops[0], CI); 23654be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 2366537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld2_v: 2367537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld2q_v: { 23688dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld2, Ty); 236906b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld2"); 23704be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 23714be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 23724be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 23734be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 2374537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3_v: 2375537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3q_v: { 23768dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld3, Ty); 237706b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld3"); 23784be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 23794be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 23804be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 23814be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 2382537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4_v: 2383537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4q_v: { 23848dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld4, Ty); 238506b6c589a5fff8e5476fe2b4cd6a660af71bfdddBob Wilson Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld4"); 23864be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 23874be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 23884be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 23894be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 2390537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld2_lane_v: 2391537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld2q_lane_v: { 23928dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld2lane, Ty); 23934be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 23944be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 2395ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 23961cbac8ac446cf513dbc7486dd50abd55bcfc62c6Frits van Bommel Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld2_lane"); 23974be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 23984be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 23994be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 24004be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 2401537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3_lane_v: 2402537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3q_lane_v: { 24038dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld3lane, Ty); 24044be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 24054be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 24064be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[4] = Builder.CreateBitCast(Ops[4], Ty); 2407ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 24081cbac8ac446cf513dbc7486dd50abd55bcfc62c6Frits van Bommel Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld3_lane"); 24094be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 24104be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 24114be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 24124be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 2413537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4_lane_v: 2414537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4q_lane_v: { 24158dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld4lane, Ty); 24164be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 24174be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 24184be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[4] = Builder.CreateBitCast(Ops[4], Ty); 24194be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[5] = Builder.CreateBitCast(Ops[5], Ty); 2420ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 24211cbac8ac446cf513dbc7486dd50abd55bcfc62c6Frits van Bommel Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld3_lane"); 24224be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 24234be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 24244be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 24254be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 2426537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld2_dup_v: 2427537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3_dup_v: 2428537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4_dup_v: { 2429a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson // Handle 64-bit elements as a special-case. There is no "dup" needed. 2430a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson if (VTy->getElementType()->getPrimitiveSizeInBits() == 64) { 2431a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson switch (BuiltinID) { 2432258f930227c1a102c9c22eee88df65f748863425Jim Grosbach case ARM::BI__builtin_neon_vld2_dup_v: 2433258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Int = Intrinsic::arm_neon_vld2; 2434a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson break; 2435537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3_dup_v: 2436258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Int = Intrinsic::arm_neon_vld3; 2437a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson break; 2438537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4_dup_v: 2439258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Int = Intrinsic::arm_neon_vld4; 2440a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson break; 2441b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("unknown vld_dup intrinsic?"); 2442a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson } 24438dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Int, Ty); 2444a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld_dup"); 2445a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 2446a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2447a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson return Builder.CreateStore(Ops[1], Ops[0]); 2448a0eb23b79aba48a8141daa4eb1aba66266b41abeBob Wilson } 24494be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman switch (BuiltinID) { 2450258f930227c1a102c9c22eee88df65f748863425Jim Grosbach case ARM::BI__builtin_neon_vld2_dup_v: 2451258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Int = Intrinsic::arm_neon_vld2lane; 24524be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman break; 2453537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld3_dup_v: 2454258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Int = Intrinsic::arm_neon_vld3lane; 24554be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman break; 2456537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vld4_dup_v: 2457258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Int = Intrinsic::arm_neon_vld4lane; 24584be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman break; 2459b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("unknown vld_dup intrinsic?"); 24604be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 24618dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer Function *F = CGM.getIntrinsic(Int, Ty); 24622acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::StructType *STy = cast<llvm::StructType>(F->getReturnType()); 2463258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 24644be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SmallVector<Value*, 6> Args; 24654be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Args.push_back(Ops[1]); 24664be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Args.append(STy->getNumElements(), UndefValue::get(Ty)); 24674be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 246877b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 24694be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Args.push_back(CI); 2470ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Args.push_back(Align); 2471258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 24724c7d9f1507d0f102bd4133bba63348636facd469Jay Foad Ops[1] = Builder.CreateCall(F, Args, "vld_dup"); 24734be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman // splat lane 0 to all elts in each vector of the result. 24744be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { 24754be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Val = Builder.CreateExtractValue(Ops[1], i); 24764be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Elt = Builder.CreateBitCast(Val, Ty); 24774be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Elt = EmitNeonSplat(Elt, CI); 24784be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Elt = Builder.CreateBitCast(Elt, Val->getType()); 24794be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[1] = Builder.CreateInsertValue(Ops[1], Elt, i); 24804be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 24814be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 24824be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 24834be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 24844be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 2485537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmax_v: 2486537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmaxq_v: 2487df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vmaxu : Intrinsic::arm_neon_vmaxs; 24888dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmax"); 2489537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmin_v: 2490537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vminq_v: 2491df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vminu : Intrinsic::arm_neon_vmins; 24928dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmin"); 2493537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmovl_v: { 24942acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *DTy =llvm::VectorType::getTruncatedElementVectorType(VTy); 24952235941293353325835d182da4470f61828fe789Bob Wilson Ops[0] = Builder.CreateBitCast(Ops[0], DTy); 24967cea322bf019b0d38867a27e20e3771d84dbb1afBob Wilson if (usgn) 24977cea322bf019b0d38867a27e20e3771d84dbb1afBob Wilson return Builder.CreateZExt(Ops[0], Ty, "vmovl"); 24987cea322bf019b0d38867a27e20e3771d84dbb1afBob Wilson return Builder.CreateSExt(Ops[0], Ty, "vmovl"); 24992235941293353325835d182da4470f61828fe789Bob Wilson } 2500537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmovn_v: { 25012acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *QTy = llvm::VectorType::getExtendedElementVectorType(VTy); 25022235941293353325835d182da4470f61828fe789Bob Wilson Ops[0] = Builder.CreateBitCast(Ops[0], QTy); 25033b6081bf49b7506cb96131247f209d1e03610df8Bob Wilson return Builder.CreateTrunc(Ops[0], Ty, "vmovn"); 25042235941293353325835d182da4470f61828fe789Bob Wilson } 2505537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmul_v: 2506537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmulq_v: 2507da95f73b59f9af964e33725c515139d34c90c863Bob Wilson assert(Type.isPoly() && "vmul builtin only supported for polynomial types"); 25088dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vmulp, Ty), 2509953d513c7ee79b3d9e37597e64317e75c0fbf7f6Bob Wilson Ops, "vmul"); 2510537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vmull_v: 25112d33e423d5091b7d2cb8618952752abd55bba965Bob Wilson Int = usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls; 2512da95f73b59f9af964e33725c515139d34c90c863Bob Wilson Int = Type.isPoly() ? (unsigned)Intrinsic::arm_neon_vmullp : Int; 25138dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull"); 251402262662b4550d0227038470f2d7b3db7ada2b87Bob Wilson case ARM::BI__builtin_neon_vfma_v: 251502262662b4550d0227038470f2d7b3db7ada2b87Bob Wilson case ARM::BI__builtin_neon_vfmaq_v: { 251602262662b4550d0227038470f2d7b3db7ada2b87Bob Wilson Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 251702262662b4550d0227038470f2d7b3db7ada2b87Bob Wilson Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 251802262662b4550d0227038470f2d7b3db7ada2b87Bob Wilson Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 251902262662b4550d0227038470f2d7b3db7ada2b87Bob Wilson Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 2520c4a04010f676ce9ff0049b0fc5d1f96a2dbe81beTim Northover 2521c4a04010f676ce9ff0049b0fc5d1f96a2dbe81beTim Northover // NEON intrinsic puts accumulator first, unlike the LLVM fma. 2522c4a04010f676ce9ff0049b0fc5d1f96a2dbe81beTim Northover return Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]); 252302262662b4550d0227038470f2d7b3db7ada2b87Bob Wilson } 2524537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpadal_v: 2525537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpadalq_v: { 2526df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vpadalu : Intrinsic::arm_neon_vpadals; 2527c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson // The source operand type has twice as many elements of half the size. 2528c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 25292acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *EltTy = 2530d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::IntegerType::get(getLLVMContext(), EltBits / 2); 25319cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *NarrowTy = 2532c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); 25339cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *Tys[2] = { Ty, NarrowTy }; 25348dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vpadal"); 2535c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson } 2536537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpadd_v: 25378dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vpadd, Ty), 2538548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vpadd"); 2539537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpaddl_v: 2540537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpaddlq_v: { 2541548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vpaddlu : Intrinsic::arm_neon_vpaddls; 2542c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson // The source operand type has twice as many elements of half the size. 2543c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 25442acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *EltTy = llvm::IntegerType::get(getLLVMContext(), EltBits / 2); 25459cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *NarrowTy = 2546c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); 25479cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *Tys[2] = { Ty, NarrowTy }; 25488dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vpaddl"); 2549c1fa01b69d9377a69087a6006a65a8fcc526d565Bob Wilson } 2550537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpmax_v: 2551548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vpmaxu : Intrinsic::arm_neon_vpmaxs; 25528dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmax"); 2553537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vpmin_v: 2554548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vpminu : Intrinsic::arm_neon_vpmins; 25558dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmin"); 2556537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqabs_v: 2557537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqabsq_v: 25588dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqabs, Ty), 2559548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vqabs"); 2560537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqadd_v: 2561537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqaddq_v: 2562548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vqaddu : Intrinsic::arm_neon_vqadds; 25638dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqadd"); 2564537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqdmlal_v: 25658dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmlal, Ty), 2566db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqdmlal"); 2567537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqdmlsl_v: 25688dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmlsl, Ty), 2569db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqdmlsl"); 2570537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqdmulh_v: 2571537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqdmulhq_v: 25728dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmulh, Ty), 2573db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqdmulh"); 2574537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqdmull_v: 25758dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmull, Ty), 2576db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqdmull"); 2577537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqmovn_v: 2578548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vqmovnu : Intrinsic::arm_neon_vqmovns; 25798dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqmovn"); 2580537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqmovun_v: 25818dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqmovnsu, Ty), 2582548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vqdmull"); 2583537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqneg_v: 2584537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqnegq_v: 25858dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqneg, Ty), 258661eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops, "vqneg"); 2587537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrdmulh_v: 2588537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrdmulhq_v: 25898dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrdmulh, Ty), 2590db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqrdmulh"); 2591537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrshl_v: 2592537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrshlq_v: 2593548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vqrshiftu : Intrinsic::arm_neon_vqrshifts; 25948dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshl"); 2595537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrshrn_n_v: 2596258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Int = 2597258f930227c1a102c9c22eee88df65f748863425Jim Grosbach usgn ? Intrinsic::arm_neon_vqrshiftnu : Intrinsic::arm_neon_vqrshiftns; 25988dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n", 259961eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman 1, true); 2600537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqrshrun_n_v: 26018dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrshiftnsu, Ty), 2602db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqrshrun_n", 1, true); 2603537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshl_v: 2604537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshlq_v: 260561eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Int = usgn ? Intrinsic::arm_neon_vqshiftu : Intrinsic::arm_neon_vqshifts; 26068dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshl"); 2607537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshl_n_v: 2608537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshlq_n_v: 260961eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Int = usgn ? Intrinsic::arm_neon_vqshiftu : Intrinsic::arm_neon_vqshifts; 26108dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshl_n", 261161eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman 1, false); 2612537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshlu_n_v: 2613537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshluq_n_v: 26148dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftsu, Ty), 2615db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqshlu", 1, false); 2616537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshrn_n_v: 261761eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Int = usgn ? Intrinsic::arm_neon_vqshiftnu : Intrinsic::arm_neon_vqshiftns; 26188dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n", 261961eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman 1, true); 2620537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqshrun_n_v: 26218dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftnsu, Ty), 2622db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vqshrun_n", 1, true); 2623537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqsub_v: 2624537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vqsubq_v: 2625464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Int = usgn ? Intrinsic::arm_neon_vqsubu : Intrinsic::arm_neon_vqsubs; 26268dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqsub"); 2627537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vraddhn_v: 26288dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vraddhn, Ty), 2629464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vraddhn"); 2630537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrecpe_v: 2631537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrecpeq_v: 26328dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecpe, Ty), 2633464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vrecpe"); 2634537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrecps_v: 2635537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrecpsq_v: 26368dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecps, Ty), 2637464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vrecps"); 2638537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrhadd_v: 2639537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrhaddq_v: 2640464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Int = usgn ? Intrinsic::arm_neon_vrhaddu : Intrinsic::arm_neon_vrhadds; 26418dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrhadd"); 2642537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrshl_v: 2643537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrshlq_v: 26445af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 26458dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshl"); 2646537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrshrn_n_v: 26478dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrshiftn, Ty), 2648db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vrshrn_n", 1, true); 2649537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrshr_n_v: 2650537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrshrq_n_v: 26515af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 26528dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshr_n", 1, true); 2653537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsqrte_v: 2654537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsqrteq_v: 26558dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsqrte, Ty), 26565af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops, "vrsqrte"); 2657537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsqrts_v: 2658537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsqrtsq_v: 26598dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsqrts, Ty), 26605af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops, "vrsqrts"); 2661537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsra_n_v: 2662537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsraq_n_v: 26635af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 26645af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 26655af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops[2] = EmitNeonShiftVector(Ops[2], Ty, true); 26665af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 2667258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Ops[1] = Builder.CreateCall2(CGM.getIntrinsic(Int, Ty), Ops[1], Ops[2]); 26685af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n"); 2669537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vrsubhn_v: 26708dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsubhn, Ty), 2671464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vrsubhn"); 2672537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshl_v: 2673537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshlq_v: 2674464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Int = usgn ? Intrinsic::arm_neon_vshiftu : Intrinsic::arm_neon_vshifts; 26758dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vshl"); 2676537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshll_n_v: 2677464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Int = usgn ? Intrinsic::arm_neon_vshiftlu : Intrinsic::arm_neon_vshiftls; 26788dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vshll", 1); 2679537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshl_n_v: 2680537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshlq_n_v: 268161eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false); 2682258f930227c1a102c9c22eee88df65f748863425Jim Grosbach return Builder.CreateShl(Builder.CreateBitCast(Ops[0],Ty), Ops[1], 2683258f930227c1a102c9c22eee88df65f748863425Jim Grosbach "vshl_n"); 2684537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshrn_n_v: 26858dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftn, Ty), 2686db3d4d036037f379f12643e067b229862d61e932Bob Wilson Ops, "vshrn_n", 1, true); 2687537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshr_n_v: 2688537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vshrq_n_v: 2689464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 269061eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false); 2691464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman if (usgn) 2692464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return Builder.CreateLShr(Ops[0], Ops[1], "vshr_n"); 2693464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman else 2694464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return Builder.CreateAShr(Ops[0], Ops[1], "vshr_n"); 2695537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsri_n_v: 2696537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsriq_n_v: 26977965396d8d6ac23ec4c4f9d01d216f2e73d7fc72Bob Wilson rightShift = true; 2698537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsli_n_v: 2699537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsliq_n_v: 27007965396d8d6ac23ec4c4f9d01d216f2e73d7fc72Bob Wilson Ops[2] = EmitNeonShiftVector(Ops[2], Ty, rightShift); 27018dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftins, Ty), 2702464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vsli_n"); 2703537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsra_n_v: 2704537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsraq_n_v: 2705464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2706464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 270761eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[2] = EmitNeonShiftVector(Ops[2], Ty, false); 2708464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman if (usgn) 2709464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateLShr(Ops[1], Ops[2], "vsra_n"); 2710464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman else 2711464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateAShr(Ops[1], Ops[2], "vsra_n"); 2712464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return Builder.CreateAdd(Ops[0], Ops[1]); 2713537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst1_v: 2714537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst1q_v: 2715ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 27168dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, Ty), 2717464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2718550a9d823a939366a9f776b58f18883acd905a93Bob Wilson case ARM::BI__builtin_neon_vst1q_lane_v: 2719550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // Handle 64-bit integer elements as a special case. Use a shuffle to get 2720550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // a one-element vector and avoid poor code for i64 in the backend. 2721550a9d823a939366a9f776b58f18883acd905a93Bob Wilson if (VTy->getElementType()->isIntegerTy(64)) { 2722550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 2723550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Value *SV = llvm::ConstantVector::get(cast<llvm::Constant>(Ops[2])); 2724550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); 2725ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops[2] = Align; 2726550a9d823a939366a9f776b58f18883acd905a93Bob Wilson return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, 2727550a9d823a939366a9f776b58f18883acd905a93Bob Wilson Ops[1]->getType()), Ops); 2728550a9d823a939366a9f776b58f18883acd905a93Bob Wilson } 2729550a9d823a939366a9f776b58f18883acd905a93Bob Wilson // fall through 2730550a9d823a939366a9f776b58f18883acd905a93Bob Wilson case ARM::BI__builtin_neon_vst1_lane_v: { 2731464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 2732464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); 2733464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 2734eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson StoreInst *St = Builder.CreateStore(Ops[1], 2735eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson Builder.CreateBitCast(Ops[0], Ty)); 2736eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson St->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); 2737eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson return St; 2738eac1f6746a2915fea3ed42284b07e274c0095a95Bob Wilson } 2739537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst2_v: 2740537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst2q_v: 2741ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 27428dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst2, Ty), 2743464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2744537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst2_lane_v: 2745537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst2q_lane_v: 2746ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 27478dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst2lane, Ty), 2748464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2749537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst3_v: 2750537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst3q_v: 2751ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 27528dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst3, Ty), 2753464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2754537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst3_lane_v: 2755537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst3q_lane_v: 2756ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 27578dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst3lane, Ty), 2758464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2759537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst4_v: 2760537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst4q_v: 2761ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 27628dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst4, Ty), 2763464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2764537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst4_lane_v: 2765537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vst4q_lane_v: 2766ea93e40785ffeadfac66b948c95f9490ec26207aEli Friedman Ops.push_back(Align); 27678dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst4lane, Ty), 2768464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 2769537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vsubhn_v: 27708dd55a3c3b28d195717c87bbc60e765951d408feBenjamin Kramer return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vsubhn, Ty), 2771548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vsubhn"); 2772537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbl1_v: 27731c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl1), 27741c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbl1"); 2775537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbl2_v: 27761c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl2), 27771c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbl2"); 2778537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbl3_v: 27791c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl3), 27801c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbl3"); 2781537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbl4_v: 27821c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl4), 27831c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbl4"); 2784537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbx1_v: 27851c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx1), 27861c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbx1"); 2787537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbx2_v: 27881c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx2), 27891c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbx2"); 2790537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbx3_v: 27911c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx3), 27921c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbx3"); 2793537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtbx4_v: 27941c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx4), 27951c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbx4"); 2796537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtst_v: 2797537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtstq_v: { 27981c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 27991c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 28001c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]); 2801258f930227c1a102c9c22eee88df65f748863425Jim Grosbach Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0], 28021c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman ConstantAggregateZero::get(Ty)); 28031c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return Builder.CreateSExt(Ops[0], Ty, "vtst"); 28041c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 2805537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtrn_v: 2806537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vtrnq_v: { 28074be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 28084be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 28094be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 28109577abc63f2c7afe5adf6e4e101ae91d29c3b8a6Ted Kremenek Value *SV = 0; 28114be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 28121c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman for (unsigned vi = 0; vi != 2; ++vi) { 28134be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SmallVector<Constant*, 16> Indices; 28144be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 28152ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner Indices.push_back(Builder.getInt32(i+vi)); 28162ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner Indices.push_back(Builder.getInt32(i+e+vi)); 28171c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 28184be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi); 2819fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner SV = llvm::ConstantVector::get(Indices); 28204be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vtrn"); 28214be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateStore(SV, Addr); 28221c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 28234be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return SV; 28241c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 2825537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vuzp_v: 2826537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vuzpq_v: { 28274be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 28281c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 28294be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 28309577abc63f2c7afe5adf6e4e101ae91d29c3b8a6Ted Kremenek Value *SV = 0; 2831258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 28324be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned vi = 0; vi != 2; ++vi) { 28334be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SmallVector<Constant*, 16> Indices; 28344be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 283577b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Indices.push_back(ConstantInt::get(Int32Ty, 2*i+vi)); 28364be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 28374be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi); 2838fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner SV = llvm::ConstantVector::get(Indices); 28394be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vuzp"); 28404be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateStore(SV, Addr); 28414be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 28424be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return SV; 28431c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 2844258f930227c1a102c9c22eee88df65f748863425Jim Grosbach case ARM::BI__builtin_neon_vzip_v: 2845537c3461166ce074d05fb7c96ffa98ed54c9aaa0Bob Wilson case ARM::BI__builtin_neon_vzipq_v: { 28464be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 28471c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 28484be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 28499577abc63f2c7afe5adf6e4e101ae91d29c3b8a6Ted Kremenek Value *SV = 0; 2850258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 28514be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned vi = 0; vi != 2; ++vi) { 28524be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SmallVector<Constant*, 16> Indices; 28534be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 2854e361cc3daa6c22e4413d48bd8b8934ea9fd5a55fDaniel Dunbar Indices.push_back(ConstantInt::get(Int32Ty, (i + vi*e) >> 1)); 2855e361cc3daa6c22e4413d48bd8b8934ea9fd5a55fDaniel Dunbar Indices.push_back(ConstantInt::get(Int32Ty, ((i + vi*e) >> 1)+e)); 28564be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 28574be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi); 2858fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner SV = llvm::ConstantVector::get(Indices); 28594be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vzip"); 28604be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateStore(SV, Addr); 28614be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 28624be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return SV; 28639eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 28642752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner } 28652752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner} 28662752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner 2867aa51e513850688b7963efc62abf1eface7037602Bill Wendlingllvm::Value *CodeGenFunction:: 2868795b10062c2eaffae9e04241fb1a73cdbcb24a37Bill WendlingBuildVector(ArrayRef<llvm::Value*> Ops) { 2869aa51e513850688b7963efc62abf1eface7037602Bill Wendling assert((Ops.size() & (Ops.size() - 1)) == 0 && 2870aa51e513850688b7963efc62abf1eface7037602Bill Wendling "Not a power-of-two sized vector!"); 2871aa51e513850688b7963efc62abf1eface7037602Bill Wendling bool AllConstants = true; 2872aa51e513850688b7963efc62abf1eface7037602Bill Wendling for (unsigned i = 0, e = Ops.size(); i != e && AllConstants; ++i) 2873aa51e513850688b7963efc62abf1eface7037602Bill Wendling AllConstants &= isa<Constant>(Ops[i]); 2874aa51e513850688b7963efc62abf1eface7037602Bill Wendling 2875aa51e513850688b7963efc62abf1eface7037602Bill Wendling // If this is a constant vector, create a ConstantVector. 2876aa51e513850688b7963efc62abf1eface7037602Bill Wendling if (AllConstants) { 28772ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner SmallVector<llvm::Constant*, 16> CstOps; 2878aa51e513850688b7963efc62abf1eface7037602Bill Wendling for (unsigned i = 0, e = Ops.size(); i != e; ++i) 2879aa51e513850688b7963efc62abf1eface7037602Bill Wendling CstOps.push_back(cast<Constant>(Ops[i])); 2880aa51e513850688b7963efc62abf1eface7037602Bill Wendling return llvm::ConstantVector::get(CstOps); 2881aa51e513850688b7963efc62abf1eface7037602Bill Wendling } 2882aa51e513850688b7963efc62abf1eface7037602Bill Wendling 2883aa51e513850688b7963efc62abf1eface7037602Bill Wendling // Otherwise, insertelement the values to build the vector. 2884aa51e513850688b7963efc62abf1eface7037602Bill Wendling Value *Result = 2885aa51e513850688b7963efc62abf1eface7037602Bill Wendling llvm::UndefValue::get(llvm::VectorType::get(Ops[0]->getType(), Ops.size())); 2886aa51e513850688b7963efc62abf1eface7037602Bill Wendling 2887aa51e513850688b7963efc62abf1eface7037602Bill Wendling for (unsigned i = 0, e = Ops.size(); i != e; ++i) 28882ce8842641cc312628c4be836d34eb250e7c3f78Chris Lattner Result = Builder.CreateInsertElement(Result, Ops[i], Builder.getInt32(i)); 2889aa51e513850688b7963efc62abf1eface7037602Bill Wendling 2890aa51e513850688b7963efc62abf1eface7037602Bill Wendling return Result; 2891aa51e513850688b7963efc62abf1eface7037602Bill Wendling} 2892aa51e513850688b7963efc62abf1eface7037602Bill Wendling 28931eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpValue *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, 28941feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner const CallExpr *E) { 28955f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Value*, 4> Ops; 28962929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson 289746c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // Find out if any arguments are required to be integer constant expressions. 289846c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner unsigned ICEArguments = 0; 289946c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner ASTContext::GetBuiltinTypeError Error; 290046c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 290146c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner assert(Error == ASTContext::GE_None && "Should not codegen an error"); 290246c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner 290346c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) { 290446c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // If this is a normal argument, just emit it as a scalar. 290546c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner if ((ICEArguments & (1 << i)) == 0) { 290646c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner Ops.push_back(EmitScalarExpr(E->getArg(i))); 290746c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner continue; 290846c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner } 290946c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner 291046c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // If this is required to be a constant, constant fold it so that we know 291146c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner // that the generated intrinsic gets a ConstantInt. 291246c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner llvm::APSInt Result; 291346c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext()); 291446c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst; 2915d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result)); 291646c5591f0fa2e35367e44234e59bb041d15b778eChris Lattner } 29172929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson 2918564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson switch (BuiltinID) { 291946a26b0b0e2ec1557bad9b70e8e20836524ebdfcAnders Carlsson default: return 0; 2920aa51e513850688b7963efc62abf1eface7037602Bill Wendling case X86::BI__builtin_ia32_vec_init_v8qi: 2921aa51e513850688b7963efc62abf1eface7037602Bill Wendling case X86::BI__builtin_ia32_vec_init_v4hi: 2922aa51e513850688b7963efc62abf1eface7037602Bill Wendling case X86::BI__builtin_ia32_vec_init_v2si: 2923aa51e513850688b7963efc62abf1eface7037602Bill Wendling return Builder.CreateBitCast(BuildVector(Ops), 2924d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::Type::getX86_MMXTy(getLLVMContext())); 29251944ec188408aff1931c62c79a069e30f2549ec2Argyrios Kyrtzidis case X86::BI__builtin_ia32_vec_ext_v2si: 29261944ec188408aff1931c62c79a069e30f2549ec2Argyrios Kyrtzidis return Builder.CreateExtractElement(Ops[0], 29271944ec188408aff1931c62c79a069e30f2549ec2Argyrios Kyrtzidis llvm::ConstantInt::get(Ops[1]->getType(), 0)); 2928e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_ldmxcsr: { 29293fc779191ce87cddf603e0c5bdbd225611201ff4Juergen Ributzka Value *Tmp = CreateMemTemp(E->getArg(0)->getType()); 2930e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Builder.CreateStore(Ops[0], Tmp); 2931e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr), 29323fc779191ce87cddf603e0c5bdbd225611201ff4Juergen Ributzka Builder.CreateBitCast(Tmp, Int8PtrTy)); 2933e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 2934e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_stmxcsr: { 2935fe0af454943374758309a1066e3304b3a56af04eJuergen Ributzka Value *Tmp = CreateMemTemp(E->getType()); 2936012614ecf78442368ec82ee30efb3bc047b413e6Ted Kremenek Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr), 29373fc779191ce87cddf603e0c5bdbd225611201ff4Juergen Ributzka Builder.CreateBitCast(Tmp, Int8PtrTy)); 2938e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman return Builder.CreateLoad(Tmp, "stmxcsr"); 2939e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 2940e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_storehps: 2941e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_storelps: { 294277b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Type *PtrTy = llvm::PointerType::getUnqual(Int64Ty); 294377b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2); 29441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2945e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman // cast val v2i64 2946e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast"); 29471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2948e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman // extract (0, 1) 2949e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1; 295077b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Value *Idx = llvm::ConstantInt::get(Int32Ty, Index); 2951e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract"); 2952e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman 2953e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman // cast pointer to i64 & store 2954e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy); 2955e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 2956e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 295728cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling case X86::BI__builtin_ia32_palignr: { 295828cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 2959258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 296028cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // If palignr is shifting the pair of input vectors less than 9 bytes, 296128cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // emit a shuffle instruction. 296228cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling if (shiftVal <= 8) { 29635f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Constant*, 8> Indices; 296428cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling for (unsigned i = 0; i != 8; ++i) 296528cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling Indices.push_back(llvm::ConstantInt::get(Int32Ty, shiftVal + i)); 2966258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 2967fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner Value* SV = llvm::ConstantVector::get(Indices); 296828cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 296928cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling } 2970258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 297128cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // If palignr is shifting the pair of input vectors more than 8 but less 297228cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // than 16 bytes, emit a logical right shift of the destination. 297328cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling if (shiftVal < 16) { 297428cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // MMX has these as 1 x i64 vectors for some odd optimization reasons. 29752acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 1); 2976258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 297728cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 297828cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling Ops[1] = llvm::ConstantInt::get(VecTy, (shiftVal-8) * 8); 2979258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 298028cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling // create i32 constant 298128cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_mmx_psrl_q); 2982e9c0265d6e6b5bf865f4a0c2c00d00ac251e6437Frits van Bommel return Builder.CreateCall(F, makeArrayRef(&Ops[0], 2), "palignr"); 298328cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling } 2984258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 29855c22ad2ef6bf39da22d5190025e0ddfd4b568b2aEli Friedman // If palignr is shifting the pair of vectors more than 16 bytes, emit zero. 298628cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling return llvm::Constant::getNullValue(ConvertType(E->getType())); 298728cab383fd9e7647d2186340eca769303cc4fbdbBill Wendling } 2988c3420ffb282c6ffc0192013bf8045b6c21eddeceNate Begeman case X86::BI__builtin_ia32_palignr128: { 2989ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 2990258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 2991ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // If palignr is shifting the pair of input vectors less than 17 bytes, 2992ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // emit a shuffle instruction. 2993ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman if (shiftVal <= 16) { 29945f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Constant*, 16> Indices; 2995ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman for (unsigned i = 0; i != 16; ++i) 299677b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Indices.push_back(llvm::ConstantInt::get(Int32Ty, shiftVal + i)); 2997258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 2998fb018d153cbf12fd2a4a278cbf7614b9a2e2835eChris Lattner Value* SV = llvm::ConstantVector::get(Indices); 2999ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 3000ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman } 3001258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 3002ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // If palignr is shifting the pair of input vectors more than 16 but less 3003ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // than 32 bytes, emit a logical right shift of the destination. 3004ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman if (shiftVal < 32) { 30052acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2); 3006258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 3007ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 300877b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Ops[1] = llvm::ConstantInt::get(Int32Ty, (shiftVal-16) * 8); 3009258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 3010ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // create i32 constant 3011ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_psrl_dq); 3012e9c0265d6e6b5bf865f4a0c2c00d00ac251e6437Frits van Bommel return Builder.CreateCall(F, makeArrayRef(&Ops[0], 2), "palignr"); 3013ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman } 3014258f930227c1a102c9c22eee88df65f748863425Jim Grosbach 3015ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 3016ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman return llvm::Constant::getNullValue(ConvertType(E->getType())); 301791b59274439f776cdd545bd7bf5849fdb1842160Eric Christopher } 30189c2ffd803af03f1728423d0d73ff87d988642633Craig Topper case X86::BI__builtin_ia32_palignr256: { 30199c2ffd803af03f1728423d0d73ff87d988642633Craig Topper unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 30209c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 30219c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // If palignr is shifting the pair of input vectors less than 17 bytes, 30229c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // emit a shuffle instruction. 30239c2ffd803af03f1728423d0d73ff87d988642633Craig Topper if (shiftVal <= 16) { 30249c2ffd803af03f1728423d0d73ff87d988642633Craig Topper SmallVector<llvm::Constant*, 32> Indices; 30259c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // 256-bit palignr operates on 128-bit lanes so we need to handle that 30269c2ffd803af03f1728423d0d73ff87d988642633Craig Topper for (unsigned l = 0; l != 2; ++l) { 30279c2ffd803af03f1728423d0d73ff87d988642633Craig Topper unsigned LaneStart = l * 16; 30289c2ffd803af03f1728423d0d73ff87d988642633Craig Topper unsigned LaneEnd = (l+1) * 16; 30299c2ffd803af03f1728423d0d73ff87d988642633Craig Topper for (unsigned i = 0; i != 16; ++i) { 30309c2ffd803af03f1728423d0d73ff87d988642633Craig Topper unsigned Idx = shiftVal + i + LaneStart; 30319c2ffd803af03f1728423d0d73ff87d988642633Craig Topper if (Idx >= LaneEnd) Idx += 16; // end of lane, switch operand 30329c2ffd803af03f1728423d0d73ff87d988642633Craig Topper Indices.push_back(llvm::ConstantInt::get(Int32Ty, Idx)); 30339c2ffd803af03f1728423d0d73ff87d988642633Craig Topper } 30349c2ffd803af03f1728423d0d73ff87d988642633Craig Topper } 30359c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 30369c2ffd803af03f1728423d0d73ff87d988642633Craig Topper Value* SV = llvm::ConstantVector::get(Indices); 30379c2ffd803af03f1728423d0d73ff87d988642633Craig Topper return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 30389c2ffd803af03f1728423d0d73ff87d988642633Craig Topper } 30399c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 30409c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // If palignr is shifting the pair of input vectors more than 16 but less 30419c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // than 32 bytes, emit a logical right shift of the destination. 30429c2ffd803af03f1728423d0d73ff87d988642633Craig Topper if (shiftVal < 32) { 30439c2ffd803af03f1728423d0d73ff87d988642633Craig Topper llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 4); 30449c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 30459c2ffd803af03f1728423d0d73ff87d988642633Craig Topper Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 30469c2ffd803af03f1728423d0d73ff87d988642633Craig Topper Ops[1] = llvm::ConstantInt::get(Int32Ty, (shiftVal-16) * 8); 30479c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 30489c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // create i32 constant 30499c2ffd803af03f1728423d0d73ff87d988642633Craig Topper llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_avx2_psrl_dq); 30509c2ffd803af03f1728423d0d73ff87d988642633Craig Topper return Builder.CreateCall(F, makeArrayRef(&Ops[0], 2), "palignr"); 30519c2ffd803af03f1728423d0d73ff87d988642633Craig Topper } 30529c2ffd803af03f1728423d0d73ff87d988642633Craig Topper 30539c2ffd803af03f1728423d0d73ff87d988642633Craig Topper // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 30549c2ffd803af03f1728423d0d73ff87d988642633Craig Topper return llvm::Constant::getNullValue(ConvertType(E->getType())); 30559c2ffd803af03f1728423d0d73ff87d988642633Craig Topper } 3056b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling case X86::BI__builtin_ia32_movntps: 30574a7376d00df98cbfcad29ee709637707a2f3d46cCraig Topper case X86::BI__builtin_ia32_movntps256: 3058b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling case X86::BI__builtin_ia32_movntpd: 30594a7376d00df98cbfcad29ee709637707a2f3d46cCraig Topper case X86::BI__builtin_ia32_movntpd256: 3060b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling case X86::BI__builtin_ia32_movntdq: 30614a7376d00df98cbfcad29ee709637707a2f3d46cCraig Topper case X86::BI__builtin_ia32_movntdq256: 3062b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling case X86::BI__builtin_ia32_movnti: { 3063b107dd02f5e365f60b036b8a27c784f2d0d0a855Bill Wendling llvm::MDNode *Node = llvm::MDNode::get(getLLVMContext(), 3064b107dd02f5e365f60b036b8a27c784f2d0d0a855Bill Wendling Builder.getInt32(1)); 3065b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling 3066b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling // Convert the type of the pointer to a pointer to the stored type. 3067b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling Value *BC = Builder.CreateBitCast(Ops[0], 3068b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling llvm::PointerType::getUnqual(Ops[1]->getType()), 3069b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling "cast"); 3070b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling StoreInst *SI = Builder.CreateStore(Ops[1], BC); 3071b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling SI->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); 3072b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling SI->setAlignment(16); 3073b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling return SI; 3074b51bddab211ba7daa8832c017d82281e0d8348d1Bill Wendling } 30758b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer // 3DNow! 30768b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer case X86::BI__builtin_ia32_pswapdsf: 30778b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer case X86::BI__builtin_ia32_pswapdsi: { 30788b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer const char *name = 0; 30798b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer Intrinsic::ID ID = Intrinsic::not_intrinsic; 30808b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer switch(BuiltinID) { 3081f8495d67ca4dd2ea15a4dc59e9a2fa32a9bfa475Craig Topper default: llvm_unreachable("Unsupported intrinsic!"); 30828b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer case X86::BI__builtin_ia32_pswapdsf: 30838b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer case X86::BI__builtin_ia32_pswapdsi: 30848b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer name = "pswapd"; 30858b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer ID = Intrinsic::x86_3dnowa_pswapd; 30868b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer break; 30878b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer } 3088345032a7211a6f983d59c30c0b3fa2b96819532aChandler Carruth llvm::Type *MMXTy = llvm::Type::getX86_MMXTy(getLLVMContext()); 3089345032a7211a6f983d59c30c0b3fa2b96819532aChandler Carruth Ops[0] = Builder.CreateBitCast(Ops[0], MMXTy, "cast"); 30908b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer llvm::Function *F = CGM.getIntrinsic(ID); 30914c7d9f1507d0f102bd4133bba63348636facd469Jay Foad return Builder.CreateCall(F, Ops, name); 30928b36a9ee7fe7204b30a85b95b11850aeb4b63ee3Michael J. Spencer } 30939a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer case X86::BI__builtin_ia32_rdrand16_step: 30949a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer case X86::BI__builtin_ia32_rdrand32_step: 30951bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao case X86::BI__builtin_ia32_rdrand64_step: 30961bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao case X86::BI__builtin_ia32_rdseed16_step: 30971bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao case X86::BI__builtin_ia32_rdseed32_step: 30981bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao case X86::BI__builtin_ia32_rdseed64_step: { 30999a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer Intrinsic::ID ID; 31009a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer switch (BuiltinID) { 31019a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer default: llvm_unreachable("Unsupported intrinsic!"); 31029a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer case X86::BI__builtin_ia32_rdrand16_step: 31039a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer ID = Intrinsic::x86_rdrand_16; 31049a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer break; 31059a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer case X86::BI__builtin_ia32_rdrand32_step: 31069a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer ID = Intrinsic::x86_rdrand_32; 31079a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer break; 31089a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer case X86::BI__builtin_ia32_rdrand64_step: 31099a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer ID = Intrinsic::x86_rdrand_64; 31109a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer break; 31111bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao case X86::BI__builtin_ia32_rdseed16_step: 31121bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao ID = Intrinsic::x86_rdseed_16; 31131bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao break; 31141bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao case X86::BI__builtin_ia32_rdseed32_step: 31151bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao ID = Intrinsic::x86_rdseed_32; 31161bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao break; 31171bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao case X86::BI__builtin_ia32_rdseed64_step: 31181bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao ID = Intrinsic::x86_rdseed_64; 31191bfc28c48c1b86a05d2e07b403107ef3da5a0f8eMichael Liao break; 31209a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer } 31219a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer 31229a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer Value *Call = Builder.CreateCall(CGM.getIntrinsic(ID)); 31239a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer Builder.CreateStore(Builder.CreateExtractValue(Call, 0), Ops[0]); 31249a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer return Builder.CreateExtractValue(Call, 1); 31259a50249cd35f3d9d4d2b194a3edd6815ccf746d7Benjamin Kramer } 31262766deb114cc5d3420027764438cf683dda8a9f0Juergen Ributzka // AVX2 broadcast 31272766deb114cc5d3420027764438cf683dda8a9f0Juergen Ributzka case X86::BI__builtin_ia32_vbroadcastsi256: { 31283fc779191ce87cddf603e0c5bdbd225611201ff4Juergen Ributzka Value *VecTmp = CreateMemTemp(E->getArg(0)->getType()); 31293fc779191ce87cddf603e0c5bdbd225611201ff4Juergen Ributzka Builder.CreateStore(Ops[0], VecTmp); 31303fc779191ce87cddf603e0c5bdbd225611201ff4Juergen Ributzka Value *F = CGM.getIntrinsic(Intrinsic::x86_avx2_vbroadcasti128); 31313fc779191ce87cddf603e0c5bdbd225611201ff4Juergen Ributzka return Builder.CreateCall(F, Builder.CreateBitCast(VecTmp, Int8PtrTy)); 31322766deb114cc5d3420027764438cf683dda8a9f0Juergen Ributzka } 3133564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson } 3134564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson} 3135564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson 31369631939f82c0eaa6fb3936a0ce58a41adfbc9011Tony Linthicum 31371eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpValue *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, 31381feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner const CallExpr *E) { 31395f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Value*, 4> Ops; 3140dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 3141dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) 3142dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner Ops.push_back(EmitScalarExpr(E->getArg(i))); 3143dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 3144dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner Intrinsic::ID ID = Intrinsic::not_intrinsic; 3145dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 3146dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner switch (BuiltinID) { 3147dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner default: return 0; 3148dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 31494d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov // vec_ld, vec_lvsl, vec_lvsr 31504d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvx: 31514d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvxl: 31524d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvebx: 31534d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvehx: 31544d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvewx: 31554d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvsl: 31564d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvsr: 31574d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov { 3158d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy); 31594d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov 3160578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Ops[0] = Builder.CreateGEP(Ops[1], Ops[0]); 31614d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov Ops.pop_back(); 31624d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov 31634d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov switch (BuiltinID) { 3164b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("Unsupported ld/lvsl/lvsr intrinsic!"); 31654d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvx: 31664d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvx; 31674d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 31684d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvxl: 31694d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvxl; 31704d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 31714d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvebx: 31724d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvebx; 31734d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 31744d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvehx: 31754d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvehx; 31764d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 31774d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvewx: 31784d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvewx; 31794d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 31804d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvsl: 31814d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvsl; 31824d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 31834d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvsr: 31844d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvsr; 31854d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 31864d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov } 31874d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov llvm::Function *F = CGM.getIntrinsic(ID); 31884c7d9f1507d0f102bd4133bba63348636facd469Jay Foad return Builder.CreateCall(F, Ops, ""); 31894d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov } 31904d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov 3191dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner // vec_st 3192dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvx: 3193dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvxl: 3194dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvebx: 3195dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvehx: 3196dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvewx: 3197dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner { 3198d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Ops[2] = Builder.CreateBitCast(Ops[2], Int8PtrTy); 3199578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Ops[1] = Builder.CreateGEP(Ops[2], Ops[1]); 3200dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner Ops.pop_back(); 3201dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 3202dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner switch (BuiltinID) { 3203b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("Unsupported st intrinsic!"); 3204dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvx: 3205dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvx; 3206dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 3207dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvxl: 3208dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvxl; 3209dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 3210dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvebx: 3211dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvebx; 3212dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 3213dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvehx: 3214dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvehx; 3215dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 3216dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvewx: 3217dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvewx; 3218dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 3219dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner } 3220dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner llvm::Function *F = CGM.getIntrinsic(ID); 32214c7d9f1507d0f102bd4133bba63348636facd469Jay Foad return Builder.CreateCall(F, Ops, ""); 3222dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner } 3223dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner } 32241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 3225