CGBuiltin.cpp revision 83c2a98012a65b51be66fd76c3a1b13ed782c558
1022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===// 2022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson// 3022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson// The LLVM Compiler Infrastructure 4022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 7022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson// 8022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson//===----------------------------------------------------------------------===// 9022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson// 10022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson// This contains code to emit Builtin calls as LLVM code. 11022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson// 12022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson//===----------------------------------------------------------------------===// 13022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson 14022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson#include "CodeGenFunction.h" 15022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson#include "CodeGenModule.h" 16ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson#include "clang/Basic/TargetInfo.h" 171f32999ec79a980576e100d64d5f3267eb19ea49Chris Lattner#include "clang/AST/APValue.h" 18bef20ac367a09555b30d6eb3847a81ec164caf88Chris Lattner#include "clang/AST/ASTContext.h" 19c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbar#include "clang/AST/Decl.h" 206b15cdc1312f8fc45c86ee75e2a85106700e97f6Chris Lattner#include "clang/Basic/TargetBuiltins.h" 21793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson#include "llvm/Intrinsics.h" 22022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlssonusing namespace clang; 23022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlssonusing namespace CodeGen; 24ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlssonusing namespace llvm; 25ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson 260002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar/// Utility to insert an atomic instruction based on Instrinsic::ID 270002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar/// and the expression node. 281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic RValue EmitBinaryAtomic(CodeGenFunction& CGF, 291ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang Intrinsic::ID Id, const CallExpr *E) { 30c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang const llvm::Type *ResType[2]; 310002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar ResType[0] = CGF.ConvertType(E->getType()); 320002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar ResType[1] = CGF.ConvertType(E->getArg(0)->getType()); 330002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Value *AtomF = CGF.CGM.getIntrinsic(Id, ResType, 2); 341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return RValue::get(CGF.Builder.CreateCall2(AtomF, 351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump CGF.EmitScalarExpr(E->getArg(0)), 360002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar CGF.EmitScalarExpr(E->getArg(1)))); 370002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar} 380002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar 390002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar/// Utility to insert an atomic instruction based Instrinsic::ID and 400002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar// the expression node, where the return value is the result of the 410002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar// operation. 421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic RValue EmitBinaryAtomicPost(CodeGenFunction& CGF, 430002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Intrinsic::ID Id, const CallExpr *E, 440002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Instruction::BinaryOps Op) { 450002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar const llvm::Type *ResType[2]; 460002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar ResType[0] = CGF.ConvertType(E->getType()); 470002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar ResType[1] = CGF.ConvertType(E->getArg(0)->getType()); 480002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Value *AtomF = CGF.CGM.getIntrinsic(Id, ResType, 2); 490002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Value *Ptr = CGF.EmitScalarExpr(E->getArg(0)); 500002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Value *Operand = CGF.EmitScalarExpr(E->getArg(1)); 510002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Value *Result = CGF.Builder.CreateCall2(AtomF, Ptr, Operand); 521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 53eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner if (Id == Intrinsic::atomic_load_nand) 54eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner Result = CGF.Builder.CreateNot(Result); 551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 570002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar return RValue::get(CGF.Builder.CreateBinOp(Op, Result, Operand)); 581ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang} 591ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang 601eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpRValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, 61ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar unsigned BuiltinID, const CallExpr *E) { 62564ea2a99b3afeac9ded332730a56db1f6358a58Chris Lattner // See if we can constant fold this builtin. If so, don't emit it at all. 63f35d35a2316dcb65d078844696c2032b71a7f103Anders Carlsson Expr::EvalResult Result; 646ee7aa154e8bbb21a21254293410b944f78b0bfeChris Lattner if (E->Evaluate(Result, CGM.getContext())) { 65f35d35a2316dcb65d078844696c2032b71a7f103Anders Carlsson if (Result.Val.isInt()) 661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return RValue::get(llvm::ConstantInt::get(VMContext, 674a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson Result.Val.getInt())); 683941b18b8e441c8c466efecd557de60b9a32d10bEli Friedman else if (Result.Val.isFloat()) 69bc0a2226c7fcd18b29b6846049e2cfcb872d3593Owen Anderson return RValue::get(ConstantFP::get(VMContext, Result.Val.getFloat())); 701f32999ec79a980576e100d64d5f3267eb19ea49Chris Lattner } 711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 72564ea2a99b3afeac9ded332730a56db1f6358a58Chris Lattner switch (BuiltinID) { 73564ea2a99b3afeac9ded332730a56db1f6358a58Chris Lattner default: break; // Handle intrinsics and libm functions below. 74506ff88f44562df267b6a06608ab841b76df2a2bChris Lattner case Builtin::BI__builtin___CFStringMakeConstantString: 75e9352cc9818ba59e7cf88500ef048991c90f3821Anders Carlsson return RValue::get(CGM.EmitConstantExpr(E, E->getType(), 0)); 766a705f0443f8398ece14d80e71d8e8c9e71aa84aChris Lattner case Builtin::BI__builtin_stdarg_start: 77793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson case Builtin::BI__builtin_va_start: 78793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson case Builtin::BI__builtin_va_end: { 790785570af3ef5f8c5a0377129e41efe6f3f8d770Daniel Dunbar Value *ArgValue = EmitVAListRef(E->getArg(0)); 803c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer const llvm::Type *DestType = llvm::Type::getInt8PtrTy(VMContext); 81793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson if (ArgValue->getType() != DestType) 821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ArgValue = Builder.CreateBitCast(ArgValue, DestType, 83b27ffbef8e8aa1e87b63cbc0d9cd630aba30dae5Daniel Dunbar ArgValue->getName().data()); 84793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson 851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Intrinsic::ID inst = (BuiltinID == Builtin::BI__builtin_va_end) ? 866a705f0443f8398ece14d80e71d8e8c9e71aa84aChris Lattner Intrinsic::vaend : Intrinsic::vastart; 877acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner return RValue::get(Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue)); 88793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson } 89a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson case Builtin::BI__builtin_va_copy: { 904fd0aa5803357d8c72eeac2cae15e12649ea08feEli Friedman Value *DstPtr = EmitVAListRef(E->getArg(0)); 914fd0aa5803357d8c72eeac2cae15e12649ea08feEli Friedman Value *SrcPtr = EmitVAListRef(E->getArg(1)); 92a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson 933c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer const llvm::Type *Type = llvm::Type::getInt8PtrTy(VMContext); 94a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson 95a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson DstPtr = Builder.CreateBitCast(DstPtr, Type); 96a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson SrcPtr = Builder.CreateBitCast(SrcPtr, Type); 971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return RValue::get(Builder.CreateCall2(CGM.getIntrinsic(Intrinsic::vacopy), 983eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner DstPtr, SrcPtr)); 99a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson } 100c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson case Builtin::BI__builtin_abs: { 1011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1039a847f598c4907a72b8593b364b9e6b94b086e75Chris Lattner Value *NegOp = Builder.CreateNeg(ArgValue, "neg"); 1041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *CmpResult = 1051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Builder.CreateICmpSGE(ArgValue, 106c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson llvm::Constant::getNullValue(ArgValue->getType()), 1079a847f598c4907a72b8593b364b9e6b94b086e75Chris Lattner "abscond"); 1081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *Result = 109c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs"); 1101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 111c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson return RValue::get(Result); 112c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson } 1133a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson case Builtin::BI__builtin_ctz: 1143a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson case Builtin::BI__builtin_ctzl: 1153a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson case Builtin::BI__builtin_ctzll: { 1163a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1183a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson const llvm::Type *ArgType = ArgValue->getType(); 1193a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson Value *F = CGM.getIntrinsic(Intrinsic::cttz, &ArgType, 1); 1203a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson 1211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const llvm::Type *ResultType = ConvertType(E->getType()); 1223a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson Value *Result = Builder.CreateCall(F, ArgValue, "tmp"); 1233a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson if (Result->getType() != ResultType) 124eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 125eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 1263a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson return RValue::get(Result); 1273a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson } 128f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman case Builtin::BI__builtin_clz: 129f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman case Builtin::BI__builtin_clzl: 130f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman case Builtin::BI__builtin_clzll: { 131f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 133f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman const llvm::Type *ArgType = ArgValue->getType(); 134f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman Value *F = CGM.getIntrinsic(Intrinsic::ctlz, &ArgType, 1); 135f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman 1361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const llvm::Type *ResultType = ConvertType(E->getType()); 137f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman Value *Result = Builder.CreateCall(F, ArgValue, "tmp"); 138f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman if (Result->getType() != ResultType) 139eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 140eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 141f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman return RValue::get(Result); 142f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman } 14304b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_ffs: 14404b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_ffsl: 14504b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_ffsll: { 14604b290030eee33295600728450f348989d1a627eDaniel Dunbar // ffs(x) -> x ? cttz(x) + 1 : 0 14704b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14904b290030eee33295600728450f348989d1a627eDaniel Dunbar const llvm::Type *ArgType = ArgValue->getType(); 15004b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::cttz, &ArgType, 1); 1511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15204b290030eee33295600728450f348989d1a627eDaniel Dunbar const llvm::Type *ResultType = ConvertType(E->getType()); 1531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *Tmp = Builder.CreateAdd(Builder.CreateCall(F, ArgValue, "tmp"), 1544a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson llvm::ConstantInt::get(ArgType, 1), "tmp"); 155c9c88b4159791c48e486ca94e3743b5979e2b7a6Owen Anderson Value *Zero = llvm::Constant::getNullValue(ArgType); 15604b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero"); 15704b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp, "ffs"); 15804b290030eee33295600728450f348989d1a627eDaniel Dunbar if (Result->getType() != ResultType) 159eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 160eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 16104b290030eee33295600728450f348989d1a627eDaniel Dunbar return RValue::get(Result); 16204b290030eee33295600728450f348989d1a627eDaniel Dunbar } 16304b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_parity: 16404b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_parityl: 16504b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_parityll: { 16604b290030eee33295600728450f348989d1a627eDaniel Dunbar // parity(x) -> ctpop(x) & 1 16704b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 16904b290030eee33295600728450f348989d1a627eDaniel Dunbar const llvm::Type *ArgType = ArgValue->getType(); 17004b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::ctpop, &ArgType, 1); 1711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 17204b290030eee33295600728450f348989d1a627eDaniel Dunbar const llvm::Type *ResultType = ConvertType(E->getType()); 17304b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *Tmp = Builder.CreateCall(F, ArgValue, "tmp"); 1741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *Result = Builder.CreateAnd(Tmp, llvm::ConstantInt::get(ArgType, 1), 17504b290030eee33295600728450f348989d1a627eDaniel Dunbar "tmp"); 17604b290030eee33295600728450f348989d1a627eDaniel Dunbar if (Result->getType() != ResultType) 177eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 178eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 17904b290030eee33295600728450f348989d1a627eDaniel Dunbar return RValue::get(Result); 18004b290030eee33295600728450f348989d1a627eDaniel Dunbar } 18104b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_popcount: 18204b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_popcountl: 18304b290030eee33295600728450f348989d1a627eDaniel Dunbar case Builtin::BI__builtin_popcountll: { 18404b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18604b290030eee33295600728450f348989d1a627eDaniel Dunbar const llvm::Type *ArgType = ArgValue->getType(); 18704b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::ctpop, &ArgType, 1); 1881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18904b290030eee33295600728450f348989d1a627eDaniel Dunbar const llvm::Type *ResultType = ConvertType(E->getType()); 19004b290030eee33295600728450f348989d1a627eDaniel Dunbar Value *Result = Builder.CreateCall(F, ArgValue, "tmp"); 19104b290030eee33295600728450f348989d1a627eDaniel Dunbar if (Result->getType() != ResultType) 192eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 193eac73e5b3eb3862945bcaa2770c71a727a3ee542Duncan Sands "cast"); 19404b290030eee33295600728450f348989d1a627eDaniel Dunbar return RValue::get(Result); 19504b290030eee33295600728450f348989d1a627eDaniel Dunbar } 1961feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner case Builtin::BI__builtin_expect: 197a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar // FIXME: pass expect through to LLVM 1981feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner return RValue::get(EmitScalarExpr(E->getArg(0))); 199df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson case Builtin::BI__builtin_bswap32: 200df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson case Builtin::BI__builtin_bswap64: { 2011feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner Value *ArgValue = EmitScalarExpr(E->getArg(0)); 202df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson const llvm::Type *ArgType = ArgValue->getType(); 2037acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner Value *F = CGM.getIntrinsic(Intrinsic::bswap, &ArgType, 1); 2041feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner return RValue::get(Builder.CreateCall(F, ArgValue, "tmp")); 2051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 206d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar case Builtin::BI__builtin_object_size: { 207b16d32f74ffc467a5604934a1f844906be20cf7dMike Stump // We pass this builtin onto the optimizer so that it can 208b16d32f74ffc467a5604934a1f844906be20cf7dMike Stump // figure out the object size in more complex cases. 209c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump const llvm::Type *ResType[] = { 210c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump ConvertType(E->getType()) 211c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump }; 212fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher 213fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher // LLVM only supports 0 and 2, make sure that we pass along that 214fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher // as a boolean. 215fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher Value *Ty = EmitScalarExpr(E->getArg(1)); 216fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher ConstantInt *CI = dyn_cast<ConstantInt>(Ty); 217fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher assert(CI); 218fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher uint64_t val = CI->getZExtValue(); 219fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher CI = ConstantInt::get(llvm::Type::getInt1Ty(VMContext), (val & 0x2) >> 1); 220fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher 221c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump Value *F = CGM.getIntrinsic(Intrinsic::objectsize, ResType, 1); 222c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump return RValue::get(Builder.CreateCall2(F, 223c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump EmitScalarExpr(E->getArg(0)), 224fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher CI)); 225d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar } 2264493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar case Builtin::BI__builtin_prefetch: { 2274493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0)); 2284493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar // FIXME: Technically these constants should of type 'int', yes? 2291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump RW = (E->getNumArgs() > 1) ? EmitScalarExpr(E->getArg(1)) : 2300032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0); 2311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : 2320032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 3); 2334493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::prefetch, 0, 0); 2344493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar return RValue::get(Builder.CreateCall3(F, Address, RW, Locality)); 2354493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar } 2364493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar case Builtin::BI__builtin_trap: { 2374493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::trap, 0, 0); 2384493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar return RValue::get(Builder.CreateCall(F)); 239df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson } 24021190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner case Builtin::BI__builtin_unreachable: { 241fba565d044a8979cfd916ce52655a6847bfaa601Mike Stump if (CatchUndefined && HaveInsertPoint()) 242fba565d044a8979cfd916ce52655a6847bfaa601Mike Stump EmitBranch(getTrapBB()); 24321190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner Value *V = Builder.CreateUnreachable(); 24421190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner Builder.ClearInsertionPoint(); 24521190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner return RValue::get(V); 24621190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner } 24721190d54634d6e244e85d28ad915ce2fe86ecbffChris Lattner 248a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar case Builtin::BI__builtin_powi: 249a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar case Builtin::BI__builtin_powif: 250a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar case Builtin::BI__builtin_powil: { 251a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar Value *Base = EmitScalarExpr(E->getArg(0)); 252a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar Value *Exponent = EmitScalarExpr(E->getArg(1)); 253a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar const llvm::Type *ArgType = Base->getType(); 254a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::powi, &ArgType, 1); 255a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp")); 256a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar } 257a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar 258fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isgreater: 259fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isgreaterequal: 260fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isless: 261fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_islessequal: 262fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_islessgreater: 263fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isunordered: { 264fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner // Ordered comparisons: we know the arguments to these are matching scalar 265fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner // floating point values. 2661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *LHS = EmitScalarExpr(E->getArg(0)); 267fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner Value *RHS = EmitScalarExpr(E->getArg(1)); 2681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 269fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner switch (BuiltinID) { 270fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner default: assert(0 && "Unknown ordered comparison"); 271fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isgreater: 272fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp"); 273fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 274fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isgreaterequal: 275fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp"); 276fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 277fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_isless: 278fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp"); 279fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 280fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_islessequal: 281fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp"); 282fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 283fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner case Builtin::BI__builtin_islessgreater: 284fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp"); 285fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 2861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case Builtin::BI__builtin_isunordered: 287fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp"); 288fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner break; 289fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner } 290fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner // ZExt bool to int type. 291fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType()), 292fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner "tmp")); 293fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner } 294d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman case Builtin::BI__builtin_isnan: { 295d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman Value *V = EmitScalarExpr(E->getArg(0)); 296d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman V = Builder.CreateFCmpUNO(V, V, "cmp"); 297d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()), "tmp")); 298d6139895f43d161a972d134ffda4229d2f548eb6Eli Friedman } 299b52fe9ce99970955a5f581f5c66fcd89be9a268bEli Friedman case Builtin::BIalloca: 3009e800e3dd80d77f6c47054738177bf824089f55aChris Lattner case Builtin::BI__builtin_alloca: { 3019e800e3dd80d77f6c47054738177bf824089f55aChris Lattner // FIXME: LLVM IR Should allow alloca with an i64 size! 3029e800e3dd80d77f6c47054738177bf824089f55aChris Lattner Value *Size = EmitScalarExpr(E->getArg(0)); 3030032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson Size = Builder.CreateIntCast(Size, llvm::Type::getInt32Ty(VMContext), false, "tmp"); 3040032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson return RValue::get(Builder.CreateAlloca(llvm::Type::getInt8Ty(VMContext), Size, "tmp")); 3051caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar } 3061caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar case Builtin::BI__builtin_bzero: { 3071caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar Value *Address = EmitScalarExpr(E->getArg(0)); 3081caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar Builder.CreateCall4(CGM.getMemSetFn(), Address, 3090032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 0), 3101caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar EmitScalarExpr(E->getArg(1)), 3110032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1)); 3121caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar return RValue::get(Address); 3139e800e3dd80d77f6c47054738177bf824089f55aChris Lattner } 314e6ec205d6d0f4aec27bf49ca1e8fbb139acc2f2bEli Friedman case Builtin::BImemcpy: 315d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman case Builtin::BI__builtin_memcpy: { 3161caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar Value *Address = EmitScalarExpr(E->getArg(0)); 3171caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar Builder.CreateCall4(CGM.getMemCpyFn(), Address, 3181caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar EmitScalarExpr(E->getArg(1)), 3191caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar EmitScalarExpr(E->getArg(2)), 3200032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1)); 3211caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar return RValue::get(Address); 3221caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar } 323e6ec205d6d0f4aec27bf49ca1e8fbb139acc2f2bEli Friedman case Builtin::BImemmove: 3241caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar case Builtin::BI__builtin_memmove: { 3251caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar Value *Address = EmitScalarExpr(E->getArg(0)); 3261caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar Builder.CreateCall4(CGM.getMemMoveFn(), Address, 3271caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar EmitScalarExpr(E->getArg(1)), 3281caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar EmitScalarExpr(E->getArg(2)), 3290032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1)); 3301caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar return RValue::get(Address); 3311caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar } 332e6ec205d6d0f4aec27bf49ca1e8fbb139acc2f2bEli Friedman case Builtin::BImemset: 3331caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar case Builtin::BI__builtin_memset: { 3341caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar Value *Address = EmitScalarExpr(E->getArg(0)); 3351caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar Builder.CreateCall4(CGM.getMemSetFn(), Address, 33662c29c667f5bcb854e99ccb3aec1280c84115951Daniel Dunbar Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), 3370032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::Type::getInt8Ty(VMContext)), 3381caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar EmitScalarExpr(E->getArg(2)), 3390032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1)); 3401caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar return RValue::get(Address); 341d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman } 342256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman case Builtin::BI__builtin_return_address: { 34383c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov Value *Depth = EmitScalarExpr(E->getArg(0)); 34483c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov Depth = Builder.CreateIntCast(Depth, 34583c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov llvm::Type::getInt32Ty(VMContext), 34683c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov false, "tmp"); 347256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman Value *F = CGM.getIntrinsic(Intrinsic::returnaddress, 0, 0); 34883c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov return RValue::get(Builder.CreateCall(F, Depth)); 349256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman } 350256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman case Builtin::BI__builtin_frame_address: { 35183c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov Value *Depth = EmitScalarExpr(E->getArg(0)); 35283c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov Depth = Builder.CreateIntCast(Depth, 35383c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov llvm::Type::getInt32Ty(VMContext), 35483c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov false, "tmp"); 355256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman Value *F = CGM.getIntrinsic(Intrinsic::frameaddress, 0, 0); 35683c2a98012a65b51be66fd76c3a1b13ed782c558Anton Korobeynikov return RValue::get(Builder.CreateCall(F, Depth)); 357256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman } 3583b660efb9f9fa3e87096f4a96a2093cd17c43c2eEli Friedman case Builtin::BI__builtin_extract_return_addr: { 3593b660efb9f9fa3e87096f4a96a2093cd17c43c2eEli Friedman // FIXME: There should be a target hook for this 3603b660efb9f9fa3e87096f4a96a2093cd17c43c2eEli Friedman return RValue::get(EmitScalarExpr(E->getArg(0))); 3613b660efb9f9fa3e87096f4a96a2093cd17c43c2eEli Friedman } 362a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman case Builtin::BI__builtin_unwind_init: { 363a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init, 0, 0); 364a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman return RValue::get(Builder.CreateCall(F)); 365a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman } 366a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman#if 0 367a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman // FIXME: Finish/enable when LLVM backend support stabilizes 368a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman case Builtin::BI__builtin_setjmp: { 369a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *Buf = EmitScalarExpr(E->getArg(0)); 370a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman // Store the frame pointer to the buffer 371a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *FrameAddrF = CGM.getIntrinsic(Intrinsic::frameaddress, 0, 0); 372a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *FrameAddr = 373a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Builder.CreateCall(FrameAddrF, 3740032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson Constant::getNullValue(llvm::Type::getInt32Ty(VMContext))); 375a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Builder.CreateStore(FrameAddr, Buf); 376a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman // Call the setjmp intrinsic 377a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp, 0, 0); 3783c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer const llvm::Type *DestType = llvm::Type::getInt8PtrTy(VMContext); 379a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Buf = Builder.CreateBitCast(Buf, DestType); 380a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman return RValue::get(Builder.CreateCall(F, Buf)); 381a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman } 382a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman case Builtin::BI__builtin_longjmp: { 383a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp, 0, 0); 384a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Value *Buf = EmitScalarExpr(E->getArg(0)); 3853c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer const llvm::Type *DestType = llvm::Type::getInt8PtrTy(VMContext); 386a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman Buf = Builder.CreateBitCast(Buf, DestType); 387a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman return RValue::get(Builder.CreateCall(F, Buf)); 388a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman } 389a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman#endif 3901ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_add: 3911ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_sub: 3925caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or: 3935caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and: 3945caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor: 3955caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch: 3965caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch: 3975caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch: 3985caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch: 3995caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch: 4005caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap: 4015caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap: 4025caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set: 4035caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release: 4045caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner assert(0 && "Shouldn't make it through sema"); 4055caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_1: 4065caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_2: 4075caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_4: 4085caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_8: 4095caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add_16: 4105caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner return EmitBinaryAtomic(*this, Intrinsic::atomic_load_add, E); 4115caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_1: 4125caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_2: 4135caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_4: 4145caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_8: 4155caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub_16: 41609b6bf5bfa2ba9cbbd353cbd7846af8f49b020e7Mon P Wang return EmitBinaryAtomic(*this, Intrinsic::atomic_load_sub, E); 4175caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_1: 4185caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_2: 4195caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_4: 4205caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_8: 4215caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or_16: 4225caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner return EmitBinaryAtomic(*this, Intrinsic::atomic_load_or, E); 4235caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_1: 4245caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_2: 4255caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_4: 4265caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_8: 4275caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and_16: 4285caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner return EmitBinaryAtomic(*this, Intrinsic::atomic_load_and, E); 4295caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_1: 4305caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_2: 4315caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_4: 4325caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_8: 4335caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor_16: 4345caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner return EmitBinaryAtomic(*this, Intrinsic::atomic_load_xor, E); 435eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner case Builtin::BI__sync_fetch_and_nand_1: 436eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner case Builtin::BI__sync_fetch_and_nand_2: 437eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner case Builtin::BI__sync_fetch_and_nand_4: 438eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner case Builtin::BI__sync_fetch_and_nand_8: 439eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner case Builtin::BI__sync_fetch_and_nand_16: 440eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner return EmitBinaryAtomic(*this, Intrinsic::atomic_load_nand, E); 4411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4425caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // Clang extensions: not overloaded yet. 4431ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_min: 4441ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang return EmitBinaryAtomic(*this, Intrinsic::atomic_load_min, E); 4451ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_max: 4461ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang return EmitBinaryAtomic(*this, Intrinsic::atomic_load_max, E); 4471ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_umin: 4481ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umin, E); 4491ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang case Builtin::BI__sync_fetch_and_umax: 4501ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umax, E); 4510002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar 4525caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_1: 4535caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_2: 4545caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_4: 4555caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_8: 4565caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch_16: 4571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_add, E, 4580002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::Add); 4595caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_1: 4605caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_2: 4615caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_4: 4625caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_8: 4635caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch_16: 4640002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_sub, E, 4650002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::Sub); 4665caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_1: 4675caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_2: 4685caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_4: 4695caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_8: 4705caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch_16: 4710002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_and, E, 4720002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::And); 4735caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_1: 4745caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_2: 4755caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_4: 4765caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_8: 4775caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch_16: 4780002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_or, E, 4790002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::Or); 4805caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_1: 4815caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_2: 4825caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_4: 4835caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_8: 4845caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch_16: 4850002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_xor, E, 4860002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar llvm::Instruction::Xor); 487eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner case Builtin::BI__sync_nand_and_fetch_1: 488eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner case Builtin::BI__sync_nand_and_fetch_2: 489eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner case Builtin::BI__sync_nand_and_fetch_4: 490eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner case Builtin::BI__sync_nand_and_fetch_8: 491eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner case Builtin::BI__sync_nand_and_fetch_16: 492eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_nand, E, 493eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner llvm::Instruction::And); 4941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4955caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap_1: 4965caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap_2: 4975caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap_4: 4985caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap_8: 4995caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap_16: 5005caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner { 501c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang const llvm::Type *ResType[2]; 502c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang ResType[0]= ConvertType(E->getType()); 503c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang ResType[1] = ConvertType(E->getArg(0)->getType()); 504c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap, ResType, 2); 5051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return RValue::get(Builder.CreateCall3(AtomF, 506958444659c5287a81a43188bfaa2a4902752b947Anders Carlsson EmitScalarExpr(E->getArg(0)), 507958444659c5287a81a43188bfaa2a4902752b947Anders Carlsson EmitScalarExpr(E->getArg(1)), 508958444659c5287a81a43188bfaa2a4902752b947Anders Carlsson EmitScalarExpr(E->getArg(2)))); 509022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson } 5100002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar 5115caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap_1: 5125caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap_2: 5135caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap_4: 5145caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap_8: 5155caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap_16: 5165caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner { 5170002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar const llvm::Type *ResType[2]; 5185caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner ResType[0]= ConvertType(E->getArg(1)->getType()); 51996e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson ResType[1] = llvm::PointerType::getUnqual(ResType[0]); 5200002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap, ResType, 2); 5210002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Value *OldVal = EmitScalarExpr(E->getArg(1)); 5221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Value *PrevVal = Builder.CreateCall3(AtomF, 5230002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar EmitScalarExpr(E->getArg(0)), 5240002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar OldVal, 5250002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar EmitScalarExpr(E->getArg(2))); 5260002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar Value *Result = Builder.CreateICmpEQ(PrevVal, OldVal); 5270002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar // zext bool to int. 5280002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar return RValue::get(Builder.CreateZExt(Result, ConvertType(E->getType()))); 5290002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar } 5300002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar 5315caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_1: 5325caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_2: 5335caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_4: 5345caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_8: 5355caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set_16: 5367ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman return EmitBinaryAtomic(*this, Intrinsic::atomic_swap, E); 5375caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release_1: 5385caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release_2: 5395caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release_4: 5405caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release_8: 541f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner case Builtin::BI__sync_lock_release_16: { 542f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner Value *Ptr = EmitScalarExpr(E->getArg(0)); 543f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner const llvm::Type *ElTy = 544f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner cast<llvm::PointerType>(Ptr->getType())->getElementType(); 545007b56738b00426688ee85baa75174358bd849f9Daniel Dunbar llvm::StoreInst *Store = 546007b56738b00426688ee85baa75174358bd849f9Daniel Dunbar Builder.CreateStore(llvm::Constant::getNullValue(ElTy), Ptr); 547007b56738b00426688ee85baa75174358bd849f9Daniel Dunbar Store->setVolatile(true); 548eb4f81e174b11633f7b85f555ea5d2834d6dae8aDaniel Dunbar return RValue::get(0); 549f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner } 550ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar 551f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner case Builtin::BI__sync_synchronize: { 552f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner Value *C[5]; 5530032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson C[0] = C[1] = C[2] = C[3] = llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 1); 5540032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson C[4] = llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0); 555f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner Builder.CreateCall(CGM.getIntrinsic(Intrinsic::memory_barrier), C, C + 5); 556eb4f81e174b11633f7b85f555ea5d2834d6dae8aDaniel Dunbar return RValue::get(0); 557f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner } 5581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 559ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar // Library functions with special handling. 560ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIsqrt: 561ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIsqrtf: 562ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIsqrtl: { 563ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar // Rewrite sqrt to intrinsic if allowed. 56440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis if (!FD->hasAttr<ConstAttr>()) 565ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar break; 566ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar Value *Arg0 = EmitScalarExpr(E->getArg(0)); 567ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar const llvm::Type *ArgType = Arg0->getType(); 568ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::sqrt, &ArgType, 1); 569ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar return RValue::get(Builder.CreateCall(F, Arg0, "tmp")); 570ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar } 571ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar 572ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIpow: 573ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIpowf: 574ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar case Builtin::BIpowl: { 575ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar // Rewrite sqrt to intrinsic if allowed. 57640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis if (!FD->hasAttr<ConstAttr>()) 577ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar break; 578ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar Value *Base = EmitScalarExpr(E->getArg(0)); 579ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar Value *Exponent = EmitScalarExpr(E->getArg(1)); 580ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar const llvm::Type *ArgType = Base->getType(); 581ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar Value *F = CGM.getIntrinsic(Intrinsic::pow, &ArgType, 1); 582ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp")); 583ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar } 5847ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman } 5851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 586b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // If this is an alias for a libm function (e.g. __builtin_sin) turn it into 587b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // that function. 5883e41d60eb627dc227c770f1c1c87d06909cf05fdDouglas Gregor if (getContext().BuiltinInfo.isLibFunction(BuiltinID) || 5893e41d60eb627dc227c770f1c1c87d06909cf05fdDouglas Gregor getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID)) 59031777a2540879051a3c643b90e02c3fd3d315243Anders Carlsson return EmitCall(E->getCallee()->getType(), 59131777a2540879051a3c643b90e02c3fd3d315243Anders Carlsson CGM.getBuiltinLibFunction(FD, BuiltinID), 592d2490a91341b57df7a7e54f8a707e7ecde2eeb4eAnders Carlsson ReturnValueSlot(), 59331777a2540879051a3c643b90e02c3fd3d315243Anders Carlsson E->arg_begin(), E->arg_end()); 5941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 595b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // See if we have a target specific intrinsic. 596a6f80ef997f0363386749087b325607eaa5adcfcDale Johannesen const char *Name = getContext().BuiltinInfo.GetName(BuiltinID); 59755cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic; 59855cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar if (const char *Prefix = 5991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Triple::getArchTypePrefix(Target.getTriple().getArch())) 60055cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix, Name); 6011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 602b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (IntrinsicID != Intrinsic::not_intrinsic) { 603b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner SmallVector<Value*, 16> Args; 6041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 605b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner Function *F = CGM.getIntrinsic(IntrinsicID); 606b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner const llvm::FunctionType *FTy = F->getFunctionType(); 6071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 608b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 609b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner Value *ArgValue = EmitScalarExpr(E->getArg(i)); 6101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 611b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // If the intrinsic arg type is different from the builtin arg type 612b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // we need to do a bit cast. 613b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner const llvm::Type *PTy = FTy->getParamType(i); 614b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (PTy != ArgValue->getType()) { 615b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) && 616b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner "Must be able to losslessly bit cast to param"); 617b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner ArgValue = Builder.CreateBitCast(ArgValue, PTy); 618b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 6191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 620b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner Args.push_back(ArgValue); 621b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 6221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 623beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad Value *V = Builder.CreateCall(F, Args.data(), Args.data() + Args.size()); 624b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner QualType BuiltinRetType = E->getType(); 6251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6260032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson const llvm::Type *RetTy = llvm::Type::getVoidTy(VMContext); 627b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (!BuiltinRetType->isVoidType()) RetTy = ConvertType(BuiltinRetType); 6281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 629b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (RetTy != V->getType()) { 630b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner assert(V->getType()->canLosslesslyBitCastTo(RetTy) && 631b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner "Must be able to losslessly bit cast result type"); 632b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner V = Builder.CreateBitCast(V, RetTy); 633b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 6341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 635b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner return RValue::get(V); 636b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner } 6371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 638b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // See if we have a target specific builtin that needs to be lowered. 639f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E)) 640b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner return RValue::get(V); 6411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 642488e993a135ce700b982bf099c3d6b856301d642Daniel Dunbar ErrorUnsupported(E, "builtin function"); 6431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 644b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner // Unknown builtin, for now just dump it out and return undef. 645b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner if (hasAggregateLLVMType(E->getType())) 646b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner return RValue::getAggregate(CreateTempAlloca(ConvertType(E->getType()))); 64703e205031b08669f05c41eed5b896fc94c4a12bbOwen Anderson return RValue::get(llvm::UndefValue::get(ConvertType(E->getType()))); 6481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 649564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson 650f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel DunbarValue *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, 651f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar const CallExpr *E) { 65255cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar switch (Target.getTriple().getArch()) { 65355cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::x86: 65455cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::x86_64: 655f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar return EmitX86BuiltinExpr(BuiltinID, E); 65655cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::ppc: 65755cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar case llvm::Triple::ppc64: 658f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar return EmitPPCBuiltinExpr(BuiltinID, E); 65955cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar default: 66055cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar return 0; 66155cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar } 662f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar} 663f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar 6641eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpValue *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, 6651feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner const CallExpr *E) { 6661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6672929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson llvm::SmallVector<Value*, 4> Ops; 6682929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson 6692929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) 6702929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson Ops.push_back(EmitScalarExpr(E->getArg(i))); 6712929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson 672564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson switch (BuiltinID) { 67346a26b0b0e2ec1557bad9b70e8e20836524ebdfcAnders Carlsson default: return 0; 6741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case X86::BI__builtin_ia32_pslldi128: 675e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psllqi128: 6761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case X86::BI__builtin_ia32_psllwi128: 677e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psradi128: 678e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrawi128: 679e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrldi128: 680e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrlqi128: 681e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrlwi128: { 6820032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::getInt64Ty(VMContext), "zext"); 6830032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson const llvm::Type *Ty = llvm::VectorType::get(llvm::Type::getInt64Ty(VMContext), 2); 6840032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::Value *Zero = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0); 68503e205031b08669f05c41eed5b896fc94c4a12bbOwen Anderson Ops[1] = Builder.CreateInsertElement(llvm::UndefValue::get(Ty), 686e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[1], Zero, "insert"); 687e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType(), "bitcast"); 688e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman const char *name = 0; 689e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Intrinsic::ID ID = Intrinsic::not_intrinsic; 6901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 691e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman switch (BuiltinID) { 692e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman default: assert(0 && "Unsupported shift intrinsic!"); 693e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_pslldi128: 694e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "pslldi"; 695e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psll_d; 696e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 697e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psllqi128: 698e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "psllqi"; 699e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psll_q; 700e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 701e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psllwi128: 702e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "psllwi"; 703e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psll_w; 704e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 705e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psradi128: 706e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "psradi"; 707e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psra_d; 708e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 709e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrawi128: 710e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "psrawi"; 711e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psra_w; 712e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 713e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrldi128: 714e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "psrldi"; 715e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psrl_d; 716e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 717e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrlqi128: 718e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "psrlqi"; 719e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psrl_q; 720e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 721e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_psrlwi128: 722e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman name = "psrlwi"; 723e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman ID = Intrinsic::x86_sse2_psrl_w; 724e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman break; 725e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 726e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman llvm::Function *F = CGM.getIntrinsic(ID); 7271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name); 728e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 7291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case X86::BI__builtin_ia32_pslldi: 7302929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psllqi: 7311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case X86::BI__builtin_ia32_psllwi: 7322929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psradi: 7332929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrawi: 7342929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrldi: 7352929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrlqi: 7362929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrlwi: { 7370032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::getInt64Ty(VMContext), "zext"); 7380032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson const llvm::Type *Ty = llvm::VectorType::get(llvm::Type::getInt64Ty(VMContext), 1); 7392929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson Ops[1] = Builder.CreateBitCast(Ops[1], Ty, "bitcast"); 7402929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson const char *name = 0; 7412929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson Intrinsic::ID ID = Intrinsic::not_intrinsic; 7421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7432929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson switch (BuiltinID) { 7442929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson default: assert(0 && "Unsupported shift intrinsic!"); 7452929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_pslldi: 7462929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "pslldi"; 7472929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psll_d; 7482929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 7492929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psllqi: 7502929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "psllqi"; 7512929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psll_q; 7522929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 7532929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psllwi: 7542929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "psllwi"; 7552929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psll_w; 7562929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 7572929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psradi: 7582929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "psradi"; 7592929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psra_d; 7602929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 7612929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrawi: 7622929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "psrawi"; 7632929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psra_w; 7642929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 7652929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrldi: 7662929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "psrldi"; 7672929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psrl_d; 7682929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 7692929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrlqi: 7702929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "psrlqi"; 7712929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psrl_q; 7722929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 7732929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson case X86::BI__builtin_ia32_psrlwi: 7742929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson name = "psrlwi"; 7752929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson ID = Intrinsic::x86_mmx_psrl_w; 7762929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson break; 7772929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson } 7787acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner llvm::Function *F = CGM.getIntrinsic(ID); 7791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name); 7802929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson } 78179dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson case X86::BI__builtin_ia32_cmpps: { 78279dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ps); 78379dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpps"); 78479dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson } 78579dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson case X86::BI__builtin_ia32_cmpss: { 78679dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ss); 78779dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpss"); 788cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson } 789e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_ldmxcsr: { 7903c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext); 7910032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson Value *One = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1); 7920032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson Value *Tmp = Builder.CreateAlloca(llvm::Type::getInt32Ty(VMContext), One, "tmp"); 793e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Builder.CreateStore(Ops[0], Tmp); 794e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr), 7953eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner Builder.CreateBitCast(Tmp, PtrTy)); 796e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 797e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_stmxcsr: { 7983c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext); 7990032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson Value *One = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1); 8000032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson Value *Tmp = Builder.CreateAlloca(llvm::Type::getInt32Ty(VMContext), One, "tmp"); 801e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman One = Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr), 8023eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner Builder.CreateBitCast(Tmp, PtrTy)); 803e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman return Builder.CreateLoad(Tmp, "stmxcsr"); 804e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 80579dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson case X86::BI__builtin_ia32_cmppd: { 80679dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_pd); 80779dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmppd"); 80879dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson } 80979dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson case X86::BI__builtin_ia32_cmpsd: { 81079dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_sd); 81179dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpsd"); 812cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson } 813e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_storehps: 814e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman case X86::BI__builtin_ia32_storelps: { 8150032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson const llvm::Type *EltTy = llvm::Type::getInt64Ty(VMContext); 81696e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson llvm::Type *PtrTy = llvm::PointerType::getUnqual(EltTy); 81796e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2); 8181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 819e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman // cast val v2i64 820e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast"); 8211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 822e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman // extract (0, 1) 823e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1; 8240032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson llvm::Value *Idx = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Index); 825e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract"); 826e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman 827e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman // cast pointer to i64 & store 828e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy); 829e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman return Builder.CreateStore(Ops[1], Ops[0]); 830e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman } 83191b59274439f776cdd545bd7bf5849fdb1842160Eric Christopher case X86::BI__builtin_ia32_palignr: { 832c3420ffb282c6ffc0192013bf8045b6c21eddeceNate Begeman Function *F = CGM.getIntrinsic(Intrinsic::x86_ssse3_palign_r); 833c3420ffb282c6ffc0192013bf8045b6c21eddeceNate Begeman return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size()); 834c3420ffb282c6ffc0192013bf8045b6c21eddeceNate Begeman } 835c3420ffb282c6ffc0192013bf8045b6c21eddeceNate Begeman case X86::BI__builtin_ia32_palignr128: { 836ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 837ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 838ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // If palignr is shifting the pair of input vectors less than 17 bytes, 839ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // emit a shuffle instruction. 840ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman if (shiftVal <= 16) { 841ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman const llvm::Type *IntTy = llvm::Type::getInt32Ty(VMContext); 842ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 843ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman llvm::SmallVector<llvm::Constant*, 16> Indices; 844ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman for (unsigned i = 0; i != 16; ++i) 845ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman Indices.push_back(llvm::ConstantInt::get(IntTy, shiftVal + i)); 846ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 847ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman Value* SV = llvm::ConstantVector::get(Indices.begin(), Indices.size()); 848ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 849ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman } 850ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 851ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // If palignr is shifting the pair of input vectors more than 16 but less 852ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // than 32 bytes, emit a logical right shift of the destination. 853ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman if (shiftVal < 32) { 854ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman const llvm::Type *EltTy = llvm::Type::getInt64Ty(VMContext); 855ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman const llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2); 856ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman const llvm::Type *IntTy = llvm::Type::getInt32Ty(VMContext); 857ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 858ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 859ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman Ops[1] = llvm::ConstantInt::get(IntTy, (shiftVal-16) * 8); 860ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 861ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // create i32 constant 862ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_psrl_dq); 863ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman return Builder.CreateCall(F, &Ops[0], &Ops[0] + 2, "palignr"); 864ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman } 865ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman 866ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 867ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman return llvm::Constant::getNullValue(ConvertType(E->getType())); 86891b59274439f776cdd545bd7bf5849fdb1842160Eric Christopher } 869564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson } 870564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson} 871564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson 8721eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpValue *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, 8731feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner const CallExpr *E) { 874b0b84385f0cb0ea4036579f5f384f1c19b917c7eDaniel Dunbar return 0; 8751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 876