CGBuiltin.cpp revision b27ffbef8e8aa1e87b63cbc0d9cd630aba30dae5
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.
280002d23aaf10f307273dab5facda01c137283d22Daniel Dunbarstatic 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);
340002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar  return RValue::get(CGF.Builder.CreateCall2(AtomF,
350002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar                                             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.
420002d23aaf10f307273dab5facda01c137283d22Daniel Dunbarstatic 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);
52eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner
53eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner  if (Id == Intrinsic::atomic_load_nand)
54eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner    Result = CGF.Builder.CreateNot(Result);
55eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner
56eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner
570002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar  return RValue::get(CGF.Builder.CreateBinOp(Op, Result, Operand));
581ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang}
591ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang
60ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel DunbarRValue 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())
664a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson      return RValue::get(llvm::ConstantInt::get(VMContext,
674a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson                                                Result.Val.getInt()));
683941b18b8e441c8c466efecd557de60b9a32d10bEli Friedman    else if (Result.Val.isFloat())
69a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson      return RValue::get(VMContext.getConstantFP(Result.Val.getFloat()));
701f32999ec79a980576e100d64d5f3267eb19ea49Chris Lattner  }
711f32999ec79a980576e100d64d5f3267eb19ea49Chris Lattner
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));
80ddc23f3e6fdc4f83dd46ef7e20394cfbd6063ff9Christopher Lamb    const llvm::Type *DestType =
81a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson      VMContext.getPointerTypeUnqual(llvm::Type::Int8Ty);
82793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson    if (ArgValue->getType() != DestType)
83793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson      ArgValue = Builder.CreateBitCast(ArgValue, DestType,
84b27ffbef8e8aa1e87b63cbc0d9cd630aba30dae5Daniel Dunbar                                       ArgValue->getName().data());
85793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson
866a705f0443f8398ece14d80e71d8e8c9e71aa84aChris Lattner    Intrinsic::ID inst = (BuiltinID == Builtin::BI__builtin_va_end) ?
876a705f0443f8398ece14d80e71d8e8c9e71aa84aChris Lattner      Intrinsic::vaend : Intrinsic::vastart;
887acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner    return RValue::get(Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue));
89793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson  }
90a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson  case Builtin::BI__builtin_va_copy: {
914fd0aa5803357d8c72eeac2cae15e12649ea08feEli Friedman    Value *DstPtr = EmitVAListRef(E->getArg(0));
924fd0aa5803357d8c72eeac2cae15e12649ea08feEli Friedman    Value *SrcPtr = EmitVAListRef(E->getArg(1));
93a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson
94a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson    const llvm::Type *Type =
95a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson      VMContext.getPointerTypeUnqual(llvm::Type::Int8Ty);
96a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson
97a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson    DstPtr = Builder.CreateBitCast(DstPtr, Type);
98a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson    SrcPtr = Builder.CreateBitCast(SrcPtr, Type);
993eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner    return RValue::get(Builder.CreateCall2(CGM.getIntrinsic(Intrinsic::vacopy),
1003eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner                                           DstPtr, SrcPtr));
101a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson  }
102c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson  case Builtin::BI__builtin_abs: {
1031feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    Value *ArgValue = EmitScalarExpr(E->getArg(0));
104c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson
1059a847f598c4907a72b8593b364b9e6b94b086e75Chris Lattner    Value *NegOp = Builder.CreateNeg(ArgValue, "neg");
1061feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    Value *CmpResult =
10769243825cb5c91ec7207256aa57ae327cfaf8cb2Owen Anderson    Builder.CreateICmpSGE(ArgValue,
108a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson                          VMContext.getNullValue(ArgValue->getType()),
1099a847f598c4907a72b8593b364b9e6b94b086e75Chris Lattner                                                            "abscond");
1101feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    Value *Result =
111c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson      Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs");
112c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson
113c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson    return RValue::get(Result);
114c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson  }
1153a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson  case Builtin::BI__builtin_ctz:
1163a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson  case Builtin::BI__builtin_ctzl:
1173a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson  case Builtin::BI__builtin_ctzll: {
1183a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson    Value *ArgValue = EmitScalarExpr(E->getArg(0));
1193a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson
1203a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson    const llvm::Type *ArgType = ArgValue->getType();
1213a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson    Value *F = CGM.getIntrinsic(Intrinsic::cttz, &ArgType, 1);
1223a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson
1233a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson    const llvm::Type *ResultType = ConvertType(E->getType());
1243a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson    Value *Result = Builder.CreateCall(F, ArgValue, "tmp");
1253a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson    if (Result->getType() != ResultType)
1263a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson      Result = Builder.CreateIntCast(Result, ResultType, "cast");
1273a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson    return RValue::get(Result);
1283a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson  }
129f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman  case Builtin::BI__builtin_clz:
130f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman  case Builtin::BI__builtin_clzl:
131f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman  case Builtin::BI__builtin_clzll: {
132f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman    Value *ArgValue = EmitScalarExpr(E->getArg(0));
133f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman
134f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman    const llvm::Type *ArgType = ArgValue->getType();
135f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman    Value *F = CGM.getIntrinsic(Intrinsic::ctlz, &ArgType, 1);
136f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman
137f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman    const llvm::Type *ResultType = ConvertType(E->getType());
138f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman    Value *Result = Builder.CreateCall(F, ArgValue, "tmp");
139f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman    if (Result->getType() != ResultType)
140f4e853340590d5c32e58379e8c379ea1777d3101Eli Friedman      Result = Builder.CreateIntCast(Result, ResultType, "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));
14804b290030eee33295600728450f348989d1a627eDaniel Dunbar
14904b290030eee33295600728450f348989d1a627eDaniel Dunbar    const llvm::Type *ArgType = ArgValue->getType();
15004b290030eee33295600728450f348989d1a627eDaniel Dunbar    Value *F = CGM.getIntrinsic(Intrinsic::cttz, &ArgType, 1);
15104b290030eee33295600728450f348989d1a627eDaniel Dunbar
15204b290030eee33295600728450f348989d1a627eDaniel Dunbar    const llvm::Type *ResultType = ConvertType(E->getType());
15304b290030eee33295600728450f348989d1a627eDaniel Dunbar    Value *Tmp = Builder.CreateAdd(Builder.CreateCall(F, ArgValue, "tmp"),
1544a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson                                   llvm::ConstantInt::get(ArgType, 1), "tmp");
155a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    Value *Zero = VMContext.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)
15904b290030eee33295600728450f348989d1a627eDaniel Dunbar      Result = Builder.CreateIntCast(Result, ResultType, "cast");
16004b290030eee33295600728450f348989d1a627eDaniel Dunbar    return RValue::get(Result);
16104b290030eee33295600728450f348989d1a627eDaniel Dunbar  }
16204b290030eee33295600728450f348989d1a627eDaniel Dunbar  case Builtin::BI__builtin_parity:
16304b290030eee33295600728450f348989d1a627eDaniel Dunbar  case Builtin::BI__builtin_parityl:
16404b290030eee33295600728450f348989d1a627eDaniel Dunbar  case Builtin::BI__builtin_parityll: {
16504b290030eee33295600728450f348989d1a627eDaniel Dunbar    // parity(x) -> ctpop(x) & 1
16604b290030eee33295600728450f348989d1a627eDaniel Dunbar    Value *ArgValue = EmitScalarExpr(E->getArg(0));
16704b290030eee33295600728450f348989d1a627eDaniel Dunbar
16804b290030eee33295600728450f348989d1a627eDaniel Dunbar    const llvm::Type *ArgType = ArgValue->getType();
16904b290030eee33295600728450f348989d1a627eDaniel Dunbar    Value *F = CGM.getIntrinsic(Intrinsic::ctpop, &ArgType, 1);
17004b290030eee33295600728450f348989d1a627eDaniel Dunbar
17104b290030eee33295600728450f348989d1a627eDaniel Dunbar    const llvm::Type *ResultType = ConvertType(E->getType());
17204b290030eee33295600728450f348989d1a627eDaniel Dunbar    Value *Tmp = Builder.CreateCall(F, ArgValue, "tmp");
1734a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson    Value *Result = Builder.CreateAnd(Tmp, llvm::ConstantInt::get(ArgType, 1),
17404b290030eee33295600728450f348989d1a627eDaniel Dunbar                                      "tmp");
17504b290030eee33295600728450f348989d1a627eDaniel Dunbar    if (Result->getType() != ResultType)
17604b290030eee33295600728450f348989d1a627eDaniel Dunbar      Result = Builder.CreateIntCast(Result, ResultType, "cast");
17704b290030eee33295600728450f348989d1a627eDaniel Dunbar    return RValue::get(Result);
17804b290030eee33295600728450f348989d1a627eDaniel Dunbar  }
17904b290030eee33295600728450f348989d1a627eDaniel Dunbar  case Builtin::BI__builtin_popcount:
18004b290030eee33295600728450f348989d1a627eDaniel Dunbar  case Builtin::BI__builtin_popcountl:
18104b290030eee33295600728450f348989d1a627eDaniel Dunbar  case Builtin::BI__builtin_popcountll: {
18204b290030eee33295600728450f348989d1a627eDaniel Dunbar    Value *ArgValue = EmitScalarExpr(E->getArg(0));
18304b290030eee33295600728450f348989d1a627eDaniel Dunbar
18404b290030eee33295600728450f348989d1a627eDaniel Dunbar    const llvm::Type *ArgType = ArgValue->getType();
18504b290030eee33295600728450f348989d1a627eDaniel Dunbar    Value *F = CGM.getIntrinsic(Intrinsic::ctpop, &ArgType, 1);
18604b290030eee33295600728450f348989d1a627eDaniel Dunbar
18704b290030eee33295600728450f348989d1a627eDaniel Dunbar    const llvm::Type *ResultType = ConvertType(E->getType());
18804b290030eee33295600728450f348989d1a627eDaniel Dunbar    Value *Result = Builder.CreateCall(F, ArgValue, "tmp");
18904b290030eee33295600728450f348989d1a627eDaniel Dunbar    if (Result->getType() != ResultType)
19004b290030eee33295600728450f348989d1a627eDaniel Dunbar      Result = Builder.CreateIntCast(Result, ResultType, "cast");
19104b290030eee33295600728450f348989d1a627eDaniel Dunbar    return RValue::get(Result);
19204b290030eee33295600728450f348989d1a627eDaniel Dunbar  }
1931feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner  case Builtin::BI__builtin_expect:
194a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar    // FIXME: pass expect through to LLVM
1951feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    return RValue::get(EmitScalarExpr(E->getArg(0)));
196df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson  case Builtin::BI__builtin_bswap32:
197df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson  case Builtin::BI__builtin_bswap64: {
1981feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    Value *ArgValue = EmitScalarExpr(E->getArg(0));
199df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson    const llvm::Type *ArgType = ArgValue->getType();
2007acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner    Value *F = CGM.getIntrinsic(Intrinsic::bswap, &ArgType, 1);
2011feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    return RValue::get(Builder.CreateCall(F, ArgValue, "tmp"));
2024493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar  }
203d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar  case Builtin::BI__builtin_object_size: {
204d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar    // FIXME: Implement. For now we just always fail and pretend we
205d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar    // don't know the object size.
2069a901bb63990574ff0bcc12ff851d7a71cff8ddbEli Friedman    llvm::APSInt TypeArg = E->getArg(1)->EvaluateAsInt(CGM.getContext());
207d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar    const llvm::Type *ResType = ConvertType(E->getType());
208d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar    //    bool UseSubObject = TypeArg.getZExtValue() & 1;
209d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar    bool UseMinimum = TypeArg.getZExtValue() & 2;
210a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    return RValue::get(
2114a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson      llvm::ConstantInt::get(ResType, UseMinimum ? 0 : -1LL));
212d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar  }
2134493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar  case Builtin::BI__builtin_prefetch: {
2144493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar    Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0));
2154493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar    // FIXME: Technically these constants should of type 'int', yes?
2164493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar    RW = (E->getNumArgs() > 1) ? EmitScalarExpr(E->getArg(1)) :
2174a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson      llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
2184493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar    Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) :
2194a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson      llvm::ConstantInt::get(llvm::Type::Int32Ty, 3);
2204493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar    Value *F = CGM.getIntrinsic(Intrinsic::prefetch, 0, 0);
2214493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar    return RValue::get(Builder.CreateCall3(F, Address, RW, Locality));
2224493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar  }
2234493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar  case Builtin::BI__builtin_trap: {
2244493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar    Value *F = CGM.getIntrinsic(Intrinsic::trap, 0, 0);
2254493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar    return RValue::get(Builder.CreateCall(F));
226df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson  }
2274493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar
228a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar  case Builtin::BI__builtin_powi:
229a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar  case Builtin::BI__builtin_powif:
230a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar  case Builtin::BI__builtin_powil: {
231a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar    Value *Base = EmitScalarExpr(E->getArg(0));
232a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar    Value *Exponent = EmitScalarExpr(E->getArg(1));
233a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar    const llvm::Type *ArgType = Base->getType();
234a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar    Value *F = CGM.getIntrinsic(Intrinsic::powi, &ArgType, 1);
235a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar    return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp"));
236a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar  }
237a933c3c052bbd87b01cc6fc7a7745e1c4b1757fbDaniel Dunbar
238fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner  case Builtin::BI__builtin_isgreater:
239fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner  case Builtin::BI__builtin_isgreaterequal:
240fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner  case Builtin::BI__builtin_isless:
241fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner  case Builtin::BI__builtin_islessequal:
242fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner  case Builtin::BI__builtin_islessgreater:
243fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner  case Builtin::BI__builtin_isunordered: {
244fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    // Ordered comparisons: we know the arguments to these are matching scalar
245fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    // floating point values.
246fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    Value *LHS = EmitScalarExpr(E->getArg(0));
247fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    Value *RHS = EmitScalarExpr(E->getArg(1));
248fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner
249fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    switch (BuiltinID) {
250fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    default: assert(0 && "Unknown ordered comparison");
251fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    case Builtin::BI__builtin_isgreater:
252fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp");
253fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      break;
254fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    case Builtin::BI__builtin_isgreaterequal:
255fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp");
256fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      break;
257fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    case Builtin::BI__builtin_isless:
258fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp");
259fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      break;
260fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    case Builtin::BI__builtin_islessequal:
261fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp");
262fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      break;
263fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    case Builtin::BI__builtin_islessgreater:
264fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp");
265fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      break;
266fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    case Builtin::BI__builtin_isunordered:
267fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp");
268fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      break;
269fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    }
270fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    // ZExt bool to int type.
271fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType()),
272fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner                                          "tmp"));
273fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner  }
274b52fe9ce99970955a5f581f5c66fcd89be9a268bEli Friedman  case Builtin::BIalloca:
2759e800e3dd80d77f6c47054738177bf824089f55aChris Lattner  case Builtin::BI__builtin_alloca: {
2769e800e3dd80d77f6c47054738177bf824089f55aChris Lattner    // FIXME: LLVM IR Should allow alloca with an i64 size!
2779e800e3dd80d77f6c47054738177bf824089f55aChris Lattner    Value *Size = EmitScalarExpr(E->getArg(0));
2789e800e3dd80d77f6c47054738177bf824089f55aChris Lattner    Size = Builder.CreateIntCast(Size, llvm::Type::Int32Ty, false, "tmp");
2791caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar    return RValue::get(Builder.CreateAlloca(llvm::Type::Int8Ty, Size, "tmp"));
2801caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar  }
2811caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar  case Builtin::BI__builtin_bzero: {
2821caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar    Value *Address = EmitScalarExpr(E->getArg(0));
2831caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar    Builder.CreateCall4(CGM.getMemSetFn(), Address,
2844a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson                        llvm::ConstantInt::get(llvm::Type::Int8Ty, 0),
2851caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar                        EmitScalarExpr(E->getArg(1)),
2864a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson                        llvm::ConstantInt::get(llvm::Type::Int32Ty, 1));
2871caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar    return RValue::get(Address);
2889e800e3dd80d77f6c47054738177bf824089f55aChris Lattner  }
289d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman  case Builtin::BI__builtin_memcpy: {
2901caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar    Value *Address = EmitScalarExpr(E->getArg(0));
2911caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar    Builder.CreateCall4(CGM.getMemCpyFn(), Address,
2921caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar                        EmitScalarExpr(E->getArg(1)),
2931caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar                        EmitScalarExpr(E->getArg(2)),
2944a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson                        llvm::ConstantInt::get(llvm::Type::Int32Ty, 1));
2951caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar    return RValue::get(Address);
2961caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar  }
2971caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar  case Builtin::BI__builtin_memmove: {
2981caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar    Value *Address = EmitScalarExpr(E->getArg(0));
2991caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar    Builder.CreateCall4(CGM.getMemMoveFn(), Address,
3001caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar                        EmitScalarExpr(E->getArg(1)),
3011caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar                        EmitScalarExpr(E->getArg(2)),
3024a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson                        llvm::ConstantInt::get(llvm::Type::Int32Ty, 1));
3031caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar    return RValue::get(Address);
3041caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar  }
3051caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar  case Builtin::BI__builtin_memset: {
3061caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar    Value *Address = EmitScalarExpr(E->getArg(0));
3071caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar    Builder.CreateCall4(CGM.getMemSetFn(), Address,
30862c29c667f5bcb854e99ccb3aec1280c84115951Daniel Dunbar                        Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)),
30962c29c667f5bcb854e99ccb3aec1280c84115951Daniel Dunbar                                            llvm::Type::Int8Ty),
3101caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar                        EmitScalarExpr(E->getArg(2)),
3114a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson                        llvm::ConstantInt::get(llvm::Type::Int32Ty, 1));
3121caae959017b355e9bb61250d5a0d04edbf468b0Daniel Dunbar    return RValue::get(Address);
313d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman  }
314256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman  case Builtin::BI__builtin_return_address: {
315256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman    Value *F = CGM.getIntrinsic(Intrinsic::returnaddress, 0, 0);
316256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman    return RValue::get(Builder.CreateCall(F, EmitScalarExpr(E->getArg(0))));
317256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman  }
318256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman  case Builtin::BI__builtin_frame_address: {
319256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman    Value *F = CGM.getIntrinsic(Intrinsic::frameaddress, 0, 0);
320256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman    return RValue::get(Builder.CreateCall(F, EmitScalarExpr(E->getArg(0))));
321256f77e431bc6b920ec94cf0bb4ad339ca21b8c9Eli Friedman  }
3223b660efb9f9fa3e87096f4a96a2093cd17c43c2eEli Friedman  case Builtin::BI__builtin_extract_return_addr: {
3233b660efb9f9fa3e87096f4a96a2093cd17c43c2eEli Friedman    // FIXME: There should be a target hook for this
3243b660efb9f9fa3e87096f4a96a2093cd17c43c2eEli Friedman    return RValue::get(EmitScalarExpr(E->getArg(0)));
3253b660efb9f9fa3e87096f4a96a2093cd17c43c2eEli Friedman  }
326a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman  case Builtin::BI__builtin_unwind_init: {
327a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    Value *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init, 0, 0);
328a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    return RValue::get(Builder.CreateCall(F));
329a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman  }
330a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman#if 0
331a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman  // FIXME: Finish/enable when LLVM backend support stabilizes
332a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman  case Builtin::BI__builtin_setjmp: {
333a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    Value *Buf = EmitScalarExpr(E->getArg(0));
334a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    // Store the frame pointer to the buffer
335a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    Value *FrameAddrF = CGM.getIntrinsic(Intrinsic::frameaddress, 0, 0);
336a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    Value *FrameAddr =
337a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman        Builder.CreateCall(FrameAddrF,
338a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman                           Constant::getNullValue(llvm::Type::Int32Ty));
339a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    Builder.CreateStore(FrameAddr, Buf);
340a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    // Call the setjmp intrinsic
341a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp, 0, 0);
342a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    const llvm::Type *DestType =
343a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman      llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
344a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    Buf = Builder.CreateBitCast(Buf, DestType);
345a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    return RValue::get(Builder.CreateCall(F, Buf));
346a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman  }
347a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman  case Builtin::BI__builtin_longjmp: {
348a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp, 0, 0);
349a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    Value *Buf = EmitScalarExpr(E->getArg(0));
350a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    const llvm::Type *DestType =
351a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman      llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
352a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    Buf = Builder.CreateBitCast(Buf, DestType);
353a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman    return RValue::get(Builder.CreateCall(F, Buf));
354a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman  }
355a6d75c0324ac690107bbaa7193b526ef21466212Eli Friedman#endif
3561ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_fetch_and_add:
3571ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_fetch_and_sub:
3585caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_or:
3595caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_and:
3605caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_xor:
3615caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_add_and_fetch:
3625caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_sub_and_fetch:
3635caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_and_and_fetch:
3645caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_or_and_fetch:
3655caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_xor_and_fetch:
3665caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_val_compare_and_swap:
3675caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_bool_compare_and_swap:
3685caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_lock_test_and_set:
3695caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_lock_release:
3705caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner    assert(0 && "Shouldn't make it through sema");
3715caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_add_1:
3725caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_add_2:
3735caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_add_4:
3745caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_add_8:
3755caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_add_16:
3765caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_add, E);
3775caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_sub_1:
3785caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_sub_2:
3795caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_sub_4:
3805caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_sub_8:
3815caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_sub_16:
38209b6bf5bfa2ba9cbbd353cbd7846af8f49b020e7Mon P Wang    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_sub, E);
3835caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_or_1:
3845caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_or_2:
3855caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_or_4:
3865caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_or_8:
3875caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_or_16:
3885caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_or, E);
3895caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_and_1:
3905caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_and_2:
3915caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_and_4:
3925caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_and_8:
3935caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_and_16:
3945caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_and, E);
3955caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_xor_1:
3965caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_xor_2:
3975caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_xor_4:
3985caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_xor_8:
3995caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_fetch_and_xor_16:
4005caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_xor, E);
401eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner  case Builtin::BI__sync_fetch_and_nand_1:
402eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner  case Builtin::BI__sync_fetch_and_nand_2:
403eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner  case Builtin::BI__sync_fetch_and_nand_4:
404eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner  case Builtin::BI__sync_fetch_and_nand_8:
405eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner  case Builtin::BI__sync_fetch_and_nand_16:
406eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_nand, E);
407eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner
4085caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  // Clang extensions: not overloaded yet.
4091ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_fetch_and_min:
4101ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_min, E);
4111ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_fetch_and_max:
4121ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_max, E);
4131ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_fetch_and_umin:
4141ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umin, E);
4151ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_fetch_and_umax:
4161ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umax, E);
4170002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar
4185caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_add_and_fetch_1:
4195caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_add_and_fetch_2:
4205caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_add_and_fetch_4:
4215caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_add_and_fetch_8:
4225caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_add_and_fetch_16:
4230002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar    return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_add, E,
4240002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar                                llvm::Instruction::Add);
4255caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_sub_and_fetch_1:
4265caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_sub_and_fetch_2:
4275caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_sub_and_fetch_4:
4285caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_sub_and_fetch_8:
4295caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_sub_and_fetch_16:
4300002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar    return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_sub, E,
4310002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar                                llvm::Instruction::Sub);
4325caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_and_and_fetch_1:
4335caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_and_and_fetch_2:
4345caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_and_and_fetch_4:
4355caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_and_and_fetch_8:
4365caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_and_and_fetch_16:
4370002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar    return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_and, E,
4380002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar                                llvm::Instruction::And);
4395caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_or_and_fetch_1:
4405caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_or_and_fetch_2:
4415caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_or_and_fetch_4:
4425caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_or_and_fetch_8:
4435caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_or_and_fetch_16:
4440002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar    return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_or, E,
4450002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar                                llvm::Instruction::Or);
4465caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_xor_and_fetch_1:
4475caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_xor_and_fetch_2:
4485caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_xor_and_fetch_4:
4495caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_xor_and_fetch_8:
4505caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_xor_and_fetch_16:
4510002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar    return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_xor, E,
4520002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar                                llvm::Instruction::Xor);
453eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner  case Builtin::BI__sync_nand_and_fetch_1:
454eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner  case Builtin::BI__sync_nand_and_fetch_2:
455eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner  case Builtin::BI__sync_nand_and_fetch_4:
456eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner  case Builtin::BI__sync_nand_and_fetch_8:
457eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner  case Builtin::BI__sync_nand_and_fetch_16:
458eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner    return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_nand, E,
459eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner                                llvm::Instruction::And);
460eebd9d2165a705ce6a8a6b6a7327864189d02785Chris Lattner
4615caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_val_compare_and_swap_1:
4625caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_val_compare_and_swap_2:
4635caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_val_compare_and_swap_4:
4645caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_val_compare_and_swap_8:
4655caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_val_compare_and_swap_16:
4665caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  {
467c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang    const llvm::Type *ResType[2];
468c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang    ResType[0]= ConvertType(E->getType());
469c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang    ResType[1] = ConvertType(E->getArg(0)->getType());
470c5004516489c931cf839bdbdde5a76e4074cc888Mon P Wang    Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap, ResType, 2);
471958444659c5287a81a43188bfaa2a4902752b947Anders Carlsson    return RValue::get(Builder.CreateCall3(AtomF,
472958444659c5287a81a43188bfaa2a4902752b947Anders Carlsson                                           EmitScalarExpr(E->getArg(0)),
473958444659c5287a81a43188bfaa2a4902752b947Anders Carlsson                                           EmitScalarExpr(E->getArg(1)),
474958444659c5287a81a43188bfaa2a4902752b947Anders Carlsson                                           EmitScalarExpr(E->getArg(2))));
475022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson  }
4760002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar
4775caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_bool_compare_and_swap_1:
4785caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_bool_compare_and_swap_2:
4795caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_bool_compare_and_swap_4:
4805caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_bool_compare_and_swap_8:
4815caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_bool_compare_and_swap_16:
4825caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  {
4830002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar    const llvm::Type *ResType[2];
4845caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner    ResType[0]= ConvertType(E->getArg(1)->getType());
485a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    ResType[1] = VMContext.getPointerTypeUnqual(ResType[0]);
4860002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar    Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap, ResType, 2);
4870002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar    Value *OldVal = EmitScalarExpr(E->getArg(1));
4880002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar    Value *PrevVal = Builder.CreateCall3(AtomF,
4890002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar                                        EmitScalarExpr(E->getArg(0)),
4900002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar                                        OldVal,
4910002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar                                        EmitScalarExpr(E->getArg(2)));
4920002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar    Value *Result = Builder.CreateICmpEQ(PrevVal, OldVal);
4930002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar    // zext bool to int.
4940002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar    return RValue::get(Builder.CreateZExt(Result, ConvertType(E->getType())));
4950002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar  }
4960002d23aaf10f307273dab5facda01c137283d22Daniel Dunbar
4975caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_lock_test_and_set_1:
4985caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_lock_test_and_set_2:
4995caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_lock_test_and_set_4:
5005caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_lock_test_and_set_8:
5015caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_lock_test_and_set_16:
5027ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman    return EmitBinaryAtomic(*this, Intrinsic::atomic_swap, E);
5035caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_lock_release_1:
5045caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_lock_release_2:
5055caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_lock_release_4:
5065caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner  case Builtin::BI__sync_lock_release_8:
507f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner  case Builtin::BI__sync_lock_release_16: {
508f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner    Value *Ptr = EmitScalarExpr(E->getArg(0));
509f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner    const llvm::Type *ElTy =
510f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner      cast<llvm::PointerType>(Ptr->getType())->getElementType();
511a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    Builder.CreateStore(VMContext.getNullValue(ElTy), Ptr, true);
512eb4f81e174b11633f7b85f555ea5d2834d6dae8aDaniel Dunbar    return RValue::get(0);
513f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner  }
514ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar
515f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner  case Builtin::BI__sync_synchronize: {
516f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner    Value *C[5];
5174a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson    C[0] = C[1] = C[2] = C[3] = llvm::ConstantInt::get(llvm::Type::Int1Ty, 1);
5184a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson    C[4] = llvm::ConstantInt::get(llvm::Type::Int1Ty, 0);
519f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner    Builder.CreateCall(CGM.getIntrinsic(Intrinsic::memory_barrier), C, C + 5);
520eb4f81e174b11633f7b85f555ea5d2834d6dae8aDaniel Dunbar    return RValue::get(0);
521f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner  }
522f58cd9bca9c2e7373300fc8bb7c57cff7e4eda4fChris Lattner
523ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    // Library functions with special handling.
524ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar  case Builtin::BIsqrt:
525ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar  case Builtin::BIsqrtf:
526ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar  case Builtin::BIsqrtl: {
527ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    // Rewrite sqrt to intrinsic if allowed.
52840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis    if (!FD->hasAttr<ConstAttr>())
529ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar      break;
530ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    Value *Arg0 = EmitScalarExpr(E->getArg(0));
531ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    const llvm::Type *ArgType = Arg0->getType();
532ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    Value *F = CGM.getIntrinsic(Intrinsic::sqrt, &ArgType, 1);
533ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    return RValue::get(Builder.CreateCall(F, Arg0, "tmp"));
534ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar  }
535ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar
536ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar  case Builtin::BIpow:
537ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar  case Builtin::BIpowf:
538ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar  case Builtin::BIpowl: {
539ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    // Rewrite sqrt to intrinsic if allowed.
54040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis    if (!FD->hasAttr<ConstAttr>())
541ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar      break;
542ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    Value *Base = EmitScalarExpr(E->getArg(0));
543ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    Value *Exponent = EmitScalarExpr(E->getArg(1));
544ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    const llvm::Type *ArgType = Base->getType();
545ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    Value *F = CGM.getIntrinsic(Intrinsic::pow, &ArgType, 1);
546ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar    return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp"));
547ef2abfee3ea16ec74942dc09e9e425f46aeb2582Daniel Dunbar  }
5487ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman  }
549b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
550b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner  // If this is an alias for a libm function (e.g. __builtin_sin) turn it into
551b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner  // that function.
5523e41d60eb627dc227c770f1c1c87d06909cf05fdDouglas Gregor  if (getContext().BuiltinInfo.isLibFunction(BuiltinID) ||
5533e41d60eb627dc227c770f1c1c87d06909cf05fdDouglas Gregor      getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID))
554986477149db76e6d9f8d3c9859c9880c11b680aeAnders Carlsson    return EmitCall(CGM.getBuiltinLibFunction(BuiltinID),
555986477149db76e6d9f8d3c9859c9880c11b680aeAnders Carlsson                    E->getCallee()->getType(), E->arg_begin(),
556986477149db76e6d9f8d3c9859c9880c11b680aeAnders Carlsson                    E->arg_end());
557b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
558b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner  // See if we have a target specific intrinsic.
559a6f80ef997f0363386749087b325607eaa5adcfcDale Johannesen  const char *Name = getContext().BuiltinInfo.GetName(BuiltinID);
560a6f80ef997f0363386749087b325607eaa5adcfcDale Johannesen  Intrinsic::ID IntrinsicID =
561a6f80ef997f0363386749087b325607eaa5adcfcDale Johannesen    Intrinsic::getIntrinsicForGCCBuiltin(Target.getTargetPrefix(), Name);
562b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
563b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner  if (IntrinsicID != Intrinsic::not_intrinsic) {
564b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    SmallVector<Value*, 16> Args;
565b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
566b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    Function *F = CGM.getIntrinsic(IntrinsicID);
567b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    const llvm::FunctionType *FTy = F->getFunctionType();
568b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
569b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
570b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner      Value *ArgValue = EmitScalarExpr(E->getArg(i));
571b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
572b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner      // If the intrinsic arg type is different from the builtin arg type
573b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner      // we need to do a bit cast.
574b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner      const llvm::Type *PTy = FTy->getParamType(i);
575b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner      if (PTy != ArgValue->getType()) {
576b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) &&
577b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner               "Must be able to losslessly bit cast to param");
578b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner        ArgValue = Builder.CreateBitCast(ArgValue, PTy);
579b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner      }
580b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
581b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner      Args.push_back(ArgValue);
582b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    }
583b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
584beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad    Value *V = Builder.CreateCall(F, Args.data(), Args.data() + Args.size());
585b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    QualType BuiltinRetType = E->getType();
586b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
587b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    const llvm::Type *RetTy = llvm::Type::VoidTy;
588b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    if (!BuiltinRetType->isVoidType()) RetTy = ConvertType(BuiltinRetType);
589b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
590b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    if (RetTy != V->getType()) {
591b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner      assert(V->getType()->canLosslesslyBitCastTo(RetTy) &&
592b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner             "Must be able to losslessly bit cast result type");
593b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner      V = Builder.CreateBitCast(V, RetTy);
594b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    }
595b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
596b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    return RValue::get(V);
597b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner  }
598b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
599b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner  // See if we have a target specific builtin that needs to be lowered.
600f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar  if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E))
601b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    return RValue::get(V);
602b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
603488e993a135ce700b982bf099c3d6b856301d642Daniel Dunbar  ErrorUnsupported(E, "builtin function");
604b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
605b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner  // Unknown builtin, for now just dump it out and return undef.
606b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner  if (hasAggregateLLVMType(E->getType()))
607b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    return RValue::getAggregate(CreateTempAlloca(ConvertType(E->getType())));
608a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson  return RValue::get(VMContext.getUndef(ConvertType(E->getType())));
609b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner}
610564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson
611f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel DunbarValue *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID,
612f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar                                              const CallExpr *E) {
613f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar  const char *TargetPrefix = Target.getTargetPrefix();
614f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar  if (strcmp(TargetPrefix, "x86") == 0)
615f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar    return EmitX86BuiltinExpr(BuiltinID, E);
616f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar  else if (strcmp(TargetPrefix, "ppc") == 0)
617f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar    return EmitPPCBuiltinExpr(BuiltinID, E);
618f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar  return 0;
619f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar}
620f02e9ddf5efc75917af712b3c7f909581205f0a5Daniel Dunbar
6211feedd84221e8dbcc3faf3de27cc42b559db845dChris LattnerValue *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
6221feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner                                           const CallExpr *E) {
6232929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
6242929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  llvm::SmallVector<Value*, 4> Ops;
6252929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
6262929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  for (unsigned i = 0, e = E->getNumArgs(); i != e; i++)
6272929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    Ops.push_back(EmitScalarExpr(E->getArg(i)));
6282929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
629564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson  switch (BuiltinID) {
63046a26b0b0e2ec1557bad9b70e8e20836524ebdfcAnders Carlsson  default: return 0;
631e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_pslldi128:
632e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psllqi128:
633e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psllwi128:
634e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psradi128:
635e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psrawi128:
636e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psrldi128:
637e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psrlqi128:
638e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psrlwi128: {
639e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::Int64Ty, "zext");
640a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    const llvm::Type *Ty = VMContext.getVectorType(llvm::Type::Int64Ty, 2);
6414a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson    llvm::Value *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
642a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    Ops[1] = Builder.CreateInsertElement(VMContext.getUndef(Ty),
643e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman                                         Ops[1], Zero, "insert");
644e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType(), "bitcast");
645e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    const char *name = 0;
646e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Intrinsic::ID ID = Intrinsic::not_intrinsic;
647e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
648e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    switch (BuiltinID) {
649e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    default: assert(0 && "Unsupported shift intrinsic!");
650e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_pslldi128:
651e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "pslldi";
652e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psll_d;
653e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
654e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psllqi128:
655e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psllqi";
656e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psll_q;
657e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
658e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psllwi128:
659e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psllwi";
660e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psll_w;
661e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
662e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psradi128:
663e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psradi";
664e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psra_d;
665e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
666e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psrawi128:
667e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psrawi";
668e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psra_w;
669e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
670e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psrldi128:
671e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psrldi";
672e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psrl_d;
673e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
674e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psrlqi128:
675e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psrlqi";
676e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psrl_q;
677e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
678e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psrlwi128:
679e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psrlwi";
680e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psrl_w;
681e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
682e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    }
683e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    llvm::Function *F = CGM.getIntrinsic(ID);
684e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
685e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  }
6862929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_pslldi:
6872929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_psllqi:
6882929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_psllwi:
6892929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_psradi:
6902929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_psrawi:
6912929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_psrldi:
6922929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_psrlqi:
6932929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_psrlwi: {
6942929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::Int64Ty, "zext");
695a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    const llvm::Type *Ty = VMContext.getVectorType(llvm::Type::Int64Ty, 1);
6962929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    Ops[1] = Builder.CreateBitCast(Ops[1], Ty, "bitcast");
6972929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    const char *name = 0;
6982929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    Intrinsic::ID ID = Intrinsic::not_intrinsic;
6994e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson
7002929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    switch (BuiltinID) {
7012929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    default: assert(0 && "Unsupported shift intrinsic!");
7022929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_pslldi:
7032929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "pslldi";
7042929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psll_d;
7052929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
7062929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_psllqi:
7072929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "psllqi";
7082929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psll_q;
7092929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
7102929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_psllwi:
7112929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "psllwi";
7122929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psll_w;
7132929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
7142929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_psradi:
7152929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "psradi";
7162929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psra_d;
7172929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
7182929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_psrawi:
7192929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "psrawi";
7202929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psra_w;
7212929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
7222929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_psrldi:
7232929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "psrldi";
7242929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psrl_d;
7252929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
7262929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_psrlqi:
7272929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "psrlqi";
7282929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psrl_q;
7292929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
7302929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_psrlwi:
7312929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "psrlwi";
7322929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psrl_w;
7332929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
7342929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    }
7357acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner    llvm::Function *F = CGM.getIntrinsic(ID);
7362929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
7372929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  }
73879dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson  case X86::BI__builtin_ia32_cmpps: {
73979dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson    llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ps);
74079dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpps");
74179dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson  }
74279dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson  case X86::BI__builtin_ia32_cmpss: {
74379dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson    llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ss);
74479dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpss");
745cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  }
746e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_ldmxcsr: {
747a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    llvm::Type *PtrTy = VMContext.getPointerTypeUnqual(llvm::Type::Int8Ty);
7484a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson    Value *One = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1);
749e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Value *Tmp = Builder.CreateAlloca(llvm::Type::Int32Ty, One, "tmp");
750e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Builder.CreateStore(Ops[0], Tmp);
751e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr),
7523eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner                              Builder.CreateBitCast(Tmp, PtrTy));
753e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  }
754e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_stmxcsr: {
755a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    llvm::Type *PtrTy = VMContext.getPointerTypeUnqual(llvm::Type::Int8Ty);
7564a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson    Value *One = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1);
757e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Value *Tmp = Builder.CreateAlloca(llvm::Type::Int32Ty, One, "tmp");
758e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    One = Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr),
7593eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner                             Builder.CreateBitCast(Tmp, PtrTy));
760e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return Builder.CreateLoad(Tmp, "stmxcsr");
761e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  }
76279dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson  case X86::BI__builtin_ia32_cmppd: {
76379dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson    llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_pd);
76479dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmppd");
76579dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson  }
76679dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson  case X86::BI__builtin_ia32_cmpsd: {
76779dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson    llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_sd);
76879dcf5f96ad75259867d19bbf69512f320032fceAnders Carlsson    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpsd");
769cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  }
770e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_storehps:
771e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_storelps: {
772e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    const llvm::Type *EltTy = llvm::Type::Int64Ty;
773a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    llvm::Type *PtrTy = VMContext.getPointerTypeUnqual(EltTy);
774a1cf15f4680e5cf39e72e28c5ea854fcba792e84Owen Anderson    llvm::Type *VecTy = VMContext.getVectorType(EltTy, 2);
775e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
776e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    // cast val v2i64
777e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast");
778e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
779e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    // extract (0, 1)
780e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1;
7814a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson    llvm::Value *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, Index);
782e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract");
783e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
784e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    // cast pointer to i64 & store
785e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy);
786e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return Builder.CreateStore(Ops[1], Ops[0]);
787e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  }
788564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson  }
789564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson}
790564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson
7911feedd84221e8dbcc3faf3de27cc42b559db845dChris LattnerValue *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
7921feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner                                           const CallExpr *E) {
793564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson  switch (BuiltinID) {
79446a26b0b0e2ec1557bad9b70e8e20836524ebdfcAnders Carlsson  default: return 0;
795564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson  }
796564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson}
797