CGBuiltin.cpp revision 7cea322bf019b0d38867a27e20e3771d84dbb1af
1022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===// 2022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson// 3022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson// The LLVM Compiler Infrastructure 4022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 7022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson// 8022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson//===----------------------------------------------------------------------===// 9022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson// 10022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson// This contains code to emit Builtin calls as LLVM code. 11022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson// 12022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson//===----------------------------------------------------------------------===// 13022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson 14d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall#include "TargetInfo.h" 15022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson#include "CodeGenFunction.h" 16022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson#include "CodeGenModule.h" 1755bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian#include "CGObjCRuntime.h" 18ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson#include "clang/Basic/TargetInfo.h" 191f32999ec79a980576e100d64d5f3267eb19ea49Chris Lattner#include "clang/AST/APValue.h" 20bef20ac367a09555b30d6eb3847a81ec164caf88Chris Lattner#include "clang/AST/ASTContext.h" 21c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbar#include "clang/AST/Decl.h" 226b15cdc1312f8fc45c86ee75e2a85106700e97f6Chris Lattner#include "clang/Basic/TargetBuiltins.h" 23793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson#include "llvm/Intrinsics.h" 24d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall#include "llvm/Target/TargetData.h" 25022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlssonusing namespace clang; 26022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlssonusing namespace CodeGen; 27ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlssonusing namespace llvm; 28ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson 29cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbarstatic void EmitMemoryBarrier(CodeGenFunction &CGF, 30cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar bool LoadLoad, bool LoadStore, 31cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar bool StoreLoad, bool StoreStore, 32cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar bool Device) { 33cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar Value *True = llvm::ConstantInt::getTrue(CGF.getLLVMContext()); 34cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar Value *False = llvm::ConstantInt::getFalse(CGF.getLLVMContext()); 35cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar Value *C[5] = { LoadLoad ? True : False, 36cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar LoadStore ? True : False, 37cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar StoreLoad ? True : False, 38cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar StoreStore ? True : False, 39cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar Device ? True : False }; 40cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar CGF.Builder.CreateCall(CGF.CGM.getIntrinsic(Intrinsic::memory_barrier), 41cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar C, C + 5); 42cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar} 43cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar 44db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruthstatic Value *EmitCastToInt(CodeGenFunction &CGF, 45db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth const llvm::Type *ToType, Value *Val) { 46db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth if (Val->getType()->isPointerTy()) { 47db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth return CGF.Builder.CreatePtrToInt(Val, ToType); 48db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth } 49db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth assert(Val->getType()->isIntegerTy() && 50db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth "Used a non-integer and non-pointer type with atomic builtin"); 51db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth assert(Val->getType()->getScalarSizeInBits() <= 52db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth ToType->getScalarSizeInBits() && "Integer type too small"); 53db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth return CGF.Builder.CreateSExtOrBitCast(Val, ToType); 54db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth} 55db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth 56db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruthstatic Value *EmitCastFromInt(CodeGenFunction &CGF, QualType ToQualType, 57db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth Value *Val) { 58db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth const llvm::Type *ToType = CGF.ConvertType(ToQualType); 59db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth if (ToType->isPointerTy()) { 60db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth return CGF.Builder.CreateIntToPtr(Val, ToType); 61db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth } 62db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth assert(Val->getType()->isIntegerTy() && 63db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth "Used a non-integer and non-pointer type with atomic builtin"); 64db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth assert(Val->getType()->getScalarSizeInBits() >= 65db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth ToType->getScalarSizeInBits() && "Integer type too small"); 66db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth return CGF.Builder.CreateTruncOrBitCast(Val, ToType); 67db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth} 68db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth 69cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar// The atomic builtins are also full memory barriers. This is a utility for 70cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar// wrapping a call to the builtins with memory barriers. 71cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbarstatic Value *EmitCallWithBarrier(CodeGenFunction &CGF, Value *Fn, 72cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar Value **ArgBegin, Value **ArgEnd) { 73cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar // FIXME: We need a target hook for whether this applies to device memory or 74cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar // not. 75cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar bool Device = true; 76cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar 77cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar // Create barriers both before and after the call. 78cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar EmitMemoryBarrier(CGF, true, true, true, true, Device); 79cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar Value *Result = CGF.Builder.CreateCall(Fn, ArgBegin, ArgEnd); 80cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar EmitMemoryBarrier(CGF, true, true, true, true, Device); 81cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar return Result; 82cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar} 83cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar 840002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar/// Utility to insert an atomic instruction based on Instrinsic::ID 850002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar/// and the expression node. 86cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbarstatic RValue EmitBinaryAtomic(CodeGenFunction &CGF, 871ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang Intrinsic::ID Id, const CallExpr *E) { 88db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth const llvm::Type *ValueType = 89db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth llvm::IntegerType::get(CGF.getLLVMContext(), 90db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth CGF.getContext().getTypeSize(E->getType())); 91db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth const llvm::Type *PtrType = ValueType->getPointerTo(); 92db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth const llvm::Type *IntrinsicTypes[2] = { ValueType, PtrType }; 93db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth Value *AtomF = CGF.CGM.getIntrinsic(Id, IntrinsicTypes, 2); 94db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth 95db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth Value *Args[2] = { CGF.Builder.CreateBitCast(CGF.EmitScalarExpr(E->getArg(0)), 96db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth PtrType), 97db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth EmitCastToInt(CGF, ValueType, 98db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth CGF.EmitScalarExpr(E->getArg(1))) }; 99db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth return RValue::get(EmitCastFromInt(CGF, E->getType(), 100db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth EmitCallWithBarrier(CGF, AtomF, Args, 101db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth Args + 2))); 1020002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar} 1030002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar 1040002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar/// Utility to insert an atomic instruction based Instrinsic::ID and 1050002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar// the expression node, where the return value is the result of the 1060002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar// operation. 107420b11850d3f4557421f43f519b59d528329c668Chris Lattnerstatic RValue EmitBinaryAtomicPost(CodeGenFunction &CGF, 1080002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Intrinsic::ID Id, const CallExpr *E, 1090002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Instruction::BinaryOps Op) { 110db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth const llvm::Type *ValueType = 111db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth llvm::IntegerType::get(CGF.getLLVMContext(), 112db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth CGF.getContext().getTypeSize(E->getType())); 113db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth const llvm::Type *PtrType = ValueType->getPointerTo(); 114db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth const llvm::Type *IntrinsicTypes[2] = { ValueType, PtrType }; 115db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth Value *AtomF = CGF.CGM.getIntrinsic(Id, IntrinsicTypes, 2); 116db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth 117db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth Value *Args[2] = { CGF.Builder.CreateBitCast(CGF.EmitScalarExpr(E->getArg(0)), 118db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth PtrType), 119db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth EmitCastToInt(CGF, ValueType, 120db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth CGF.EmitScalarExpr(E->getArg(1))) }; 121cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar Value *Result = EmitCallWithBarrier(CGF, AtomF, Args, Args + 2); 122db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth return RValue::get(EmitCastFromInt(CGF, E->getType(), 123db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth CGF.Builder.CreateBinOp(Op, Result, 124db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth Args[1]))); 1251ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang} 1261ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang 127420b11850d3f4557421f43f519b59d528329c668Chris Lattner/// EmitFAbs - Emit a call to fabs/fabsf/fabsl, depending on the type of ValTy, 128420b11850d3f4557421f43f519b59d528329c668Chris Lattner/// which must be a scalar floating point type. 129420b11850d3f4557421f43f519b59d528329c668Chris Lattnerstatic Value *EmitFAbs(CodeGenFunction &CGF, Value *V, QualType ValTy) { 130420b11850d3f4557421f43f519b59d528329c668Chris Lattner const BuiltinType *ValTyP = ValTy->getAs<BuiltinType>(); 131420b11850d3f4557421f43f519b59d528329c668Chris Lattner assert(ValTyP && "isn't scalar fp type!"); 132420b11850d3f4557421f43f519b59d528329c668Chris Lattner 133420b11850d3f4557421f43f519b59d528329c668Chris Lattner StringRef FnName; 134420b11850d3f4557421f43f519b59d528329c668Chris Lattner switch (ValTyP->getKind()) { 135420b11850d3f4557421f43f519b59d528329c668Chris Lattner default: assert(0 && "Isn't a scalar fp type!"); 136420b11850d3f4557421f43f519b59d528329c668Chris Lattner case BuiltinType::Float: FnName = "fabsf"; break; 137420b11850d3f4557421f43f519b59d528329c668Chris Lattner case BuiltinType::Double: FnName = "fabs"; break; 138420b11850d3f4557421f43f519b59d528329c668Chris Lattner case BuiltinType::LongDouble: FnName = "fabsl"; break; 139420b11850d3f4557421f43f519b59d528329c668Chris Lattner } 140420b11850d3f4557421f43f519b59d528329c668Chris Lattner 141420b11850d3f4557421f43f519b59d528329c668Chris Lattner // The prototype is something that takes and returns whatever V's type is. 142420b11850d3f4557421f43f519b59d528329c668Chris Lattner std::vector<const llvm::Type*> Args; 143420b11850d3f4557421f43f519b59d528329c668Chris Lattner Args.push_back(V->getType()); 144420b11850d3f4557421f43f519b59d528329c668Chris Lattner llvm::FunctionType *FT = llvm::FunctionType::get(V->getType(), Args, false); 145420b11850d3f4557421f43f519b59d528329c668Chris Lattner llvm::Value *Fn = CGF.CGM.CreateRuntimeFunction(FT, FnName); 146420b11850d3f4557421f43f519b59d528329c668Chris Lattner 147420b11850d3f4557421f43f519b59d528329c668Chris Lattner return CGF.Builder.CreateCall(Fn, V, "abs"); 148420b11850d3f4557421f43f519b59d528329c668Chris Lattner} 149420b11850d3f4557421f43f519b59d528329c668Chris Lattner 1501eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpRValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, 151ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar unsigned BuiltinID, const CallExpr *E) { 152564ea2a99b3afeac9ded332730a56db1f6358a58Chris Lattner // See if we can constant fold this builtin. If so, don't emit it at all. 153f35d35a2316dcb65d078844696c2032b71a7f103Anders Carlsson Expr::EvalResult Result; 1546ee7aa154e8bbb21a21254293410b944f78b0bfeChris Lattner if (E->Evaluate(Result, CGM.getContext())) { 155f35d35a2316dcb65d078844696c2032b71a7f103Anders Carlsson if (Result.Val.isInt()) 1561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return RValue::get(llvm::ConstantInt::get(VMContext, 1574a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Result.Val.getInt())); 1583941b18b8e441c8c466efecd557de60b9a32d10bEli Friedman else if (Result.Val.isFloat()) 159bc0a2226c7fcd18b29b6846049e2cfcb872d3593Owen Anderson return RValue::get(ConstantFP::get(VMContext, Result.Val.getFloat())); 1601f32999ec79a980576e100d64d5f3267eb19ea49Chris Lattner } 1611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 162564ea2a99b3afeac9ded332730a56db1f6358a58Chris Lattner switch (BuiltinID) { 163564ea2a99b3afeac9ded332730a56db1f6358a58Chris Lattner default: break; // Handle intrinsics and libm functions below. 164506ff88f44562df267b6a06608ab841b76df2a2bChris Lattner case Builtin::BI__builtin___CFStringMakeConstantString: 1650d13f6fdbdd6f06e2449b8834dda53334abd399aDavid Chisnall case Builtin::BI__builtin___NSStringMakeConstantString: 166e9352cc9818ba59e7cf88500ef048991c90f3821Anders Carlsson return RValue::get(CGM.EmitConstantExpr(E, E->getType(), 0)); 1676a705f0443f8398ece14d80e71d8e8c9e71aa84aChris Lattner case Builtin::BI__builtin_stdarg_start: 168793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson case Builtin::BI__builtin_va_start: 169793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson case Builtin::BI__builtin_va_end: { 1700785570af3ef5f8c5a0377129e41efe6f3f8d770Daniel Dunbar Value *ArgValue = EmitVAListRef(E->getArg(0)); 1713c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer const llvm::Type *DestType = llvm::Type::getInt8PtrTy(VMContext); 172793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson if (ArgValue->getType() != DestType) 1731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ArgValue = Builder.CreateBitCast(ArgValue, DestType, 174b27ffbef8e8aa1e87b63cbc0d9cd630aba30dae5Daniel Dunbar ArgValue->getName().data()); 175793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson 1761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Intrinsic::ID inst = (BuiltinID == Builtin::BI__builtin_va_end) ? 1776a705f0443f8398ece14d80e71d8e8c9e71aa84aChris Lattner Intrinsic::vaend : Intrinsic::vastart; 1787acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner return RValue::get(Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue)); 179793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson } 180a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson case Builtin::BI__builtin_va_copy: { 1814fd0aa5803357d8c72eeac2cae15e12649ea08feEli Friedman Value *DstPtr = EmitVAListRef(E->getArg(0)); 1824fd0aa5803357d8c72eeac2cae15e12649ea08feEli Friedman Value *SrcPtr = EmitVAListRef(E->getArg(1)); 183a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson 1843c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer const llvm::Type *Type = llvm::Type::getInt8PtrTy(VMContext); 185a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson 186a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson DstPtr = Builder.CreateBitCast(DstPtr, Type); 187a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson SrcPtr = Builder.CreateBitCast(SrcPtr, Type); 1881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return RValue::get(Builder.CreateCall2(CGM.getIntrinsic(Intrinsic::vacopy), 1893eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner DstPtr, SrcPtr)); 190a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson } 191c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson case Builtin::BI__builtin_abs: { 1921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1949a847f598c4907a72b8593b364b9e6b94b086e75Chris Lattner Value *NegOp = Builder.CreateNeg(ArgValue, "neg"); 1951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *CmpResult = 1961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Builder.CreateICmpSGE(ArgValue, 197c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson llvm::Constant::getNullValue(ArgValue->getType()), 1989a847f598c4907a72b8593b364b9e6b94b086e75Chris Lattner "abscond"); 1991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *Result = 200c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs"); 2011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 202c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson return RValue::get(Result); 203c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson } 2043a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson case Builtin::BI__builtin_ctz: 2053a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson case Builtin::BI__builtin_ctzl: 2063a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson case Builtin::BI__builtin_ctzll: { 2073a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson Value *ArgValue = EmitScalarExpr(E->getArg(0)); 2081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2093a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson const llvm::Type *ArgType = ArgValue->getType(); 2103a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson Value *F = CGM.getIntrinsic(Intrinsic::cttz, &ArgType, 1); 2113a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson 2121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const llvm::Type *ResultType = ConvertType(E->getType()); 2133a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson Value *Result = Builder.CreateCall(F, ArgValue, "tmp"); 2143a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson if (Result->getType() != ResultType) 215eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 216eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 2173a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson return RValue::get(Result); 2183a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson } 219f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman case Builtin::BI__builtin_clz: 220f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman case Builtin::BI__builtin_clzl: 221f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman case Builtin::BI__builtin_clzll: { 222f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman Value *ArgValue = EmitScalarExpr(E->getArg(0)); 2231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 224f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman const llvm::Type *ArgType = ArgValue->getType(); 225f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman Value *F = CGM.getIntrinsic(Intrinsic::ctlz, &ArgType, 1); 226f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman 2271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const llvm::Type *ResultType = ConvertType(E->getType()); 228f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman Value *Result = Builder.CreateCall(F, ArgValue, "tmp"); 229f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman if (Result->getType() != ResultType) 230eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 231eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 232f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman return RValue::get(Result); 233f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman } 23404b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_ffs: 23504b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_ffsl: 23604b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_ffsll: { 23704b290030eee33295600728450f348989d1a627eDaniel Dunbar // ffs(x) -> x ? cttz(x) + 1 : 0 23804b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *ArgValue = EmitScalarExpr(E->getArg(0)); 2391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 24004b290030eee33295600728450f348989d1a627eDaniel Dunbar const llvm::Type *ArgType = ArgValue->getType(); 24104b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::cttz, &ArgType, 1); 2421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 24304b290030eee33295600728450f348989d1a627eDaniel Dunbar const llvm::Type *ResultType = ConvertType(E->getType()); 2441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *Tmp = Builder.CreateAdd(Builder.CreateCall(F, ArgValue, "tmp"), 2454a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson llvm::ConstantInt::get(ArgType, 1), "tmp"); 246c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Value *Zero = llvm::Constant::getNullValue(ArgType); 24704b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero"); 24804b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp, "ffs"); 24904b290030eee33295600728450f348989d1a627eDaniel Dunbar if (Result->getType() != ResultType) 250eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 251eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 25204b290030eee33295600728450f348989d1a627eDaniel Dunbar return RValue::get(Result); 25304b290030eee33295600728450f348989d1a627eDaniel Dunbar } 25404b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_parity: 25504b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_parityl: 25604b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_parityll: { 25704b290030eee33295600728450f348989d1a627eDaniel Dunbar // parity(x) -> ctpop(x) & 1 25804b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *ArgValue = EmitScalarExpr(E->getArg(0)); 2591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 26004b290030eee33295600728450f348989d1a627eDaniel Dunbar const llvm::Type *ArgType = ArgValue->getType(); 26104b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::ctpop, &ArgType, 1); 2621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 26304b290030eee33295600728450f348989d1a627eDaniel Dunbar const llvm::Type *ResultType = ConvertType(E->getType()); 26404b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *Tmp = Builder.CreateCall(F, ArgValue, "tmp"); 2651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *Result = Builder.CreateAnd(Tmp, llvm::ConstantInt::get(ArgType, 1), 26604b290030eee33295600728450f348989d1a627eDaniel Dunbar "tmp"); 26704b290030eee33295600728450f348989d1a627eDaniel Dunbar if (Result->getType() != ResultType) 268eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 269eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 27004b290030eee33295600728450f348989d1a627eDaniel Dunbar return RValue::get(Result); 27104b290030eee33295600728450f348989d1a627eDaniel Dunbar } 27204b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_popcount: 27304b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_popcountl: 27404b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_popcountll: { 27504b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *ArgValue = EmitScalarExpr(E->getArg(0)); 2761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 27704b290030eee33295600728450f348989d1a627eDaniel Dunbar const llvm::Type *ArgType = ArgValue->getType(); 27804b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::ctpop, &ArgType, 1); 2791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 28004b290030eee33295600728450f348989d1a627eDaniel Dunbar const llvm::Type *ResultType = ConvertType(E->getType()); 28104b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *Result = Builder.CreateCall(F, ArgValue, "tmp"); 28204b290030eee33295600728450f348989d1a627eDaniel Dunbar if (Result->getType() != ResultType) 283eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 284eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 28504b290030eee33295600728450f348989d1a627eDaniel Dunbar return RValue::get(Result); 28604b290030eee33295600728450f348989d1a627eDaniel Dunbar } 287e42b8a596886fc98e367c73e54d761446700029eFariborz Jahanian case Builtin::BI__builtin_expect: { 288a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar // FIXME: pass expect through to LLVM 289e42b8a596886fc98e367c73e54d761446700029eFariborz Jahanian if (E->getArg(1)->HasSideEffects(getContext())) 290e42b8a596886fc98e367c73e54d761446700029eFariborz Jahanian (void)EmitScalarExpr(E->getArg(1)); 2911feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner return RValue::get(EmitScalarExpr(E->getArg(0))); 292e42b8a596886fc98e367c73e54d761446700029eFariborz Jahanian } 293df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson case Builtin::BI__builtin_bswap32: 294df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson case Builtin::BI__builtin_bswap64: { 2951feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner Value *ArgValue = EmitScalarExpr(E->getArg(0)); 296df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson const llvm::Type *ArgType = ArgValue->getType(); 2977acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner Value *F = CGM.getIntrinsic(Intrinsic::bswap, &ArgType, 1); 2981feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner return RValue::get(Builder.CreateCall(F, ArgValue, "tmp")); 2991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 300d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar case Builtin::BI__builtin_object_size: { 301b16d32f74ffc467a5604934a1f844906be20cf7dMike Stump // We pass this builtin onto the optimizer so that it can 302b16d32f74ffc467a5604934a1f844906be20cf7dMike Stump // figure out the object size in more complex cases. 303c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump const llvm::Type *ResType[] = { 304c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump ConvertType(E->getType()) 305c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump }; 306fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher 307fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher // LLVM only supports 0 and 2, make sure that we pass along that 308fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher // as a boolean. 309fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher Value *Ty = EmitScalarExpr(E->getArg(1)); 310fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher ConstantInt *CI = dyn_cast<ConstantInt>(Ty); 311fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher assert(CI); 312fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher uint64_t val = CI->getZExtValue(); 313fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher CI = ConstantInt::get(llvm::Type::getInt1Ty(VMContext), (val & 0x2) >> 1); 314fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher 315c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump Value *F = CGM.getIntrinsic(Intrinsic::objectsize, ResType, 1); 316c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump return RValue::get(Builder.CreateCall2(F, 317c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump EmitScalarExpr(E->getArg(0)), 318fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher CI)); 319d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar } 3204493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar case Builtin::BI__builtin_prefetch: { 3214493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0)); 3224493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar // FIXME: Technically these constants should of type 'int', yes? 3231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump RW = (E->getNumArgs() > 1) ? EmitScalarExpr(E->getArg(1)) : 32477b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::ConstantInt::get(Int32Ty, 0); 3251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : 32677b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::ConstantInt::get(Int32Ty, 3); 3274493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::prefetch, 0, 0); 3284493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar return RValue::get(Builder.CreateCall3(F, Address, RW, Locality)); 3294493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar } 3304493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar case Builtin::BI__builtin_trap: { 3314493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::trap, 0, 0); 3324493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar return RValue::get(Builder.CreateCall(F)); 333df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson } 33421190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner case Builtin::BI__builtin_unreachable: { 335fba565d044a8979cfd916ce52655a6847bfaa601Mike Stump if (CatchUndefined && HaveInsertPoint()) 336fba565d044a8979cfd916ce52655a6847bfaa601Mike Stump EmitBranch(getTrapBB()); 33721190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner Value *V = Builder.CreateUnreachable(); 33821190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner Builder.ClearInsertionPoint(); 33921190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner return RValue::get(V); 34021190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner } 34121190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner 342a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar case Builtin::BI__builtin_powi: 343a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar case Builtin::BI__builtin_powif: 344a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar case Builtin::BI__builtin_powil: { 345a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar Value *Base = EmitScalarExpr(E->getArg(0)); 346a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar Value *Exponent = EmitScalarExpr(E->getArg(1)); 347a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar const llvm::Type *ArgType = Base->getType(); 348a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::powi, &ArgType, 1); 349a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp")); 350a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar } 351a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar 352fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isgreater: 353fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isgreaterequal: 354fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isless: 355fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_islessequal: 356fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_islessgreater: 357fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isunordered: { 358fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner // Ordered comparisons: we know the arguments to these are matching scalar 359fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner // floating point values. 3601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *LHS = EmitScalarExpr(E->getArg(0)); 361fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner Value *RHS = EmitScalarExpr(E->getArg(1)); 3621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 363fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner switch (BuiltinID) { 364fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner default: assert(0 && "Unknown ordered comparison"); 365fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isgreater: 366fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp"); 367fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 368fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isgreaterequal: 369fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp"); 370fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 371fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isless: 372fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp"); 373fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 374fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_islessequal: 375fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp"); 376fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 377fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_islessgreater: 378fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp"); 379fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 3801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case Builtin::BI__builtin_isunordered: 381fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp"); 382fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 383fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner } 384fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner // ZExt bool to int type. 385fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType()), 386fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner "tmp")); 387fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner } 388d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman case Builtin::BI__builtin_isnan: { 389d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman Value *V = EmitScalarExpr(E->getArg(0)); 390d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman V = Builder.CreateFCmpUNO(V, V, "cmp"); 391d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()), "tmp")); 392d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman } 393420b11850d3f4557421f43f519b59d528329c668Chris Lattner 394420b11850d3f4557421f43f519b59d528329c668Chris Lattner case Builtin::BI__builtin_isinf: { 395420b11850d3f4557421f43f519b59d528329c668Chris Lattner // isinf(x) --> fabs(x) == infinity 396420b11850d3f4557421f43f519b59d528329c668Chris Lattner Value *V = EmitScalarExpr(E->getArg(0)); 397420b11850d3f4557421f43f519b59d528329c668Chris Lattner V = EmitFAbs(*this, V, E->getArg(0)->getType()); 398420b11850d3f4557421f43f519b59d528329c668Chris Lattner 399420b11850d3f4557421f43f519b59d528329c668Chris Lattner V = Builder.CreateFCmpOEQ(V, ConstantFP::getInfinity(V->getType()),"isinf"); 400420b11850d3f4557421f43f519b59d528329c668Chris Lattner return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()), "tmp")); 401420b11850d3f4557421f43f519b59d528329c668Chris Lattner } 40258ae5b4b1e2fc02b95d6650af5755a59639aa153Chris Lattner 40358ae5b4b1e2fc02b95d6650af5755a59639aa153Chris Lattner // TODO: BI__builtin_isinf_sign 40458ae5b4b1e2fc02b95d6650af5755a59639aa153Chris Lattner // isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0 4056349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer 4066349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer case Builtin::BI__builtin_isnormal: { 4076349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer // isnormal(x) --> x == x && fabsf(x) < infinity && fabsf(x) >= float_min 4086349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer Value *V = EmitScalarExpr(E->getArg(0)); 4096349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq"); 4106349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer 4116349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer Value *Abs = EmitFAbs(*this, V, E->getArg(0)->getType()); 4126349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer Value *IsLessThanInf = 4136349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer Builder.CreateFCmpULT(Abs, ConstantFP::getInfinity(V->getType()),"isinf"); 4146349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer APFloat Smallest = APFloat::getSmallestNormalized( 4156349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer getContext().getFloatTypeSemantics(E->getArg(0)->getType())); 4166349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer Value *IsNormal = 4176349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer Builder.CreateFCmpUGE(Abs, ConstantFP::get(V->getContext(), Smallest), 4186349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer "isnormal"); 4196349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer V = Builder.CreateAnd(Eq, IsLessThanInf, "and"); 4206349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer V = Builder.CreateAnd(V, IsNormal, "and"); 4216349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 4226349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer } 4236349ce94d1b4fa560bf060c5ca5ad5728ce4fad9Benjamin Kramer 424ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner case Builtin::BI__builtin_isfinite: { 425ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner // isfinite(x) --> x == x && fabs(x) != infinity; } 426ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner Value *V = EmitScalarExpr(E->getArg(0)); 427ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq"); 428ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner 429ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner Value *Abs = EmitFAbs(*this, V, E->getArg(0)->getType()); 430ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner Value *IsNotInf = 431ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner Builder.CreateFCmpUNE(Abs, ConstantFP::getInfinity(V->getType()),"isinf"); 432ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner 433ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner V = Builder.CreateAnd(Eq, IsNotInf, "and"); 434ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 435ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner } 4367867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer 4377867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer case Builtin::BI__builtin_fpclassify: { 4387867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *V = EmitScalarExpr(E->getArg(5)); 4397867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer const llvm::Type *Ty = ConvertType(E->getArg(5)->getType()); 4407867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer 4417867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer // Create Result 4427867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer BasicBlock *Begin = Builder.GetInsertBlock(); 4437867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer BasicBlock *End = createBasicBlock("fpclassify_end", this->CurFn); 4447867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.SetInsertPoint(End); 4457867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer PHINode *Result = 4467867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.CreatePHI(ConvertType(E->getArg(0)->getType()), 4477867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer "fpclassify_result"); 4487867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer 4497867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer // if (V==0) return FP_ZERO 4507867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.SetInsertPoint(Begin); 4517867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *IsZero = Builder.CreateFCmpOEQ(V, Constant::getNullValue(Ty), 4527867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer "iszero"); 4537867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *ZeroLiteral = EmitScalarExpr(E->getArg(4)); 4547867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer BasicBlock *NotZero = createBasicBlock("fpclassify_not_zero", this->CurFn); 4557867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.CreateCondBr(IsZero, End, NotZero); 4567867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Result->addIncoming(ZeroLiteral, Begin); 4577867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer 4587867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer // if (V != V) return FP_NAN 4597867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.SetInsertPoint(NotZero); 4607867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *IsNan = Builder.CreateFCmpUNO(V, V, "cmp"); 4617867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *NanLiteral = EmitScalarExpr(E->getArg(0)); 4627867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer BasicBlock *NotNan = createBasicBlock("fpclassify_not_nan", this->CurFn); 4637867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.CreateCondBr(IsNan, End, NotNan); 4647867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Result->addIncoming(NanLiteral, NotZero); 4657867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer 4667867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer // if (fabs(V) == infinity) return FP_INFINITY 4677867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.SetInsertPoint(NotNan); 4687867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *VAbs = EmitFAbs(*this, V, E->getArg(5)->getType()); 4697867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *IsInf = 4707867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.CreateFCmpOEQ(VAbs, ConstantFP::getInfinity(V->getType()), 4717867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer "isinf"); 4727867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *InfLiteral = EmitScalarExpr(E->getArg(1)); 4737867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer BasicBlock *NotInf = createBasicBlock("fpclassify_not_inf", this->CurFn); 4747867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.CreateCondBr(IsInf, End, NotInf); 4757867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Result->addIncoming(InfLiteral, NotNan); 4767867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer 4777867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer // if (fabs(V) >= MIN_NORMAL) return FP_NORMAL else FP_SUBNORMAL 4787867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.SetInsertPoint(NotInf); 4797867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer APFloat Smallest = APFloat::getSmallestNormalized( 4807867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer getContext().getFloatTypeSemantics(E->getArg(5)->getType())); 4817867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *IsNormal = 4827867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.CreateFCmpUGE(VAbs, ConstantFP::get(V->getContext(), Smallest), 4837867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer "isnormal"); 4847867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Value *NormalResult = 4857867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.CreateSelect(IsNormal, EmitScalarExpr(E->getArg(2)), 4867867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer EmitScalarExpr(E->getArg(3))); 4877867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.CreateBr(End); 4887867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Result->addIncoming(NormalResult, NotInf); 4897867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer 4907867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer // return Result 4917867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer Builder.SetInsertPoint(End); 4927867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer return RValue::get(Result); 4937867f1a62b8b42cc2a55cc571608a75db2d516e0Benjamin Kramer } 494ed074150c9a775c5e2e1c4ececeba18ba880ce7dChris Lattner 495b52fe9ce99970955a5f581f5c66fcd89be9a268bEli Friedman case Builtin::BIalloca: 4969e800e3dd80d77f6c47054738177bf824089f55aChris Lattner case Builtin::BI__builtin_alloca: { 4979e800e3dd80d77f6c47054738177bf824089f55aChris Lattner Value *Size = EmitScalarExpr(E->getArg(0)); 4980032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson return RValue::get(Builder.CreateAlloca(llvm::Type::getInt8Ty(VMContext), Size, "tmp")); 4991caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar } 500e6dddfd907f6ea58daed5e26eeaacd893d98db9bEli Friedman case Builtin::BIbzero: 5011caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar case Builtin::BI__builtin_bzero: { 5021caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar Value *Address = EmitScalarExpr(E->getArg(0)); 5033ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Value *SizeVal = EmitScalarExpr(E->getArg(1)); 5043ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Builder.CreateCall5(CGM.getMemSetFn(Address->getType(), SizeVal->getType()), 5053ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Address, 5063ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 0), 5073ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang SizeVal, 50877b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::ConstantInt::get(Int32Ty, 1), 5093ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0)); 5101caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar return RValue::get(Address); 5119e800e3dd80d77f6c47054738177bf824089f55aChris Lattner } 512e6ec205d6d0f4aec27bf49ca1e8fbb139acc2f2bEli Friedman case Builtin::BImemcpy: 513d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman case Builtin::BI__builtin_memcpy: { 5141caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar Value *Address = EmitScalarExpr(E->getArg(0)); 5153ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Value *SrcAddr = EmitScalarExpr(E->getArg(1)); 5163ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Value *SizeVal = EmitScalarExpr(E->getArg(2)); 5173ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Builder.CreateCall5(CGM.getMemCpyFn(Address->getType(), SrcAddr->getType(), 5183ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang SizeVal->getType()), 5193ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Address, SrcAddr, SizeVal, 52077b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::ConstantInt::get(Int32Ty, 1), 5213ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0)); 5221caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar return RValue::get(Address); 5231caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar } 52455bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian 5258e2eab27056a78bf1db50ee09929438ed5ea9d93Fariborz Jahanian case Builtin::BI__builtin_objc_memmove_collectable: { 52655bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian Value *Address = EmitScalarExpr(E->getArg(0)); 52755bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian Value *SrcAddr = EmitScalarExpr(E->getArg(1)); 52855bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian Value *SizeVal = EmitScalarExpr(E->getArg(2)); 52955bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, 53055bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian Address, SrcAddr, SizeVal); 53155bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian return RValue::get(Address); 53255bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian } 53355bcace250e1ff366e4482714b344b8cbc8be5f3Fariborz Jahanian 534e6ec205d6d0f4aec27bf49ca1e8fbb139acc2f2bEli Friedman case Builtin::BImemmove: 5351caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar case Builtin::BI__builtin_memmove: { 5361caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar Value *Address = EmitScalarExpr(E->getArg(0)); 5373ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Value *SrcAddr = EmitScalarExpr(E->getArg(1)); 5383ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Value *SizeVal = EmitScalarExpr(E->getArg(2)); 5393ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Builder.CreateCall5(CGM.getMemMoveFn(Address->getType(), SrcAddr->getType(), 5403ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang SizeVal->getType()), 5413ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Address, SrcAddr, SizeVal, 54277b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::ConstantInt::get(Int32Ty, 1), 5433ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0)); 5441caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar return RValue::get(Address); 5451caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar } 546e6ec205d6d0f4aec27bf49ca1e8fbb139acc2f2bEli Friedman case Builtin::BImemset: 5471caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar case Builtin::BI__builtin_memset: { 5481caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar Value *Address = EmitScalarExpr(E->getArg(0)); 5493ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Value *SizeVal = EmitScalarExpr(E->getArg(2)); 5503ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Builder.CreateCall5(CGM.getMemSetFn(Address->getType(), SizeVal->getType()), 5513ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Address, 5523ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), 5533ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang llvm::Type::getInt8Ty(VMContext)), 5543ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang SizeVal, 55577b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::ConstantInt::get(Int32Ty, 1), 5563ecd785aff34381f3704d9cb28fe3ef85af759deMon P Wang llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0)); 5571caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar return RValue::get(Address); 558d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman } 559fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall case Builtin::BI__builtin_dwarf_cfa: { 560fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // The offset in bytes from the first argument to the CFA. 561fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // 562fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // Why on earth is this in the frontend? Is there any reason at 563fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // all that the backend can't reasonably determine this while 564fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // lowering llvm.eh.dwarf.cfa()? 565fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // 566fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // TODO: If there's a satisfactory reason, add a target hook for 567fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // this instead of hard-coding 0, which is correct for most targets. 568fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall int32_t Offset = 0; 569fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall 570fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall Value *F = CGM.getIntrinsic(Intrinsic::eh_dwarf_cfa, 0, 0); 57177b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner return RValue::get(Builder.CreateCall(F, 57277b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::ConstantInt::get(Int32Ty, Offset))); 573fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall } 574256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman case Builtin::BI__builtin_return_address: { 57583c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov Value *Depth = EmitScalarExpr(E->getArg(0)); 57677b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Depth = Builder.CreateIntCast(Depth, Int32Ty, false, "tmp"); 577256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman Value *F = CGM.getIntrinsic(Intrinsic::returnaddress, 0, 0); 57883c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov return RValue::get(Builder.CreateCall(F, Depth)); 579256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman } 580256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman case Builtin::BI__builtin_frame_address: { 58183c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov Value *Depth = EmitScalarExpr(E->getArg(0)); 58277b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Depth = Builder.CreateIntCast(Depth, Int32Ty, false, "tmp"); 583256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman Value *F = CGM.getIntrinsic(Intrinsic::frameaddress, 0, 0); 58483c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov return RValue::get(Builder.CreateCall(F, Depth)); 585256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman } 5863b660efb9f9fa3e87096f4a96a2093cd17c43c2eEli Friedman case Builtin::BI__builtin_extract_return_addr: { 587492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall Value *Address = EmitScalarExpr(E->getArg(0)); 588492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall Value *Result = getTargetHooks().decodeReturnAddress(*this, Address); 589492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall return RValue::get(Result); 590492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall } 591492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall case Builtin::BI__builtin_frob_return_addr: { 592492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall Value *Address = EmitScalarExpr(E->getArg(0)); 593492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall Value *Result = getTargetHooks().encodeReturnAddress(*this, Address); 594492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall return RValue::get(Result); 5953b660efb9f9fa3e87096f4a96a2093cd17c43c2eEli Friedman } 5966374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall case Builtin::BI__builtin_dwarf_sp_column: { 5976374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall const llvm::IntegerType *Ty 5986374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall = cast<llvm::IntegerType>(ConvertType(E->getType())); 5996374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall int Column = getTargetHooks().getDwarfEHStackPointer(CGM); 6006374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall if (Column == -1) { 6016374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall CGM.ErrorUnsupported(E, "__builtin_dwarf_sp_column"); 6026374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall return RValue::get(llvm::UndefValue::get(Ty)); 6036374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall } 6046374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall return RValue::get(llvm::ConstantInt::get(Ty, Column, true)); 6056374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall } 6066374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall case Builtin::BI__builtin_init_dwarf_reg_size_table: { 6076374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall Value *Address = EmitScalarExpr(E->getArg(0)); 6086374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall if (getTargetHooks().initDwarfEHRegSizeTable(*this, Address)) 6096374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall CGM.ErrorUnsupported(E, "__builtin_init_dwarf_reg_size_table"); 6106374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall return RValue::get(llvm::UndefValue::get(ConvertType(E->getType()))); 6116374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall } 6127ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall case Builtin::BI__builtin_eh_return: { 6137ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall Value *Int = EmitScalarExpr(E->getArg(0)); 6147ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall Value *Ptr = EmitScalarExpr(E->getArg(1)); 6157ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall 6167ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(Int->getType()); 6177ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall assert((IntTy->getBitWidth() == 32 || IntTy->getBitWidth() == 64) && 6187ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall "LLVM's __builtin_eh_return only supports 32- and 64-bit variants"); 6197ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall Value *F = CGM.getIntrinsic(IntTy->getBitWidth() == 32 6207ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall ? Intrinsic::eh_return_i32 6217ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall : Intrinsic::eh_return_i64, 6227ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall 0, 0); 6237ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall Builder.CreateCall2(F, Int, Ptr); 6247ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall Value *V = Builder.CreateUnreachable(); 6257ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall Builder.ClearInsertionPoint(); 6267ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall return RValue::get(V); 6277ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall } 628a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman case Builtin::BI__builtin_unwind_init: { 629a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init, 0, 0); 630a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman return RValue::get(Builder.CreateCall(F)); 631a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman } 6325e11085830d4d4c53ff75575ab75889ee5126854John McCall case Builtin::BI__builtin_extend_pointer: { 6335e11085830d4d4c53ff75575ab75889ee5126854John McCall // Extends a pointer to the size of an _Unwind_Word, which is 634d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // uint64_t on all platforms. Generally this gets poked into a 635d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // register and eventually used as an address, so if the 636d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // addressing registers are wider than pointers and the platform 637d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // doesn't implicitly ignore high-order bits when doing 638d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // addressing, we need to make sure we zext / sext based on 639d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // the platform's expectations. 6405e11085830d4d4c53ff75575ab75889ee5126854John McCall // 6415e11085830d4d4c53ff75575ab75889ee5126854John McCall // See: http://gcc.gnu.org/ml/gcc-bugs/2002-02/msg00237.html 642d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall 643d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall LLVMContext &C = CGM.getLLVMContext(); 644d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall 645d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // Cast the pointer to intptr_t. 6465e11085830d4d4c53ff75575ab75889ee5126854John McCall Value *Ptr = EmitScalarExpr(E->getArg(0)); 647d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall const llvm::IntegerType *IntPtrTy = CGM.getTargetData().getIntPtrType(C); 648d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall Value *Result = Builder.CreatePtrToInt(Ptr, IntPtrTy, "extend.cast"); 649d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall 650d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // If that's 64 bits, we're done. 651d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall if (IntPtrTy->getBitWidth() == 64) 652d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall return RValue::get(Result); 653d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall 654d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // Otherwise, ask the codegen data what to do. 655492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall if (getTargetHooks().extendPointerWithSExt()) 656d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall return RValue::get(Builder.CreateSExt(Result, Int64Ty, "extend.sext")); 657d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall else 658d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall return RValue::get(Builder.CreateZExt(Result, Int64Ty, "extend.zext")); 6595e11085830d4d4c53ff75575ab75889ee5126854John McCall } 660a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman case Builtin::BI__builtin_setjmp: { 66178673d9f910e8dfe13248c2426c51d8f9fb28572John McCall // Buffer is a void**. 662a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *Buf = EmitScalarExpr(E->getArg(0)); 66378673d9f910e8dfe13248c2426c51d8f9fb28572John McCall 66478673d9f910e8dfe13248c2426c51d8f9fb28572John McCall // Store the frame pointer to the setjmp buffer. 665a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *FrameAddr = 66678673d9f910e8dfe13248c2426c51d8f9fb28572John McCall Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress), 66777b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner ConstantInt::get(Int32Ty, 0)); 668a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Builder.CreateStore(FrameAddr, Buf); 66978673d9f910e8dfe13248c2426c51d8f9fb28572John McCall 6706d172e2985346e55095c75f456901ea5d40fddaaJim Grosbach // Store the stack pointer to the setjmp buffer. 6716d172e2985346e55095c75f456901ea5d40fddaaJim Grosbach Value *StackAddr = 6726d172e2985346e55095c75f456901ea5d40fddaaJim Grosbach Builder.CreateCall(CGM.getIntrinsic(Intrinsic::stacksave)); 6736d172e2985346e55095c75f456901ea5d40fddaaJim Grosbach Value *StackSaveSlot = 67477b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Builder.CreateGEP(Buf, ConstantInt::get(Int32Ty, 2)); 6756d172e2985346e55095c75f456901ea5d40fddaaJim Grosbach Builder.CreateStore(StackAddr, StackSaveSlot); 6766d172e2985346e55095c75f456901ea5d40fddaaJim Grosbach 67778673d9f910e8dfe13248c2426c51d8f9fb28572John McCall // Call LLVM's EH setjmp, which is lightweight. 67878673d9f910e8dfe13248c2426c51d8f9fb28572John McCall Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp); 67978673d9f910e8dfe13248c2426c51d8f9fb28572John McCall Buf = Builder.CreateBitCast(Buf, llvm::Type::getInt8PtrTy(VMContext)); 680a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman return RValue::get(Builder.CreateCall(F, Buf)); 681a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman } 682a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman case Builtin::BI__builtin_longjmp: { 683a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *Buf = EmitScalarExpr(E->getArg(0)); 68478673d9f910e8dfe13248c2426c51d8f9fb28572John McCall Buf = Builder.CreateBitCast(Buf, llvm::Type::getInt8PtrTy(VMContext)); 68578673d9f910e8dfe13248c2426c51d8f9fb28572John McCall 68678673d9f910e8dfe13248c2426c51d8f9fb28572John McCall // Call LLVM's EH longjmp, which is lightweight. 68778673d9f910e8dfe13248c2426c51d8f9fb28572John McCall Builder.CreateCall(CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp), Buf); 68878673d9f910e8dfe13248c2426c51d8f9fb28572John McCall 68978673d9f910e8dfe13248c2426c51d8f9fb28572John McCall // longjmp doesn't return; mark this as unreachable 69078673d9f910e8dfe13248c2426c51d8f9fb28572John McCall Value *V = Builder.CreateUnreachable(); 69178673d9f910e8dfe13248c2426c51d8f9fb28572John McCall Builder.ClearInsertionPoint(); 69278673d9f910e8dfe13248c2426c51d8f9fb28572John McCall return RValue::get(V); 693a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman } 6941ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_add: 6951ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_sub: 6965caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or: 6975caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and: 6985caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor: 6995caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch: 7005caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch: 7015caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch: 7025caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch: 7035caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch: 7045caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap: 7055caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap: 7065caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set: 7075caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release: 7085caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner assert(0 && "Shouldn't make it through sema"); 7095caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_1: 7105caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_2: 7115caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_4: 7125caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_8: 7135caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_16: 7145caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner return EmitBinaryAtomic(*this, Intrinsic::atomic_load_add, E); 7155caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_1: 7165caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_2: 7175caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_4: 7185caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_8: 7195caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_16: 72009b6bf5bfa2ba9cbbd353cbd7846af8f49b020e7Mon P Wang return EmitBinaryAtomic(*this, Intrinsic::atomic_load_sub, E); 7215caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_1: 7225caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_2: 7235caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_4: 7245caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_8: 7255caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_16: 7265caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner return EmitBinaryAtomic(*this, Intrinsic::atomic_load_or, E); 7275caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_1: 7285caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_2: 7295caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_4: 7305caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_8: 7315caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_16: 7325caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner return EmitBinaryAtomic(*this, Intrinsic::atomic_load_and, E); 7335caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_1: 7345caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_2: 7355caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_4: 7365caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_8: 7375caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_16: 7385caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner return EmitBinaryAtomic(*this, Intrinsic::atomic_load_xor, E); 7391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7405caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // Clang extensions: not overloaded yet. 7411ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_min: 7421ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang return EmitBinaryAtomic(*this, Intrinsic::atomic_load_min, E); 7431ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_max: 7441ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang return EmitBinaryAtomic(*this, Intrinsic::atomic_load_max, E); 7451ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_umin: 7461ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umin, E); 7471ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_umax: 7481ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umax, E); 7490002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar 7505caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_1: 7515caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_2: 7525caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_4: 7535caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_8: 7545caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_16: 7551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_add, E, 7560002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::Add); 7575caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_1: 7585caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_2: 7595caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_4: 7605caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_8: 7615caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_16: 7620002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_sub, E, 7630002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::Sub); 7645caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_1: 7655caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_2: 7665caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_4: 7675caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_8: 7685caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_16: 7690002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_and, E, 7700002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::And); 7715caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_1: 7725caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_2: 7735caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_4: 7745caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_8: 7755caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_16: 7760002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_or, E, 7770002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::Or); 7785caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_1: 7795caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_2: 7805caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_4: 7815caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_8: 7825caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_16: 7830002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_xor, E, 7840002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::Xor); 7851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7865caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap_1: 7875caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap_2: 7885caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap_4: 7895caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap_8: 790cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar case Builtin::BI__sync_val_compare_and_swap_16: { 791db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth const llvm::Type *ValueType = 792db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth llvm::IntegerType::get(CGF.getLLVMContext(), 793db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth CGF.getContext().getTypeSize(E->getType())); 794db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth const llvm::Type *PtrType = ValueType->getPointerTo(); 795db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth const llvm::Type *IntrinsicTypes[2] = { ValueType, PtrType }; 796db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap, 797db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth IntrinsicTypes, 2); 798db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth 799db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth Value *Args[3] = { Builder.CreateBitCast(CGF.EmitScalarExpr(E->getArg(0)), 800db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth PtrType), 801db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth EmitCastToInt(CGF, ValueType, 802db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth CGF.EmitScalarExpr(E->getArg(1))), 803db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth EmitCastToInt(CGF, ValueType, 804db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth CGF.EmitScalarExpr(E->getArg(2))) }; 805db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth return RValue::get(EmitCastFromInt(CGF, E->getType(), 806db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth EmitCallWithBarrier(CGF, AtomF, Args, 807db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth Args + 3))); 808022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson } 8090002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar 8105caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap_1: 8115caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap_2: 8125caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap_4: 8135caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap_8: 814cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar case Builtin::BI__sync_bool_compare_and_swap_16: { 815db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth const llvm::Type *ValueType = 816db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth llvm::IntegerType::get( 817db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth CGF.getLLVMContext(), 818db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth CGF.getContext().getTypeSize(E->getArg(1)->getType())); 819db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth const llvm::Type *PtrType = ValueType->getPointerTo(); 820db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth const llvm::Type *IntrinsicTypes[2] = { ValueType, PtrType }; 821db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap, 822db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth IntrinsicTypes, 2); 823db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth 824db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth Value *Args[3] = { Builder.CreateBitCast(CGF.EmitScalarExpr(E->getArg(0)), 825db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth PtrType), 826db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth EmitCastToInt(CGF, ValueType, 827db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth CGF.EmitScalarExpr(E->getArg(1))), 828db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth EmitCastToInt(CGF, ValueType, 829db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth CGF.EmitScalarExpr(E->getArg(2))) }; 830db4325b098eff5e9e660db19f0148423fb21f27fChandler Carruth Value *OldVal = Args[1]; 831cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar Value *PrevVal = EmitCallWithBarrier(*this, AtomF, Args, Args + 3); 8320002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Value *Result = Builder.CreateICmpEQ(PrevVal, OldVal); 8330002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar // zext bool to int. 8340002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar return RValue::get(Builder.CreateZExt(Result, ConvertType(E->getType()))); 8350002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar } 8360002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar 8375caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_1: 8385caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_2: 8395caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_4: 8405caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_8: 8415caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_16: 8427ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman return EmitBinaryAtomic(*this, Intrinsic::atomic_swap, E); 843cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar 8445caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release_1: 8455caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release_2: 8465caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release_4: 8475caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release_8: 848f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner case Builtin::BI__sync_lock_release_16: { 849f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner Value *Ptr = EmitScalarExpr(E->getArg(0)); 850f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner const llvm::Type *ElTy = 851f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner cast<llvm::PointerType>(Ptr->getType())->getElementType(); 852007b56738b00426688ee85baa75174358bd849f9Daniel Dunbar llvm::StoreInst *Store = 853007b56738b00426688ee85baa75174358bd849f9Daniel Dunbar Builder.CreateStore(llvm::Constant::getNullValue(ElTy), Ptr); 854007b56738b00426688ee85baa75174358bd849f9Daniel Dunbar Store->setVolatile(true); 855eb4f81e174b11633f7b85f555ea5d2834d6dae8aDaniel Dunbar return RValue::get(0); 856f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner } 857ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar 858f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner case Builtin::BI__sync_synchronize: { 859cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar // We assume like gcc appears to, that this only applies to cached memory. 860cb61a7bbe635cfa941b1aeaaa1fbda1bf900ee51Daniel Dunbar EmitMemoryBarrier(*this, true, true, true, true, false); 861eb4f81e174b11633f7b85f555ea5d2834d6dae8aDaniel Dunbar return RValue::get(0); 862f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner } 8631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8640b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner case Builtin::BI__builtin_llvm_memory_barrier: { 8650b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner Value *C[5] = { 8660b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner EmitScalarExpr(E->getArg(0)), 8670b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner EmitScalarExpr(E->getArg(1)), 8680b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner EmitScalarExpr(E->getArg(2)), 8690b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner EmitScalarExpr(E->getArg(3)), 8700b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner EmitScalarExpr(E->getArg(4)) 8710b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner }; 8720b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner Builder.CreateCall(CGM.getIntrinsic(Intrinsic::memory_barrier), C, C + 5); 8730b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner return RValue::get(0); 8740b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner } 8750b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner 876ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar // Library functions with special handling. 877ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIsqrt: 878ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIsqrtf: 879ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIsqrtl: { 880beb41281f8355caa05700d0a77539defbdf428f8John McCall // TODO: there is currently no set of optimizer flags 881beb41281f8355caa05700d0a77539defbdf428f8John McCall // sufficient for us to rewrite sqrt to @llvm.sqrt. 882beb41281f8355caa05700d0a77539defbdf428f8John McCall // -fmath-errno=0 is not good enough; we need finiteness. 883beb41281f8355caa05700d0a77539defbdf428f8John McCall // We could probably precondition the call with an ult 884beb41281f8355caa05700d0a77539defbdf428f8John McCall // against 0, but is that worth the complexity? 885beb41281f8355caa05700d0a77539defbdf428f8John McCall break; 886ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar } 887ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar 888ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIpow: 889ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIpowf: 890ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIpowl: { 891ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar // Rewrite sqrt to intrinsic if allowed. 89240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis if (!FD->hasAttr<ConstAttr>()) 893ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar break; 894ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar Value *Base = EmitScalarExpr(E->getArg(0)); 895ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar Value *Exponent = EmitScalarExpr(E->getArg(1)); 896ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar const llvm::Type *ArgType = Base->getType(); 897ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::pow, &ArgType, 1); 898ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp")); 899ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar } 900ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman 901ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman case Builtin::BI__builtin_signbit: 902ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman case Builtin::BI__builtin_signbitf: 903ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman case Builtin::BI__builtin_signbitl: { 904ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman LLVMContext &C = CGM.getLLVMContext(); 905ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman 906ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *Arg = EmitScalarExpr(E->getArg(0)); 907ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman const llvm::Type *ArgTy = Arg->getType(); 908ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman if (ArgTy->isPPC_FP128Ty()) 909ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman break; // FIXME: I'm not sure what the right implementation is here. 910ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman int ArgWidth = ArgTy->getPrimitiveSizeInBits(); 911ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman const llvm::Type *ArgIntTy = llvm::IntegerType::get(C, ArgWidth); 912ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *BCArg = Builder.CreateBitCast(Arg, ArgIntTy); 913ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *ZeroCmp = llvm::Constant::getNullValue(ArgIntTy); 914ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *Result = Builder.CreateICmpSLT(BCArg, ZeroCmp); 915ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman return RValue::get(Builder.CreateZExt(Result, ConvertType(E->getType()))); 916ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman } 9177ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman } 9181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 919b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // If this is an alias for a libm function (e.g. __builtin_sin) turn it into 920b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // that function. 9213e41d60eb627dc227c770f1c1c87d06909cf05fdDouglas Gregor if (getContext().BuiltinInfo.isLibFunction(BuiltinID) || 9223e41d60eb627dc227c770f1c1c87d06909cf05fdDouglas Gregor getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID)) 92331777a2540879051a3c643b90e02c3fd3d315243Anders Carlsson return EmitCall(E->getCallee()->getType(), 92431777a2540879051a3c643b90e02c3fd3d315243Anders Carlsson CGM.getBuiltinLibFunction(FD, BuiltinID), 925d2490a91341b57df7a7e54f8a707e7ecde2eeb4eAnders Carlsson ReturnValueSlot(), 92631777a2540879051a3c643b90e02c3fd3d315243Anders Carlsson E->arg_begin(), E->arg_end()); 9271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 928b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // See if we have a target specific intrinsic. 929a6f80ef997f0363386749087b325607eaa5adcfcDale Johannesen const char *Name = getContext().BuiltinInfo.GetName(BuiltinID); 93055cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic; 93155cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar if (const char *Prefix = 9321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Triple::getArchTypePrefix(Target.getTriple().getArch())) 93355cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix, Name); 9341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 935b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (IntrinsicID != Intrinsic::not_intrinsic) { 936b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner SmallVector<Value*, 16> Args; 9371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 938b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner Function *F = CGM.getIntrinsic(IntrinsicID); 939b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner const llvm::FunctionType *FTy = F->getFunctionType(); 9401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 941b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 942b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner Value *ArgValue = EmitScalarExpr(E->getArg(i)); 9431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 944b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // If the intrinsic arg type is different from the builtin arg type 945b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // we need to do a bit cast. 946b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner const llvm::Type *PTy = FTy->getParamType(i); 947b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (PTy != ArgValue->getType()) { 948b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) && 949b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner "Must be able to losslessly bit cast to param"); 950b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner ArgValue = Builder.CreateBitCast(ArgValue, PTy); 951b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 9521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 953b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner Args.push_back(ArgValue); 954b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 9551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 956beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad Value *V = Builder.CreateCall(F, Args.data(), Args.data() + Args.size()); 957b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner QualType BuiltinRetType = E->getType(); 9581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9590032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson const llvm::Type *RetTy = llvm::Type::getVoidTy(VMContext); 960b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (!BuiltinRetType->isVoidType()) RetTy = ConvertType(BuiltinRetType); 9611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 962b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (RetTy != V->getType()) { 963b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner assert(V->getType()->canLosslesslyBitCastTo(RetTy) && 964b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner "Must be able to losslessly bit cast result type"); 965b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner V = Builder.CreateBitCast(V, RetTy); 966b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 9671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 968b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner return RValue::get(V); 969b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 9701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 971b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // See if we have a target specific builtin that needs to be lowered. 972f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E)) 973b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner return RValue::get(V); 9741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 975488e993a135ce700b982bf099c3d6b856301d642Daniel Dunbar ErrorUnsupported(E, "builtin function"); 9761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 977b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // Unknown builtin, for now just dump it out and return undef. 978b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (hasAggregateLLVMType(E->getType())) 979195337d2e5d4625ae9dc1328c7cdbc7115b0261bDaniel Dunbar return RValue::getAggregate(CreateMemTemp(E->getType())); 98003e205031b08669f05c41eed5b896fc94c4a12bbOwen Anderson return RValue::get(llvm::UndefValue::get(ConvertType(E->getType()))); 9811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 982564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson 983f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel DunbarValue *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, 984f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar const CallExpr *E) { 98555cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar switch (Target.getTriple().getArch()) { 9862752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner case llvm::Triple::arm: 9872752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner case llvm::Triple::thumb: 9882752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner return EmitARMBuiltinExpr(BuiltinID, E); 98955cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::x86: 99055cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::x86_64: 991f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar return EmitX86BuiltinExpr(BuiltinID, E); 99255cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::ppc: 99355cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::ppc64: 994f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar return EmitPPCBuiltinExpr(BuiltinID, E); 99555cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar default: 99655cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar return 0; 99755cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar } 998f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar} 999f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar 10004be54302da40d3e7cba3d93115f312d2fcca1879Nate Begemanconst llvm::VectorType *GetNeonType(LLVMContext &C, unsigned type, bool q) { 1001998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman switch (type) { 1002998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman default: break; 1003998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman case 0: 10044be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case 5: return llvm::VectorType::get(llvm::Type::getInt8Ty(C), 8 << (int)q); 1005998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman case 6: 1006998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman case 7: 10074be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case 1: return llvm::VectorType::get(llvm::Type::getInt16Ty(C),4 << (int)q); 10084be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case 2: return llvm::VectorType::get(llvm::Type::getInt32Ty(C),2 << (int)q); 10094be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case 3: return llvm::VectorType::get(llvm::Type::getInt64Ty(C),1 << (int)q); 10104be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case 4: return llvm::VectorType::get(llvm::Type::getFloatTy(C),2 << (int)q); 1011998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman }; 1012998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman return 0; 1013998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman} 1014998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman 1015cd480ad90ff4c144084805761d2dfa52ee9e1c92Nate BegemanValue *CodeGenFunction::EmitNeonSplat(Value *V, Constant *C, bool widen) { 1016d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman unsigned nElts = cast<llvm::VectorType>(V->getType())->getNumElements(); 1017cd480ad90ff4c144084805761d2dfa52ee9e1c92Nate Begeman if (widen) 1018cd480ad90ff4c144084805761d2dfa52ee9e1c92Nate Begeman nElts <<= 1; 1019d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman SmallVector<Constant*, 16> Indices(nElts, C); 1020d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman Value* SV = llvm::ConstantVector::get(Indices.begin(), Indices.size()); 1021d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman return Builder.CreateShuffleVector(V, V, SV, "lane"); 1022d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman} 1023d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman 102430d91718a676177f0d0d0210ce4fdb4f616df6e5Nate BegemanValue *CodeGenFunction::EmitNeonCall(Function *F, SmallVectorImpl<Value*> &Ops, 102561eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman const char *name, bool splat, 102661eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman unsigned shift, bool rightshift) { 102730d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman unsigned j = 0; 102830d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end(); 102930d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman ai != ae; ++ai, ++j) 103061eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman if (shift > 0 && shift == j) 103161eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[j] = EmitNeonShiftVector(Ops[j], ai->getType(), rightshift); 103261eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman else 103361eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[j] = Builder.CreateBitCast(Ops[j], ai->getType(), name); 103430d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman 1035d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman if (splat) { 1036d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman Ops[j-1] = EmitNeonSplat(Ops[j-1], cast<Constant>(Ops[j])); 1037d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman Ops.resize(j); 1038d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman } 103930d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return Builder.CreateCall(F, Ops.begin(), Ops.end(), name); 104030d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman} 104130d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman 1042464ccb68f22a7e1c0a2844551c16f721540c91c3Nate BegemanValue *CodeGenFunction::EmitNeonShiftVector(Value *V, const llvm::Type *Ty, 1043464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman bool neg) { 1044464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman ConstantInt *CI = cast<ConstantInt>(V); 1045464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman int SV = CI->getSExtValue(); 1046464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman 1047464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman const llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 1048464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman llvm::Constant *C = ConstantInt::get(VTy->getElementType(), neg ? -SV : SV); 1049464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman SmallVector<llvm::Constant*, 16> CV(VTy->getNumElements(), C); 1050464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return llvm::ConstantVector::get(CV.begin(), CV.size()); 1051464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman} 1052464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman 10532752c0137d95aa2f4ee1cdff4b564bac842e041bChris LattnerValue *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, 10542752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner const CallExpr *E) { 1055e140af3e27016f902146023fba7680b43043ec07Rafael Espindola if (BuiltinID == ARM::BI__clear_cache) { 105679ba509b0106fd0a1ff832baeb1fdb5430527efeRafael Espindola const FunctionDecl *FD = E->getDirectCallee(); 105779ba509b0106fd0a1ff832baeb1fdb5430527efeRafael Espindola Value *a = EmitScalarExpr(E->getArg(0)); 105879ba509b0106fd0a1ff832baeb1fdb5430527efeRafael Espindola Value *b = EmitScalarExpr(E->getArg(1)); 105979ba509b0106fd0a1ff832baeb1fdb5430527efeRafael Espindola const llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); 106079ba509b0106fd0a1ff832baeb1fdb5430527efeRafael Espindola const llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); 106179ba509b0106fd0a1ff832baeb1fdb5430527efeRafael Espindola llvm::StringRef Name = FD->getName(); 106279ba509b0106fd0a1ff832baeb1fdb5430527efeRafael Espindola return Builder.CreateCall2(CGM.CreateRuntimeFunction(FTy, Name), 106379ba509b0106fd0a1ff832baeb1fdb5430527efeRafael Espindola a, b); 10642752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner } 1065e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 1066d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman llvm::SmallVector<Value*, 4> Ops; 1067e140af3e27016f902146023fba7680b43043ec07Rafael Espindola for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) 1068e140af3e27016f902146023fba7680b43043ec07Rafael Espindola Ops.push_back(EmitScalarExpr(E->getArg(i))); 1069e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 1070e140af3e27016f902146023fba7680b43043ec07Rafael Espindola llvm::APSInt Result; 1071e140af3e27016f902146023fba7680b43043ec07Rafael Espindola const Expr *Arg = E->getArg(E->getNumArgs()-1); 1072e140af3e27016f902146023fba7680b43043ec07Rafael Espindola if (!Arg->isIntegerConstantExpr(Result, getContext())) 1073e140af3e27016f902146023fba7680b43043ec07Rafael Espindola return 0; 1074e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 107599c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f || 107699c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman BuiltinID == ARM::BI__builtin_arm_vcvtr_d) { 107799c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman // Determine the overloaded type of this builtin. 107899c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman const llvm::Type *Ty; 107999c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f) 108099c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman Ty = llvm::Type::getFloatTy(VMContext); 108199c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman else 108299c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman Ty = llvm::Type::getDoubleTy(VMContext); 108399c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman 108499c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman // Determine whether this is an unsigned conversion or not. 108599c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman bool usgn = Result.getZExtValue() == 1; 108699c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman unsigned Int = usgn ? Intrinsic::arm_vcvtru : Intrinsic::arm_vcvtr; 108799c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman 108899c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman // Call the appropriate intrinsic. 108999c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman Function *F = CGM.getIntrinsic(Int, &Ty, 1); 109099c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman return Builder.CreateCall(F, Ops.begin(), Ops.end(), "vcvtr"); 109199c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman } 109299c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman 109399c40bb13b523d58d7aeb6446e4f486d6918ca58Nate Begeman // Determine the type of this overloaded NEON intrinsic. 1094e140af3e27016f902146023fba7680b43043ec07Rafael Espindola unsigned type = Result.getZExtValue(); 1095e140af3e27016f902146023fba7680b43043ec07Rafael Espindola bool usgn = type & 0x08; 1096e140af3e27016f902146023fba7680b43043ec07Rafael Espindola bool quad = type & 0x10; 10970d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman bool poly = (type & 0x7) == 5 || (type & 0x7) == 6; 1098d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman bool splat = false; 1099e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 11004be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman const llvm::VectorType *VTy = GetNeonType(VMContext, type & 0x7, quad); 11014be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman const llvm::Type *Ty = VTy; 1102e140af3e27016f902146023fba7680b43043ec07Rafael Espindola if (!Ty) 1103e140af3e27016f902146023fba7680b43043ec07Rafael Espindola return 0; 1104e140af3e27016f902146023fba7680b43043ec07Rafael Espindola 1105e140af3e27016f902146023fba7680b43043ec07Rafael Espindola unsigned Int; 1106e140af3e27016f902146023fba7680b43043ec07Rafael Espindola switch (BuiltinID) { 1107e140af3e27016f902146023fba7680b43043ec07Rafael Espindola default: return 0; 1108998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman case ARM::BI__builtin_neon_vaba_v: 110930d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman case ARM::BI__builtin_neon_vabaq_v: 1110998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman Int = usgn ? Intrinsic::arm_neon_vabau : Intrinsic::arm_neon_vabas; 111130d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vaba"); 111230d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman case ARM::BI__builtin_neon_vabal_v: 1113998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman Int = usgn ? Intrinsic::arm_neon_vabalu : Intrinsic::arm_neon_vabals; 111430d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vabal"); 1115998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman case ARM::BI__builtin_neon_vabd_v: 111630d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman case ARM::BI__builtin_neon_vabdq_v: 1117998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman Int = usgn ? Intrinsic::arm_neon_vabdu : Intrinsic::arm_neon_vabds; 111830d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vabd"); 111930d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman case ARM::BI__builtin_neon_vabdl_v: 1120998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman Int = usgn ? Intrinsic::arm_neon_vabdlu : Intrinsic::arm_neon_vabdls; 112130d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vabdl"); 1122998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman case ARM::BI__builtin_neon_vabs_v: 1123548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vabsq_v: 1124548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vabs, &Ty, 1), 1125548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vabs"); 1126548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vaddhn_v: 1127548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vaddhn, &Ty, 1), 1128548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vaddhn"); 112930d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman case ARM::BI__builtin_neon_vaddl_v: 1130998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman Int = usgn ? Intrinsic::arm_neon_vaddlu : Intrinsic::arm_neon_vaddls; 113130d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vaddl"); 113230d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman case ARM::BI__builtin_neon_vaddw_v: 1133998622c10198a25ba06c93d7e908f88ba0acc920Nate Begeman Int = usgn ? Intrinsic::arm_neon_vaddws : Intrinsic::arm_neon_vaddwu; 113430d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vaddw"); 11359eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman case ARM::BI__builtin_neon_vcale_v: 11369eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman std::swap(Ops[0], Ops[1]); 113730d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman case ARM::BI__builtin_neon_vcage_v: { 113830d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacged, &Ty, 1); 113930d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcage"); 114030d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 11419eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman case ARM::BI__builtin_neon_vcaleq_v: 11429eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman std::swap(Ops[0], Ops[1]); 114330d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman case ARM::BI__builtin_neon_vcageq_v: { 114430d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgeq, &Ty, 1); 114530d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcage"); 114630d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 11479eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman case ARM::BI__builtin_neon_vcalt_v: 11489eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman std::swap(Ops[0], Ops[1]); 114930d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman case ARM::BI__builtin_neon_vcagt_v: { 115030d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgtd, &Ty, 1); 115130d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcagt"); 115230d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 11539eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman case ARM::BI__builtin_neon_vcaltq_v: 11549eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman std::swap(Ops[0], Ops[1]); 115530d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman case ARM::BI__builtin_neon_vcagtq_v: { 115630d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgtq, &Ty, 1); 115730d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcagt"); 115830d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 11599eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman case ARM::BI__builtin_neon_vcls_v: 11609eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman case ARM::BI__builtin_neon_vclsq_v: { 116130d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcls, &Ty, 1); 116230d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcls"); 11639eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 11649eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman case ARM::BI__builtin_neon_vclz_v: 11659eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman case ARM::BI__builtin_neon_vclzq_v: { 116630d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vclz, &Ty, 1); 116730d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vclz"); 11689eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 11699eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman case ARM::BI__builtin_neon_vcnt_v: 11709eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman case ARM::BI__builtin_neon_vcntq_v: { 117130d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcnt, &Ty, 1); 117230d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcnt"); 11739eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 11749eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman // FIXME: intrinsics for f16<->f32 convert missing from ARM target. 11759eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman case ARM::BI__builtin_neon_vcvt_f32_v: 11769eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman case ARM::BI__builtin_neon_vcvtq_f32_v: { 117730d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 117830d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Ty = GetNeonType(VMContext, 4, quad); 11799eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") 11809eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); 11819eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 11829eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman case ARM::BI__builtin_neon_vcvt_s32_v: 11839eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman case ARM::BI__builtin_neon_vcvt_u32_v: 11849eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman case ARM::BI__builtin_neon_vcvtq_s32_v: 11859eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman case ARM::BI__builtin_neon_vcvtq_u32_v: { 118630d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(VMContext, 4, quad)); 11879eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman return usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt") 11889eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman : Builder.CreateFPToSI(Ops[0], Ty, "vcvt"); 11899eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 11909eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman case ARM::BI__builtin_neon_vcvt_n_f32_v: 11919eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman case ARM::BI__builtin_neon_vcvtq_n_f32_v: { 119230d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman const llvm::Type *Tys[2] = { GetNeonType(VMContext, 4, quad), Ty }; 11939eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman Int = usgn ? Intrinsic::arm_neon_vcvtfxu2fp : Intrinsic::arm_neon_vcvtfxs2fp; 119430d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Function *F = CGM.getIntrinsic(Int, Tys, 2); 119530d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcvt_n"); 11969eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 11979eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman case ARM::BI__builtin_neon_vcvt_n_s32_v: 11989eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman case ARM::BI__builtin_neon_vcvt_n_u32_v: 11999eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman case ARM::BI__builtin_neon_vcvtq_n_s32_v: 12009eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman case ARM::BI__builtin_neon_vcvtq_n_u32_v: { 120130d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman const llvm::Type *Tys[2] = { Ty, GetNeonType(VMContext, 4, quad) }; 12029eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman Int = usgn ? Intrinsic::arm_neon_vcvtfp2fxu : Intrinsic::arm_neon_vcvtfp2fxs; 120330d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Function *F = CGM.getIntrinsic(Int, Tys, 2); 120430d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman return EmitNeonCall(F, Ops, "vcvt_n"); 120530d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman } 1206cd480ad90ff4c144084805761d2dfa52ee9e1c92Nate Begeman case ARM::BI__builtin_neon_vdup_lane_v: 1207cd480ad90ff4c144084805761d2dfa52ee9e1c92Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 1208cd480ad90ff4c144084805761d2dfa52ee9e1c92Nate Begeman return EmitNeonSplat(Ops[0], cast<Constant>(Ops[1])); 1209cd480ad90ff4c144084805761d2dfa52ee9e1c92Nate Begeman case ARM::BI__builtin_neon_vdupq_lane_v: 1210cd480ad90ff4c144084805761d2dfa52ee9e1c92Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 1211cd480ad90ff4c144084805761d2dfa52ee9e1c92Nate Begeman return EmitNeonSplat(Ops[0], cast<Constant>(Ops[1]), true); 121230d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman case ARM::BI__builtin_neon_vext_v: 121330d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman case ARM::BI__builtin_neon_vextq_v: { 121430d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman ConstantInt *C = dyn_cast<ConstantInt>(Ops[2]); 121530d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman int CV = C->getSExtValue(); 12161c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman SmallVector<Constant*, 16> Indices; 12174be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 121877b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Indices.push_back(ConstantInt::get(Int32Ty, i+CV)); 121930d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman 122030d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 122130d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 122230d91718a676177f0d0d0210ce4fdb4f616df6e5Nate Begeman Value* SV = llvm::ConstantVector::get(Indices.begin(), Indices.size()); 12231c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return Builder.CreateShuffleVector(Ops[0], Ops[1], SV, "vext"); 12241c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 122595450f6ffc89ee218faa550433265f80930469c4Nate Begeman case ARM::BI__builtin_neon_vget_lane_i8: 122695450f6ffc89ee218faa550433265f80930469c4Nate Begeman case ARM::BI__builtin_neon_vget_lane_i16: 122795450f6ffc89ee218faa550433265f80930469c4Nate Begeman case ARM::BI__builtin_neon_vget_lane_i32: 122895450f6ffc89ee218faa550433265f80930469c4Nate Begeman case ARM::BI__builtin_neon_vget_lane_i64: 122995450f6ffc89ee218faa550433265f80930469c4Nate Begeman case ARM::BI__builtin_neon_vget_lane_f32: 123095450f6ffc89ee218faa550433265f80930469c4Nate Begeman case ARM::BI__builtin_neon_vgetq_lane_i8: 123195450f6ffc89ee218faa550433265f80930469c4Nate Begeman case ARM::BI__builtin_neon_vgetq_lane_i16: 123295450f6ffc89ee218faa550433265f80930469c4Nate Begeman case ARM::BI__builtin_neon_vgetq_lane_i32: 123395450f6ffc89ee218faa550433265f80930469c4Nate Begeman case ARM::BI__builtin_neon_vgetq_lane_i64: 123495450f6ffc89ee218faa550433265f80930469c4Nate Begeman case ARM::BI__builtin_neon_vgetq_lane_f32: 1235df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 1236df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman "vget_lane"); 1237df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman case ARM::BI__builtin_neon_vhadd_v: 1238df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman case ARM::BI__builtin_neon_vhaddq_v: 1239df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vhaddu : Intrinsic::arm_neon_vhadds; 1240df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vhadd"); 1241df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman case ARM::BI__builtin_neon_vhsub_v: 1242df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman case ARM::BI__builtin_neon_vhsubq_v: 1243df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vhsubu : Intrinsic::arm_neon_vhsubs; 1244df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vhsub"); 12454be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld1_v: 12464be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld1q_v: 12474be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vld1, &Ty, 1), 12484be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops, "vld1"); 12494be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld1_lane_v: 12504be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld1q_lane_v: 12514be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 12524be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 12534be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 12544be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateLoad(Ops[0]); 12554be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vld1_lane"); 12564be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld1_dup_v: 12574be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld1q_dup_v: { 12584be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *V = UndefValue::get(Ty); 12594be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 12604be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 12614be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateLoad(Ops[0]); 126277b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 12634be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateInsertElement(V, Ops[0], CI); 12644be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return EmitNeonSplat(Ops[0], CI); 12654be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 12664be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld2_v: 12674be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld2q_v: { 12684be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld2, &Ty, 1); 12694be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[1] = Builder.CreateCall(F, Ops[1], "vld2"); 12704be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 12714be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 12724be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 12734be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 12744be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld3_v: 12754be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld3q_v: { 12764be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld3, &Ty, 1); 12774be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[1] = Builder.CreateCall(F, Ops[1], "vld3"); 12784be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 12794be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 12804be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 12814be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 12824be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld4_v: 12834be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld4q_v: { 12844be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld4, &Ty, 1); 12854be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[1] = Builder.CreateCall(F, Ops[1], "vld4"); 12864be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 12874be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 12884be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 12894be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 12904be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld2_lane_v: 12914be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld2q_lane_v: { 12924be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld2lane, &Ty, 1); 12934be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 12944be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 12954be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[1] = Builder.CreateCall(F, Ops.begin() + 1, Ops.end(), "vld2_lane"); 12964be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 12974be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 12984be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 12994be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 13004be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld3_lane_v: 13014be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld3q_lane_v: { 13024be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld3lane, &Ty, 1); 13034be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 13044be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 13054be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[4] = Builder.CreateBitCast(Ops[4], Ty); 13064be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[1] = Builder.CreateCall(F, Ops.begin() + 1, Ops.end(), "vld3_lane"); 13074be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 13084be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 13094be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 13104be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 13114be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld4_lane_v: 13124be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld4q_lane_v: { 13134be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld4lane, &Ty, 1); 13144be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 13154be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 13164be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[4] = Builder.CreateBitCast(Ops[4], Ty); 13174be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[5] = Builder.CreateBitCast(Ops[5], Ty); 13184be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[1] = Builder.CreateCall(F, Ops.begin() + 1, Ops.end(), "vld3_lane"); 13194be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 13204be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 13214be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 13224be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 13234be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld2_dup_v: 13244be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld3_dup_v: 13254be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld4_dup_v: { 13264be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman switch (BuiltinID) { 13274be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld2_dup_v: 13284be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Int = Intrinsic::arm_neon_vld2lane; 13294be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman break; 13304be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld3_dup_v: 13314be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Int = Intrinsic::arm_neon_vld2lane; 13324be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman break; 13334be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman case ARM::BI__builtin_neon_vld4_dup_v: 13344be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Int = Intrinsic::arm_neon_vld2lane; 13354be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman break; 13364be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman default: assert(0 && "unknown vld_dup intrinsic?"); 13374be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 13384be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Function *F = CGM.getIntrinsic(Int, &Ty, 1); 13394be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman const llvm::StructType *STy = cast<llvm::StructType>(F->getReturnType()); 13404be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 13414be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SmallVector<Value*, 6> Args; 13424be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Args.push_back(Ops[1]); 13434be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Args.append(STy->getNumElements(), UndefValue::get(Ty)); 13444be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 134577b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 13464be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Args.push_back(CI); 13474be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 13484be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[1] = Builder.CreateCall(F, Args.begin(), Args.end(), "vld_dup"); 13494be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman // splat lane 0 to all elts in each vector of the result. 13504be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { 13514be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Val = Builder.CreateExtractValue(Ops[1], i); 13524be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Elt = Builder.CreateBitCast(Val, Ty); 13534be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Elt = EmitNeonSplat(Elt, CI); 13544be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Elt = Builder.CreateBitCast(Elt, Val->getType()); 13554be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[1] = Builder.CreateInsertValue(Ops[1], Elt, i); 13564be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 13574be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 13584be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 13594be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 13604be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 1361df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman case ARM::BI__builtin_neon_vmax_v: 1362df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman case ARM::BI__builtin_neon_vmaxq_v: 1363df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vmaxu : Intrinsic::arm_neon_vmaxs; 1364df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vmax"); 1365df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman case ARM::BI__builtin_neon_vmin_v: 1366df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman case ARM::BI__builtin_neon_vminq_v: 1367df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vminu : Intrinsic::arm_neon_vmins; 1368df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vmin"); 1369d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman case ARM::BI__builtin_neon_vmlal_lane_v: 1370d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman splat = true; 1371df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman case ARM::BI__builtin_neon_vmlal_v: 1372df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vmlalu : Intrinsic::arm_neon_vmlals; 1373d075c01c359b9cc120c3accc7166990f9f4ac423Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vmlal", splat); 1374548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vmlsl_lane_v: 1375548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman splat = true; 1376548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vmlsl_v: 1377548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vmlslu : Intrinsic::arm_neon_vmlsls; 1378548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vmlsl", splat); 1379df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman case ARM::BI__builtin_neon_vmovl_v: 13807cea322bf019b0d38867a27e20e3771d84dbb1afBob Wilson if (usgn) 13817cea322bf019b0d38867a27e20e3771d84dbb1afBob Wilson return Builder.CreateZExt(Ops[0], Ty, "vmovl"); 13827cea322bf019b0d38867a27e20e3771d84dbb1afBob Wilson return Builder.CreateSExt(Ops[0], Ty, "vmovl"); 1383df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman case ARM::BI__builtin_neon_vmovn_v: 1384df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vmovn, &Ty, 1), 1385df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Ops, "vmovn"); 1386548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vmull_lane_v: 1387548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman splat = true; 1388548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vmull_v: 1389548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls; 1390548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = poly ? (unsigned)Intrinsic::arm_neon_vmullp : Int; 1391548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vmlal", splat); 1392df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman case ARM::BI__builtin_neon_vpadal_v: 1393df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman case ARM::BI__builtin_neon_vpadalq_v: 1394df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman Int = usgn ? Intrinsic::arm_neon_vpadalu : Intrinsic::arm_neon_vpadals; 1395df98e1d1da5ab1ca7c325378fc1c2eaa90a6476dNate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vpadal"); 1396548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vpadd_v: 1397548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vpadd, &Ty, 1), 1398548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vpadd"); 1399548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vpaddl_v: 1400548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vpaddlq_v: 1401548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vpaddlu : Intrinsic::arm_neon_vpaddls; 1402548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vpaddl"); 1403548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vpmax_v: 1404548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vpmaxu : Intrinsic::arm_neon_vpmaxs; 1405548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vpmax"); 1406548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vpmin_v: 1407548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vpminu : Intrinsic::arm_neon_vpmins; 1408548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vpmin"); 1409548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqabs_v: 1410548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqabsq_v: 1411548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqabs, &Ty, 1), 1412548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vqabs"); 1413548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqadd_v: 1414548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqaddq_v: 1415548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vqaddu : Intrinsic::arm_neon_vqadds; 1416548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vqadd"); 1417548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqdmlal_lane_v: 1418548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman splat = true; 1419548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqdmlal_v: 1420548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmlal, &Ty, 1), 142161eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops, "vqdmlal", splat); 1422548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqdmlsl_lane_v: 1423548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman splat = true; 1424548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqdmlsl_v: 1425548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmlsl, &Ty, 1), 142661eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops, "vqdmlsl", splat); 1427548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqdmulh_lane_v: 1428548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqdmulhq_lane_v: 1429548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman splat = true; 1430548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqdmulh_v: 1431548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqdmulhq_v: 1432548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmulh, &Ty, 1), 143361eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops, "vqdmulh", splat); 1434548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqdmull_lane_v: 1435548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman splat = true; 1436548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqdmull_v: 1437548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmull, &Ty, 1), 143861eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops, "vqdmull", splat); 1439548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqmovn_v: 1440548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vqmovnu : Intrinsic::arm_neon_vqmovns; 1441548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vqmovn"); 1442548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqmovun_v: 1443548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqmovnsu, &Ty, 1), 1444548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vqdmull"); 1445548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqneg_v: 144661eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqneg, &Ty, 1), 144761eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops, "vqneg"); 1448548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqrdmulh_lane_v: 1449548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqrdmulhq_lane_v: 1450548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman splat = true; 1451548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqrdmulh_v: 1452548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqrdmulhq_v: 1453548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrdmulh, &Ty, 1), 145461eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops, "vqrdmulh", splat); 1455548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqrshl_v: 1456548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqrshlq_v: 1457548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vqrshiftu : Intrinsic::arm_neon_vqrshifts; 1458548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vqrshl"); 1459548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqrshrn_n_v: 1460548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vqrshiftnu : Intrinsic::arm_neon_vqrshiftns; 146161eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vqrshrn_n", false, 146261eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman 1, true); 1463548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vqrshrun_n_v: 1464548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrshiftnsu, &Ty, 1), 146561eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops, "vqrshrun_n", false, 1, true); 146661eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman case ARM::BI__builtin_neon_vqshl_v: 146761eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman case ARM::BI__builtin_neon_vqshlq_v: 146861eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Int = usgn ? Intrinsic::arm_neon_vqshiftu : Intrinsic::arm_neon_vqshifts; 146961eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vqshl"); 147061eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman case ARM::BI__builtin_neon_vqshl_n_v: 147161eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman case ARM::BI__builtin_neon_vqshlq_n_v: 147261eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Int = usgn ? Intrinsic::arm_neon_vqshiftu : Intrinsic::arm_neon_vqshifts; 147361eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vqshl_n", false, 147461eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman 1, false); 147561eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman case ARM::BI__builtin_neon_vqshlu_n_v: 147661eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman case ARM::BI__builtin_neon_vqshluq_n_v: 147761eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftsu, &Ty, 1), 147861eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops, "vqshlu", 1, false); 147961eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman case ARM::BI__builtin_neon_vqshrn_n_v: 148061eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Int = usgn ? Intrinsic::arm_neon_vqshiftnu : Intrinsic::arm_neon_vqshiftns; 148161eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vqshrn_n", false, 148261eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman 1, true); 148361eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman case ARM::BI__builtin_neon_vqshrun_n_v: 148461eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftnsu, &Ty, 1), 148561eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops, "vqshrun_n", false, 1, true); 1486464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vqsub_v: 1487464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vqsubq_v: 1488464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Int = usgn ? Intrinsic::arm_neon_vqsubu : Intrinsic::arm_neon_vqsubs; 1489464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vqsub"); 1490464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vraddhn_v: 1491464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vraddhn, &Ty, 1), 1492464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vraddhn"); 1493464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vrecpe_v: 1494464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vrecpeq_v: 1495464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecpe, &Ty, 1), 1496464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vrecpe"); 1497464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vrecps_v: 1498464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vrecpsq_v: 1499464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecps, &Ty, 1), 1500464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vrecps"); 1501464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vrhadd_v: 1502464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vrhaddq_v: 1503464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Int = usgn ? Intrinsic::arm_neon_vrhaddu : Intrinsic::arm_neon_vrhadds; 1504464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vrhadd"); 15055af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman case ARM::BI__builtin_neon_vrshl_v: 15065af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman case ARM::BI__builtin_neon_vrshlq_v: 15075af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 15085af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vrshl"); 15095af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman case ARM::BI__builtin_neon_vrshrn_n_v: 15105af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrshiftn, &Ty, 1), 151161eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops, "vrshrn_n", false, 1, true); 15125af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman case ARM::BI__builtin_neon_vrshr_n_v: 15135af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman case ARM::BI__builtin_neon_vrshrq_n_v: 15145af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 151561eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vrshr_n", false, 151661eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman 1, true); 15175af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman case ARM::BI__builtin_neon_vrsqrte_v: 15185af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman case ARM::BI__builtin_neon_vrsqrteq_v: 15195af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsqrte, &Ty, 1), 15205af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops, "vrsqrte"); 15215af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman case ARM::BI__builtin_neon_vrsqrts_v: 15225af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman case ARM::BI__builtin_neon_vrsqrtsq_v: 15235af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsqrts, &Ty, 1), 15245af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops, "vrsqrts"); 15255af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman case ARM::BI__builtin_neon_vrsra_n_v: 15265af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman case ARM::BI__builtin_neon_vrsraq_n_v: 15275af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 15285af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 15295af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops[2] = EmitNeonShiftVector(Ops[2], Ty, true); 15305af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 15315af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman Ops[1] = Builder.CreateCall2(CGM.getIntrinsic(Int, &Ty, 1), Ops[1], Ops[2]); 15325af93efc01f4acd247aa6d3124db6c92c3679198Nate Begeman return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n"); 1533464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vrsubhn_v: 1534464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsubhn, &Ty, 1), 1535464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vrsubhn"); 1536548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vset_lane_i8: 1537548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vset_lane_i16: 1538548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vset_lane_i32: 1539548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vset_lane_i64: 1540548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vset_lane_f32: 1541548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vsetq_lane_i8: 1542548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vsetq_lane_i16: 1543548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vsetq_lane_i32: 1544548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vsetq_lane_i64: 1545548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vsetq_lane_f32: 1546548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops.push_back(EmitScalarExpr(E->getArg(2))); 1547548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 1548464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vshl_v: 1549464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vshlq_v: 1550464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Int = usgn ? Intrinsic::arm_neon_vshiftu : Intrinsic::arm_neon_vshifts; 1551464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vshl"); 1552464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vshll_n_v: 1553464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Int = usgn ? Intrinsic::arm_neon_vshiftlu : Intrinsic::arm_neon_vshiftls; 155461eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vshll", false, 1); 1555464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vshl_n_v: 1556464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vshlq_n_v: 155761eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false); 155861eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman return Builder.CreateShl(Builder.CreateBitCast(Ops[0],Ty), Ops[1], "vshl_n"); 1559464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vshrn_n_v: 1560464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftn, &Ty, 1), 156161eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops, "vshrn_n", false, 1, true); 1562464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vshr_n_v: 1563464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vshrq_n_v: 1564464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 156561eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false); 1566464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman if (usgn) 1567464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return Builder.CreateLShr(Ops[0], Ops[1], "vshr_n"); 1568464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman else 1569464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return Builder.CreateAShr(Ops[0], Ops[1], "vshr_n"); 1570464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vsri_n_v: 1571464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vsriq_n_v: 1572464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman poly = true; 1573464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vsli_n_v: 1574464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vsliq_n_v: 1575464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[2] = EmitNeonShiftVector(Ops[2], Ty, poly); 1576464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftins, &Ty, 1), 1577464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, "vsli_n"); 1578464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vsra_n_v: 1579464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vsraq_n_v: 1580464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 1581464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 158261eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman Ops[2] = EmitNeonShiftVector(Ops[2], Ty, false); 1583464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman if (usgn) 1584464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateLShr(Ops[1], Ops[2], "vsra_n"); 1585464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman else 1586464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateAShr(Ops[1], Ops[2], "vsra_n"); 1587464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return Builder.CreateAdd(Ops[0], Ops[1]); 1588464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vst1_v: 1589464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vst1q_v: 1590464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, &Ty, 1), 1591464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 1592464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vst1_lane_v: 1593464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vst1q_lane_v: 1594464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 1595464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); 1596464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 1597464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return Builder.CreateStore(Ops[1], Builder.CreateBitCast(Ops[0], Ty)); 1598464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vst2_v: 1599464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vst2q_v: 1600464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst2, &Ty, 1), 1601464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 1602464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vst2_lane_v: 1603464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vst2q_lane_v: 1604464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst2lane, &Ty, 1), 1605464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 1606464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vst3_v: 1607464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vst3q_v: 1608464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst3, &Ty, 1), 1609464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 1610464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vst3_lane_v: 1611464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vst3q_lane_v: 1612464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst3lane, &Ty, 1), 1613464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 1614464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vst4_v: 1615464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vst4q_v: 1616464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst4, &Ty, 1), 1617464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 1618464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vst4_lane_v: 1619464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman case ARM::BI__builtin_neon_vst4q_lane_v: 1620464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst4lane, &Ty, 1), 1621464ccb68f22a7e1c0a2844551c16f721540c91c3Nate Begeman Ops, ""); 1622548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vsubhn_v: 1623548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vsubhn, &Ty, 1), 1624548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Ops, "vsubhn"); 1625548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vsubl_v: 1626548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vsublu : Intrinsic::arm_neon_vsubls; 1627548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vsubl"); 1628548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman case ARM::BI__builtin_neon_vsubw_v: 1629548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman Int = usgn ? Intrinsic::arm_neon_vsubws : Intrinsic::arm_neon_vsubwu; 1630548f7daa59012df2e20420e86c2722d19367ef17Nate Begeman return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vsubw"); 16311c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman case ARM::BI__builtin_neon_vtbl1_v: 16321c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl1), 16331c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbl1"); 16341c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman case ARM::BI__builtin_neon_vtbl2_v: 16351c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl2), 16361c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbl2"); 16371c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman case ARM::BI__builtin_neon_vtbl3_v: 16381c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl3), 16391c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbl3"); 16401c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman case ARM::BI__builtin_neon_vtbl4_v: 16411c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl4), 16421c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbl4"); 16431c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman case ARM::BI__builtin_neon_vtbx1_v: 16441c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx1), 16451c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbx1"); 16461c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman case ARM::BI__builtin_neon_vtbx2_v: 16471c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx2), 16481c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbx2"); 16491c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman case ARM::BI__builtin_neon_vtbx3_v: 16501c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx3), 16511c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbx3"); 16521c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman case ARM::BI__builtin_neon_vtbx4_v: 16531c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx4), 16541c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops, "vtbx4"); 16551c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman case ARM::BI__builtin_neon_vtst_v: 16561c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman case ARM::BI__builtin_neon_vtstq_v: { 16571c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 16581c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 16591c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]); 16601c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0], 16611c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman ConstantAggregateZero::get(Ty)); 16621c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman return Builder.CreateSExt(Ops[0], Ty, "vtst"); 16631c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 16641c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman case ARM::BI__builtin_neon_vtrn_v: 16651c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman case ARM::BI__builtin_neon_vtrnq_v: { 16664be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 16674be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 16684be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 16694be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *SV; 16704be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 16711c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman for (unsigned vi = 0; vi != 2; ++vi) { 16724be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SmallVector<Constant*, 16> Indices; 16734be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 167477b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Indices.push_back(ConstantInt::get(Int32Ty, i+vi)); 167577b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Indices.push_back(ConstantInt::get(Int32Ty, i+e+vi)); 16761c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 16774be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi); 16784be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = llvm::ConstantVector::get(Indices.begin(), Indices.size()); 16794be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vtrn"); 16804be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateStore(SV, Addr); 16811c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 16824be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return SV; 16831c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 16841c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman case ARM::BI__builtin_neon_vuzp_v: 16851c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman case ARM::BI__builtin_neon_vuzpq_v: { 16864be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 16871c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 16884be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 16894be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *SV; 16904be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 16914be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned vi = 0; vi != 2; ++vi) { 16924be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SmallVector<Constant*, 16> Indices; 16934be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 169477b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Indices.push_back(ConstantInt::get(Int32Ty, 2*i+vi)); 16954be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 16964be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi); 16974be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = llvm::ConstantVector::get(Indices.begin(), Indices.size()); 16984be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vuzp"); 16994be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateStore(SV, Addr); 17004be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 17014be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return SV; 17021c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 17031c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman case ARM::BI__builtin_neon_vzip_v: 17041c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman case ARM::BI__builtin_neon_vzipq_v: { 17054be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 17061c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 17074be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 17084be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *SV; 17094be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman 17104be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned vi = 0; vi != 2; ++vi) { 17114be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SmallVector<Constant*, 16> Indices; 17124be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 171377b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Indices.push_back(ConstantInt::get(Int32Ty, (i >> 1))); 171477b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Indices.push_back(ConstantInt::get(Int32Ty, (i >> 1)+e)); 17154be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 17164be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi); 17174be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = llvm::ConstantVector::get(Indices.begin(), Indices.size()); 17184be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vzip"); 17194be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman SV = Builder.CreateStore(SV, Addr); 17204be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman } 17214be54302da40d3e7cba3d93115f312d2fcca1879Nate Begeman return SV; 17229eb65a56e18bee1e5392bf2dff01cbd7b895f685Nate Begeman } 17232752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner } 17242752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner} 17252752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner 17261eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpValue *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, 17271feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner const CallExpr *E) { 17281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 17292929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson llvm::SmallVector<Value*, 4> Ops; 17302929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson 17312929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) 17322929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson Ops.push_back(EmitScalarExpr(E->getArg(i))); 17332929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson 1734564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson switch (BuiltinID) { 173546a26b0b0e2ec1557bad9b70e8e20836524ebdfcAnders Carlsson default: return 0; 17361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case X86::BI__builtin_ia32_pslldi128: 1737e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psllqi128: 17381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case X86::BI__builtin_ia32_psllwi128: 1739e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psradi128: 1740e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrawi128: 1741e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrldi128: 1742e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrlqi128: 1743e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrlwi128: { 174477b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Ops[1] = Builder.CreateZExt(Ops[1], Int64Ty, "zext"); 174577b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner const llvm::Type *Ty = llvm::VectorType::get(Int64Ty, 2); 174677b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Value *Zero = llvm::ConstantInt::get(Int32Ty, 0); 174703e205031b08669f05c41eed5b896fc94c4a12bbOwen Anderson Ops[1] = Builder.CreateInsertElement(llvm::UndefValue::get(Ty), 1748e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[1], Zero, "insert"); 1749e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType(), "bitcast"); 1750e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman const char *name = 0; 1751e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Intrinsic::ID ID = Intrinsic::not_intrinsic; 17521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1753e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman switch (BuiltinID) { 1754e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman default: assert(0 && "Unsupported shift intrinsic!"); 1755e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_pslldi128: 1756e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "pslldi"; 1757e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psll_d; 1758e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 1759e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psllqi128: 1760e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "psllqi"; 1761e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psll_q; 1762e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 1763e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psllwi128: 1764e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "psllwi"; 1765e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psll_w; 1766e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 1767e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psradi128: 1768e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "psradi"; 1769e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psra_d; 1770e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 1771e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrawi128: 1772e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "psrawi"; 1773e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psra_w; 1774e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 1775e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrldi128: 1776e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "psrldi"; 1777e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psrl_d; 1778e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 1779e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrlqi128: 1780e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "psrlqi"; 1781e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psrl_q; 1782e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 1783e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrlwi128: 1784e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "psrlwi"; 1785e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psrl_w; 1786e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 1787e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 1788e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman llvm::Function *F = CGM.getIntrinsic(ID); 17891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name); 1790e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 17911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case X86::BI__builtin_ia32_pslldi: 17922929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psllqi: 17931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case X86::BI__builtin_ia32_psllwi: 17942929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psradi: 17952929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrawi: 17962929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrldi: 17972929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrlqi: 17982929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrlwi: { 179977b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Ops[1] = Builder.CreateZExt(Ops[1], Int64Ty, "zext"); 180077b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner const llvm::Type *Ty = llvm::VectorType::get(Int64Ty, 1); 18012929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson Ops[1] = Builder.CreateBitCast(Ops[1], Ty, "bitcast"); 18022929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson const char *name = 0; 18032929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson Intrinsic::ID ID = Intrinsic::not_intrinsic; 18041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18052929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson switch (BuiltinID) { 18062929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson default: assert(0 && "Unsupported shift intrinsic!"); 18072929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_pslldi: 18082929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "pslldi"; 18092929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psll_d; 18102929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 18112929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psllqi: 18122929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "psllqi"; 18132929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psll_q; 18142929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 18152929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psllwi: 18162929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "psllwi"; 18172929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psll_w; 18182929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 18192929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psradi: 18202929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "psradi"; 18212929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psra_d; 18222929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 18232929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrawi: 18242929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "psrawi"; 18252929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psra_w; 18262929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 18272929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrldi: 18282929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "psrldi"; 18292929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psrl_d; 18302929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 18312929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrlqi: 18322929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "psrlqi"; 18332929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psrl_q; 18342929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 18352929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrlwi: 18362929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "psrlwi"; 18372929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psrl_w; 18382929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 18392929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson } 18407acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner llvm::Function *F = CGM.getIntrinsic(ID); 18411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name); 18422929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson } 184379dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson case X86::BI__builtin_ia32_cmpps: { 184479dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ps); 184579dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpps"); 184679dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson } 184779dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson case X86::BI__builtin_ia32_cmpss: { 184879dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ss); 184979dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpss"); 1850cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson } 1851e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_ldmxcsr: { 18523c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext); 185377b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Value *One = llvm::ConstantInt::get(Int32Ty, 1); 185477b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Value *Tmp = Builder.CreateAlloca(Int32Ty, One, "tmp"); 1855e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Builder.CreateStore(Ops[0], Tmp); 1856e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr), 18573eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner Builder.CreateBitCast(Tmp, PtrTy)); 1858e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 1859e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_stmxcsr: { 18603c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext); 186177b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Value *One = llvm::ConstantInt::get(Int32Ty, 1); 186277b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Value *Tmp = Builder.CreateAlloca(Int32Ty, One, "tmp"); 1863e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman One = Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr), 18643eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner Builder.CreateBitCast(Tmp, PtrTy)); 1865e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman return Builder.CreateLoad(Tmp, "stmxcsr"); 1866e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 186779dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson case X86::BI__builtin_ia32_cmppd: { 186879dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_pd); 186979dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmppd"); 187079dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson } 187179dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson case X86::BI__builtin_ia32_cmpsd: { 187279dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_sd); 187379dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpsd"); 1874cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson } 1875e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_storehps: 1876e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_storelps: { 187777b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Type *PtrTy = llvm::PointerType::getUnqual(Int64Ty); 187877b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2); 18791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1880e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman // cast val v2i64 1881e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast"); 18821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1883e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman // extract (0, 1) 1884e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1; 188577b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner llvm::Value *Idx = llvm::ConstantInt::get(Int32Ty, Index); 1886e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract"); 1887e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman 1888e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman // cast pointer to i64 & store 1889e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy); 1890e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 1891e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 189291b59274439f776cdd545bd7bf5849fdb1842160Eric Christopher case X86::BI__builtin_ia32_palignr: { 1893e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 1894e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher 1895e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher // If palignr is shifting the pair of input vectors less than 9 bytes, 1896e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher // emit a shuffle instruction. 1897e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher if (shiftVal <= 8) { 1898e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher llvm::SmallVector<llvm::Constant*, 8> Indices; 1899e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher for (unsigned i = 0; i != 8; ++i) 190077b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Indices.push_back(llvm::ConstantInt::get(Int32Ty, shiftVal + i)); 1901e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher 1902e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher Value* SV = llvm::ConstantVector::get(Indices.begin(), Indices.size()); 1903e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 1904e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher } 1905e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher 1906e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher // If palignr is shifting the pair of input vectors more than 8 but less 1907e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher // than 16 bytes, emit a logical right shift of the destination. 1908e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher if (shiftVal < 16) { 1909e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher // MMX has these as 1 x i64 vectors for some odd optimization reasons. 191077b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner const llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 1); 1911e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher 1912e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 1913e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher Ops[1] = llvm::ConstantInt::get(VecTy, (shiftVal-8) * 8); 1914e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher 1915e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher // create i32 constant 1916e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_mmx_psrl_q); 1917e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher return Builder.CreateCall(F, &Ops[0], &Ops[0] + 2, "palignr"); 1918e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher } 1919e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher 1920e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 1921e57aa9e367af227214140e1a174cc561aabaa0b9Eric Christopher return llvm::Constant::getNullValue(ConvertType(E->getType())); 1922c3420ffb282c6ffc0192013bf8045b6c21eddeceNate Begeman } 1923c3420ffb282c6ffc0192013bf8045b6c21eddeceNate Begeman case X86::BI__builtin_ia32_palignr128: { 1924ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 1925ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 1926ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // If palignr is shifting the pair of input vectors less than 17 bytes, 1927ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // emit a shuffle instruction. 1928ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman if (shiftVal <= 16) { 1929ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman llvm::SmallVector<llvm::Constant*, 16> Indices; 1930ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman for (unsigned i = 0; i != 16; ++i) 193177b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Indices.push_back(llvm::ConstantInt::get(Int32Ty, shiftVal + i)); 1932ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 1933ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman Value* SV = llvm::ConstantVector::get(Indices.begin(), Indices.size()); 1934ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 1935ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman } 1936ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 1937ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // If palignr is shifting the pair of input vectors more than 16 but less 1938ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // than 32 bytes, emit a logical right shift of the destination. 1939ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman if (shiftVal < 32) { 194077b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner const llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2); 1941ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 1942ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 194377b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Ops[1] = llvm::ConstantInt::get(Int32Ty, (shiftVal-16) * 8); 1944ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 1945ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // create i32 constant 1946ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_psrl_dq); 1947ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman return Builder.CreateCall(F, &Ops[0], &Ops[0] + 2, "palignr"); 1948ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman } 1949ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 1950ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 1951ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman return llvm::Constant::getNullValue(ConvertType(E->getType())); 195291b59274439f776cdd545bd7bf5849fdb1842160Eric Christopher } 1953564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson } 1954564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson} 1955564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson 19561eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpValue *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, 19571feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner const CallExpr *E) { 1958dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner llvm::SmallVector<Value*, 4> Ops; 1959dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 1960dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) 1961dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner Ops.push_back(EmitScalarExpr(E->getArg(i))); 1962dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 1963dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner Intrinsic::ID ID = Intrinsic::not_intrinsic; 1964dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 1965dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner switch (BuiltinID) { 1966dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner default: return 0; 1967dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 19684d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov // vec_ld, vec_lvsl, vec_lvsr 19694d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvx: 19704d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvxl: 19714d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvebx: 19724d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvehx: 19734d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvewx: 19744d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvsl: 19754d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvsr: 19764d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov { 19774d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov Ops[1] = Builder.CreateBitCast(Ops[1], llvm::Type::getInt8PtrTy(VMContext)); 19784d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov 19794d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov Ops[0] = Builder.CreateGEP(Ops[1], Ops[0], "tmp"); 19804d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov Ops.pop_back(); 19814d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov 19824d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov switch (BuiltinID) { 19834d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov default: assert(0 && "Unsupported ld/lvsl/lvsr intrinsic!"); 19844d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvx: 19854d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvx; 19864d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 19874d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvxl: 19884d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvxl; 19894d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 19904d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvebx: 19914d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvebx; 19924d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 19934d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvehx: 19944d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvehx; 19954d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 19964d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvewx: 19974d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvewx; 19984d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 19994d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvsl: 20004d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvsl; 20014d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 20024d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov case PPC::BI__builtin_altivec_lvsr: 20034d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov ID = Intrinsic::ppc_altivec_lvsr; 20044d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov break; 20054d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov } 20064d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov llvm::Function *F = CGM.getIntrinsic(ID); 20074d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), ""); 20084d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov } 20094d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov 2010dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner // vec_st 2011dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvx: 2012dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvxl: 2013dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvebx: 2014dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvehx: 2015dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvewx: 2016dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner { 2017dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner Ops[2] = Builder.CreateBitCast(Ops[2], llvm::Type::getInt8PtrTy(VMContext)); 20184d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov Ops[1] = Builder.CreateGEP(Ops[2], Ops[1], "tmp"); 2019dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner Ops.pop_back(); 2020dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner 2021dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner switch (BuiltinID) { 20224d3a7b0a0608febe3cdac68f6121546672ca875eAnton Korobeynikov default: assert(0 && "Unsupported st intrinsic!"); 2023dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvx: 2024dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvx; 2025dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 2026dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvxl: 2027dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvxl; 2028dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 2029dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvebx: 2030dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvebx; 2031dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 2032dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvehx: 2033dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvehx; 2034dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 2035dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner case PPC::BI__builtin_altivec_stvewx: 2036dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner ID = Intrinsic::ppc_altivec_stvewx; 2037dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner break; 2038dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner } 2039dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner llvm::Function *F = CGM.getIntrinsic(ID); 2040dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), ""); 2041dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner } 2042dd17394d225b06376e9ae1d23f36cec463fdef01Chris Lattner } 2043b0b84385f0cb0ea4036579f5f384f1c19b917c7eDaniel Dunbar return 0; 20441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 2045