CGBuiltin.cpp revision d4b32e46517358f34e8cfbea35010adfcc3786e0
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"
17bef20ac367a09555b30d6eb3847a81ec164caf88Chris Lattner#include "clang/AST/ASTContext.h"
18022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson#include "clang/AST/Builtins.h"
19022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson#include "clang/AST/Expr.h"
20564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson#include "clang/AST/TargetBuiltins.h"
216de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner#include "llvm/Constants.h"
22c5e940fa551840ecd71e8116c316c9131490f5faChris Lattner#include "llvm/Function.h"
23793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson#include "llvm/Intrinsics.h"
24022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlssonusing namespace clang;
25022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlssonusing namespace CodeGen;
26ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlssonusing namespace llvm;
27ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson
281ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang/// Utility to insert an atomic instruction based Instrinsic::ID and
291ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang// the expression node
301ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wangstatic RValue EmitBinaryAtomic(CodeGenFunction& CFG,
311ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang                               Intrinsic::ID Id, const CallExpr *E) {
321ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  const llvm::Type *ResType = CFG.ConvertType(E->getType());
331ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  Value *AtomF = CFG.CGM.getIntrinsic(Id, &ResType, 1);
341ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  return RValue::get(CFG.Builder.CreateCall2(AtomF,
351ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang                                             CFG.EmitScalarExpr(E->getArg(0)),
361ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang                                             CFG.EmitScalarExpr(E->getArg(1))));
371ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang}
381ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang
396de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris LattnerRValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) {
406de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner  switch (BuiltinID) {
41ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson  default: {
42c5e940fa551840ecd71e8116c316c9131490f5faChris Lattner    if (getContext().BuiltinInfo.isLibFunction(BuiltinID))
43eed50586435ce4d2690f44ceabd69ad531d80970Nate Begeman      return EmitCallExpr(CGM.getBuiltinLibFunction(BuiltinID),
445193b8a3e57c4f696161aeddfe8227c294c0a7feEli Friedman                          E->getCallee()->getType(), E->arg_begin(),
455193b8a3e57c4f696161aeddfe8227c294c0a7feEli Friedman                          E->getNumArgs());
46ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson
47ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson    // See if we have a target specific intrinsic.
481feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    Intrinsic::ID IntrinsicID;
49ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson    const char *TargetPrefix = Target.getTargetPrefix();
50ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson    const char *BuiltinName = getContext().BuiltinInfo.GetName(BuiltinID);
51ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson#define GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
52ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson#include "llvm/Intrinsics.gen"
53ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson#undef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
54ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson
55ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson    if (IntrinsicID != Intrinsic::not_intrinsic) {
561feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner      SmallVector<Value*, 16> Args;
57ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson
587acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner      Function *F = CGM.getIntrinsic(IntrinsicID);
59ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson      const llvm::FunctionType *FTy = F->getFunctionType();
60ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson
61ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson      for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
621feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner        Value *ArgValue = EmitScalarExpr(E->getArg(i));
63ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson
64ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson        // If the intrinsic arg type is different from the builtin arg type
65ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson        // we need to do a bit cast.
66ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson        const llvm::Type *PTy = FTy->getParamType(i);
67ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson        if (PTy != ArgValue->getType()) {
68ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson          assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) &&
69ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson                 "Must be able to losslessly bit cast to param");
70ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson          ArgValue = Builder.CreateBitCast(ArgValue, PTy);
71ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson        }
72ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson
73ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson        Args.push_back(ArgValue);
74ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson      }
75ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson
761feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner      Value *V = Builder.CreateCall(F, &Args[0], &Args[0] + Args.size());
77ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson      QualType BuiltinRetType = E->getType();
78ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson
791feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner      const llvm::Type *RetTy = llvm::Type::VoidTy;
801feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner      if (!BuiltinRetType->isVoidType()) RetTy = ConvertType(BuiltinRetType);
81ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson
82ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson      if (RetTy != V->getType()) {
83ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson        assert(V->getType()->canLosslesslyBitCastTo(RetTy) &&
84ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson               "Must be able to losslessly bit cast result type");
85ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson        V = Builder.CreateBitCast(V, RetTy);
86ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson      }
87ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson
88ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson      return RValue::get(V);
89ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson    }
90564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson
91564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson    // See if we have a target specific builtin that needs to be lowered.
921feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    Value *V = 0;
93564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson
94564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson    if (strcmp(TargetPrefix, "x86") == 0)
95564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson      V = EmitX86BuiltinExpr(BuiltinID, E);
96564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson    else if (strcmp(TargetPrefix, "ppc") == 0)
97564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson      V = EmitPPCBuiltinExpr(BuiltinID, E);
98564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson
99564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson    if (V)
100564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson      return RValue::get(V);
101c5e940fa551840ecd71e8116c316c9131490f5faChris Lattner
102dc4d280136d3301fcbf3c7b4b2782c8bd804342cChris Lattner    WarnUnsupported(E, "builtin function");
1036de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner
1046de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner    // Unknown builtin, for now just dump it out and return undef.
1056de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner    if (hasAggregateLLVMType(E->getType()))
1066de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner      return RValue::getAggregate(CreateTempAlloca(ConvertType(E->getType())));
1071feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    return RValue::get(UndefValue::get(ConvertType(E->getType())));
108ca6fcfad547dcec3fdd17790b4fab0918df74b37Anders Carlsson  }
1096de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner  case Builtin::BI__builtin___CFStringMakeConstantString: {
1106de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner    const Expr *Arg = E->getArg(0);
1116de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner
112d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson    while (1) {
113d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson      if (const ParenExpr *PE = dyn_cast<ParenExpr>(Arg))
114d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson        Arg = PE->getSubExpr();
115d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson      else if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(Arg))
116d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson        Arg = CE->getSubExpr();
117d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson      else
118d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson        break;
119d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson    }
1206de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner
1216de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner    const StringLiteral *Literal = cast<StringLiteral>(Arg);
1226de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner    std::string S(Literal->getStrData(), Literal->getByteLength());
1236de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner
1246de93ff81c5fe89b96a589ef13ea2beb4d7c3775Chris Lattner    return RValue::get(CGM.GetAddrOfConstantCFString(S));
125793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson  }
126793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson  case Builtin::BI__builtin_va_start:
127793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson  case Builtin::BI__builtin_va_end: {
1281feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    Value *ArgValue = EmitScalarExpr(E->getArg(0));
129ddc23f3e6fdc4f83dd46ef7e20394cfbd6063ff9Christopher Lamb    const llvm::Type *DestType =
130ddc23f3e6fdc4f83dd46ef7e20394cfbd6063ff9Christopher Lamb      llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
131793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson    if (ArgValue->getType() != DestType)
132793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson      ArgValue = Builder.CreateBitCast(ArgValue, DestType,
133793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson                                       ArgValue->getNameStart());
134793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson
1351feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    Intrinsic::ID inst = (BuiltinID == Builtin::BI__builtin_va_start) ?
1361feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner      Intrinsic::vastart : Intrinsic::vaend;
1377acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner    return RValue::get(Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue));
138793680ed8104bf088d1b382b963a8badcb3f07deAnders Carlsson  }
139a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson  case Builtin::BI__builtin_va_copy: {
140a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson    // FIXME: This does not yet handle architectures where va_list is a struct.
141a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson    Value *DstPtr = EmitScalarExpr(E->getArg(0));
142a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson    Value *SrcValue = EmitScalarExpr(E->getArg(1));
143a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson
144a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson    Value *SrcPtr = CreateTempAlloca(SrcValue->getType(), "dst_ptr");
145a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson
146a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson    // FIXME: Volatile
147a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson    Builder.CreateStore(SrcValue, SrcPtr, false);
148a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson
149a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson    const llvm::Type *Type =
150a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson      llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
151a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson
152a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson    DstPtr = Builder.CreateBitCast(DstPtr, Type);
153a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson    SrcPtr = Builder.CreateBitCast(SrcPtr, Type);
1543eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner    return RValue::get(Builder.CreateCall2(CGM.getIntrinsic(Intrinsic::vacopy),
1553eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner                                           DstPtr, SrcPtr));
156a28ef8b5c6ea452472d89041128fac8b683fe968Anders Carlsson  }
15789799cf254c91ca110f113a33eebe8b1b4d1a761Anders Carlsson  case Builtin::BI__builtin_classify_type: {
1581feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    APSInt Result(32);
15989799cf254c91ca110f113a33eebe8b1b4d1a761Anders Carlsson    if (!E->isBuiltinClassifyType(Result))
16089799cf254c91ca110f113a33eebe8b1b4d1a761Anders Carlsson      assert(0 && "Expr not __builtin_classify_type!");
1611feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    return RValue::get(ConstantInt::get(Result));
16289799cf254c91ca110f113a33eebe8b1b4d1a761Anders Carlsson  }
163d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson  case Builtin::BI__builtin_constant_p: {
1641feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    APSInt Result(32);
165d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson    // FIXME: Analyze the parameter and check if it is a constant.
166d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson    Result = 0;
1671feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    return RValue::get(ConstantInt::get(Result));
168d6a275f9a27d1c91e4084398d04030719b5b8f18Anders Carlsson  }
169c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson  case Builtin::BI__builtin_abs: {
1701feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    Value *ArgValue = EmitScalarExpr(E->getArg(0));
171c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson
172c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson    llvm::BinaryOperator *NegOp =
173c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson      Builder.CreateNeg(ArgValue, (ArgValue->getName() + "neg").c_str());
1741feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    Value *CmpResult =
175c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson      Builder.CreateICmpSGE(ArgValue, NegOp->getOperand(0), "abscond");
1761feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    Value *Result =
177c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson      Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs");
178c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson
179c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson    return RValue::get(Result);
180c2251dc59b0edc28f9303637dec970a7520939adAnders Carlsson  }
1813a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson  case Builtin::BI__builtin_ctz:
1823a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson  case Builtin::BI__builtin_ctzl:
1833a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson  case Builtin::BI__builtin_ctzll: {
1843a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson    Value *ArgValue = EmitScalarExpr(E->getArg(0));
1853a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson
1863a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson    const llvm::Type *ArgType = ArgValue->getType();
1873a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson    Value *F = CGM.getIntrinsic(Intrinsic::cttz, &ArgType, 1);
1883a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson
1893a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson    const llvm::Type *ResultType = ConvertType(E->getType());
1903a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson    Value *Result = Builder.CreateCall(F, ArgValue, "tmp");
1913a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson    if (Result->getType() != ResultType)
1923a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson      Result = Builder.CreateIntCast(Result, ResultType, "cast");
1933a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson    return RValue::get(Result);
1943a31d60cffedfb7c9e6d129a5c9ba15fa74f179aAnders Carlsson  }
1951feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner  case Builtin::BI__builtin_expect:
1961feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    return RValue::get(EmitScalarExpr(E->getArg(0)));
197df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson  case Builtin::BI__builtin_bswap32:
198df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson  case Builtin::BI__builtin_bswap64: {
1991feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    Value *ArgValue = EmitScalarExpr(E->getArg(0));
200df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson    const llvm::Type *ArgType = ArgValue->getType();
2017acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner    Value *F = CGM.getIntrinsic(Intrinsic::bswap, &ArgType, 1);
2021feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    return RValue::get(Builder.CreateCall(F, ArgValue, "tmp"));
203df4852ac816e6050d53b808b86d7c1c9738eb99eAnders Carlsson  }
204c8ee7988c4ea9ec784625d2a47a8575feb191421Anders Carlsson  case Builtin::BI__builtin_inff: {
2051feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    APFloat f(APFloat::IEEEsingle, APFloat::fcInfinity, false);
2062c62a1aa398d5582db00d2bad6b2d999ee50ec14Chris Lattner    return RValue::get(ConstantFP::get(f));
207c8ee7988c4ea9ec784625d2a47a8575feb191421Anders Carlsson  }
208478547cd2163d86ed9d691aa8fe45949eebf6cbfAnders Carlsson  case Builtin::BI__builtin_huge_val:
209c8ee7988c4ea9ec784625d2a47a8575feb191421Anders Carlsson  case Builtin::BI__builtin_inf:
210c8ee7988c4ea9ec784625d2a47a8575feb191421Anders Carlsson  // FIXME: mapping long double onto double.
211c8ee7988c4ea9ec784625d2a47a8575feb191421Anders Carlsson  case Builtin::BI__builtin_infl: {
2121feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner    APFloat f(APFloat::IEEEdouble, APFloat::fcInfinity, false);
2132c62a1aa398d5582db00d2bad6b2d999ee50ec14Chris Lattner    return RValue::get(ConstantFP::get(f));
214c8ee7988c4ea9ec784625d2a47a8575feb191421Anders Carlsson  }
215fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner  case Builtin::BI__builtin_isgreater:
216fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner  case Builtin::BI__builtin_isgreaterequal:
217fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner  case Builtin::BI__builtin_isless:
218fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner  case Builtin::BI__builtin_islessequal:
219fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner  case Builtin::BI__builtin_islessgreater:
220fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner  case Builtin::BI__builtin_isunordered: {
221fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    // Ordered comparisons: we know the arguments to these are matching scalar
222fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    // floating point values.
223fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    Value *LHS = EmitScalarExpr(E->getArg(0));
224fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    Value *RHS = EmitScalarExpr(E->getArg(1));
225fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner
226fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    switch (BuiltinID) {
227fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    default: assert(0 && "Unknown ordered comparison");
228fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    case Builtin::BI__builtin_isgreater:
229fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp");
230fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      break;
231fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    case Builtin::BI__builtin_isgreaterequal:
232fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp");
233fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      break;
234fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    case Builtin::BI__builtin_isless:
235fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp");
236fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      break;
237fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    case Builtin::BI__builtin_islessequal:
238fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp");
239fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      break;
240fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    case Builtin::BI__builtin_islessgreater:
241fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp");
242fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      break;
243fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    case Builtin::BI__builtin_isunordered:
244fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp");
245fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner      break;
246fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    }
247fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    // ZExt bool to int type.
248fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner    return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType()),
249fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner                                          "tmp"));
250fe23e217774aaec350086fab839210d7d9e1e3f4Chris Lattner  }
2514efe45919836728a2a38a50b8d79cd36432e1708Nate Begeman  case Builtin::BI__builtin_alloca:
2524efe45919836728a2a38a50b8d79cd36432e1708Nate Begeman    return RValue::get(Builder.CreateAlloca(llvm::Type::Int8Ty,
2534efe45919836728a2a38a50b8d79cd36432e1708Nate Begeman                                            EmitScalarExpr(E->getArg(0)),
2544efe45919836728a2a38a50b8d79cd36432e1708Nate Begeman                                            "tmp"));
255d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman  case Builtin::BI__builtin_memcpy: {
256d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman    Value* MemCpyOps[4] = {
257d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman      EmitScalarExpr(E->getArg(0)),
258d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman      EmitScalarExpr(E->getArg(1)),
259d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman      EmitScalarExpr(E->getArg(2)),
260d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman      llvm::ConstantInt::get(llvm::Type::Int32Ty, 0)
261d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman    };
262d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman    Builder.CreateCall(CGM.getMemCpyFn(), MemCpyOps, MemCpyOps+4);
263d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman    return RValue::get(MemCpyOps[0]);
264d4b32e46517358f34e8cfbea35010adfcc3786e0Eli Friedman  }
2651ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_fetch_and_add:
2661ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    return EmitBinaryAtomic(*this, Intrinsic::atomic_las, E);
2671ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_fetch_and_sub:
2681ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    return EmitBinaryAtomic(*this, Intrinsic::atomic_lss, E);
2691ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_fetch_and_min:
2701ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_min, E);
2711ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_fetch_and_max:
2721ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_max, E);
2731ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_fetch_and_umin:
2741ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umin, E);
2751ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_fetch_and_umax:
2761ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umax, E);
2771ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_fetch_and_and:
2781ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_and, E);
2791ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_fetch_and_or:
2801ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_or, E);
2811ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_fetch_and_xor:
2821ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    return EmitBinaryAtomic(*this, Intrinsic::atomic_load_xor, E);
2831ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_val_compare_and_swap: {
2841ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    Value *Args[3];
2851ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    Args[0]= EmitScalarExpr(E->getArg(0));
2861ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    Args[1] = EmitScalarExpr(E->getArg(1));
2871ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    Args[2] = EmitScalarExpr(E->getArg(2));
2881ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    const llvm::Type *ResType = ConvertType(E->getType());
2891ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_lcs, &ResType, 1);
2901ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang    return RValue::get(Builder.CreateCall(AtomF, &Args[0], &Args[1]+2));
291022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson  }
2921ffe281890f3cd7728316b45a1f3dd4d3120af7bMon P Wang  case Builtin::BI__sync_lock_test_and_set:
2937ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman    return EmitBinaryAtomic(*this, Intrinsic::atomic_swap, E);
2947ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman  }
295022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson  return RValue::get(0);
296022012e6e5626c3372e1a5493c0929dfc1fa9e47Anders Carlsson}
297564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson
2981feedd84221e8dbcc3faf3de27cc42b559db845dChris LattnerValue *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
2991feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner                                           const CallExpr *E) {
3002929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
3012929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  llvm::SmallVector<Value*, 4> Ops;
3022929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
3032929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  for (unsigned i = 0, e = E->getNumArgs(); i != e; i++)
3042929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    Ops.push_back(EmitScalarExpr(E->getArg(i)));
3052929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson
306564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson  switch (BuiltinID) {
30746a26b0b0e2ec1557bad9b70e8e20836524ebdfcAnders Carlsson  default: return 0;
30846a26b0b0e2ec1557bad9b70e8e20836524ebdfcAnders Carlsson  case X86::BI__builtin_ia32_mulps:
3092929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    return Builder.CreateMul(Ops[0], Ops[1], "mulps");
310e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_mulpd:
311e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return Builder.CreateMul(Ops[0], Ops[1], "mulpd");
3124e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson  case X86::BI__builtin_ia32_pand:
313e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_pand128:
3142929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    return Builder.CreateAnd(Ops[0], Ops[1], "pand");
3154e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson  case X86::BI__builtin_ia32_por:
316e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_por128:
317e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return Builder.CreateOr(Ops[0], Ops[1], "por");
3184e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson  case X86::BI__builtin_ia32_pxor:
319e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_pxor128:
320e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return Builder.CreateXor(Ops[0], Ops[1], "pxor");
321e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_pandn:
322e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_pandn128:
3232929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    Ops[0] = Builder.CreateNot(Ops[0], "tmp");
3242929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    return Builder.CreateAnd(Ops[0], Ops[1], "pandn");
3254e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson  case X86::BI__builtin_ia32_paddb:
326e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_paddb128:
3274e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson  case X86::BI__builtin_ia32_paddd:
328e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_paddd128:
3294e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson  case X86::BI__builtin_ia32_paddq:
330e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_paddq128:
3314e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson  case X86::BI__builtin_ia32_paddw:
332e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_paddw128:
333cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  case X86::BI__builtin_ia32_addps:
334e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_addpd:
335cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    return Builder.CreateAdd(Ops[0], Ops[1], "add");
3364e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson  case X86::BI__builtin_ia32_psubb:
337e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psubb128:
3384e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson  case X86::BI__builtin_ia32_psubd:
339e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psubd128:
3404e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson  case X86::BI__builtin_ia32_psubq:
341e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psubq128:
3424e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson  case X86::BI__builtin_ia32_psubw:
343e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psubw128:
344cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  case X86::BI__builtin_ia32_subps:
345e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_subpd:
346cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    return Builder.CreateSub(Ops[0], Ops[1], "sub");
347cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  case X86::BI__builtin_ia32_divps:
348cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    return Builder.CreateFDiv(Ops[0], Ops[1], "divps");
349e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_divpd:
350e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return Builder.CreateFDiv(Ops[0], Ops[1], "divpd");
351db832305d35a7c9ef08bbafcf79d8da162af3374Anders Carlsson  case X86::BI__builtin_ia32_pmullw:
352e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_pmullw128:
3532929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    return Builder.CreateMul(Ops[0], Ops[1], "pmul");
354db832305d35a7c9ef08bbafcf79d8da162af3374Anders Carlsson  case X86::BI__builtin_ia32_punpckhbw:
3557acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner    return EmitShuffleVector(Ops[0], Ops[1], 4, 12, 5, 13, 6, 14, 7, 15,
356db832305d35a7c9ef08bbafcf79d8da162af3374Anders Carlsson                             "punpckhbw");
357e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_punpckhbw128:
358e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return EmitShuffleVector(Ops[0], Ops[1],  8, 24,  9, 25, 10, 26, 11, 27,
359e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman                                             12, 28, 13, 29, 14, 30, 15, 31,
360e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman                             "punpckhbw");
361db832305d35a7c9ef08bbafcf79d8da162af3374Anders Carlsson  case X86::BI__builtin_ia32_punpckhwd:
3627acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner    return EmitShuffleVector(Ops[0], Ops[1], 2, 6, 3, 7, "punpckhwd");
363e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_punpckhwd128:
364e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return EmitShuffleVector(Ops[0], Ops[1], 4, 12, 5, 13, 6, 14, 7, 15,
365e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman                             "punpckhwd");
366db832305d35a7c9ef08bbafcf79d8da162af3374Anders Carlsson  case X86::BI__builtin_ia32_punpckhdq:
3677acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner    return EmitShuffleVector(Ops[0], Ops[1], 1, 3, "punpckhdq");
368e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_punpckhdq128:
369e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return EmitShuffleVector(Ops[0], Ops[1], 2, 6, 3, 7, "punpckhdq");
370db832305d35a7c9ef08bbafcf79d8da162af3374Anders Carlsson  case X86::BI__builtin_ia32_punpcklbw:
3717acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner    return EmitShuffleVector(Ops[0], Ops[1], 0, 8, 1, 9, 2, 10, 3, 11,
372db832305d35a7c9ef08bbafcf79d8da162af3374Anders Carlsson                             "punpcklbw");
373db832305d35a7c9ef08bbafcf79d8da162af3374Anders Carlsson  case X86::BI__builtin_ia32_punpcklwd:
3747acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner    return EmitShuffleVector(Ops[0], Ops[1], 0, 4, 1, 5, "punpcklwd");
375db832305d35a7c9ef08bbafcf79d8da162af3374Anders Carlsson  case X86::BI__builtin_ia32_punpckldq:
3767acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner    return EmitShuffleVector(Ops[0], Ops[1], 0, 2, "punpckldq");
377e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_punpckldq128:
378e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return EmitShuffleVector(Ops[0], Ops[1], 0, 4, 1, 5, "punpckldq");
379e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_pslldi128:
380e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psllqi128:
381e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psllwi128:
382e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psradi128:
383e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psrawi128:
384e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psrldi128:
385e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psrlqi128:
386e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_psrlwi128: {
387e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::Int64Ty, "zext");
388e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    const llvm::Type *Ty = llvm::VectorType::get(llvm::Type::Int64Ty, 2);
389e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    llvm::Value *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
390e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[1] = Builder.CreateInsertElement(llvm::UndefValue::get(Ty),
391e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman                                         Ops[1], Zero, "insert");
392e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType(), "bitcast");
393e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    const char *name = 0;
394e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Intrinsic::ID ID = Intrinsic::not_intrinsic;
395e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
396e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    switch (BuiltinID) {
397e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    default: assert(0 && "Unsupported shift intrinsic!");
398e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_pslldi128:
399e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "pslldi";
400e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psll_d;
401e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
402e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psllqi128:
403e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psllqi";
404e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psll_q;
405e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
406e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psllwi128:
407e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psllwi";
408e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psll_w;
409e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
410e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psradi128:
411e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psradi";
412e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psra_d;
413e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
414e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psrawi128:
415e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psrawi";
416e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psra_w;
417e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
418e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psrldi128:
419e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psrldi";
420e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psrl_d;
421e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
422e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psrlqi128:
423e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psrlqi";
424e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psrl_q;
425e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
426e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psrlwi128:
427e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psrlwi";
428e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psrl_w;
429e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
430e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    }
431e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    llvm::Function *F = CGM.getIntrinsic(ID);
432e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
433e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  }
4342929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_pslldi:
4352929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_psllqi:
4362929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_psllwi:
4372929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_psradi:
4382929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_psrawi:
4392929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_psrldi:
4402929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_psrlqi:
4412929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_psrlwi: {
4422929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::Int64Ty, "zext");
4432929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    const llvm::Type *Ty = llvm::VectorType::get(llvm::Type::Int64Ty, 1);
4442929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    Ops[1] = Builder.CreateBitCast(Ops[1], Ty, "bitcast");
4452929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    const char *name = 0;
4462929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    Intrinsic::ID ID = Intrinsic::not_intrinsic;
4474e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson
4482929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    switch (BuiltinID) {
4492929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    default: assert(0 && "Unsupported shift intrinsic!");
4502929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_pslldi:
4512929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "pslldi";
4522929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psll_d;
4532929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
4542929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_psllqi:
4552929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "psllqi";
4562929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psll_q;
4572929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
4582929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_psllwi:
4592929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "psllwi";
4602929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psll_w;
4612929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
4622929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_psradi:
4632929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "psradi";
4642929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psra_d;
4652929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
4662929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_psrawi:
4672929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "psrawi";
4682929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psra_w;
4692929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
4702929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_psrldi:
4712929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "psrldi";
4722929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psrl_d;
4732929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
4742929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_psrlqi:
4752929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "psrlqi";
4762929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psrl_q;
4772929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
4782929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    case X86::BI__builtin_ia32_psrlwi:
4792929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      name = "psrlwi";
4802929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      ID = Intrinsic::x86_mmx_psrl_w;
4812929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson      break;
482e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_pslldi128:
483e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "pslldi";
484e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psll_d;
485e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
486e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psllqi128:
487e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psllqi";
488e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psll_q;
489e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
490e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psllwi128:
491e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psllwi";
492e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psll_w;
493e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
494e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psradi128:
495e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psradi";
496e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psra_d;
497e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
498e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psrawi128:
499e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psrawi";
500e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psra_w;
501e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
502e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psrldi128:
503e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psrldi";
504e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psrl_d;
505e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
506e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psrlqi128:
507e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psrlqi";
508e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psrl_q;
509e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
510e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_psrlwi128:
511e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "psrlwi";
512e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      ID = Intrinsic::x86_sse2_psrl_w;
513e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
5142929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    }
5157acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner    llvm::Function *F = CGM.getIntrinsic(ID);
5162929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
5172929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  }
5187ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman  case X86::BI__builtin_ia32_pshuflw: {
5197ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman    unsigned i = cast<ConstantInt>(Ops[1])->getZExtValue();
5207ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman    return EmitShuffleVector(Ops[0], Ops[0],
5217ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman                             i & 0x3, (i & 0xc) >> 2,
5227ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman                             (i & 0x30) >> 4, (i & 0xc0) >> 6, 4, 5, 6, 7,
5237ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman                             "pshuflw");
5247ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman  }
5257ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman  case X86::BI__builtin_ia32_pshufhw: {
5267ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman    unsigned i = cast<ConstantInt>(Ops[1])->getZExtValue();
5277ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman    return EmitShuffleVector(Ops[0], Ops[0], 0, 1, 2, 3,
5287ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman                             4 + (i & 0x3), 4 + ((i & 0xc) >> 2),
5297ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman                             4 + ((i & 0x30) >> 4), 4 + ((i & 0xc0) >> 6),
5307ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman                             "pshufhw");
5317ea2e3f6aae9b7511686d3d26dee690fee81c3aaNate Begeman  }
5322929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson  case X86::BI__builtin_ia32_pshufd: {
5337acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner    unsigned i = cast<ConstantInt>(Ops[1])->getZExtValue();
5342929cfa9b7df1d5b0571b54161783e4d791a0b77Anders Carlsson    return EmitShuffleVector(Ops[0], Ops[0],
5354e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson                             i & 0x3, (i & 0xc) >> 2,
5364e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson                             (i & 0x30) >> 4, (i & 0xc0) >> 6,
5374e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson                             "pshufd");
5384e4ee211b56e3276df80b350a6194f7cbf04b92cAnders Carlsson  }
5396086bbd1799e22e75561c3d31dc9b923f0508fa5Anders Carlsson  case X86::BI__builtin_ia32_vec_init_v4hi:
5406086bbd1799e22e75561c3d31dc9b923f0508fa5Anders Carlsson  case X86::BI__builtin_ia32_vec_init_v8qi:
5416086bbd1799e22e75561c3d31dc9b923f0508fa5Anders Carlsson  case X86::BI__builtin_ia32_vec_init_v2si:
5426086bbd1799e22e75561c3d31dc9b923f0508fa5Anders Carlsson    return EmitVector(&Ops[0], Ops.size());
5436086bbd1799e22e75561c3d31dc9b923f0508fa5Anders Carlsson  case X86::BI__builtin_ia32_vec_ext_v2si:
544e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_vec_ext_v2di:
545e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_vec_ext_v4sf:
546e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_vec_ext_v4si:
547e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_vec_ext_v2df:
5486086bbd1799e22e75561c3d31dc9b923f0508fa5Anders Carlsson    return Builder.CreateExtractElement(Ops[0], Ops[1], "result");
549cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  case X86::BI__builtin_ia32_cmpordss:
550e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpordsd:
551cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  case X86::BI__builtin_ia32_cmpunordss:
552e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpunordsd:
553e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpeqss:
554e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpeqsd:
555e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpltss:
556e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpltsd:
557cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  case X86::BI__builtin_ia32_cmpless:
558e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmplesd:
559cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  case X86::BI__builtin_ia32_cmpneqss:
560e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpneqsd:
561e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpnltss:
562e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpnltsd:
563e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpnless:
564e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpnlesd: {
5657acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner    unsigned i = 0;
566cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    const char *name = 0;
567cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    switch (BuiltinID) {
568cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    default: assert(0 && "Unknown compare builtin!");
569cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    case X86::BI__builtin_ia32_cmpeqss:
570e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpeqsd:
571cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      i = 0;
572e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "cmpeq";
573cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      break;
574cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    case X86::BI__builtin_ia32_cmpltss:
575e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpltsd:
576cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      i = 1;
577e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "cmplt";
578cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      break;
579cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    case X86::BI__builtin_ia32_cmpless:
580e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmplesd:
581cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      i = 2;
582e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "cmple";
583cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      break;
584cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    case X86::BI__builtin_ia32_cmpunordss:
585e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpunordsd:
586cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      i = 3;
587e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "cmpunord";
588cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      break;
589cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    case X86::BI__builtin_ia32_cmpneqss:
590e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpneqsd:
591cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      i = 4;
592e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "cmpneq";
593cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      break;
594cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    case X86::BI__builtin_ia32_cmpnltss:
595e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpnltsd:
596cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      i = 5;
597e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "cmpntl";
598cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      break;
599cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    case X86::BI__builtin_ia32_cmpnless:
600e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpnlesd:
601cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      i = 6;
602e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "cmpnle";
603cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      break;
604cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    case X86::BI__builtin_ia32_cmpordss:
605e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpordsd:
606cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      i = 7;
607e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "cmpord";
608cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      break;
609cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    }
610cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson
611e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    llvm::Function *F;
612e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    if (cast<llvm::VectorType>(Ops[0]->getType())->getElementType() ==
613e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        llvm::Type::FloatTy)
614e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ss);
615e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    else
616e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_sd);
617e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
618cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    Ops.push_back(llvm::ConstantInt::get(llvm::Type::Int8Ty, i));
619cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
620cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  }
621e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_ldmxcsr: {
622e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    llvm::Type *PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
623e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Value *One = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1);
624e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Value *Tmp = Builder.CreateAlloca(llvm::Type::Int32Ty, One, "tmp");
625e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Builder.CreateStore(Ops[0], Tmp);
626e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr),
6273eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner                              Builder.CreateBitCast(Tmp, PtrTy));
628e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  }
629e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_stmxcsr: {
630e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    llvm::Type *PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
631e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Value *One = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1);
632e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Value *Tmp = Builder.CreateAlloca(llvm::Type::Int32Ty, One, "tmp");
633e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    One = Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr),
6343eae03e7d165f20a863a9a4d7122ba2a691ab16dChris Lattner                             Builder.CreateBitCast(Tmp, PtrTy));
635e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return Builder.CreateLoad(Tmp, "stmxcsr");
636e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  }
637cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  case X86::BI__builtin_ia32_cmpordps:
638e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpordpd:
639cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  case X86::BI__builtin_ia32_cmpunordps:
640e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpunordpd:
641cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  case X86::BI__builtin_ia32_cmpeqps:
642e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpeqpd:
643cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  case X86::BI__builtin_ia32_cmpltps:
644e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpltpd:
645cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  case X86::BI__builtin_ia32_cmpleps:
646e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmplepd:
647cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  case X86::BI__builtin_ia32_cmpneqps:
648e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpneqpd:
649cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  case X86::BI__builtin_ia32_cmpngtps:
650e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpngtpd:
651cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  case X86::BI__builtin_ia32_cmpnltps:
652e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpnltpd:
653cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  case X86::BI__builtin_ia32_cmpgtps:
654e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpgtpd:
655cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  case X86::BI__builtin_ia32_cmpgeps:
656e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpgepd:
657cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  case X86::BI__builtin_ia32_cmpngeps:
658e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpngepd:
659e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpnleps:
660e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_cmpnlepd: {
6617acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner    unsigned i = 0;
662cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    const char *name = 0;
663cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    bool ShouldSwap = false;
664cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    switch (BuiltinID) {
665cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    default: assert(0 && "Unknown compare builtin!");
666e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpeqps:
667e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpeqpd:    i = 0; name = "cmpeq"; break;
668e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpltps:
669e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpltpd:    i = 1; name = "cmplt"; break;
670e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpleps:
671e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmplepd:    i = 2; name = "cmple"; break;
672e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpunordps:
673e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpunordpd: i = 3; name = "cmpunord"; break;
674e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpneqps:
675e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpneqpd:   i = 4; name = "cmpneq"; break;
676e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpnltps:
677e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpnltpd:   i = 5; name = "cmpntl"; break;
678e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpnleps:
679e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpnlepd:   i = 6; name = "cmpnle"; break;
680e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpordps:
681e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpordpd:   i = 7; name = "cmpord"; break;
682cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    case X86::BI__builtin_ia32_cmpgtps:
683e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpgtpd:
6847acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner      ShouldSwap = true;
685cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      i = 1;
686e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "cmpgt";
687cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      break;
688cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    case X86::BI__builtin_ia32_cmpgeps:
689e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpgepd:
690cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      i = 2;
691e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "cmpge";
692cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      ShouldSwap = true;
693cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      break;
694cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    case X86::BI__builtin_ia32_cmpngtps:
695e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpngtpd:
696cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      i = 5;
697e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "cmpngt";
698cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      ShouldSwap = true;
699cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      break;
700cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    case X86::BI__builtin_ia32_cmpngeps:
701e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_cmpngepd:
702cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      i = 6;
703e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      name = "cmpnge";
704cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      ShouldSwap = true;
705cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      break;
706cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    }
707cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson
708cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    if (ShouldSwap)
709cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson      std::swap(Ops[0], Ops[1]);
710e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
711e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    llvm::Function *F;
712e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    if (cast<llvm::VectorType>(Ops[0]->getType())->getElementType() ==
713e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman        llvm::Type::FloatTy)
714e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ps);
715e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    else
716e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_pd);
717cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson
718cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    Ops.push_back(llvm::ConstantInt::get(llvm::Type::Int8Ty, i));
719cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
720cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  }
721cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson  case X86::BI__builtin_ia32_movss:
722cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    return EmitShuffleVector(Ops[0], Ops[1], 4, 1, 2, 3, "movss");
723730f2c13e8ff0a2a3cc54fce9913add68107cb51Torok Edwin  case X86::BI__builtin_ia32_shufps: {
7247acda7c4a0e4aec6c003b3169ca45a5f3bc7e033Chris Lattner    unsigned i = cast<ConstantInt>(Ops[2])->getZExtValue();
725cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson    return EmitShuffleVector(Ops[0], Ops[1],
726cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson                             i & 0x3, (i & 0xc) >> 2,
727cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson                             ((i & 0x30) >> 4) + 4,
728cc8b7f911892b3257e381677d0a82d43bf7b067cAnders Carlsson                             ((i & 0x60) >> 6) + 4, "shufps");
729730f2c13e8ff0a2a3cc54fce9913add68107cb51Torok Edwin  }
730dbebb73b86d9fe56c2227bf75c13ea3a49248261Nate Begeman  case X86::BI__builtin_ia32_punpcklbw128:
731dbebb73b86d9fe56c2227bf75c13ea3a49248261Nate Begeman    return EmitShuffleVector(Ops[0], Ops[1], 0, 16, 1, 17, 2, 18, 3, 19,
732dbebb73b86d9fe56c2227bf75c13ea3a49248261Nate Begeman                                             4, 20, 5, 21, 6, 22, 7, 23,
733dbebb73b86d9fe56c2227bf75c13ea3a49248261Nate Begeman                                             "punpcklbw");
734dbebb73b86d9fe56c2227bf75c13ea3a49248261Nate Begeman  case X86::BI__builtin_ia32_punpcklwd128:
735dbebb73b86d9fe56c2227bf75c13ea3a49248261Nate Begeman    return EmitShuffleVector(Ops[0], Ops[1], 0, 8, 1, 9, 2, 10, 3, 11,
736dbebb73b86d9fe56c2227bf75c13ea3a49248261Nate Begeman                             "punpcklwd");
737e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_movlhps:
738e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return EmitShuffleVector(Ops[0], Ops[1], 0, 1, 4, 5, "movlhps");
739e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_movhlps:
740e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return EmitShuffleVector(Ops[0], Ops[1], 6, 7, 2, 3, "movhlps");
741e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_unpckhps:
742e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return EmitShuffleVector(Ops[0], Ops[1], 2, 6, 3, 7, "unpckhps");
743e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_unpcklps:
744e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return EmitShuffleVector(Ops[0], Ops[1], 0, 4, 1, 5, "unpcklps");
745e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_movqv4si: {
746e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    llvm::Type *Ty = llvm::VectorType::get(llvm::Type::Int64Ty, 2);
747e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return Builder.CreateBitCast(Ops[0], Ty);
748e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  }
749e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_loadlps:
750e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_loadhps: {
751e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    // FIXME: This should probably be represented as
752e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    // shuffle (dst, (v4f32 (insert undef, (load i64), 0)), shuf mask hi/lo)
753e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    const llvm::Type *EltTy = llvm::Type::DoubleTy;
754e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    const llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2);
755e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    const llvm::Type *OrigTy = Ops[0]->getType();
756e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    unsigned Index = BuiltinID == X86::BI__builtin_ia32_loadlps ? 0 : 1;
757e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    llvm::Value *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, Index);
758e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[1] = Builder.CreateBitCast(Ops[1], llvm::PointerType::getUnqual(EltTy));
759e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[1] = Builder.CreateLoad(Ops[1], "tmp");
760e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast");
761e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[0] = Builder.CreateInsertElement(Ops[0], Ops[1], Idx, "loadps");
762e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return Builder.CreateBitCast(Ops[0], OrigTy, "loadps");
763e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  }
764e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_storehps:
765e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_storelps: {
766e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    const llvm::Type *EltTy = llvm::Type::Int64Ty;
767e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    llvm::Type *PtrTy = llvm::PointerType::getUnqual(EltTy);
768e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2);
769e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
770e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    // cast val v2i64
771e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast");
772e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
773e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    // extract (0, 1)
774e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1;
775e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    llvm::Value *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, Index);
776e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract");
777e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
778e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    // cast pointer to i64 & store
779e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy);
780e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return Builder.CreateStore(Ops[1], Ops[0]);
781e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  }
782e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_loadlv4si: {
783e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    // load i64
784e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    const llvm::Type *EltTy = llvm::Type::Int64Ty;
785e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    llvm::Type *PtrTy = llvm::PointerType::getUnqual(EltTy);
786e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy);
787e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[0] = Builder.CreateLoad(Ops[0], "load");
788e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
789e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    // scalar to vector: insert i64 into 2 x i64 undef
790e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2);
791e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    llvm::Value *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
792e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[0] = Builder.CreateInsertElement(llvm::UndefValue::get(VecTy),
793e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman                                         Ops[0], Zero, "s2v");
794e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
795e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    // shuffle into zero vector.
796e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    std::vector<llvm::Constant *>Elts;
797e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Elts.resize(2, llvm::ConstantInt::get(EltTy, 0));
798e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    llvm::Value *ZV = ConstantVector::get(Elts);
799e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[0] = EmitShuffleVector(ZV, Ops[0], 2, 1, "loadl");
800e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman
801e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    // bitcast to result.
802e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return Builder.CreateBitCast(Ops[0],
803e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman                                 llvm::VectorType::get(llvm::Type::Int32Ty, 4));
804e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  }
80524512501319aa6d7f70b1bd79470df0197b832c8Nate Begeman  case X86::BI__builtin_ia32_vec_set_v4hi:
80624512501319aa6d7f70b1bd79470df0197b832c8Nate Begeman  case X86::BI__builtin_ia32_vec_set_v8hi:
80724512501319aa6d7f70b1bd79470df0197b832c8Nate Begeman    return Builder.CreateInsertElement(Ops[0], Ops[1], Ops[2], "pinsrw");
808e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_andps:
809e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_andpd:
810e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_andnps:
811e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_andnpd:
812e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_orps:
813e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_orpd:
814e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_xorpd:
815e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  case X86::BI__builtin_ia32_xorps: {
816e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    const llvm::Type *ITy = llvm::VectorType::get(llvm::Type::Int32Ty, 4);
817e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    const llvm::Type *FTy = Ops[0]->getType();
818e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[0] = Builder.CreateBitCast(Ops[0], ITy, "bitcast");
819e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    Ops[1] = Builder.CreateBitCast(Ops[1], ITy, "bitcast");
820e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    switch (BuiltinID) {
821e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_andps:
822e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      Ops[0] = Builder.CreateAnd(Ops[0], Ops[1], "andps");
823e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
824e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_andpd:
825e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      Ops[0] = Builder.CreateAnd(Ops[0], Ops[1], "andpd");
826e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
827e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_andnps:
828e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      Ops[0] = Builder.CreateNot(Ops[0], "not");
829e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      Ops[0] = Builder.CreateAnd(Ops[0], Ops[1], "andnps");
830e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
831e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_andnpd:
832e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      Ops[0] = Builder.CreateNot(Ops[0], "not");
833e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      Ops[0] = Builder.CreateAnd(Ops[0], Ops[1], "andnpd");
834e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
835e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_orps:
836e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      Ops[0] = Builder.CreateOr(Ops[0], Ops[1], "orps");
837e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
838e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_orpd:
839e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      Ops[0] = Builder.CreateOr(Ops[0], Ops[1], "orpd");
840e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
841e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_xorps:
842e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      Ops[0] = Builder.CreateXor(Ops[0], Ops[1], "xorps");
843e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
844e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    case X86::BI__builtin_ia32_xorpd:
845e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      Ops[0] = Builder.CreateXor(Ops[0], Ops[1], "xorpd");
846e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman      break;
847e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    }
848e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman    return Builder.CreateBitCast(Ops[0], FTy, "bitcast");
849e7722103abc4583366c914374d6aa8560e145fa1Nate Begeman  }
850564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson  }
851564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson}
852564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson
8531feedd84221e8dbcc3faf3de27cc42b559db845dChris LattnerValue *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
8541feedd84221e8dbcc3faf3de27cc42b559db845dChris Lattner                                           const CallExpr *E) {
855564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson  switch (BuiltinID) {
85646a26b0b0e2ec1557bad9b70e8e20836524ebdfcAnders Carlsson  default: return 0;
857564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson  }
858564f1de67d7ba43646b8740db86d6269e3dfbe0bAnders Carlsson}
859