CGBuiltin.cpp revision 31777a2540879051a3c643b90e02c3fd3d315243
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: {
343256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman    Value *F = CGM.getIntrinsic(Intrinsic::returnaddress, 0, 0);
344256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman    return RValue::get(Builder.CreateCall(F, EmitScalarExpr(E->getArg(0))));
345256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman  }
346256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman  case Builtin::BI__builtin_frame_address: {
347256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman    Value *F = CGM.getIntrinsic(Intrinsic::frameaddress, 0, 0);
348256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman    return RValue::get(Builder.CreateCall(F, EmitScalarExpr(E->getArg(0))));
349256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman  }
3503b660efb9f9fa3e87096f4a96a2093cd17c43c2eEli Friedman  case Builtin::BI__builtin_extract_return_addr: {
3513b660efb9f9fa3e87096f4a96a2093cd17c43c2eEli Friedman    // FIXME: There should be a target hook for this
3523b660efb9f9fa3e87096f4a96a2093cd17c43c2eEli Friedman    return RValue::get(EmitScalarExpr(E->getArg(0)));
3533b660efb9f9fa3e87096f4a96a2093cd17c43c2eEli Friedman  }
354a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman  case Builtin::BI__builtin_unwind_init: {
355a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    Value *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init, 0, 0);
356a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    return RValue::get(Builder.CreateCall(F));
357a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman  }
358a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman#if 0
359a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman  // FIXME: Finish/enable when LLVM backend support stabilizes
360a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman  case Builtin::BI__builtin_setjmp: {
361a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    Value *Buf = EmitScalarExpr(E->getArg(0));
362a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    // Store the frame pointer to the buffer
363a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    Value *FrameAddrF = CGM.getIntrinsic(Intrinsic::frameaddress, 0, 0);
364a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    Value *FrameAddr =
365a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman        Builder.CreateCall(FrameAddrF,
3660032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson                           Constant::getNullValue(llvm::Type::getInt32Ty(VMContext)));
367a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    Builder.CreateStore(FrameAddr, Buf);
368a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    // Call the setjmp intrinsic
369a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp, 0, 0);
3703c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer    const llvm::Type *DestType = llvm::Type::getInt8PtrTy(VMContext);
371a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    Buf = Builder.CreateBitCast(Buf, DestType);
372a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    return RValue::get(Builder.CreateCall(F, Buf));
373a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman  }
374a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman  case Builtin::BI__builtin_longjmp: {
375a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp, 0, 0);
376a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    Value *Buf = EmitScalarExpr(E->getArg(0));
3773c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer    const llvm::Type *DestType = llvm::Type::getInt8PtrTy(VMContext);
378a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    Buf = Builder.CreateBitCast(Buf, DestType);
379a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    return RValue::get(Builder.CreateCall(F, Buf));
380a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman  }
381a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman#endif
3821ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_fetch_and_add:
3831ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_fetch_and_sub:
3845caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_or:
3855caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_and:
3865caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_xor:
3875caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_add_and_fetch:
3885caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_sub_and_fetch:
3895caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_and_and_fetch:
3905caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_or_and_fetch:
3915caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_xor_and_fetch:
3925caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_val_compare_and_swap:
3935caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_bool_compare_and_swap:
3945caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_lock_test_and_set:
3955caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_lock_release:
3965caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner    assert(0 && "Shouldn't make it through sema");
3975caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_add_1:
3985caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_add_2:
3995caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_add_4:
4005caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_add_8:
4015caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_add_16:
4025caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_add, E);
4035caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_sub_1:
4045caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_sub_2:
4055caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_sub_4:
4065caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_sub_8:
4075caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_sub_16:
40809b6bf5bfa2ba9cbbd353cbd7846af8f49b020e7Mon P Wang    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_sub, E);
4095caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_or_1:
4105caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_or_2:
4115caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_or_4:
4125caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_or_8:
4135caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_or_16:
4145caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_or, E);
4155caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_and_1:
4165caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_and_2:
4175caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_and_4:
4185caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_and_8:
4195caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_and_16:
4205caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_and, E);
4215caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_xor_1:
4225caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_xor_2:
4235caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_xor_4:
4245caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_xor_8:
4255caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_xor_16:
4265caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_xor, E);
427eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner  case Builtin::BI__sync_fetch_and_nand_1:
428eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner  case Builtin::BI__sync_fetch_and_nand_2:
429eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner  case Builtin::BI__sync_fetch_and_nand_4:
430eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner  case Builtin::BI__sync_fetch_and_nand_8:
431eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner  case Builtin::BI__sync_fetch_and_nand_16:
432eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_nand, E);
4331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4345caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  // Clang extensions: not overloaded yet.
4351ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_fetch_and_min:
4361ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_min, E);
4371ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_fetch_and_max:
4381ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_max, E);
4391ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_fetch_and_umin:
4401ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umin, E);
4411ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_fetch_and_umax:
4421ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umax, E);
4430002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar
4445caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_add_and_fetch_1:
4455caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_add_and_fetch_2:
4465caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_add_and_fetch_4:
4475caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_add_and_fetch_8:
4485caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_add_and_fetch_16:
4491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_add, E,
4500002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar                                llvm::Instruction::Add);
4515caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_sub_and_fetch_1:
4525caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_sub_and_fetch_2:
4535caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_sub_and_fetch_4:
4545caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_sub_and_fetch_8:
4555caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_sub_and_fetch_16:
4560002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar    return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_sub, E,
4570002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar                                llvm::Instruction::Sub);
4585caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_and_and_fetch_1:
4595caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_and_and_fetch_2:
4605caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_and_and_fetch_4:
4615caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_and_and_fetch_8:
4625caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_and_and_fetch_16:
4630002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar    return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_and, E,
4640002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar                                llvm::Instruction::And);
4655caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_or_and_fetch_1:
4665caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_or_and_fetch_2:
4675caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_or_and_fetch_4:
4685caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_or_and_fetch_8:
4695caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_or_and_fetch_16:
4700002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar    return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_or, E,
4710002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar                                llvm::Instruction::Or);
4725caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_xor_and_fetch_1:
4735caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_xor_and_fetch_2:
4745caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_xor_and_fetch_4:
4755caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_xor_and_fetch_8:
4765caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_xor_and_fetch_16:
4770002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar    return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_xor, E,
4780002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar                                llvm::Instruction::Xor);
479eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner  case Builtin::BI__sync_nand_and_fetch_1:
480eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner  case Builtin::BI__sync_nand_and_fetch_2:
481eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner  case Builtin::BI__sync_nand_and_fetch_4:
482eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner  case Builtin::BI__sync_nand_and_fetch_8:
483eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner  case Builtin::BI__sync_nand_and_fetch_16:
484eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner    return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_nand, E,
485eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner                                llvm::Instruction::And);
4861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4875caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_val_compare_and_swap_1:
4885caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_val_compare_and_swap_2:
4895caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_val_compare_and_swap_4:
4905caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_val_compare_and_swap_8:
4915caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_val_compare_and_swap_16:
4925caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  {
493c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang    const llvm::Type *ResType[2];
494c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang    ResType[0]= ConvertType(E->getType());
495c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang    ResType[1] = ConvertType(E->getArg(0)->getType());
496c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang    Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap, ResType, 2);
4971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return RValue::get(Builder.CreateCall3(AtomF,
498958444659c5287a81a43188bfaa2a4902752b947Anders Carlsson                                           EmitScalarExpr(E->getArg(0)),
499958444659c5287a81a43188bfaa2a4902752b947Anders Carlsson                                           EmitScalarExpr(E->getArg(1)),
500958444659c5287a81a43188bfaa2a4902752b947Anders Carlsson                                           EmitScalarExpr(E->getArg(2))));
501022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson  }
5020002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar
5035caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_bool_compare_and_swap_1:
5045caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_bool_compare_and_swap_2:
5055caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_bool_compare_and_swap_4:
5065caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_bool_compare_and_swap_8:
5075caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_bool_compare_and_swap_16:
5085caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  {
5090002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar    const llvm::Type *ResType[2];
5105caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner    ResType[0]= ConvertType(E->getArg(1)->getType());
51196e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    ResType[1] = llvm::PointerType::getUnqual(ResType[0]);
5120002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar    Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap, ResType, 2);
5130002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar    Value *OldVal = EmitScalarExpr(E->getArg(1));
5141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Value *PrevVal = Builder.CreateCall3(AtomF,
5150002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar                                        EmitScalarExpr(E->getArg(0)),
5160002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar                                        OldVal,
5170002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar                                        EmitScalarExpr(E->getArg(2)));
5180002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar    Value *Result = Builder.CreateICmpEQ(PrevVal, OldVal);
5190002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar    // zext bool to int.
5200002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar    return RValue::get(Builder.CreateZExt(Result, ConvertType(E->getType())));
5210002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar  }
5220002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar
5235caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_lock_test_and_set_1:
5245caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_lock_test_and_set_2:
5255caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_lock_test_and_set_4:
5265caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_lock_test_and_set_8:
5275caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_lock_test_and_set_16:
5287ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman    return EmitBinaryAtomic(*this, Intrinsic::atomic_swap, E);
5295caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_lock_release_1:
5305caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_lock_release_2:
5315caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_lock_release_4:
5325caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_lock_release_8:
533f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner  case Builtin::BI__sync_lock_release_16: {
534f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner    Value *Ptr = EmitScalarExpr(E->getArg(0));
535f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner    const llvm::Type *ElTy =
536f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner      cast<llvm::PointerType>(Ptr->getType())->getElementType();
537007b56738b00426688ee85baa75174358bd849f9Daniel Dunbar    llvm::StoreInst *Store =
538007b56738b00426688ee85baa75174358bd849f9Daniel Dunbar      Builder.CreateStore(llvm::Constant::getNullValue(ElTy), Ptr);
539007b56738b00426688ee85baa75174358bd849f9Daniel Dunbar    Store->setVolatile(true);
540eb4f81e174b11633f7b85f555ea5d2834d6dae8aDaniel Dunbar    return RValue::get(0);
541f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner  }
542ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar
543f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner  case Builtin::BI__sync_synchronize: {
544f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner    Value *C[5];
5450032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    C[0] = C[1] = C[2] = C[3] = llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 1);
5460032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    C[4] = llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0);
547f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner    Builder.CreateCall(CGM.getIntrinsic(Intrinsic::memory_barrier), C, C + 5);
548eb4f81e174b11633f7b85f555ea5d2834d6dae8aDaniel Dunbar    return RValue::get(0);
549f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner  }
5501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
551ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    // Library functions with special handling.
552ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar  case Builtin::BIsqrt:
553ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar  case Builtin::BIsqrtf:
554ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar  case Builtin::BIsqrtl: {
555ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    // Rewrite sqrt to intrinsic if allowed.
55640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis    if (!FD->hasAttr<ConstAttr>())
557ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar      break;
558ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    Value *Arg0 = EmitScalarExpr(E->getArg(0));
559ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    const llvm::Type *ArgType = Arg0->getType();
560ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    Value *F = CGM.getIntrinsic(Intrinsic::sqrt, &ArgType, 1);
561ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    return RValue::get(Builder.CreateCall(F, Arg0, "tmp"));
562ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar  }
563ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar
564ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar  case Builtin::BIpow:
565ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar  case Builtin::BIpowf:
566ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar  case Builtin::BIpowl: {
567ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    // Rewrite sqrt to intrinsic if allowed.
56840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis    if (!FD->hasAttr<ConstAttr>())
569ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar      break;
570ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    Value *Base = EmitScalarExpr(E->getArg(0));
571ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    Value *Exponent = EmitScalarExpr(E->getArg(1));
572ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    const llvm::Type *ArgType = Base->getType();
573ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    Value *F = CGM.getIntrinsic(Intrinsic::pow, &ArgType, 1);
574ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp"));
575ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar  }
5767ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman  }
5771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
578b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner  // If this is an alias for a libm function (e.g. __builtin_sin) turn it into
579b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner  // that function.
5803e41d60eb627dc227c770f1c1c87d06909cf05fdDouglas Gregor  if (getContext().BuiltinInfo.isLibFunction(BuiltinID) ||
5813e41d60eb627dc227c770f1c1c87d06909cf05fdDouglas Gregor      getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID))
58231777a2540879051a3c643b90e02c3fd3d315243Anders Carlsson    return EmitCall(E->getCallee()->getType(),
58331777a2540879051a3c643b90e02c3fd3d315243Anders Carlsson                    CGM.getBuiltinLibFunction(FD, BuiltinID),
58431777a2540879051a3c643b90e02c3fd3d315243Anders Carlsson                    E->arg_begin(), E->arg_end());
5851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
586b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner  // See if we have a target specific intrinsic.
587a6f80ef997f0363386749087b325607eaa5adcfcDale Johannesen  const char *Name = getContext().BuiltinInfo.GetName(BuiltinID);
58855cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar  Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic;
58955cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar  if (const char *Prefix =
5901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      llvm::Triple::getArchTypePrefix(Target.getTriple().getArch()))
59155cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar    IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix, Name);
5921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
593b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner  if (IntrinsicID != Intrinsic::not_intrinsic) {
594b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    SmallVector<Value*, 16> Args;
5951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
596b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    Function *F = CGM.getIntrinsic(IntrinsicID);
597b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    const llvm::FunctionType *FTy = F->getFunctionType();
5981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
599b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
600b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner      Value *ArgValue = EmitScalarExpr(E->getArg(i));
6011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
602b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner      // If the intrinsic arg type is different from the builtin arg type
603b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner      // we need to do a bit cast.
604b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner      const llvm::Type *PTy = FTy->getParamType(i);
605b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner      if (PTy != ArgValue->getType()) {
606b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) &&
607b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner               "Must be able to losslessly bit cast to param");
608b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        ArgValue = Builder.CreateBitCast(ArgValue, PTy);
609b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner      }
6101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
611b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner      Args.push_back(ArgValue);
612b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    }
6131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
614beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad    Value *V = Builder.CreateCall(F, Args.data(), Args.data() + Args.size());
615b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    QualType BuiltinRetType = E->getType();
6161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6170032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    const llvm::Type *RetTy = llvm::Type::getVoidTy(VMContext);
618b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    if (!BuiltinRetType->isVoidType()) RetTy = ConvertType(BuiltinRetType);
6191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
620b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    if (RetTy != V->getType()) {
621b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner      assert(V->getType()->canLosslesslyBitCastTo(RetTy) &&
622b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner             "Must be able to losslessly bit cast result type");
623b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner      V = Builder.CreateBitCast(V, RetTy);
624b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    }
6251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
626b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    return RValue::get(V);
627b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner  }
6281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
629b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner  // See if we have a target specific builtin that needs to be lowered.
630f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar  if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E))
631b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    return RValue::get(V);
6321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
633488e993a135ce700b982bf099c3d6b856301d642Daniel Dunbar  ErrorUnsupported(E, "builtin function");
6341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
635b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner  // Unknown builtin, for now just dump it out and return undef.
636b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner  if (hasAggregateLLVMType(E->getType()))
637b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    return RValue::getAggregate(CreateTempAlloca(ConvertType(E->getType())));
63803e205031b08669f05c41eed5b896fc94c4a12bbOwen Anderson  return RValue::get(llvm::UndefValue::get(ConvertType(E->getType())));
6391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}
640564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson
641f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel DunbarValue *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID,
642f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar                                              const CallExpr *E) {
64355cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar  switch (Target.getTriple().getArch()) {
64455cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar  case llvm::Triple::x86:
64555cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar  case llvm::Triple::x86_64:
646f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar    return EmitX86BuiltinExpr(BuiltinID, E);
64755cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar  case llvm::Triple::ppc:
64855cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar  case llvm::Triple::ppc64:
649f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar    return EmitPPCBuiltinExpr(BuiltinID, E);
65055cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar  default:
65155cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar    return 0;
65255cc2ed722e041228670d26d548e5590e355acedDaniel Dunbar  }
653f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar}
654f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar
6551eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpValue *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
6561feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner                                           const CallExpr *E) {
6571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6582929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  llvm::SmallVector<Value*, 4> Ops;
6592929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
6602929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  for (unsigned i = 0, e = E->getNumArgs(); i != e; i++)
6612929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    Ops.push_back(EmitScalarExpr(E->getArg(i)));
6622929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
663564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson  switch (BuiltinID) {
66446a26b0b0e2ec1557bad9b70e8e20836524ebdfcAnders Carlsson  default: return 0;
6651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  case X86::BI__builtin_ia32_pslldi128:
666e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psllqi128:
6671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  case X86::BI__builtin_ia32_psllwi128:
668e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psradi128:
669e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psrawi128:
670e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psrldi128:
671e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psrlqi128:
672e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psrlwi128: {
6730032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::getInt64Ty(VMContext), "zext");
6740032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    const llvm::Type *Ty = llvm::VectorType::get(llvm::Type::getInt64Ty(VMContext), 2);
6750032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    llvm::Value *Zero = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0);
67603e205031b08669f05c41eed5b896fc94c4a12bbOwen Anderson    Ops[1] = Builder.CreateInsertElement(llvm::UndefValue::get(Ty),
677e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman                                         Ops[1], Zero, "insert");
678e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType(), "bitcast");
679e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    const char *name = 0;
680e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Intrinsic::ID ID = Intrinsic::not_intrinsic;
6811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
682e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    switch (BuiltinID) {
683e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    default: assert(0 && "Unsupported shift intrinsic!");
684e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_pslldi128:
685e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "pslldi";
686e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psll_d;
687e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
688e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psllqi128:
689e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psllqi";
690e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psll_q;
691e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
692e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psllwi128:
693e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psllwi";
694e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psll_w;
695e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
696e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psradi128:
697e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psradi";
698e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psra_d;
699e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
700e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psrawi128:
701e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psrawi";
702e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psra_w;
703e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
704e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psrldi128:
705e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psrldi";
706e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psrl_d;
707e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
708e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psrlqi128:
709e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psrlqi";
710e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psrl_q;
711e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
712e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psrlwi128:
713e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psrlwi";
714e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psrl_w;
715e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
716e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    }
717e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    llvm::Function *F = CGM.getIntrinsic(ID);
7181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
719e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  }
7201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  case X86::BI__builtin_ia32_pslldi:
7212929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_psllqi:
7221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  case X86::BI__builtin_ia32_psllwi:
7232929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_psradi:
7242929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_psrawi:
7252929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_psrldi:
7262929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_psrlqi:
7272929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_psrlwi: {
7280032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::getInt64Ty(VMContext), "zext");
7290032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    const llvm::Type *Ty = llvm::VectorType::get(llvm::Type::getInt64Ty(VMContext), 1);
7302929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    Ops[1] = Builder.CreateBitCast(Ops[1], Ty, "bitcast");
7312929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    const char *name = 0;
7322929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    Intrinsic::ID ID = Intrinsic::not_intrinsic;
7331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7342929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    switch (BuiltinID) {
7352929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    default: assert(0 && "Unsupported shift intrinsic!");
7362929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_pslldi:
7372929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "pslldi";
7382929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psll_d;
7392929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
7402929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_psllqi:
7412929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "psllqi";
7422929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psll_q;
7432929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
7442929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_psllwi:
7452929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "psllwi";
7462929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psll_w;
7472929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
7482929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_psradi:
7492929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "psradi";
7502929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psra_d;
7512929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
7522929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_psrawi:
7532929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "psrawi";
7542929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psra_w;
7552929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
7562929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_psrldi:
7572929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "psrldi";
7582929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psrl_d;
7592929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
7602929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_psrlqi:
7612929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "psrlqi";
7622929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psrl_q;
7632929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
7642929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_psrlwi:
7652929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "psrlwi";
7662929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psrl_w;
7672929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
7682929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    }
7697acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner    llvm::Function *F = CGM.getIntrinsic(ID);
7701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
7712929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  }
77279dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson  case X86::BI__builtin_ia32_cmpps: {
77379dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson    llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ps);
77479dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpps");
77579dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson  }
77679dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson  case X86::BI__builtin_ia32_cmpss: {
77779dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson    llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ss);
77879dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpss");
779cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  }
780e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_ldmxcsr: {
7813c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer    const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext);
7820032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    Value *One = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1);
7830032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    Value *Tmp = Builder.CreateAlloca(llvm::Type::getInt32Ty(VMContext), One, "tmp");
784e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Builder.CreateStore(Ops[0], Tmp);
785e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr),
7863eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner                              Builder.CreateBitCast(Tmp, PtrTy));
787e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  }
788e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_stmxcsr: {
7893c0ef8cc0dc246bd3083e8cdd63005e8873d36d2Benjamin Kramer    const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext);
7900032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    Value *One = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1);
7910032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    Value *Tmp = Builder.CreateAlloca(llvm::Type::getInt32Ty(VMContext), One, "tmp");
792e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    One = Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr),
7933eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner                             Builder.CreateBitCast(Tmp, PtrTy));
794e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return Builder.CreateLoad(Tmp, "stmxcsr");
795e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  }
79679dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson  case X86::BI__builtin_ia32_cmppd: {
79779dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson    llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_pd);
79879dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmppd");
79979dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson  }
80079dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson  case X86::BI__builtin_ia32_cmpsd: {
80179dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson    llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_sd);
80279dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpsd");
803cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  }
804e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_storehps:
805e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_storelps: {
8060032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    const llvm::Type *EltTy = llvm::Type::getInt64Ty(VMContext);
80796e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    llvm::Type *PtrTy = llvm::PointerType::getUnqual(EltTy);
80896e0fc726c6fe7538522c60743705d5e696b40afOwen Anderson    llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2);
8091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
810e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    // cast val v2i64
811e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast");
8121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
813e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    // extract (0, 1)
814e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1;
8150032b2781b4deb131f8c9b7968f2030bf2489cddOwen Anderson    llvm::Value *Idx = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Index);
816e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract");
817e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
818e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    // cast pointer to i64 & store
819e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy);
820e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return Builder.CreateStore(Ops[1], Ops[0]);
821e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  }
82291b59274439f776cdd545bd7bf5849fdb1842160Eric Christopher  case X86::BI__builtin_ia32_palignr: {
823c3420ffb282c6ffc0192013bf8045b6c21eddeceNate Begeman    Function *F = CGM.getIntrinsic(Intrinsic::x86_ssse3_palign_r);
824c3420ffb282c6ffc0192013bf8045b6c21eddeceNate Begeman    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size());
825c3420ffb282c6ffc0192013bf8045b6c21eddeceNate Begeman  }
826c3420ffb282c6ffc0192013bf8045b6c21eddeceNate Begeman  case X86::BI__builtin_ia32_palignr128: {
827ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman    unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();
828ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman
829ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman    // If palignr is shifting the pair of input vectors less than 17 bytes,
830ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman    // emit a shuffle instruction.
831ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman    if (shiftVal <= 16) {
832ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman      const llvm::Type *IntTy = llvm::Type::getInt32Ty(VMContext);
833ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman
834ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman      llvm::SmallVector<llvm::Constant*, 16> Indices;
835ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman      for (unsigned i = 0; i != 16; ++i)
836ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman        Indices.push_back(llvm::ConstantInt::get(IntTy, shiftVal + i));
837ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman
838ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman      Value* SV = llvm::ConstantVector::get(Indices.begin(), Indices.size());
839ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman      return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr");
840ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman    }
841ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman
842ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman    // If palignr is shifting the pair of input vectors more than 16 but less
843ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman    // than 32 bytes, emit a logical right shift of the destination.
844ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman    if (shiftVal < 32) {
845ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman      const llvm::Type *EltTy = llvm::Type::getInt64Ty(VMContext);
846ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman      const llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2);
847ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman      const llvm::Type *IntTy = llvm::Type::getInt32Ty(VMContext);
848ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman
849ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman      Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast");
850ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman      Ops[1] = llvm::ConstantInt::get(IntTy, (shiftVal-16) * 8);
851ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman
852ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman      // create i32 constant
853ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman      llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_psrl_dq);
854ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman      return Builder.CreateCall(F, &Ops[0], &Ops[0] + 2, "palignr");
855ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman    }
856ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman
857ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman    // If palignr is shifting the pair of vectors more than 32 bytes, emit zero.
858ce5818a19a8f77d1540d0352649d6687eca4af6bNate Begeman    return llvm::Constant::getNullValue(ConvertType(E->getType()));
85991b59274439f776cdd545bd7bf5849fdb1842160Eric Christopher  }
860564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson  }
861564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson}
862564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson
8631eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpValue *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
8641feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner                                           const CallExpr *E) {
865b0b84385f0cb0ea4036579f5f384f1c19b917c7eDaniel Dunbar  return 0;
8661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}
867