zcov: / lib/CodeGen/CGBuiltin.cpp


Files: 1 Branches Taken: 74.5% 123 / 165
Generated: 2010-02-10 01:31 Branches Executed: 84.2% 139 / 165
Line Coverage: 77.2% 288 / 373


Programs: 1 Runs 2897


       1                 : //===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===//
       2                 : //
       3                 : //                     The LLVM Compiler Infrastructure
       4                 : //
       5                 : // This file is distributed under the University of Illinois Open Source
       6                 : // License. See LICENSE.TXT for details.
       7                 : //
       8                 : //===----------------------------------------------------------------------===//
       9                 : //
      10                 : // This contains code to emit Builtin calls as LLVM code.
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : #include "CodeGenFunction.h"
      15                 : #include "CodeGenModule.h"
      16                 : #include "clang/Basic/TargetInfo.h"
      17                 : #include "clang/AST/APValue.h"
      18                 : #include "clang/AST/ASTContext.h"
      19                 : #include "clang/AST/Decl.h"
      20                 : #include "clang/Basic/TargetBuiltins.h"
      21                 : #include "llvm/Intrinsics.h"
      22                 : using namespace clang;
      23                 : using namespace CodeGen;
      24                 : using namespace llvm;
      25                 : 
      26                 : /// Utility to insert an atomic instruction based on Instrinsic::ID
      27                 : /// and the expression node.
      28                 : static RValue EmitBinaryAtomic(CodeGenFunction& CGF,
      29               11:                                Intrinsic::ID Id, const CallExpr *E) {
      30                 :   const llvm::Type *ResType[2];
      31               11:   ResType[0] = CGF.ConvertType(E->getType());
      32               11:   ResType[1] = CGF.ConvertType(E->getArg(0)->getType());
      33               11:   Value *AtomF = CGF.CGM.getIntrinsic(Id, ResType, 2);
      34                 :   return RValue::get(CGF.Builder.CreateCall2(AtomF,
      35                 :                                              CGF.EmitScalarExpr(E->getArg(0)),
      36               11:                                              CGF.EmitScalarExpr(E->getArg(1))));
      37                 : }
      38                 : 
      39                 : /// Utility to insert an atomic instruction based Instrinsic::ID and
      40                 : // the expression node, where the return value is the result of the
      41                 : // operation.
      42                 : static RValue EmitBinaryAtomicPost(CodeGenFunction& CGF,
      43                 :                                    Intrinsic::ID Id, const CallExpr *E,
      44                6:                                    Instruction::BinaryOps Op) {
      45                 :   const llvm::Type *ResType[2];
      46                6:   ResType[0] = CGF.ConvertType(E->getType());
      47                6:   ResType[1] = CGF.ConvertType(E->getArg(0)->getType());
      48                6:   Value *AtomF = CGF.CGM.getIntrinsic(Id, ResType, 2);
      49                6:   Value *Ptr = CGF.EmitScalarExpr(E->getArg(0));
      50                6:   Value *Operand = CGF.EmitScalarExpr(E->getArg(1));
      51                6:   Value *Result = CGF.Builder.CreateCall2(AtomF, Ptr, Operand);
      52                 : 
                        1: branch 0 taken
                        5: branch 1 taken
      53                6:   if (Id == Intrinsic::atomic_load_nand)
      54                1:     Result = CGF.Builder.CreateNot(Result);
      55                 : 
      56                 : 
      57                6:   return RValue::get(CGF.Builder.CreateBinOp(Op, Result, Operand));
      58                 : }
      59                 : 
      60                 : RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
      61              796:                                         unsigned BuiltinID, const CallExpr *E) {
      62                 :   // See if we can constant fold this builtin.  If so, don't emit it at all.
      63              796:   Expr::EvalResult Result;
                       43: branch 2 taken
                      753: branch 3 taken
      64              796:   if (E->Evaluate(Result, CGM.getContext())) {
                       29: branch 1 taken
                       14: branch 2 taken
      65               43:     if (Result.Val.isInt())
      66                 :       return RValue::get(llvm::ConstantInt::get(VMContext,
      67               29:                                                 Result.Val.getInt()));
                       12: branch 1 taken
                        2: branch 2 taken
      68               14:     else if (Result.Val.isFloat())
      69               12:       return RValue::get(ConstantFP::get(VMContext, Result.Val.getFloat()));
      70                 :   }
      71                 : 
                      660: branch 0 taken
                        2: branch 1 taken
                        1: branch 2 taken
                        5: branch 3 taken
                        1: branch 4 taken
                        5: branch 5 taken
                        5: branch 6 taken
                        3: branch 7 taken
                        3: branch 8 taken
                        3: branch 9 taken
                        1: branch 10 taken
                        2: branch 11 taken
                        3: branch 12 taken
                        3: branch 13 taken
                        1: branch 14 taken
                        0: branch 15 not taken
                        3: branch 16 taken
                        7: branch 17 taken
                        1: branch 18 taken
                        1: branch 19 taken
                        1: branch 20 taken
                        2: branch 21 taken
                        1: branch 22 taken
                        1: branch 23 taken
                        2: branch 24 taken
                        2: branch 25 taken
                        1: branch 26 taken
                        1: branch 27 taken
                        0: branch 28 not taken
                        1: branch 29 taken
                        1: branch 30 taken
                        1: branch 31 taken
                        1: branch 32 taken
                        1: branch 33 taken
                        1: branch 34 taken
                        1: branch 35 taken
                        1: branch 36 taken
                        1: branch 37 taken
                        1: branch 38 taken
                        1: branch 39 taken
                        1: branch 40 taken
                        1: branch 41 taken
                        1: branch 42 taken
                        1: branch 43 taken
                        1: branch 44 taken
                        2: branch 45 taken
                        1: branch 46 taken
                        1: branch 47 taken
                        1: branch 48 taken
                        1: branch 49 taken
                        0: branch 50 not taken
                        6: branch 51 taken
                        6: branch 52 taken
      72              755:   switch (BuiltinID) {
      73              660:   default: break;  // Handle intrinsics and libm functions below.
      74                 :   case Builtin::BI__builtin___CFStringMakeConstantString:
      75                 :   case Builtin::BI__builtin___NSStringMakeConstantString:
      76                2:     return RValue::get(CGM.EmitConstantExpr(E, E->getType(), 0));
      77                 :   case Builtin::BI__builtin_stdarg_start:
      78                 :   case Builtin::BI__builtin_va_start:
      79                 :   case Builtin::BI__builtin_va_end: {
      80                1:     Value *ArgValue = EmitVAListRef(E->getArg(0));
      81                1:     const llvm::Type *DestType = llvm::Type::getInt8PtrTy(VMContext);
                        1: branch 1 taken
                        0: branch 2 not taken
      82                1:     if (ArgValue->getType() != DestType)
      83                 :       ArgValue = Builder.CreateBitCast(ArgValue, DestType,
      84                1:                                        ArgValue->getName().data());
      85                 : 
      86                 :     Intrinsic::ID inst = (BuiltinID == Builtin::BI__builtin_va_end) ?
                        0: branch 0 not taken
                        1: branch 1 taken
      87                1:       Intrinsic::vaend : Intrinsic::vastart;
      88                1:     return RValue::get(Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue));
      89                 :   }
      90                 :   case Builtin::BI__builtin_va_copy: {
      91                5:     Value *DstPtr = EmitVAListRef(E->getArg(0));
      92                5:     Value *SrcPtr = EmitVAListRef(E->getArg(1));
      93                 : 
      94                5:     const llvm::Type *Type = llvm::Type::getInt8PtrTy(VMContext);
      95                 : 
      96                5:     DstPtr = Builder.CreateBitCast(DstPtr, Type);
      97                5:     SrcPtr = Builder.CreateBitCast(SrcPtr, Type);
      98                 :     return RValue::get(Builder.CreateCall2(CGM.getIntrinsic(Intrinsic::vacopy),
      99                5:                                            DstPtr, SrcPtr));
     100                 :   }
     101                 :   case Builtin::BI__builtin_abs: {
     102                1:     Value *ArgValue = EmitScalarExpr(E->getArg(0));
     103                 : 
     104                1:     Value *NegOp = Builder.CreateNeg(ArgValue, "neg");
     105                 :     Value *CmpResult =
     106                 :     Builder.CreateICmpSGE(ArgValue,
     107                 :                           llvm::Constant::getNullValue(ArgValue->getType()),
     108                1:                                                             "abscond");
     109                 :     Value *Result =
     110                1:       Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs");
     111                 : 
     112                1:     return RValue::get(Result);
     113                 :   }
     114                 :   case Builtin::BI__builtin_ctz:
     115                 :   case Builtin::BI__builtin_ctzl:
     116                 :   case Builtin::BI__builtin_ctzll: {
     117                5:     Value *ArgValue = EmitScalarExpr(E->getArg(0));
     118                 : 
     119                5:     const llvm::Type *ArgType = ArgValue->getType();
     120                5:     Value *F = CGM.getIntrinsic(Intrinsic::cttz, &ArgType, 1);
     121                 : 
     122                5:     const llvm::Type *ResultType = ConvertType(E->getType());
     123                5:     Value *Result = Builder.CreateCall(F, ArgValue, "tmp");
                        1: branch 1 taken
                        4: branch 2 taken
     124                5:     if (Result->getType() != ResultType)
     125                 :       Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
     126                1:                                      "cast");
     127                5:     return RValue::get(Result);
     128                 :   }
     129                 :   case Builtin::BI__builtin_clz:
     130                 :   case Builtin::BI__builtin_clzl:
     131                 :   case Builtin::BI__builtin_clzll: {
     132                5:     Value *ArgValue = EmitScalarExpr(E->getArg(0));
     133                 : 
     134                5:     const llvm::Type *ArgType = ArgValue->getType();
     135                5:     Value *F = CGM.getIntrinsic(Intrinsic::ctlz, &ArgType, 1);
     136                 : 
     137                5:     const llvm::Type *ResultType = ConvertType(E->getType());
     138                5:     Value *Result = Builder.CreateCall(F, ArgValue, "tmp");
                        1: branch 1 taken
                        4: branch 2 taken
     139                5:     if (Result->getType() != ResultType)
     140                 :       Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
     141                1:                                      "cast");
     142                5:     return RValue::get(Result);
     143                 :   }
     144                 :   case Builtin::BI__builtin_ffs:
     145                 :   case Builtin::BI__builtin_ffsl:
     146                 :   case Builtin::BI__builtin_ffsll: {
     147                 :     // ffs(x) -> x ? cttz(x) + 1 : 0
     148                3:     Value *ArgValue = EmitScalarExpr(E->getArg(0));
     149                 : 
     150                3:     const llvm::Type *ArgType = ArgValue->getType();
     151                3:     Value *F = CGM.getIntrinsic(Intrinsic::cttz, &ArgType, 1);
     152                 : 
     153                3:     const llvm::Type *ResultType = ConvertType(E->getType());
     154                 :     Value *Tmp = Builder.CreateAdd(Builder.CreateCall(F, ArgValue, "tmp"),
     155                3:                                    llvm::ConstantInt::get(ArgType, 1), "tmp");
     156                3:     Value *Zero = llvm::Constant::getNullValue(ArgType);
     157                3:     Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero");
     158                3:     Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp, "ffs");
                        1: branch 1 taken
                        2: branch 2 taken
     159                3:     if (Result->getType() != ResultType)
     160                 :       Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
     161                1:                                      "cast");
     162                3:     return RValue::get(Result);
     163                 :   }
     164                 :   case Builtin::BI__builtin_parity:
     165                 :   case Builtin::BI__builtin_parityl:
     166                 :   case Builtin::BI__builtin_parityll: {
     167                 :     // parity(x) -> ctpop(x) & 1
     168                3:     Value *ArgValue = EmitScalarExpr(E->getArg(0));
     169                 : 
     170                3:     const llvm::Type *ArgType = ArgValue->getType();
     171                3:     Value *F = CGM.getIntrinsic(Intrinsic::ctpop, &ArgType, 1);
     172                 : 
     173                3:     const llvm::Type *ResultType = ConvertType(E->getType());
     174                3:     Value *Tmp = Builder.CreateCall(F, ArgValue, "tmp");
     175                 :     Value *Result = Builder.CreateAnd(Tmp, llvm::ConstantInt::get(ArgType, 1),
     176                3:                                       "tmp");
                        1: branch 1 taken
                        2: branch 2 taken
     177                3:     if (Result->getType() != ResultType)
     178                 :       Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
     179                1:                                      "cast");
     180                3:     return RValue::get(Result);
     181                 :   }
     182                 :   case Builtin::BI__builtin_popcount:
     183                 :   case Builtin::BI__builtin_popcountl:
     184                 :   case Builtin::BI__builtin_popcountll: {
     185                3:     Value *ArgValue = EmitScalarExpr(E->getArg(0));
     186                 : 
     187                3:     const llvm::Type *ArgType = ArgValue->getType();
     188                3:     Value *F = CGM.getIntrinsic(Intrinsic::ctpop, &ArgType, 1);
     189                 : 
     190                3:     const llvm::Type *ResultType = ConvertType(E->getType());
     191                3:     Value *Result = Builder.CreateCall(F, ArgValue, "tmp");
                        1: branch 1 taken
                        2: branch 2 taken
     192                3:     if (Result->getType() != ResultType)
     193                 :       Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
     194                1:                                      "cast");
     195                3:     return RValue::get(Result);
     196                 :   }
     197                 :   case Builtin::BI__builtin_expect:
     198                 :     // FIXME: pass expect through to LLVM
     199                1:     return RValue::get(EmitScalarExpr(E->getArg(0)));
     200                 :   case Builtin::BI__builtin_bswap32:
     201                 :   case Builtin::BI__builtin_bswap64: {
     202                2:     Value *ArgValue = EmitScalarExpr(E->getArg(0));
     203                2:     const llvm::Type *ArgType = ArgValue->getType();
     204                2:     Value *F = CGM.getIntrinsic(Intrinsic::bswap, &ArgType, 1);
     205                2:     return RValue::get(Builder.CreateCall(F, ArgValue, "tmp"));
     206                 :   }
     207                 :   case Builtin::BI__builtin_object_size: {
     208                 :     // We pass this builtin onto the optimizer so that it can
     209                 :     // figure out the object size in more complex cases.
     210                 :     const llvm::Type *ResType[] = {
     211                 :       ConvertType(E->getType())
     212                3:     };
     213                 :     
     214                 :     // LLVM only supports 0 and 2, make sure that we pass along that
     215                 :     // as a boolean.
     216                3:     Value *Ty = EmitScalarExpr(E->getArg(1));
     217                3:     ConstantInt *CI = dyn_cast<ConstantInt>(Ty);
                        0: branch 0 not taken
                        3: branch 1 taken
     218                3:     assert(CI);
     219                3:     uint64_t val = CI->getZExtValue();
     220                3:     CI = ConstantInt::get(llvm::Type::getInt1Ty(VMContext), (val & 0x2) >> 1);    
     221                 :     
     222                3:     Value *F = CGM.getIntrinsic(Intrinsic::objectsize, ResType, 1);
     223                 :     return RValue::get(Builder.CreateCall2(F,
     224                 :                                            EmitScalarExpr(E->getArg(0)),
     225                3:                                            CI));
     226                 :   }
     227                 :   case Builtin::BI__builtin_prefetch: {
     228                3:     Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0));
     229                 :     // FIXME: Technically these constants should of type 'int', yes?
     230                 :     RW = (E->getNumArgs() > 1) ? EmitScalarExpr(E->getArg(1)) :
                        2: branch 1 taken
                        1: branch 2 taken
     231                3:       llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0);
     232                 :     Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) :
                        1: branch 1 taken
                        2: branch 2 taken
     233                3:       llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 3);
     234                3:     Value *F = CGM.getIntrinsic(Intrinsic::prefetch, 0, 0);
     235                3:     return RValue::get(Builder.CreateCall3(F, Address, RW, Locality));
     236                 :   }
     237                 :   case Builtin::BI__builtin_trap: {
     238                1:     Value *F = CGM.getIntrinsic(Intrinsic::trap, 0, 0);
     239                1:     return RValue::get(Builder.CreateCall(F));
     240                 :   }
     241                 :   case Builtin::BI__builtin_unreachable: {
                        0: branch 0 not taken
                        0: branch 1 not taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
     242                0:     if (CatchUndefined && HaveInsertPoint())
     243                0:       EmitBranch(getTrapBB());
     244                0:     Value *V = Builder.CreateUnreachable();
     245                0:     Builder.ClearInsertionPoint();
     246                0:     return RValue::get(V);
     247                 :   }
     248                 :       
     249                 :   case Builtin::BI__builtin_powi:
     250                 :   case Builtin::BI__builtin_powif:
     251                 :   case Builtin::BI__builtin_powil: {
     252                3:     Value *Base = EmitScalarExpr(E->getArg(0));
     253                3:     Value *Exponent = EmitScalarExpr(E->getArg(1));
     254                3:     const llvm::Type *ArgType = Base->getType();
     255                3:     Value *F = CGM.getIntrinsic(Intrinsic::powi, &ArgType, 1);
     256                3:     return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp"));
     257                 :   }
     258                 : 
     259                 :   case Builtin::BI__builtin_isgreater:
     260                 :   case Builtin::BI__builtin_isgreaterequal:
     261                 :   case Builtin::BI__builtin_isless:
     262                 :   case Builtin::BI__builtin_islessequal:
     263                 :   case Builtin::BI__builtin_islessgreater:
     264                 :   case Builtin::BI__builtin_isunordered: {
     265                 :     // Ordered comparisons: we know the arguments to these are matching scalar
     266                 :     // floating point values.
     267                7:     Value *LHS = EmitScalarExpr(E->getArg(0));
     268                7:     Value *RHS = EmitScalarExpr(E->getArg(1));
     269                 : 
                        0: branch 0 not taken
                        1: branch 1 taken
                        1: branch 2 taken
                        2: branch 3 taken
                        1: branch 4 taken
                        1: branch 5 taken
                        1: branch 6 taken
     270                7:     switch (BuiltinID) {
     271                0:     default: assert(0 && "Unknown ordered comparison");
     272                 :     case Builtin::BI__builtin_isgreater:
     273                1:       LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp");
     274                1:       break;
     275                 :     case Builtin::BI__builtin_isgreaterequal:
     276                1:       LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp");
     277                1:       break;
     278                 :     case Builtin::BI__builtin_isless:
     279                2:       LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp");
     280                2:       break;
     281                 :     case Builtin::BI__builtin_islessequal:
     282                1:       LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp");
     283                1:       break;
     284                 :     case Builtin::BI__builtin_islessgreater:
     285                1:       LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp");
     286                1:       break;
     287                 :     case Builtin::BI__builtin_isunordered:
     288                1:       LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp");
     289                 :       break;
     290                 :     }
     291                 :     // ZExt bool to int type.
     292                 :     return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType()),
     293                7:                                           "tmp"));
     294                 :   }
     295                 :   case Builtin::BI__builtin_isnan: {
     296                1:     Value *V = EmitScalarExpr(E->getArg(0));
     297                1:     V = Builder.CreateFCmpUNO(V, V, "cmp");
     298                1:     return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()), "tmp"));
     299                 :   }
     300                 :   case Builtin::BIalloca:
     301                 :   case Builtin::BI__builtin_alloca: {
     302                 :     // FIXME: LLVM IR Should allow alloca with an i64 size!
     303                1:     Value *Size = EmitScalarExpr(E->getArg(0));
     304                1:     Size = Builder.CreateIntCast(Size, llvm::Type::getInt32Ty(VMContext), false, "tmp");
     305                1:     return RValue::get(Builder.CreateAlloca(llvm::Type::getInt8Ty(VMContext), Size, "tmp"));
     306                 :   }
     307                 :   case Builtin::BIbzero:
     308                 :   case Builtin::BI__builtin_bzero: {
     309                1:     Value *Address = EmitScalarExpr(E->getArg(0));
     310                 :     Builder.CreateCall4(CGM.getMemSetFn(), Address,
     311                 :                         llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 0),
     312                 :                         EmitScalarExpr(E->getArg(1)),
     313                1:                         llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1));
     314                1:     return RValue::get(Address);
     315                 :   }
     316                 :   case Builtin::BImemcpy:
     317                 :   case Builtin::BI__builtin_memcpy: {
     318                2:     Value *Address = EmitScalarExpr(E->getArg(0));
     319                 :     Builder.CreateCall4(CGM.getMemCpyFn(), Address,
     320                 :                         EmitScalarExpr(E->getArg(1)),
     321                 :                         EmitScalarExpr(E->getArg(2)),
     322                2:                         llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1));
     323                2:     return RValue::get(Address);
     324                 :   }
     325                 :   case Builtin::BImemmove:
     326                 :   case Builtin::BI__builtin_memmove: {
     327                1:     Value *Address = EmitScalarExpr(E->getArg(0));
     328                 :     Builder.CreateCall4(CGM.getMemMoveFn(), Address,
     329                 :                         EmitScalarExpr(E->getArg(1)),
     330                 :                         EmitScalarExpr(E->getArg(2)),
     331                1:                         llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1));
     332                1:     return RValue::get(Address);
     333                 :   }
     334                 :   case Builtin::BImemset:
     335                 :   case Builtin::BI__builtin_memset: {
     336                1:     Value *Address = EmitScalarExpr(E->getArg(0));
     337                 :     Builder.CreateCall4(CGM.getMemSetFn(), Address,
     338                 :                         Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)),
     339                 :                                             llvm::Type::getInt8Ty(VMContext)),
     340                 :                         EmitScalarExpr(E->getArg(2)),
     341                1:                         llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1));
     342                1:     return RValue::get(Address);
     343                 :   }
     344                 :   case Builtin::BI__builtin_return_address: {
     345                2:     Value *Depth = EmitScalarExpr(E->getArg(0));
     346                 :     Depth = Builder.CreateIntCast(Depth,
     347                 :                                   llvm::Type::getInt32Ty(VMContext),
     348                2:                                   false, "tmp");
     349                2:     Value *F = CGM.getIntrinsic(Intrinsic::returnaddress, 0, 0);
     350                2:     return RValue::get(Builder.CreateCall(F, Depth));
     351                 :   }
     352                 :   case Builtin::BI__builtin_frame_address: {
     353                2:     Value *Depth = EmitScalarExpr(E->getArg(0));
     354                 :     Depth = Builder.CreateIntCast(Depth,
     355                 :                                   llvm::Type::getInt32Ty(VMContext),
     356                2:                                   false, "tmp");
     357                2:     Value *F = CGM.getIntrinsic(Intrinsic::frameaddress, 0, 0);
     358                2:     return RValue::get(Builder.CreateCall(F, Depth));
     359                 :   }
     360                 :   case Builtin::BI__builtin_extract_return_addr: {
     361                 :     // FIXME: There should be a target hook for this
     362                1:     return RValue::get(EmitScalarExpr(E->getArg(0)));
     363                 :   }
     364                 :   case Builtin::BI__builtin_unwind_init: {
     365                1:     Value *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init, 0, 0);
     366                1:     return RValue::get(Builder.CreateCall(F));
     367                 :   }
     368                 : #if 0
     369                 :   // FIXME: Finish/enable when LLVM backend support stabilizes
     370                 :   case Builtin::BI__builtin_setjmp: {
     371                 :     Value *Buf = EmitScalarExpr(E->getArg(0));
     372                 :     // Store the frame pointer to the buffer
     373                 :     Value *FrameAddrF = CGM.getIntrinsic(Intrinsic::frameaddress, 0, 0);
     374                 :     Value *FrameAddr =
     375                 :         Builder.CreateCall(FrameAddrF,
     376                 :                            Constant::getNullValue(llvm::Type::getInt32Ty(VMContext)));
     377                 :     Builder.CreateStore(FrameAddr, Buf);
     378                 :     // Call the setjmp intrinsic
     379                 :     Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp, 0, 0);
     380                 :     const llvm::Type *DestType = llvm::Type::getInt8PtrTy(VMContext);
     381                 :     Buf = Builder.CreateBitCast(Buf, DestType);
     382                 :     return RValue::get(Builder.CreateCall(F, Buf));
     383                 :   }
     384                 :   case Builtin::BI__builtin_longjmp: {
     385                 :     Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp, 0, 0);
     386                 :     Value *Buf = EmitScalarExpr(E->getArg(0));
     387                 :     const llvm::Type *DestType = llvm::Type::getInt8PtrTy(VMContext);
     388                 :     Buf = Builder.CreateBitCast(Buf, DestType);
     389                 :     return RValue::get(Builder.CreateCall(F, Buf));
     390                 :   }
     391                 : #endif
     392                 :   case Builtin::BI__sync_fetch_and_add:
     393                 :   case Builtin::BI__sync_fetch_and_sub:
     394                 :   case Builtin::BI__sync_fetch_and_or:
     395                 :   case Builtin::BI__sync_fetch_and_and:
     396                 :   case Builtin::BI__sync_fetch_and_xor:
     397                 :   case Builtin::BI__sync_add_and_fetch:
     398                 :   case Builtin::BI__sync_sub_and_fetch:
     399                 :   case Builtin::BI__sync_and_and_fetch:
     400                 :   case Builtin::BI__sync_or_and_fetch:
     401                 :   case Builtin::BI__sync_xor_and_fetch:
     402                 :   case Builtin::BI__sync_val_compare_and_swap:
     403                 :   case Builtin::BI__sync_bool_compare_and_swap:
     404                 :   case Builtin::BI__sync_lock_test_and_set:
     405                 :   case Builtin::BI__sync_lock_release:
     406                0:     assert(0 && "Shouldn't make it through sema");
     407                 :   case Builtin::BI__sync_fetch_and_add_1:
     408                 :   case Builtin::BI__sync_fetch_and_add_2:
     409                 :   case Builtin::BI__sync_fetch_and_add_4:
     410                 :   case Builtin::BI__sync_fetch_and_add_8:
     411                 :   case Builtin::BI__sync_fetch_and_add_16:
     412                1:     return EmitBinaryAtomic(*this, Intrinsic::atomic_load_add, E);
     413                 :   case Builtin::BI__sync_fetch_and_sub_1:
     414                 :   case Builtin::BI__sync_fetch_and_sub_2:
     415                 :   case Builtin::BI__sync_fetch_and_sub_4:
     416                 :   case Builtin::BI__sync_fetch_and_sub_8:
     417                 :   case Builtin::BI__sync_fetch_and_sub_16:
     418                1:     return EmitBinaryAtomic(*this, Intrinsic::atomic_load_sub, E);
     419                 :   case Builtin::BI__sync_fetch_and_or_1:
     420                 :   case Builtin::BI__sync_fetch_and_or_2:
     421                 :   case Builtin::BI__sync_fetch_and_or_4:
     422                 :   case Builtin::BI__sync_fetch_and_or_8:
     423                 :   case Builtin::BI__sync_fetch_and_or_16:
     424                1:     return EmitBinaryAtomic(*this, Intrinsic::atomic_load_or, E);
     425                 :   case Builtin::BI__sync_fetch_and_and_1:
     426                 :   case Builtin::BI__sync_fetch_and_and_2:
     427                 :   case Builtin::BI__sync_fetch_and_and_4:
     428                 :   case Builtin::BI__sync_fetch_and_and_8:
     429                 :   case Builtin::BI__sync_fetch_and_and_16:
     430                1:     return EmitBinaryAtomic(*this, Intrinsic::atomic_load_and, E);
     431                 :   case Builtin::BI__sync_fetch_and_xor_1:
     432                 :   case Builtin::BI__sync_fetch_and_xor_2:
     433                 :   case Builtin::BI__sync_fetch_and_xor_4:
     434                 :   case Builtin::BI__sync_fetch_and_xor_8:
     435                 :   case Builtin::BI__sync_fetch_and_xor_16:
     436                1:     return EmitBinaryAtomic(*this, Intrinsic::atomic_load_xor, E);
     437                 :   case Builtin::BI__sync_fetch_and_nand_1:
     438                 :   case Builtin::BI__sync_fetch_and_nand_2:
     439                 :   case Builtin::BI__sync_fetch_and_nand_4:
     440                 :   case Builtin::BI__sync_fetch_and_nand_8:
     441                 :   case Builtin::BI__sync_fetch_and_nand_16:
     442                1:     return EmitBinaryAtomic(*this, Intrinsic::atomic_load_nand, E);
     443                 : 
     444                 :   // Clang extensions: not overloaded yet.
     445                 :   case Builtin::BI__sync_fetch_and_min:
     446                1:     return EmitBinaryAtomic(*this, Intrinsic::atomic_load_min, E);
     447                 :   case Builtin::BI__sync_fetch_and_max:
     448                1:     return EmitBinaryAtomic(*this, Intrinsic::atomic_load_max, E);
     449                 :   case Builtin::BI__sync_fetch_and_umin:
     450                1:     return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umin, E);
     451                 :   case Builtin::BI__sync_fetch_and_umax:
     452                1:     return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umax, E);
     453                 : 
     454                 :   case Builtin::BI__sync_add_and_fetch_1:
     455                 :   case Builtin::BI__sync_add_and_fetch_2:
     456                 :   case Builtin::BI__sync_add_and_fetch_4:
     457                 :   case Builtin::BI__sync_add_and_fetch_8:
     458                 :   case Builtin::BI__sync_add_and_fetch_16:
     459                 :     return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_add, E,
     460                1:                                 llvm::Instruction::Add);
     461                 :   case Builtin::BI__sync_sub_and_fetch_1:
     462                 :   case Builtin::BI__sync_sub_and_fetch_2:
     463                 :   case Builtin::BI__sync_sub_and_fetch_4:
     464                 :   case Builtin::BI__sync_sub_and_fetch_8:
     465                 :   case Builtin::BI__sync_sub_and_fetch_16:
     466                 :     return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_sub, E,
     467                1:                                 llvm::Instruction::Sub);
     468                 :   case Builtin::BI__sync_and_and_fetch_1:
     469                 :   case Builtin::BI__sync_and_and_fetch_2:
     470                 :   case Builtin::BI__sync_and_and_fetch_4:
     471                 :   case Builtin::BI__sync_and_and_fetch_8:
     472                 :   case Builtin::BI__sync_and_and_fetch_16:
     473                 :     return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_and, E,
     474                1:                                 llvm::Instruction::And);
     475                 :   case Builtin::BI__sync_or_and_fetch_1:
     476                 :   case Builtin::BI__sync_or_and_fetch_2:
     477                 :   case Builtin::BI__sync_or_and_fetch_4:
     478                 :   case Builtin::BI__sync_or_and_fetch_8:
     479                 :   case Builtin::BI__sync_or_and_fetch_16:
     480                 :     return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_or, E,
     481                1:                                 llvm::Instruction::Or);
     482                 :   case Builtin::BI__sync_xor_and_fetch_1:
     483                 :   case Builtin::BI__sync_xor_and_fetch_2:
     484                 :   case Builtin::BI__sync_xor_and_fetch_4:
     485                 :   case Builtin::BI__sync_xor_and_fetch_8:
     486                 :   case Builtin::BI__sync_xor_and_fetch_16:
     487                 :     return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_xor, E,
     488                1:                                 llvm::Instruction::Xor);
     489                 :   case Builtin::BI__sync_nand_and_fetch_1:
     490                 :   case Builtin::BI__sync_nand_and_fetch_2:
     491                 :   case Builtin::BI__sync_nand_and_fetch_4:
     492                 :   case Builtin::BI__sync_nand_and_fetch_8:
     493                 :   case Builtin::BI__sync_nand_and_fetch_16:
     494                 :     return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_nand, E,
     495                1:                                 llvm::Instruction::And);
     496                 : 
     497                 :   case Builtin::BI__sync_val_compare_and_swap_1:
     498                 :   case Builtin::BI__sync_val_compare_and_swap_2:
     499                 :   case Builtin::BI__sync_val_compare_and_swap_4:
     500                 :   case Builtin::BI__sync_val_compare_and_swap_8:
     501                 :   case Builtin::BI__sync_val_compare_and_swap_16:
     502                 :   {
     503                 :     const llvm::Type *ResType[2];
     504                2:     ResType[0]= ConvertType(E->getType());
     505                2:     ResType[1] = ConvertType(E->getArg(0)->getType());
     506                2:     Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap, ResType, 2);
     507                 :     return RValue::get(Builder.CreateCall3(AtomF,
     508                 :                                            EmitScalarExpr(E->getArg(0)),
     509                 :                                            EmitScalarExpr(E->getArg(1)),
     510                2:                                            EmitScalarExpr(E->getArg(2))));
     511                 :   }
     512                 : 
     513                 :   case Builtin::BI__sync_bool_compare_and_swap_1:
     514                 :   case Builtin::BI__sync_bool_compare_and_swap_2:
     515                 :   case Builtin::BI__sync_bool_compare_and_swap_4:
     516                 :   case Builtin::BI__sync_bool_compare_and_swap_8:
     517                 :   case Builtin::BI__sync_bool_compare_and_swap_16:
     518                 :   {
     519                 :     const llvm::Type *ResType[2];
     520                1:     ResType[0]= ConvertType(E->getArg(1)->getType());
     521                1:     ResType[1] = llvm::PointerType::getUnqual(ResType[0]);
     522                1:     Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap, ResType, 2);
     523                1:     Value *OldVal = EmitScalarExpr(E->getArg(1));
     524                 :     Value *PrevVal = Builder.CreateCall3(AtomF,
     525                 :                                         EmitScalarExpr(E->getArg(0)),
     526                 :                                         OldVal,
     527                1:                                         EmitScalarExpr(E->getArg(2)));
     528                1:     Value *Result = Builder.CreateICmpEQ(PrevVal, OldVal);
     529                 :     // zext bool to int.
     530                1:     return RValue::get(Builder.CreateZExt(Result, ConvertType(E->getType())));
     531                 :   }
     532                 : 
     533                 :   case Builtin::BI__sync_lock_test_and_set_1:
     534                 :   case Builtin::BI__sync_lock_test_and_set_2:
     535                 :   case Builtin::BI__sync_lock_test_and_set_4:
     536                 :   case Builtin::BI__sync_lock_test_and_set_8:
     537                 :   case Builtin::BI__sync_lock_test_and_set_16:
     538                1:     return EmitBinaryAtomic(*this, Intrinsic::atomic_swap, E);
     539                 :   case Builtin::BI__sync_lock_release_1:
     540                 :   case Builtin::BI__sync_lock_release_2:
     541                 :   case Builtin::BI__sync_lock_release_4:
     542                 :   case Builtin::BI__sync_lock_release_8:
     543                 :   case Builtin::BI__sync_lock_release_16: {
     544                1:     Value *Ptr = EmitScalarExpr(E->getArg(0));
     545                 :     const llvm::Type *ElTy =
     546                1:       cast<llvm::PointerType>(Ptr->getType())->getElementType();
     547                 :     llvm::StoreInst *Store = 
     548                1:       Builder.CreateStore(llvm::Constant::getNullValue(ElTy), Ptr);
     549                1:     Store->setVolatile(true);
     550                1:     return RValue::get(0);
     551                 :   }
     552                 : 
     553                 :   case Builtin::BI__sync_synchronize: {
     554                 :     Value *C[5];
     555                1:     C[0] = C[1] = C[2] = C[3] = llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 1);
     556                1:     C[4] = llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0);
     557                1:     Builder.CreateCall(CGM.getIntrinsic(Intrinsic::memory_barrier), C, C + 5);
     558                1:     return RValue::get(0);
     559                 :   }
     560                 : 
     561                 :   case Builtin::BI__builtin_llvm_memory_barrier: {
     562                 :     Value *C[5] = {
     563                 :       EmitScalarExpr(E->getArg(0)),
     564                 :       EmitScalarExpr(E->getArg(1)),
     565                 :       EmitScalarExpr(E->getArg(2)),
     566                 :       EmitScalarExpr(E->getArg(3)),
     567                 :       EmitScalarExpr(E->getArg(4))
     568                0:     };
     569                0:     Builder.CreateCall(CGM.getIntrinsic(Intrinsic::memory_barrier), C, C + 5);
     570                0:     return RValue::get(0);
     571                 :   }
     572                 :       
     573                 :     // Library functions with special handling.
     574                 :   case Builtin::BIsqrt:
     575                 :   case Builtin::BIsqrtf:
     576                 :   case Builtin::BIsqrtl: {
     577                 :     // Rewrite sqrt to intrinsic if allowed.
                        4: branch 1 taken
                        2: branch 2 taken
     578                6:     if (!FD->hasAttr<ConstAttr>())
     579                2:       break;
     580                4:     Value *Arg0 = EmitScalarExpr(E->getArg(0));
     581                4:     const llvm::Type *ArgType = Arg0->getType();
     582                4:     Value *F = CGM.getIntrinsic(Intrinsic::sqrt, &ArgType, 1);
     583                4:     return RValue::get(Builder.CreateCall(F, Arg0, "tmp"));
     584                 :   }
     585                 : 
     586                 :   case Builtin::BIpow:
     587                 :   case Builtin::BIpowf:
     588                 :   case Builtin::BIpowl: {
     589                 :     // Rewrite sqrt to intrinsic if allowed.
                        3: branch 1 taken
                        3: branch 2 taken
     590                6:     if (!FD->hasAttr<ConstAttr>())
     591                3:       break;
     592                3:     Value *Base = EmitScalarExpr(E->getArg(0));
     593                3:     Value *Exponent = EmitScalarExpr(E->getArg(1));
     594                3:     const llvm::Type *ArgType = Base->getType();
     595                3:     Value *F = CGM.getIntrinsic(Intrinsic::pow, &ArgType, 1);
     596                3:     return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp"));
     597                 :   }
     598                 :   }
     599                 : 
     600                 :   // If this is an alias for a libm function (e.g. __builtin_sin) turn it into
     601                 :   // that function.
                      639: branch 2 taken
                       26: branch 3 taken
                      388: branch 6 taken
                      251: branch 7 taken
                      414: branch 8 taken
                      251: branch 9 taken
     602              665:   if (getContext().BuiltinInfo.isLibFunction(BuiltinID) ||
     603                 :       getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID))
     604                 :     return EmitCall(E->getCallee()->getType(),
     605                 :                     CGM.getBuiltinLibFunction(FD, BuiltinID),
     606                 :                     ReturnValueSlot(),
     607              414:                     E->arg_begin(), E->arg_end());
     608                 : 
     609                 :   // See if we have a target specific intrinsic.
     610              251:   const char *Name = getContext().BuiltinInfo.GetName(BuiltinID);
     611              251:   Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic;
                      251: branch 0 taken
                        0: branch 1 not taken
     612              251:   if (const char *Prefix =
     613              251:       llvm::Triple::getArchTypePrefix(Target.getTriple().getArch()))
     614              251:     IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix, Name);
     615                 : 
                      208: branch 0 taken
                       43: branch 1 taken
     616              251:   if (IntrinsicID != Intrinsic::not_intrinsic) {
     617              208:     SmallVector<Value*, 16> Args;
     618                 : 
     619              208:     Function *F = CGM.getIntrinsic(IntrinsicID);
     620              208:     const llvm::FunctionType *FTy = F->getFunctionType();
     621                 : 
                      371: branch 1 taken
                      208: branch 2 taken
     622              579:     for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
     623              371:       Value *ArgValue = EmitScalarExpr(E->getArg(i));
     624                 : 
     625                 :       // If the intrinsic arg type is different from the builtin arg type
     626                 :       // we need to do a bit cast.
     627              371:       const llvm::Type *PTy = FTy->getParamType(i);
                       17: branch 1 taken
                      354: branch 2 taken
     628              371:       if (PTy != ArgValue->getType()) {
     629                 :         assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) &&
                       17: branch 2 taken
                        0: branch 3 not taken
     630               17:                "Must be able to losslessly bit cast to param");
     631               17:         ArgValue = Builder.CreateBitCast(ArgValue, PTy);
     632                 :       }
     633                 : 
     634              371:       Args.push_back(ArgValue);
     635                 :     }
     636                 : 
     637              208:     Value *V = Builder.CreateCall(F, Args.data(), Args.data() + Args.size());
     638              208:     QualType BuiltinRetType = E->getType();
     639                 : 
     640              208:     const llvm::Type *RetTy = llvm::Type::getVoidTy(VMContext);
                      190: branch 2 taken
                       18: branch 3 taken
     641              208:     if (!BuiltinRetType->isVoidType()) RetTy = ConvertType(BuiltinRetType);
     642                 : 
                        9: branch 1 taken
                      199: branch 2 taken
     643              208:     if (RetTy != V->getType()) {
     644                 :       assert(V->getType()->canLosslesslyBitCastTo(RetTy) &&
                        9: branch 2 taken
                        0: branch 3 not taken
     645                9:              "Must be able to losslessly bit cast result type");
     646                9:       V = Builder.CreateBitCast(V, RetTy);
     647                 :     }
     648                 : 
     649              208:     return RValue::get(V);
     650                 :   }
     651                 : 
     652                 :   // See if we have a target specific builtin that needs to be lowered.
                       43: branch 1 taken
                        0: branch 2 not taken
     653               43:   if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E))
     654               43:     return RValue::get(V);
     655                 : 
     656                0:   ErrorUnsupported(E, "builtin function");
     657                 : 
     658                 :   // Unknown builtin, for now just dump it out and return undef.
                        0: branch 2 not taken
                        0: branch 3 not taken
     659                0:   if (hasAggregateLLVMType(E->getType()))
     660                0:     return RValue::getAggregate(CreateMemTemp(E->getType()));
     661                0:   return RValue::get(llvm::UndefValue::get(ConvertType(E->getType())));
     662                 : }
     663                 : 
     664                 : Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID,
     665               43:                                               const CallExpr *E) {
                       43: branch 2 taken
                        0: branch 3 not taken
                        0: branch 4 not taken
     666               43:   switch (Target.getTriple().getArch()) {
     667                 :   case llvm::Triple::x86:
     668                 :   case llvm::Triple::x86_64:
     669               43:     return EmitX86BuiltinExpr(BuiltinID, E);
     670                 :   case llvm::Triple::ppc:
     671                 :   case llvm::Triple::ppc64:
     672                0:     return EmitPPCBuiltinExpr(BuiltinID, E);
     673                 :   default:
     674                0:     return 0;
     675                 :   }
     676                 : }
     677                 : 
     678                 : Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
     679               43:                                            const CallExpr *E) {
     680                 : 
     681               43:   llvm::SmallVector<Value*, 4> Ops;
     682                 : 
                      122: branch 1 taken
                       43: branch 2 taken
     683              165:   for (unsigned i = 0, e = E->getNumArgs(); i != e; i++)
     684              122:     Ops.push_back(EmitScalarExpr(E->getArg(i)));
     685                 : 
                        0: branch 0 not taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                        8: branch 3 taken
                        8: branch 4 taken
                        1: branch 5 taken
                        1: branch 6 taken
                        8: branch 7 taken
                        8: branch 8 taken
                        2: branch 9 taken
                        2: branch 10 taken
                        5: branch 11 taken
     686               43:   switch (BuiltinID) {
     687                0:   default: return 0;
     688                 :   case X86::BI__builtin_ia32_pslldi128:
     689                 :   case X86::BI__builtin_ia32_psllqi128:
     690                 :   case X86::BI__builtin_ia32_psllwi128:
     691                 :   case X86::BI__builtin_ia32_psradi128:
     692                 :   case X86::BI__builtin_ia32_psrawi128:
     693                 :   case X86::BI__builtin_ia32_psrldi128:
     694                 :   case X86::BI__builtin_ia32_psrlqi128:
     695                 :   case X86::BI__builtin_ia32_psrlwi128: {
     696                0:     Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::getInt64Ty(VMContext), "zext");
     697                0:     const llvm::Type *Ty = llvm::VectorType::get(llvm::Type::getInt64Ty(VMContext), 2);
     698                0:     llvm::Value *Zero = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0);
     699                 :     Ops[1] = Builder.CreateInsertElement(llvm::UndefValue::get(Ty),
     700                0:                                          Ops[1], Zero, "insert");
     701                0:     Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType(), "bitcast");
     702                0:     const char *name = 0;
     703                0:     Intrinsic::ID ID = Intrinsic::not_intrinsic;
     704                 : 
                        0: branch 0 not taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
     705                0:     switch (BuiltinID) {
     706                0:     default: assert(0 && "Unsupported shift intrinsic!");
     707                 :     case X86::BI__builtin_ia32_pslldi128:
     708                0:       name = "pslldi";
     709                0:       ID = Intrinsic::x86_sse2_psll_d;
     710                0:       break;
     711                 :     case X86::BI__builtin_ia32_psllqi128:
     712                0:       name = "psllqi";
     713                0:       ID = Intrinsic::x86_sse2_psll_q;
     714                0:       break;
     715                 :     case X86::BI__builtin_ia32_psllwi128:
     716                0:       name = "psllwi";
     717                0:       ID = Intrinsic::x86_sse2_psll_w;
     718                0:       break;
     719                 :     case X86::BI__builtin_ia32_psradi128:
     720                0:       name = "psradi";
     721                0:       ID = Intrinsic::x86_sse2_psra_d;
     722                0:       break;
     723                 :     case X86::BI__builtin_ia32_psrawi128:
     724                0:       name = "psrawi";
     725                0:       ID = Intrinsic::x86_sse2_psra_w;
     726                0:       break;
     727                 :     case X86::BI__builtin_ia32_psrldi128:
     728                0:       name = "psrldi";
     729                0:       ID = Intrinsic::x86_sse2_psrl_d;
     730                0:       break;
     731                 :     case X86::BI__builtin_ia32_psrlqi128:
     732                0:       name = "psrlqi";
     733                0:       ID = Intrinsic::x86_sse2_psrl_q;
     734                0:       break;
     735                 :     case X86::BI__builtin_ia32_psrlwi128:
     736                0:       name = "psrlwi";
     737                0:       ID = Intrinsic::x86_sse2_psrl_w;
     738                 :       break;
     739                 :     }
     740                0:     llvm::Function *F = CGM.getIntrinsic(ID);
     741                0:     return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
     742                 :   }
     743                 :   case X86::BI__builtin_ia32_pslldi:
     744                 :   case X86::BI__builtin_ia32_psllqi:
     745                 :   case X86::BI__builtin_ia32_psllwi:
     746                 :   case X86::BI__builtin_ia32_psradi:
     747                 :   case X86::BI__builtin_ia32_psrawi:
     748                 :   case X86::BI__builtin_ia32_psrldi:
     749                 :   case X86::BI__builtin_ia32_psrlqi:
     750                 :   case X86::BI__builtin_ia32_psrlwi: {
     751                0:     Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::getInt64Ty(VMContext), "zext");
     752                0:     const llvm::Type *Ty = llvm::VectorType::get(llvm::Type::getInt64Ty(VMContext), 1);
     753                0:     Ops[1] = Builder.CreateBitCast(Ops[1], Ty, "bitcast");
     754                0:     const char *name = 0;
     755                0:     Intrinsic::ID ID = Intrinsic::not_intrinsic;
     756                 : 
                        0: branch 0 not taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
     757                0:     switch (BuiltinID) {
     758                0:     default: assert(0 && "Unsupported shift intrinsic!");
     759                 :     case X86::BI__builtin_ia32_pslldi:
     760                0:       name = "pslldi";
     761                0:       ID = Intrinsic::x86_mmx_psll_d;
     762                0:       break;
     763                 :     case X86::BI__builtin_ia32_psllqi:
     764                0:       name = "psllqi";
     765                0:       ID = Intrinsic::x86_mmx_psll_q;
     766                0:       break;
     767                 :     case X86::BI__builtin_ia32_psllwi:
     768                0:       name = "psllwi";
     769                0:       ID = Intrinsic::x86_mmx_psll_w;
     770                0:       break;
     771                 :     case X86::BI__builtin_ia32_psradi:
     772                0:       name = "psradi";
     773                0:       ID = Intrinsic::x86_mmx_psra_d;
     774                0:       break;
     775                 :     case X86::BI__builtin_ia32_psrawi:
     776                0:       name = "psrawi";
     777                0:       ID = Intrinsic::x86_mmx_psra_w;
     778                0:       break;
     779                 :     case X86::BI__builtin_ia32_psrldi:
     780                0:       name = "psrldi";
     781                0:       ID = Intrinsic::x86_mmx_psrl_d;
     782                0:       break;
     783                 :     case X86::BI__builtin_ia32_psrlqi:
     784                0:       name = "psrlqi";
     785                0:       ID = Intrinsic::x86_mmx_psrl_q;
     786                0:       break;
     787                 :     case X86::BI__builtin_ia32_psrlwi:
     788                0:       name = "psrlwi";
     789                0:       ID = Intrinsic::x86_mmx_psrl_w;
     790                 :       break;
     791                 :     }
     792                0:     llvm::Function *F = CGM.getIntrinsic(ID);
     793                0:     return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
     794                 :   }
     795                 :   case X86::BI__builtin_ia32_cmpps: {
     796                8:     llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ps);
     797                8:     return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpps");
     798                 :   }
     799                 :   case X86::BI__builtin_ia32_cmpss: {
     800                8:     llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ss);
     801                8:     return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpss");
     802                 :   }
     803                 :   case X86::BI__builtin_ia32_ldmxcsr: {
     804                1:     const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext);
     805                1:     Value *One = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1);
     806                1:     Value *Tmp = Builder.CreateAlloca(llvm::Type::getInt32Ty(VMContext), One, "tmp");
     807                1:     Builder.CreateStore(Ops[0], Tmp);
     808                 :     return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr),
     809                1:                               Builder.CreateBitCast(Tmp, PtrTy));
     810                 :   }
     811                 :   case X86::BI__builtin_ia32_stmxcsr: {
     812                1:     const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext);
     813                1:     Value *One = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1);
     814                1:     Value *Tmp = Builder.CreateAlloca(llvm::Type::getInt32Ty(VMContext), One, "tmp");
     815                 :     One = Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr),
     816                1:                              Builder.CreateBitCast(Tmp, PtrTy));
     817                1:     return Builder.CreateLoad(Tmp, "stmxcsr");
     818                 :   }
     819                 :   case X86::BI__builtin_ia32_cmppd: {
     820                8:     llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_pd);
     821                8:     return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmppd");
     822                 :   }
     823                 :   case X86::BI__builtin_ia32_cmpsd: {
     824                8:     llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_sd);
     825                8:     return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "cmpsd");
     826                 :   }
     827                 :   case X86::BI__builtin_ia32_storehps:
     828                 :   case X86::BI__builtin_ia32_storelps: {
     829                2:     const llvm::Type *EltTy = llvm::Type::getInt64Ty(VMContext);
     830                2:     llvm::Type *PtrTy = llvm::PointerType::getUnqual(EltTy);
     831                2:     llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2);
     832                 : 
     833                 :     // cast val v2i64
     834                2:     Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast");
     835                 : 
     836                 :     // extract (0, 1)
     837                2:     unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1;
     838                2:     llvm::Value *Idx = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Index);
     839                2:     Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract");
     840                 : 
     841                 :     // cast pointer to i64 & store
     842                2:     Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy);
     843                2:     return Builder.CreateStore(Ops[1], Ops[0]);
     844                 :   }
     845                 :   case X86::BI__builtin_ia32_palignr: {
     846                2:     Function *F = CGM.getIntrinsic(Intrinsic::x86_ssse3_palign_r);
     847                2:     return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size());
     848                 :   }
     849                 :   case X86::BI__builtin_ia32_palignr128: {
     850                5:     unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();
     851                 :     
     852                 :     // If palignr is shifting the pair of input vectors less than 17 bytes,
     853                 :     // emit a shuffle instruction.
                        2: branch 0 taken
                        3: branch 1 taken
     854                5:     if (shiftVal <= 16) {
     855                2:       const llvm::Type *IntTy = llvm::Type::getInt32Ty(VMContext);
     856                 : 
     857                2:       llvm::SmallVector<llvm::Constant*, 16> Indices;
                       32: branch 0 taken
                        2: branch 1 taken
     858               34:       for (unsigned i = 0; i != 16; ++i)
     859               32:         Indices.push_back(llvm::ConstantInt::get(IntTy, shiftVal + i));
     860                 :       
     861                2:       Value* SV = llvm::ConstantVector::get(Indices.begin(), Indices.size());
     862                2:       return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr");
     863                 :     }
     864                 :     
     865                 :     // If palignr is shifting the pair of input vectors more than 16 but less
     866                 :     // than 32 bytes, emit a logical right shift of the destination.
                        1: branch 0 taken
                        2: branch 1 taken
     867                3:     if (shiftVal < 32) {
     868                1:       const llvm::Type *EltTy = llvm::Type::getInt64Ty(VMContext);
     869                1:       const llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2);
     870                1:       const llvm::Type *IntTy = llvm::Type::getInt32Ty(VMContext);
     871                 :       
     872                1:       Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast");
     873                1:       Ops[1] = llvm::ConstantInt::get(IntTy, (shiftVal-16) * 8);
     874                 :       
     875                 :       // create i32 constant
     876                1:       llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_psrl_dq);
     877                1:       return Builder.CreateCall(F, &Ops[0], &Ops[0] + 2, "palignr");
     878                 :     }
     879                 :     
     880                 :     // If palignr is shifting the pair of vectors more than 32 bytes, emit zero.
     881                2:     return llvm::Constant::getNullValue(ConvertType(E->getType()));
     882                 :   }
     883               43:   }
     884                 : }
     885                 : 
     886                 : Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
     887                0:                                            const CallExpr *E) {
     888                0:   return 0;
     889                 : }

Generated: 2010-02-10 01:31 by zcov