CGBuiltin.cpp revision ba68b08a05587490ed4c2e3d26f3a742c995c660
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" 17ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson#include "clang/Basic/TargetInfo.h" 181f32999ec79a980576e100d64d5f3267eb19ea49Chris Lattner#include "clang/AST/APValue.h" 19bef20ac367a09555b30d6eb3847a81ec164caf88Chris Lattner#include "clang/AST/ASTContext.h" 20c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbar#include "clang/AST/Decl.h" 216b15cdc1312f8fc45c86ee75e2a85106700e97f6Chris Lattner#include "clang/Basic/TargetBuiltins.h" 22793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson#include "llvm/Intrinsics.h" 23d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall#include "llvm/Target/TargetData.h" 24022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlssonusing namespace clang; 25022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlssonusing namespace CodeGen; 26ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlssonusing namespace llvm; 27ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson 280002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar/// Utility to insert an atomic instruction based on Instrinsic::ID 290002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar/// and the expression node. 301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic RValue EmitBinaryAtomic(CodeGenFunction& CGF, 311ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang Intrinsic::ID Id, const CallExpr *E) { 32c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang const llvm::Type *ResType[2]; 330002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar ResType[0] = CGF.ConvertType(E->getType()); 340002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar ResType[1] = CGF.ConvertType(E->getArg(0)->getType()); 350002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Value *AtomF = CGF.CGM.getIntrinsic(Id, ResType, 2); 361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return RValue::get(CGF.Builder.CreateCall2(AtomF, 371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump CGF.EmitScalarExpr(E->getArg(0)), 380002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar CGF.EmitScalarExpr(E->getArg(1)))); 390002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar} 400002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar 410002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar/// Utility to insert an atomic instruction based Instrinsic::ID and 420002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar// the expression node, where the return value is the result of the 430002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar// operation. 441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic RValue EmitBinaryAtomicPost(CodeGenFunction& CGF, 450002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Intrinsic::ID Id, const CallExpr *E, 460002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Instruction::BinaryOps Op) { 470002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar const llvm::Type *ResType[2]; 480002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar ResType[0] = CGF.ConvertType(E->getType()); 490002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar ResType[1] = CGF.ConvertType(E->getArg(0)->getType()); 500002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Value *AtomF = CGF.CGM.getIntrinsic(Id, ResType, 2); 510002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Value *Ptr = CGF.EmitScalarExpr(E->getArg(0)); 520002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Value *Operand = CGF.EmitScalarExpr(E->getArg(1)); 530002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Value *Result = CGF.Builder.CreateCall2(AtomF, Ptr, Operand); 541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 55eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner if (Id == Intrinsic::atomic_load_nand) 56eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner Result = CGF.Builder.CreateNot(Result); 571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 590002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar return RValue::get(CGF.Builder.CreateBinOp(Op, Result, Operand)); 601ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang} 611ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang 62fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCallstatic llvm::ConstantInt *getInt32(llvm::LLVMContext &Context, int32_t Value) { 63fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall return llvm::ConstantInt::get(llvm::Type::getInt32Ty(Context), Value); 64fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall} 65fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall 661eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpRValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, 67ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar unsigned BuiltinID, const CallExpr *E) { 68564ea2a99b3afeac9ded332730a56db1f6358a58Chris Lattner // See if we can constant fold this builtin. If so, don't emit it at all. 69f35d35a2316dcb65d078844696c2032b71a7f103Anders Carlsson Expr::EvalResult Result; 706ee7aa154e8bbb21a21254293410b944f78b0bfeChris Lattner if (E->Evaluate(Result, CGM.getContext())) { 71f35d35a2316dcb65d078844696c2032b71a7f103Anders Carlsson if (Result.Val.isInt()) 721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return RValue::get(llvm::ConstantInt::get(VMContext, 734a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Result.Val.getInt())); 743941b18b8e441c8c466efecd557de60b9a32d10bEli Friedman else if (Result.Val.isFloat()) 75bc0a2226c7fcd18b29b6846049e2cfcb872d3593Owen Anderson return RValue::get(ConstantFP::get(VMContext, Result.Val.getFloat())); 761f32999ec79a980576e100d64d5f3267eb19ea49Chris Lattner } 771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 78564ea2a99b3afeac9ded332730a56db1f6358a58Chris Lattner switch (BuiltinID) { 79564ea2a99b3afeac9ded332730a56db1f6358a58Chris Lattner default: break; // Handle intrinsics and libm functions below. 80506ff88f44562df267b6a06608ab841b76df2a2bChris Lattner case Builtin::BI__builtin___CFStringMakeConstantString: 810d13f6fdbdd6f06e2449b8834dda53334abd399aDavid Chisnall case Builtin::BI__builtin___NSStringMakeConstantString: 82e9352cc9818ba59e7cf88500ef048991c90f3821Anders Carlsson return RValue::get(CGM.EmitConstantExpr(E, E->getType(), 0)); 836a705f0443f8398ece14d80e71d8e8c9e71aa84aChris Lattner case Builtin::BI__builtin_stdarg_start: 84793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson case Builtin::BI__builtin_va_start: 85793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson case Builtin::BI__builtin_va_end: { 860785570af3ef5f8c5a0377129e41efe6f3f8d770Daniel Dunbar Value *ArgValue = EmitVAListRef(E->getArg(0)); 873c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer const llvm::Type *DestType = llvm::Type::getInt8PtrTy(VMContext); 88793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson if (ArgValue->getType() != DestType) 891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ArgValue = Builder.CreateBitCast(ArgValue, DestType, 90b27ffbef8e8aa1e87b63cbc0d9cd630aba30dae5Daniel Dunbar ArgValue->getName().data()); 91793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson 921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Intrinsic::ID inst = (BuiltinID == Builtin::BI__builtin_va_end) ? 936a705f0443f8398ece14d80e71d8e8c9e71aa84aChris Lattner Intrinsic::vaend : Intrinsic::vastart; 947acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner return RValue::get(Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue)); 95793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson } 96a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson case Builtin::BI__builtin_va_copy: { 974fd0aa5803357d8c72eeac2cae15e12649ea08feEli Friedman Value *DstPtr = EmitVAListRef(E->getArg(0)); 984fd0aa5803357d8c72eeac2cae15e12649ea08feEli Friedman Value *SrcPtr = EmitVAListRef(E->getArg(1)); 99a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson 1003c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer const llvm::Type *Type = llvm::Type::getInt8PtrTy(VMContext); 101a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson 102a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson DstPtr = Builder.CreateBitCast(DstPtr, Type); 103a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson SrcPtr = Builder.CreateBitCast(SrcPtr, Type); 1041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return RValue::get(Builder.CreateCall2(CGM.getIntrinsic(Intrinsic::vacopy), 1053eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner DstPtr, SrcPtr)); 106a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson } 107c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson case Builtin::BI__builtin_abs: { 1081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1109a847f598c4907a72b8593b364b9e6b94b086e75Chris Lattner Value *NegOp = Builder.CreateNeg(ArgValue, "neg"); 1111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *CmpResult = 1121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Builder.CreateICmpSGE(ArgValue, 113c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson llvm::Constant::getNullValue(ArgValue->getType()), 1149a847f598c4907a72b8593b364b9e6b94b086e75Chris Lattner "abscond"); 1151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *Result = 116c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs"); 1171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 118c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson return RValue::get(Result); 119c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson } 1203a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson case Builtin::BI__builtin_ctz: 1213a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson case Builtin::BI__builtin_ctzl: 1223a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson case Builtin::BI__builtin_ctzll: { 1233a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1253a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson const llvm::Type *ArgType = ArgValue->getType(); 1263a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson Value *F = CGM.getIntrinsic(Intrinsic::cttz, &ArgType, 1); 1273a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson 1281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const llvm::Type *ResultType = ConvertType(E->getType()); 1293a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson Value *Result = Builder.CreateCall(F, ArgValue, "tmp"); 1303a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson if (Result->getType() != ResultType) 131eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 132eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 1333a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson return RValue::get(Result); 1343a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson } 135f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman case Builtin::BI__builtin_clz: 136f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman case Builtin::BI__builtin_clzl: 137f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman case Builtin::BI__builtin_clzll: { 138f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 140f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman const llvm::Type *ArgType = ArgValue->getType(); 141f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman Value *F = CGM.getIntrinsic(Intrinsic::ctlz, &ArgType, 1); 142f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman 1431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const llvm::Type *ResultType = ConvertType(E->getType()); 144f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman Value *Result = Builder.CreateCall(F, ArgValue, "tmp"); 145f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman if (Result->getType() != ResultType) 146eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 147eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 148f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman return RValue::get(Result); 149f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman } 15004b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_ffs: 15104b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_ffsl: 15204b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_ffsll: { 15304b290030eee33295600728450f348989d1a627eDaniel Dunbar // ffs(x) -> x ? cttz(x) + 1 : 0 15404b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15604b290030eee33295600728450f348989d1a627eDaniel Dunbar const llvm::Type *ArgType = ArgValue->getType(); 15704b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::cttz, &ArgType, 1); 1581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15904b290030eee33295600728450f348989d1a627eDaniel Dunbar const llvm::Type *ResultType = ConvertType(E->getType()); 1601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *Tmp = Builder.CreateAdd(Builder.CreateCall(F, ArgValue, "tmp"), 1614a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson llvm::ConstantInt::get(ArgType, 1), "tmp"); 162c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Value *Zero = llvm::Constant::getNullValue(ArgType); 16304b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero"); 16404b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp, "ffs"); 16504b290030eee33295600728450f348989d1a627eDaniel Dunbar if (Result->getType() != ResultType) 166eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 167eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 16804b290030eee33295600728450f348989d1a627eDaniel Dunbar return RValue::get(Result); 16904b290030eee33295600728450f348989d1a627eDaniel Dunbar } 17004b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_parity: 17104b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_parityl: 17204b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_parityll: { 17304b290030eee33295600728450f348989d1a627eDaniel Dunbar // parity(x) -> ctpop(x) & 1 17404b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 17604b290030eee33295600728450f348989d1a627eDaniel Dunbar const llvm::Type *ArgType = ArgValue->getType(); 17704b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::ctpop, &ArgType, 1); 1781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 17904b290030eee33295600728450f348989d1a627eDaniel Dunbar const llvm::Type *ResultType = ConvertType(E->getType()); 18004b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *Tmp = Builder.CreateCall(F, ArgValue, "tmp"); 1811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *Result = Builder.CreateAnd(Tmp, llvm::ConstantInt::get(ArgType, 1), 18204b290030eee33295600728450f348989d1a627eDaniel Dunbar "tmp"); 18304b290030eee33295600728450f348989d1a627eDaniel Dunbar if (Result->getType() != ResultType) 184eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 185eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 18604b290030eee33295600728450f348989d1a627eDaniel Dunbar return RValue::get(Result); 18704b290030eee33295600728450f348989d1a627eDaniel Dunbar } 18804b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_popcount: 18904b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_popcountl: 19004b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_popcountll: { 19104b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19304b290030eee33295600728450f348989d1a627eDaniel Dunbar const llvm::Type *ArgType = ArgValue->getType(); 19404b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::ctpop, &ArgType, 1); 1951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19604b290030eee33295600728450f348989d1a627eDaniel Dunbar const llvm::Type *ResultType = ConvertType(E->getType()); 19704b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *Result = Builder.CreateCall(F, ArgValue, "tmp"); 19804b290030eee33295600728450f348989d1a627eDaniel Dunbar if (Result->getType() != ResultType) 199eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 200eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 20104b290030eee33295600728450f348989d1a627eDaniel Dunbar return RValue::get(Result); 20204b290030eee33295600728450f348989d1a627eDaniel Dunbar } 2031feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner case Builtin::BI__builtin_expect: 204a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar // FIXME: pass expect through to LLVM 2051feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner return RValue::get(EmitScalarExpr(E->getArg(0))); 206df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson case Builtin::BI__builtin_bswap32: 207df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson case Builtin::BI__builtin_bswap64: { 2081feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner Value *ArgValue = EmitScalarExpr(E->getArg(0)); 209df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson const llvm::Type *ArgType = ArgValue->getType(); 2107acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner Value *F = CGM.getIntrinsic(Intrinsic::bswap, &ArgType, 1); 2111feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner return RValue::get(Builder.CreateCall(F, ArgValue, "tmp")); 2121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 213d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar case Builtin::BI__builtin_object_size: { 214b16d32f74ffc467a5604934a1f844906be20cf7dMike Stump // We pass this builtin onto the optimizer so that it can 215b16d32f74ffc467a5604934a1f844906be20cf7dMike Stump // figure out the object size in more complex cases. 216c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump const llvm::Type *ResType[] = { 217c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump ConvertType(E->getType()) 218c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump }; 219fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher 220fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher // LLVM only supports 0 and 2, make sure that we pass along that 221fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher // as a boolean. 222fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher Value *Ty = EmitScalarExpr(E->getArg(1)); 223fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher ConstantInt *CI = dyn_cast<ConstantInt>(Ty); 224fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher assert(CI); 225fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher uint64_t val = CI->getZExtValue(); 226fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher CI = ConstantInt::get(llvm::Type::getInt1Ty(VMContext), (val & 0x2) >> 1); 227fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher 228c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump Value *F = CGM.getIntrinsic(Intrinsic::objectsize, ResType, 1); 229c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump return RValue::get(Builder.CreateCall2(F, 230c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump EmitScalarExpr(E->getArg(0)), 231fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher CI)); 232d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar } 2334493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar case Builtin::BI__builtin_prefetch: { 2344493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0)); 2354493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar // FIXME: Technically these constants should of type 'int', yes? 2361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump RW = (E->getNumArgs() > 1) ? EmitScalarExpr(E->getArg(1)) : 2370032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0); 2381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : 2390032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 3); 2404493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::prefetch, 0, 0); 2414493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar return RValue::get(Builder.CreateCall3(F, Address, RW, Locality)); 2424493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar } 2434493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar case Builtin::BI__builtin_trap: { 2444493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::trap, 0, 0); 2454493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar return RValue::get(Builder.CreateCall(F)); 246df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson } 24721190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner case Builtin::BI__builtin_unreachable: { 248fba565d044a8979cfd916ce52655a6847bfaa601Mike Stump if (CatchUndefined && HaveInsertPoint()) 249fba565d044a8979cfd916ce52655a6847bfaa601Mike Stump EmitBranch(getTrapBB()); 25021190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner Value *V = Builder.CreateUnreachable(); 25121190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner Builder.ClearInsertionPoint(); 25221190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner return RValue::get(V); 25321190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner } 25421190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner 255a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar case Builtin::BI__builtin_powi: 256a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar case Builtin::BI__builtin_powif: 257a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar case Builtin::BI__builtin_powil: { 258a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar Value *Base = EmitScalarExpr(E->getArg(0)); 259a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar Value *Exponent = EmitScalarExpr(E->getArg(1)); 260a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar const llvm::Type *ArgType = Base->getType(); 261a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::powi, &ArgType, 1); 262a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp")); 263a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar } 264a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar 265fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isgreater: 266fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isgreaterequal: 267fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isless: 268fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_islessequal: 269fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_islessgreater: 270fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isunordered: { 271fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner // Ordered comparisons: we know the arguments to these are matching scalar 272fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner // floating point values. 2731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *LHS = EmitScalarExpr(E->getArg(0)); 274fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner Value *RHS = EmitScalarExpr(E->getArg(1)); 2751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 276fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner switch (BuiltinID) { 277fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner default: assert(0 && "Unknown ordered comparison"); 278fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isgreater: 279fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp"); 280fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 281fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isgreaterequal: 282fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp"); 283fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 284fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isless: 285fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp"); 286fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 287fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_islessequal: 288fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp"); 289fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 290fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_islessgreater: 291fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp"); 292fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 2931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case Builtin::BI__builtin_isunordered: 294fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp"); 295fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 296fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner } 297fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner // ZExt bool to int type. 298fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType()), 299fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner "tmp")); 300fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner } 301d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman case Builtin::BI__builtin_isnan: { 302d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman Value *V = EmitScalarExpr(E->getArg(0)); 303d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman V = Builder.CreateFCmpUNO(V, V, "cmp"); 304d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()), "tmp")); 305d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman } 306b52fe9ce99970955a5f581f5c66fcd89be9a268bEli Friedman case Builtin::BIalloca: 3079e800e3dd80d77f6c47054738177bf824089f55aChris Lattner case Builtin::BI__builtin_alloca: { 3089e800e3dd80d77f6c47054738177bf824089f55aChris Lattner // FIXME: LLVM IR Should allow alloca with an i64 size! 3099e800e3dd80d77f6c47054738177bf824089f55aChris Lattner Value *Size = EmitScalarExpr(E->getArg(0)); 3100032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson Size = Builder.CreateIntCast(Size, llvm::Type::getInt32Ty(VMContext), false, "tmp"); 3110032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson return RValue::get(Builder.CreateAlloca(llvm::Type::getInt8Ty(VMContext), Size, "tmp")); 3121caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar } 313e6dddfd907f6ea58daed5e26eeaacd893d98db9bEli Friedman case Builtin::BIbzero: 3141caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar case Builtin::BI__builtin_bzero: { 3151caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar Value *Address = EmitScalarExpr(E->getArg(0)); 3161caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar Builder.CreateCall4(CGM.getMemSetFn(), Address, 3170032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 0), 3181caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar EmitScalarExpr(E->getArg(1)), 3190032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1)); 3201caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar return RValue::get(Address); 3219e800e3dd80d77f6c47054738177bf824089f55aChris Lattner } 322e6ec205d6d0f4aec27bf49ca1e8fbb139acc2f2bEli Friedman case Builtin::BImemcpy: 323d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman case Builtin::BI__builtin_memcpy: { 3241caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar Value *Address = EmitScalarExpr(E->getArg(0)); 3251caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar Builder.CreateCall4(CGM.getMemCpyFn(), Address, 3261caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar EmitScalarExpr(E->getArg(1)), 3271caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar EmitScalarExpr(E->getArg(2)), 3280032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1)); 3291caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar return RValue::get(Address); 3301caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar } 331e6ec205d6d0f4aec27bf49ca1e8fbb139acc2f2bEli Friedman case Builtin::BImemmove: 3321caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar case Builtin::BI__builtin_memmove: { 3331caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar Value *Address = EmitScalarExpr(E->getArg(0)); 3341caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar Builder.CreateCall4(CGM.getMemMoveFn(), Address, 3351caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar EmitScalarExpr(E->getArg(1)), 3361caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar EmitScalarExpr(E->getArg(2)), 3370032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1)); 3381caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar return RValue::get(Address); 3391caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar } 340e6ec205d6d0f4aec27bf49ca1e8fbb139acc2f2bEli Friedman case Builtin::BImemset: 3411caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar case Builtin::BI__builtin_memset: { 3421caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar Value *Address = EmitScalarExpr(E->getArg(0)); 3431caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar Builder.CreateCall4(CGM.getMemSetFn(), Address, 34462c29c667f5bcb854e99ccb3aec1280c84115951Daniel Dunbar Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), 3450032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::Type::getInt8Ty(VMContext)), 3461caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar EmitScalarExpr(E->getArg(2)), 3470032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1)); 3481caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar return RValue::get(Address); 349d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman } 350fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall case Builtin::BI__builtin_dwarf_cfa: { 351fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // The offset in bytes from the first argument to the CFA. 352fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // 353fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // Why on earth is this in the frontend? Is there any reason at 354fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // all that the backend can't reasonably determine this while 355fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // lowering llvm.eh.dwarf.cfa()? 356fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // 357fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // TODO: If there's a satisfactory reason, add a target hook for 358fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall // this instead of hard-coding 0, which is correct for most targets. 359fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall int32_t Offset = 0; 360fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall 361fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall Value *F = CGM.getIntrinsic(Intrinsic::eh_dwarf_cfa, 0, 0); 362fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall return RValue::get(Builder.CreateCall(F, getInt32(VMContext, Offset))); 363fb17a562135dd7597121da9245d0c1bdcda4146fJohn McCall } 364256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman case Builtin::BI__builtin_return_address: { 36583c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov Value *Depth = EmitScalarExpr(E->getArg(0)); 36683c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov Depth = Builder.CreateIntCast(Depth, 36783c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov llvm::Type::getInt32Ty(VMContext), 36883c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov false, "tmp"); 369256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman Value *F = CGM.getIntrinsic(Intrinsic::returnaddress, 0, 0); 37083c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov return RValue::get(Builder.CreateCall(F, Depth)); 371256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman } 372256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman case Builtin::BI__builtin_frame_address: { 37383c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov Value *Depth = EmitScalarExpr(E->getArg(0)); 37483c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov Depth = Builder.CreateIntCast(Depth, 37583c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov llvm::Type::getInt32Ty(VMContext), 37683c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov false, "tmp"); 377256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman Value *F = CGM.getIntrinsic(Intrinsic::frameaddress, 0, 0); 37883c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov return RValue::get(Builder.CreateCall(F, Depth)); 379256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman } 3803b660efb9f9fa3e87096f4a96a2093cd17c43c2eEli Friedman case Builtin::BI__builtin_extract_return_addr: { 381492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall Value *Address = EmitScalarExpr(E->getArg(0)); 382492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall Value *Result = getTargetHooks().decodeReturnAddress(*this, Address); 383492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall return RValue::get(Result); 384492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall } 385492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall case Builtin::BI__builtin_frob_return_addr: { 386492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall Value *Address = EmitScalarExpr(E->getArg(0)); 387492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall Value *Result = getTargetHooks().encodeReturnAddress(*this, Address); 388492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall return RValue::get(Result); 3893b660efb9f9fa3e87096f4a96a2093cd17c43c2eEli Friedman } 3906374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall case Builtin::BI__builtin_dwarf_sp_column: { 3916374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall const llvm::IntegerType *Ty 3926374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall = cast<llvm::IntegerType>(ConvertType(E->getType())); 3936374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall int Column = getTargetHooks().getDwarfEHStackPointer(CGM); 3946374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall if (Column == -1) { 3956374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall CGM.ErrorUnsupported(E, "__builtin_dwarf_sp_column"); 3966374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall return RValue::get(llvm::UndefValue::get(Ty)); 3976374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall } 3986374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall return RValue::get(llvm::ConstantInt::get(Ty, Column, true)); 3996374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall } 4006374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall case Builtin::BI__builtin_init_dwarf_reg_size_table: { 4016374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall Value *Address = EmitScalarExpr(E->getArg(0)); 4026374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall if (getTargetHooks().initDwarfEHRegSizeTable(*this, Address)) 4036374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall CGM.ErrorUnsupported(E, "__builtin_init_dwarf_reg_size_table"); 4046374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall return RValue::get(llvm::UndefValue::get(ConvertType(E->getType()))); 4056374c3307e2d73348f7b8cc73eeeb0998ad0ac94John McCall } 4067ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall case Builtin::BI__builtin_eh_return: { 4077ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall Value *Int = EmitScalarExpr(E->getArg(0)); 4087ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall Value *Ptr = EmitScalarExpr(E->getArg(1)); 4097ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall 4107ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(Int->getType()); 4117ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall assert((IntTy->getBitWidth() == 32 || IntTy->getBitWidth() == 64) && 4127ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall "LLVM's __builtin_eh_return only supports 32- and 64-bit variants"); 4137ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall Value *F = CGM.getIntrinsic(IntTy->getBitWidth() == 32 4147ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall ? Intrinsic::eh_return_i32 4157ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall : Intrinsic::eh_return_i64, 4167ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall 0, 0); 4177ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall Builder.CreateCall2(F, Int, Ptr); 4187ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall Value *V = Builder.CreateUnreachable(); 4197ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall Builder.ClearInsertionPoint(); 4207ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall return RValue::get(V); 4217ada111fd5e81aff355e67bad0e4083f552b34bdJohn McCall } 422a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman case Builtin::BI__builtin_unwind_init: { 423a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init, 0, 0); 424a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman return RValue::get(Builder.CreateCall(F)); 425a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman } 4265e11085830d4d4c53ff75575ab75889ee5126854John McCall case Builtin::BI__builtin_extend_pointer: { 4275e11085830d4d4c53ff75575ab75889ee5126854John McCall // Extends a pointer to the size of an _Unwind_Word, which is 428d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // uint64_t on all platforms. Generally this gets poked into a 429d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // register and eventually used as an address, so if the 430d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // addressing registers are wider than pointers and the platform 431d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // doesn't implicitly ignore high-order bits when doing 432d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // addressing, we need to make sure we zext / sext based on 433d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // the platform's expectations. 4345e11085830d4d4c53ff75575ab75889ee5126854John McCall // 4355e11085830d4d4c53ff75575ab75889ee5126854John McCall // See: http://gcc.gnu.org/ml/gcc-bugs/2002-02/msg00237.html 436d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall 437d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall LLVMContext &C = CGM.getLLVMContext(); 438d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall 439d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // Cast the pointer to intptr_t. 4405e11085830d4d4c53ff75575ab75889ee5126854John McCall Value *Ptr = EmitScalarExpr(E->getArg(0)); 441d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall const llvm::IntegerType *IntPtrTy = CGM.getTargetData().getIntPtrType(C); 442d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall Value *Result = Builder.CreatePtrToInt(Ptr, IntPtrTy, "extend.cast"); 443d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall 444d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // If that's 64 bits, we're done. 445d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall if (IntPtrTy->getBitWidth() == 64) 446d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall return RValue::get(Result); 447d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall 448d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall // Otherwise, ask the codegen data what to do. 449d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall const llvm::IntegerType *Int64Ty = llvm::IntegerType::get(C, 64); 450492c4f998d848673d3d6c9e6416115df4036a71dJohn McCall if (getTargetHooks().extendPointerWithSExt()) 451d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall return RValue::get(Builder.CreateSExt(Result, Int64Ty, "extend.sext")); 452d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall else 453d0b76ca10feefcfda5cb16698e50197e87a7d876John McCall return RValue::get(Builder.CreateZExt(Result, Int64Ty, "extend.zext")); 4545e11085830d4d4c53ff75575ab75889ee5126854John McCall } 455a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman#if 0 456a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman // FIXME: Finish/enable when LLVM backend support stabilizes 457a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman case Builtin::BI__builtin_setjmp: { 458a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *Buf = EmitScalarExpr(E->getArg(0)); 459a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman // Store the frame pointer to the buffer 460a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *FrameAddrF = CGM.getIntrinsic(Intrinsic::frameaddress, 0, 0); 461a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *FrameAddr = 462a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Builder.CreateCall(FrameAddrF, 4630032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson Constant::getNullValue(llvm::Type::getInt32Ty(VMContext))); 464a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Builder.CreateStore(FrameAddr, Buf); 465a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman // Call the setjmp intrinsic 466a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp, 0, 0); 4673c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer const llvm::Type *DestType = llvm::Type::getInt8PtrTy(VMContext); 468a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Buf = Builder.CreateBitCast(Buf, DestType); 469a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman return RValue::get(Builder.CreateCall(F, Buf)); 470a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman } 471a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman case Builtin::BI__builtin_longjmp: { 472a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp, 0, 0); 473a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *Buf = EmitScalarExpr(E->getArg(0)); 4743c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer const llvm::Type *DestType = llvm::Type::getInt8PtrTy(VMContext); 475a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Buf = Builder.CreateBitCast(Buf, DestType); 476a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman return RValue::get(Builder.CreateCall(F, Buf)); 477a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman } 478a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman#endif 4791ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_add: 4801ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_sub: 4815caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or: 4825caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and: 4835caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor: 4845caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch: 4855caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch: 4865caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch: 4875caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch: 4885caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch: 4895caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap: 4905caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap: 4915caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set: 4925caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release: 4935caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner assert(0 && "Shouldn't make it through sema"); 4945caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_1: 4955caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_2: 4965caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_4: 4975caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_8: 4985caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_16: 4995caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner return EmitBinaryAtomic(*this, Intrinsic::atomic_load_add, E); 5005caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_1: 5015caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_2: 5025caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_4: 5035caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_8: 5045caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_16: 50509b6bf5bfa2ba9cbbd353cbd7846af8f49b020e7Mon P Wang return EmitBinaryAtomic(*this, Intrinsic::atomic_load_sub, E); 5065caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_1: 5075caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_2: 5085caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_4: 5095caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_8: 5105caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_16: 5115caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner return EmitBinaryAtomic(*this, Intrinsic::atomic_load_or, E); 5125caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_1: 5135caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_2: 5145caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_4: 5155caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_8: 5165caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_16: 5175caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner return EmitBinaryAtomic(*this, Intrinsic::atomic_load_and, E); 5185caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_1: 5195caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_2: 5205caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_4: 5215caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_8: 5225caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_16: 5235caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner return EmitBinaryAtomic(*this, Intrinsic::atomic_load_xor, E); 524eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner case Builtin::BI__sync_fetch_and_nand_1: 525eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner case Builtin::BI__sync_fetch_and_nand_2: 526eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner case Builtin::BI__sync_fetch_and_nand_4: 527eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner case Builtin::BI__sync_fetch_and_nand_8: 528eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner case Builtin::BI__sync_fetch_and_nand_16: 529eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner return EmitBinaryAtomic(*this, Intrinsic::atomic_load_nand, E); 5301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5315caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // Clang extensions: not overloaded yet. 5321ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_min: 5331ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang return EmitBinaryAtomic(*this, Intrinsic::atomic_load_min, E); 5341ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_max: 5351ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang return EmitBinaryAtomic(*this, Intrinsic::atomic_load_max, E); 5361ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_umin: 5371ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umin, E); 5381ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_umax: 5391ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umax, E); 5400002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar 5415caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_1: 5425caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_2: 5435caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_4: 5445caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_8: 5455caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_16: 5461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_add, E, 5470002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::Add); 5485caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_1: 5495caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_2: 5505caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_4: 5515caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_8: 5525caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_16: 5530002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_sub, E, 5540002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::Sub); 5555caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_1: 5565caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_2: 5575caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_4: 5585caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_8: 5595caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_16: 5600002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_and, E, 5610002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::And); 5625caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_1: 5635caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_2: 5645caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_4: 5655caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_8: 5665caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_16: 5670002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_or, E, 5680002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::Or); 5695caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_1: 5705caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_2: 5715caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_4: 5725caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_8: 5735caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_16: 5740002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_xor, E, 5750002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::Xor); 576eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner case Builtin::BI__sync_nand_and_fetch_1: 577eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner case Builtin::BI__sync_nand_and_fetch_2: 578eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner case Builtin::BI__sync_nand_and_fetch_4: 579eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner case Builtin::BI__sync_nand_and_fetch_8: 580eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner case Builtin::BI__sync_nand_and_fetch_16: 581eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_nand, E, 582eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner llvm::Instruction::And); 5831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5845caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap_1: 5855caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap_2: 5865caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap_4: 5875caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap_8: 5885caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap_16: 5895caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner { 590c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang const llvm::Type *ResType[2]; 591c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang ResType[0]= ConvertType(E->getType()); 592c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang ResType[1] = ConvertType(E->getArg(0)->getType()); 593c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap, ResType, 2); 5941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return RValue::get(Builder.CreateCall3(AtomF, 595958444659c5287a81a43188bfaa2a4902752b947Anders Carlsson EmitScalarExpr(E->getArg(0)), 596958444659c5287a81a43188bfaa2a4902752b947Anders Carlsson EmitScalarExpr(E->getArg(1)), 597958444659c5287a81a43188bfaa2a4902752b947Anders Carlsson EmitScalarExpr(E->getArg(2)))); 598022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson } 5990002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar 6005caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap_1: 6015caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap_2: 6025caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap_4: 6035caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap_8: 6045caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap_16: 6055caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner { 6060002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar const llvm::Type *ResType[2]; 6075caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner ResType[0]= ConvertType(E->getArg(1)->getType()); 60896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson ResType[1] = llvm::PointerType::getUnqual(ResType[0]); 6090002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap, ResType, 2); 6100002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Value *OldVal = EmitScalarExpr(E->getArg(1)); 6111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *PrevVal = Builder.CreateCall3(AtomF, 6120002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar EmitScalarExpr(E->getArg(0)), 6130002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar OldVal, 6140002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar EmitScalarExpr(E->getArg(2))); 6150002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Value *Result = Builder.CreateICmpEQ(PrevVal, OldVal); 6160002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar // zext bool to int. 6170002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar return RValue::get(Builder.CreateZExt(Result, ConvertType(E->getType()))); 6180002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar } 6190002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar 6205caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_1: 6215caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_2: 6225caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_4: 6235caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_8: 6245caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_16: 6257ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman return EmitBinaryAtomic(*this, Intrinsic::atomic_swap, E); 6265caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release_1: 6275caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release_2: 6285caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release_4: 6295caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release_8: 630f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner case Builtin::BI__sync_lock_release_16: { 631f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner Value *Ptr = EmitScalarExpr(E->getArg(0)); 632f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner const llvm::Type *ElTy = 633f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner cast<llvm::PointerType>(Ptr->getType())->getElementType(); 634007b56738b00426688ee85baa75174358bd849f9Daniel Dunbar llvm::StoreInst *Store = 635007b56738b00426688ee85baa75174358bd849f9Daniel Dunbar Builder.CreateStore(llvm::Constant::getNullValue(ElTy), Ptr); 636007b56738b00426688ee85baa75174358bd849f9Daniel Dunbar Store->setVolatile(true); 637eb4f81e174b11633f7b85f555ea5d2834d6dae8aDaniel Dunbar return RValue::get(0); 638f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner } 639ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar 640f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner case Builtin::BI__sync_synchronize: { 641f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner Value *C[5]; 6420032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson C[0] = C[1] = C[2] = C[3] = llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 1); 6430032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson C[4] = llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0); 644f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner Builder.CreateCall(CGM.getIntrinsic(Intrinsic::memory_barrier), C, C + 5); 645eb4f81e174b11633f7b85f555ea5d2834d6dae8aDaniel Dunbar return RValue::get(0); 646f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner } 6471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6480b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner case Builtin::BI__builtin_llvm_memory_barrier: { 6490b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner Value *C[5] = { 6500b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner EmitScalarExpr(E->getArg(0)), 6510b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner EmitScalarExpr(E->getArg(1)), 6520b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner EmitScalarExpr(E->getArg(2)), 6530b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner EmitScalarExpr(E->getArg(3)), 6540b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner EmitScalarExpr(E->getArg(4)) 6550b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner }; 6560b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner Builder.CreateCall(CGM.getIntrinsic(Intrinsic::memory_barrier), C, C + 5); 6570b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner return RValue::get(0); 6580b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner } 6590b5716469b4be89adeb15a9819ac82a86ef19ca8Tanya Lattner 660ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar // Library functions with special handling. 661ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIsqrt: 662ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIsqrtf: 663ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIsqrtl: { 664ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar // Rewrite sqrt to intrinsic if allowed. 66540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis if (!FD->hasAttr<ConstAttr>()) 666ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar break; 667ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar Value *Arg0 = EmitScalarExpr(E->getArg(0)); 668ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar const llvm::Type *ArgType = Arg0->getType(); 669ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::sqrt, &ArgType, 1); 670ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar return RValue::get(Builder.CreateCall(F, Arg0, "tmp")); 671ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar } 672ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar 673ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIpow: 674ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIpowf: 675ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIpowl: { 676ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar // Rewrite sqrt to intrinsic if allowed. 67740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis if (!FD->hasAttr<ConstAttr>()) 678ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar break; 679ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar Value *Base = EmitScalarExpr(E->getArg(0)); 680ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar Value *Exponent = EmitScalarExpr(E->getArg(1)); 681ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar const llvm::Type *ArgType = Base->getType(); 682ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::pow, &ArgType, 1); 683ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp")); 684ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar } 685ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman 686ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman case Builtin::BI__builtin_signbit: 687ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman case Builtin::BI__builtin_signbitf: 688ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman case Builtin::BI__builtin_signbitl: { 689ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman LLVMContext &C = CGM.getLLVMContext(); 690ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman 691ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *Arg = EmitScalarExpr(E->getArg(0)); 692ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman const llvm::Type *ArgTy = Arg->getType(); 693ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman if (ArgTy->isPPC_FP128Ty()) 694ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman break; // FIXME: I'm not sure what the right implementation is here. 695ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman int ArgWidth = ArgTy->getPrimitiveSizeInBits(); 696ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman const llvm::Type *ArgIntTy = llvm::IntegerType::get(C, ArgWidth); 697ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *BCArg = Builder.CreateBitCast(Arg, ArgIntTy); 698ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *ZeroCmp = llvm::Constant::getNullValue(ArgIntTy); 699ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman Value *Result = Builder.CreateICmpSLT(BCArg, ZeroCmp); 700ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman return RValue::get(Builder.CreateZExt(Result, ConvertType(E->getType()))); 701ba68b08a05587490ed4c2e3d26f3a742c995c660Eli Friedman } 7027ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman } 7031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 704b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // If this is an alias for a libm function (e.g. __builtin_sin) turn it into 705b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // that function. 7063e41d60eb627dc227c770f1c1c87d06909cf05fdDouglas Gregor if (getContext().BuiltinInfo.isLibFunction(BuiltinID) || 7073e41d60eb627dc227c770f1c1c87d06909cf05fdDouglas Gregor getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID)) 70831777a2540879051a3c643b90e02c3fd3d315243Anders Carlsson return EmitCall(E->getCallee()->getType(), 70931777a2540879051a3c643b90e02c3fd3d315243Anders Carlsson CGM.getBuiltinLibFunction(FD, BuiltinID), 710d2490a91341b57df7a7e54f8a707e7ecde2eeb4eAnders Carlsson ReturnValueSlot(), 71131777a2540879051a3c643b90e02c3fd3d315243Anders Carlsson E->arg_begin(), E->arg_end()); 7121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 713b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // See if we have a target specific intrinsic. 714a6f80ef997f0363386749087b325607eaa5adcfcDale Johannesen const char *Name = getContext().BuiltinInfo.GetName(BuiltinID); 71555cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic; 71655cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar if (const char *Prefix = 7171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Triple::getArchTypePrefix(Target.getTriple().getArch())) 71855cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix, Name); 7191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 720b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (IntrinsicID != Intrinsic::not_intrinsic) { 721b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner SmallVector<Value*, 16> Args; 7221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 723b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner Function *F = CGM.getIntrinsic(IntrinsicID); 724b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner const llvm::FunctionType *FTy = F->getFunctionType(); 7251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 726b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 727b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner Value *ArgValue = EmitScalarExpr(E->getArg(i)); 7281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 729b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // If the intrinsic arg type is different from the builtin arg type 730b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // we need to do a bit cast. 731b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner const llvm::Type *PTy = FTy->getParamType(i); 732b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (PTy != ArgValue->getType()) { 733b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) && 734b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner "Must be able to losslessly bit cast to param"); 735b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner ArgValue = Builder.CreateBitCast(ArgValue, PTy); 736b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 7371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 738b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner Args.push_back(ArgValue); 739b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 7401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 741beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad Value *V = Builder.CreateCall(F, Args.data(), Args.data() + Args.size()); 742b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner QualType BuiltinRetType = E->getType(); 7431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7440032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson const llvm::Type *RetTy = llvm::Type::getVoidTy(VMContext); 745b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (!BuiltinRetType->isVoidType()) RetTy = ConvertType(BuiltinRetType); 7461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 747b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (RetTy != V->getType()) { 748b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner assert(V->getType()->canLosslesslyBitCastTo(RetTy) && 749b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner "Must be able to losslessly bit cast result type"); 750b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner V = Builder.CreateBitCast(V, RetTy); 751b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 7521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 753b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner return RValue::get(V); 754b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 7551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 756b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // See if we have a target specific builtin that needs to be lowered. 757f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E)) 758b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner return RValue::get(V); 7591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 760488e993a135ce700b982bf099c3d6b856301d642Daniel Dunbar ErrorUnsupported(E, "builtin function"); 7611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 762b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // Unknown builtin, for now just dump it out and return undef. 763b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (hasAggregateLLVMType(E->getType())) 764195337d2e5d4625ae9dc1328c7cdbc7115b0261bDaniel Dunbar return RValue::getAggregate(CreateMemTemp(E->getType())); 76503e205031b08669f05c41eed5b896fc94c4a12bbOwen Anderson return RValue::get(llvm::UndefValue::get(ConvertType(E->getType()))); 7661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 767564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson 768f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel DunbarValue *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, 769f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar const CallExpr *E) { 77055cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar switch (Target.getTriple().getArch()) { 7712752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner case llvm::Triple::arm: 7722752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner case llvm::Triple::thumb: 7732752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner return EmitARMBuiltinExpr(BuiltinID, E); 77455cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::x86: 77555cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::x86_64: 776f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar return EmitX86BuiltinExpr(BuiltinID, E); 77755cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::ppc: 77855cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::ppc64: 779f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar return EmitPPCBuiltinExpr(BuiltinID, E); 78055cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar default: 78155cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar return 0; 78255cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar } 783f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar} 784f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar 7852752c0137d95aa2f4ee1cdff4b564bac842e041bChris LattnerValue *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, 7862752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner const CallExpr *E) { 7872752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner switch (BuiltinID) { 7882752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner default: return 0; 7892752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner 7902752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner case ARM::BI__builtin_thread_pointer: { 7912752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner Value *AtomF = CGM.getIntrinsic(Intrinsic::arm_thread_pointer, 0, 0); 7922752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner return Builder.CreateCall(AtomF); 7932752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner } 7942752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner } 7952752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner} 7962752c0137d95aa2f4ee1cdff4b564bac842e041bChris Lattner 7971eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpValue *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, 7981feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner const CallExpr *E) { 7991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8002929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson llvm::SmallVector<Value*, 4> Ops; 8012929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson 8022929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) 8032929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson Ops.push_back(EmitScalarExpr(E->getArg(i))); 8042929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson 805564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson switch (BuiltinID) { 80646a26b0b0e2ec1557bad9b70e8e20836524ebdfcAnders Carlsson default: return 0; 8071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case X86::BI__builtin_ia32_pslldi128: 808e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psllqi128: 8091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case X86::BI__builtin_ia32_psllwi128: 810e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psradi128: 811e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrawi128: 812e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrldi128: 813e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrlqi128: 814e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrlwi128: { 8150032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::getInt64Ty(VMContext), "zext"); 8160032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson const llvm::Type *Ty = llvm::VectorType::get(llvm::Type::getInt64Ty(VMContext), 2); 8170032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::Value *Zero = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0); 81803e205031b08669f05c41eed5b896fc94c4a12bbOwen Anderson Ops[1] = Builder.CreateInsertElement(llvm::UndefValue::get(Ty), 819e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[1], Zero, "insert"); 820e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType(), "bitcast"); 821e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman const char *name = 0; 822e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Intrinsic::ID ID = Intrinsic::not_intrinsic; 8231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 824e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman switch (BuiltinID) { 825e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman default: assert(0 && "Unsupported shift intrinsic!"); 826e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_pslldi128: 827e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "pslldi"; 828e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psll_d; 829e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 830e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psllqi128: 831e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "psllqi"; 832e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psll_q; 833e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 834e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psllwi128: 835e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "psllwi"; 836e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psll_w; 837e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 838e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psradi128: 839e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "psradi"; 840e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psra_d; 841e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 842e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrawi128: 843e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "psrawi"; 844e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psra_w; 845e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 846e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrldi128: 847e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "psrldi"; 848e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psrl_d; 849e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 850e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrlqi128: 851e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "psrlqi"; 852e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psrl_q; 853e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 854e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrlwi128: 855e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "psrlwi"; 856e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psrl_w; 857e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 858e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 859e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman llvm::Function *F = CGM.getIntrinsic(ID); 8601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name); 861e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 8621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case X86::BI__builtin_ia32_pslldi: 8632929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psllqi: 8641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case X86::BI__builtin_ia32_psllwi: 8652929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psradi: 8662929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrawi: 8672929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrldi: 8682929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrlqi: 8692929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrlwi: { 8700032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::getInt64Ty(VMContext), "zext"); 8710032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson const llvm::Type *Ty = llvm::VectorType::get(llvm::Type::getInt64Ty(VMContext), 1); 8722929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson Ops[1] = Builder.CreateBitCast(Ops[1], Ty, "bitcast"); 8732929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson const char *name = 0; 8742929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson Intrinsic::ID ID = Intrinsic::not_intrinsic; 8751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8762929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson switch (BuiltinID) { 8772929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson default: assert(0 && "Unsupported shift intrinsic!"); 8782929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_pslldi: 8792929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "pslldi"; 8802929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psll_d; 8812929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 8822929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psllqi: 8832929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "psllqi"; 8842929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psll_q; 8852929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 8862929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psllwi: 8872929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "psllwi"; 8882929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psll_w; 8892929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 8902929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psradi: 8912929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "psradi"; 8922929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psra_d; 8932929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 8942929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrawi: 8952929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "psrawi"; 8962929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psra_w; 8972929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 8982929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrldi: 8992929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "psrldi"; 9002929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psrl_d; 9012929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 9022929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrlqi: 9032929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "psrlqi"; 9042929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psrl_q; 9052929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 9062929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrlwi: 9072929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "psrlwi"; 9082929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psrl_w; 9092929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 9102929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson } 9117acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner llvm::Function *F = CGM.getIntrinsic(ID); 9121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name); 9132929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson } 91479dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson case X86::BI__builtin_ia32_cmpps: { 91579dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ps); 91679dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpps"); 91779dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson } 91879dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson case X86::BI__builtin_ia32_cmpss: { 91979dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ss); 92079dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpss"); 921cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson } 922e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_ldmxcsr: { 9233c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext); 9240032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson Value *One = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1); 9250032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson Value *Tmp = Builder.CreateAlloca(llvm::Type::getInt32Ty(VMContext), One, "tmp"); 926e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Builder.CreateStore(Ops[0], Tmp); 927e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr), 9283eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner Builder.CreateBitCast(Tmp, PtrTy)); 929e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 930e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_stmxcsr: { 9313c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext); 9320032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson Value *One = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1); 9330032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson Value *Tmp = Builder.CreateAlloca(llvm::Type::getInt32Ty(VMContext), One, "tmp"); 934e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman One = Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr), 9353eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner Builder.CreateBitCast(Tmp, PtrTy)); 936e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman return Builder.CreateLoad(Tmp, "stmxcsr"); 937e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 93879dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson case X86::BI__builtin_ia32_cmppd: { 93979dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_pd); 94079dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmppd"); 94179dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson } 94279dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson case X86::BI__builtin_ia32_cmpsd: { 94379dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_sd); 94479dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpsd"); 945cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson } 946e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_storehps: 947e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_storelps: { 9480032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson const llvm::Type *EltTy = llvm::Type::getInt64Ty(VMContext); 94996e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson llvm::Type *PtrTy = llvm::PointerType::getUnqual(EltTy); 95096e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2); 9511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 952e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman // cast val v2i64 953e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast"); 9541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 955e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman // extract (0, 1) 956e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1; 9570032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::Value *Idx = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Index); 958e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract"); 959e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman 960e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman // cast pointer to i64 & store 961e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy); 962e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 963e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 96491b59274439f776cdd545bd7bf5849fdb1842160Eric Christopher case X86::BI__builtin_ia32_palignr: { 965c3420ffb282c6ffc0192013bf8045b6c21eddeceNate Begeman Function *F = CGM.getIntrinsic(Intrinsic::x86_ssse3_palign_r); 966c3420ffb282c6ffc0192013bf8045b6c21eddeceNate Begeman return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size()); 967c3420ffb282c6ffc0192013bf8045b6c21eddeceNate Begeman } 968c3420ffb282c6ffc0192013bf8045b6c21eddeceNate Begeman case X86::BI__builtin_ia32_palignr128: { 969ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 970ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 971ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // If palignr is shifting the pair of input vectors less than 17 bytes, 972ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // emit a shuffle instruction. 973ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman if (shiftVal <= 16) { 974ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman const llvm::Type *IntTy = llvm::Type::getInt32Ty(VMContext); 975ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 976ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman llvm::SmallVector<llvm::Constant*, 16> Indices; 977ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman for (unsigned i = 0; i != 16; ++i) 978ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman Indices.push_back(llvm::ConstantInt::get(IntTy, shiftVal + i)); 979ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 980ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman Value* SV = llvm::ConstantVector::get(Indices.begin(), Indices.size()); 981ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 982ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman } 983ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 984ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // If palignr is shifting the pair of input vectors more than 16 but less 985ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // than 32 bytes, emit a logical right shift of the destination. 986ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman if (shiftVal < 32) { 987ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman const llvm::Type *EltTy = llvm::Type::getInt64Ty(VMContext); 988ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman const llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2); 989ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman const llvm::Type *IntTy = llvm::Type::getInt32Ty(VMContext); 990ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 991ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 992ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman Ops[1] = llvm::ConstantInt::get(IntTy, (shiftVal-16) * 8); 993ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 994ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // create i32 constant 995ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_psrl_dq); 996ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman return Builder.CreateCall(F, &Ops[0], &Ops[0] + 2, "palignr"); 997ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman } 998ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 999ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 1000ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman return llvm::Constant::getNullValue(ConvertType(E->getType())); 100191b59274439f776cdd545bd7bf5849fdb1842160Eric Christopher } 1002564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson } 1003564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson} 1004564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson 10051eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpValue *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, 10061feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner const CallExpr *E) { 1007b0b84385f0cb0ea4036579f5f384f1c19b917c7eDaniel Dunbar return 0; 10081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 1009