CGBuiltin.cpp revision c5004516489c931cf839bdbdde5a76e4074cc888
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/ASTContext.h" 18#include "clang/AST/Builtins.h" 19#include "clang/AST/Expr.h" 20#include "clang/AST/TargetBuiltins.h" 21#include "llvm/Constants.h" 22#include "llvm/Function.h" 23#include "llvm/Intrinsics.h" 24using namespace clang; 25using namespace CodeGen; 26using namespace llvm; 27 28/// Utility to insert an atomic instruction based Instrinsic::ID and 29// the expression node 30static RValue EmitBinaryAtomic(CodeGenFunction& CFG, 31 Intrinsic::ID Id, const CallExpr *E) { 32 const llvm::Type *ResType[2]; 33 ResType[0] = CFG.ConvertType(E->getType()); 34 ResType[1] = CFG.ConvertType(E->getArg(0)->getType()); 35 Value *AtomF = CFG.CGM.getIntrinsic(Id, ResType, 2); 36 return RValue::get(CFG.Builder.CreateCall2(AtomF, 37 CFG.EmitScalarExpr(E->getArg(0)), 38 CFG.EmitScalarExpr(E->getArg(1)))); 39} 40 41RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { 42 switch (BuiltinID) { 43 default: break; // Handle intrinsics and libm functions below. 44 45 case Builtin::BI__builtin___CFStringMakeConstantString: { 46 const Expr *Arg = E->getArg(0); 47 48 while (1) { 49 if (const ParenExpr *PE = dyn_cast<ParenExpr>(Arg)) 50 Arg = PE->getSubExpr(); 51 else if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(Arg)) 52 Arg = CE->getSubExpr(); 53 else 54 break; 55 } 56 57 const StringLiteral *Literal = cast<StringLiteral>(Arg); 58 std::string S(Literal->getStrData(), Literal->getByteLength()); 59 60 return RValue::get(CGM.GetAddrOfConstantCFString(S)); 61 } 62 case Builtin::BI__builtin_stdarg_start: 63 case Builtin::BI__builtin_va_start: 64 case Builtin::BI__builtin_va_end: { 65 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 66 const llvm::Type *DestType = 67 llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 68 if (ArgValue->getType() != DestType) 69 ArgValue = Builder.CreateBitCast(ArgValue, DestType, 70 ArgValue->getNameStart()); 71 72 Intrinsic::ID inst = (BuiltinID == Builtin::BI__builtin_va_end) ? 73 Intrinsic::vaend : Intrinsic::vastart; 74 return RValue::get(Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue)); 75 } 76 case Builtin::BI__builtin_va_copy: { 77 // FIXME: This does not yet handle architectures where va_list is a struct. 78 Value *DstPtr = EmitScalarExpr(E->getArg(0)); 79 Value *SrcValue = EmitScalarExpr(E->getArg(1)); 80 81 Value *SrcPtr = CreateTempAlloca(SrcValue->getType(), "dst_ptr"); 82 83 Builder.CreateStore(SrcValue, SrcPtr, false); 84 85 const llvm::Type *Type = 86 llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 87 88 DstPtr = Builder.CreateBitCast(DstPtr, Type); 89 SrcPtr = Builder.CreateBitCast(SrcPtr, Type); 90 return RValue::get(Builder.CreateCall2(CGM.getIntrinsic(Intrinsic::vacopy), 91 DstPtr, SrcPtr)); 92 } 93 case Builtin::BI__builtin_classify_type: { 94 APSInt Result(32); 95 if (!E->isBuiltinClassifyType(Result)) 96 assert(0 && "Expr not __builtin_classify_type!"); 97 return RValue::get(ConstantInt::get(Result)); 98 } 99 case Builtin::BI__builtin_constant_p: { 100 APSInt Result(32); 101 // FIXME: Analyze the parameter and check if it is a constant. 102 Result = 0; 103 return RValue::get(ConstantInt::get(Result)); 104 } 105 case Builtin::BI__builtin_abs: { 106 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 107 108 Value *NegOp = Builder.CreateNeg(ArgValue, "neg"); 109 Value *CmpResult = 110 Builder.CreateICmpSGE(ArgValue, Constant::getNullValue(ArgValue->getType()), 111 "abscond"); 112 Value *Result = 113 Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs"); 114 115 return RValue::get(Result); 116 } 117 case Builtin::BI__builtin_ctz: 118 case Builtin::BI__builtin_ctzl: 119 case Builtin::BI__builtin_ctzll: { 120 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 121 122 const llvm::Type *ArgType = ArgValue->getType(); 123 Value *F = CGM.getIntrinsic(Intrinsic::cttz, &ArgType, 1); 124 125 const llvm::Type *ResultType = ConvertType(E->getType()); 126 Value *Result = Builder.CreateCall(F, ArgValue, "tmp"); 127 if (Result->getType() != ResultType) 128 Result = Builder.CreateIntCast(Result, ResultType, "cast"); 129 return RValue::get(Result); 130 } 131 case Builtin::BI__builtin_clz: 132 case Builtin::BI__builtin_clzl: 133 case Builtin::BI__builtin_clzll: { 134 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 135 136 const llvm::Type *ArgType = ArgValue->getType(); 137 Value *F = CGM.getIntrinsic(Intrinsic::ctlz, &ArgType, 1); 138 139 const llvm::Type *ResultType = ConvertType(E->getType()); 140 Value *Result = Builder.CreateCall(F, ArgValue, "tmp"); 141 if (Result->getType() != ResultType) 142 Result = Builder.CreateIntCast(Result, ResultType, "cast"); 143 return RValue::get(Result); 144 } 145 case Builtin::BI__builtin_ffs: 146 case Builtin::BI__builtin_ffsl: 147 case Builtin::BI__builtin_ffsll: { 148 // ffs(x) -> x ? cttz(x) + 1 : 0 149 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 150 151 const llvm::Type *ArgType = ArgValue->getType(); 152 Value *F = CGM.getIntrinsic(Intrinsic::cttz, &ArgType, 1); 153 154 const llvm::Type *ResultType = ConvertType(E->getType()); 155 Value *Tmp = Builder.CreateAdd(Builder.CreateCall(F, ArgValue, "tmp"), 156 ConstantInt::get(ArgType, 1), "tmp"); 157 Value *Zero = llvm::Constant::getNullValue(ArgType); 158 Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero"); 159 Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp, "ffs"); 160 if (Result->getType() != ResultType) 161 Result = Builder.CreateIntCast(Result, ResultType, "cast"); 162 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 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 169 170 const llvm::Type *ArgType = ArgValue->getType(); 171 Value *F = CGM.getIntrinsic(Intrinsic::ctpop, &ArgType, 1); 172 173 const llvm::Type *ResultType = ConvertType(E->getType()); 174 Value *Tmp = Builder.CreateCall(F, ArgValue, "tmp"); 175 Value *Result = Builder.CreateAnd(Tmp, ConstantInt::get(ArgType, 1), 176 "tmp"); 177 if (Result->getType() != ResultType) 178 Result = Builder.CreateIntCast(Result, ResultType, "cast"); 179 return RValue::get(Result); 180 } 181 case Builtin::BI__builtin_popcount: 182 case Builtin::BI__builtin_popcountl: 183 case Builtin::BI__builtin_popcountll: { 184 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 185 186 const llvm::Type *ArgType = ArgValue->getType(); 187 Value *F = CGM.getIntrinsic(Intrinsic::ctpop, &ArgType, 1); 188 189 const llvm::Type *ResultType = ConvertType(E->getType()); 190 Value *Result = Builder.CreateCall(F, ArgValue, "tmp"); 191 if (Result->getType() != ResultType) 192 Result = Builder.CreateIntCast(Result, ResultType, "cast"); 193 return RValue::get(Result); 194 } 195 case Builtin::BI__builtin_expect: 196 // FIXME: pass expect through to LLVM 197 return RValue::get(EmitScalarExpr(E->getArg(0))); 198 case Builtin::BI__builtin_bswap32: 199 case Builtin::BI__builtin_bswap64: { 200 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 201 const llvm::Type *ArgType = ArgValue->getType(); 202 Value *F = CGM.getIntrinsic(Intrinsic::bswap, &ArgType, 1); 203 return RValue::get(Builder.CreateCall(F, ArgValue, "tmp")); 204 } 205 case Builtin::BI__builtin_prefetch: { 206 Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0)); 207 // FIXME: Technically these constants should of type 'int', yes? 208 RW = (E->getNumArgs() > 1) ? EmitScalarExpr(E->getArg(1)) : 209 ConstantInt::get(llvm::Type::Int32Ty, 0); 210 Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : 211 ConstantInt::get(llvm::Type::Int32Ty, 3); 212 Value *F = CGM.getIntrinsic(Intrinsic::prefetch, 0, 0); 213 return RValue::get(Builder.CreateCall3(F, Address, RW, Locality)); 214 } 215 case Builtin::BI__builtin_trap: { 216 Value *F = CGM.getIntrinsic(Intrinsic::trap, 0, 0); 217 return RValue::get(Builder.CreateCall(F)); 218 } 219 220 case Builtin::BI__builtin_huge_val: 221 case Builtin::BI__builtin_huge_valf: 222 case Builtin::BI__builtin_huge_vall: 223 case Builtin::BI__builtin_inf: 224 case Builtin::BI__builtin_inff: 225 case Builtin::BI__builtin_infl: { 226 const llvm::fltSemantics &Sem = 227 CGM.getContext().getFloatTypeSemantics(E->getType()); 228 return RValue::get(ConstantFP::get(APFloat::getInf(Sem))); 229 } 230 case Builtin::BI__builtin_nan: 231 case Builtin::BI__builtin_nanf: 232 case Builtin::BI__builtin_nanl: { 233 // If this is __builtin_nan("") turn this into a simple nan, otherwise just 234 // call libm nan. 235 if (const StringLiteral *S = 236 dyn_cast<StringLiteral>(E->getArg(0)->IgnoreParenCasts())) { 237 if (!S->isWide() && S->getByteLength() == 0) { // empty string. 238 const llvm::fltSemantics &Sem = 239 CGM.getContext().getFloatTypeSemantics(E->getType()); 240 return RValue::get(ConstantFP::get(APFloat::getNaN(Sem))); 241 } 242 } 243 // Otherwise, call libm 'nan'. 244 break; 245 } 246 case Builtin::BI__builtin_powi: 247 case Builtin::BI__builtin_powif: 248 case Builtin::BI__builtin_powil: { 249 Value *Base = EmitScalarExpr(E->getArg(0)); 250 Value *Exponent = EmitScalarExpr(E->getArg(1)); 251 const llvm::Type *ArgType = Base->getType(); 252 Value *F = CGM.getIntrinsic(Intrinsic::powi, &ArgType, 1); 253 return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp")); 254 } 255 256 case Builtin::BI__builtin_isgreater: 257 case Builtin::BI__builtin_isgreaterequal: 258 case Builtin::BI__builtin_isless: 259 case Builtin::BI__builtin_islessequal: 260 case Builtin::BI__builtin_islessgreater: 261 case Builtin::BI__builtin_isunordered: { 262 // Ordered comparisons: we know the arguments to these are matching scalar 263 // floating point values. 264 Value *LHS = EmitScalarExpr(E->getArg(0)); 265 Value *RHS = EmitScalarExpr(E->getArg(1)); 266 267 switch (BuiltinID) { 268 default: assert(0 && "Unknown ordered comparison"); 269 case Builtin::BI__builtin_isgreater: 270 LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp"); 271 break; 272 case Builtin::BI__builtin_isgreaterequal: 273 LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp"); 274 break; 275 case Builtin::BI__builtin_isless: 276 LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp"); 277 break; 278 case Builtin::BI__builtin_islessequal: 279 LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp"); 280 break; 281 case Builtin::BI__builtin_islessgreater: 282 LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp"); 283 break; 284 case Builtin::BI__builtin_isunordered: 285 LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp"); 286 break; 287 } 288 // ZExt bool to int type. 289 return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType()), 290 "tmp")); 291 } 292 case Builtin::BI__builtin_alloca: { 293 // FIXME: LLVM IR Should allow alloca with an i64 size! 294 Value *Size = EmitScalarExpr(E->getArg(0)); 295 Size = Builder.CreateIntCast(Size, llvm::Type::Int32Ty, false, "tmp"); 296 return RValue::get(Builder.CreateAlloca(llvm::Type::Int8Ty, Size, "tmp")); 297 } 298 case Builtin::BI__builtin_bzero: { 299 Value *Address = EmitScalarExpr(E->getArg(0)); 300 Builder.CreateCall4(CGM.getMemSetFn(), Address, 301 llvm::ConstantInt::get(llvm::Type::Int8Ty, 0), 302 EmitScalarExpr(E->getArg(1)), 303 llvm::ConstantInt::get(llvm::Type::Int32Ty, 1)); 304 return RValue::get(Address); 305 } 306 case Builtin::BI__builtin_memcpy: { 307 Value *Address = EmitScalarExpr(E->getArg(0)); 308 Builder.CreateCall4(CGM.getMemCpyFn(), Address, 309 EmitScalarExpr(E->getArg(1)), 310 EmitScalarExpr(E->getArg(2)), 311 llvm::ConstantInt::get(llvm::Type::Int32Ty, 1)); 312 return RValue::get(Address); 313 } 314 case Builtin::BI__builtin_memmove: { 315 Value *Address = EmitScalarExpr(E->getArg(0)); 316 Builder.CreateCall4(CGM.getMemMoveFn(), Address, 317 EmitScalarExpr(E->getArg(1)), 318 EmitScalarExpr(E->getArg(2)), 319 llvm::ConstantInt::get(llvm::Type::Int32Ty, 1)); 320 return RValue::get(Address); 321 } 322 case Builtin::BI__builtin_memset: { 323 Value *Address = EmitScalarExpr(E->getArg(0)); 324 Builder.CreateCall4(CGM.getMemSetFn(), Address, 325 EmitScalarExpr(E->getArg(1)), 326 EmitScalarExpr(E->getArg(2)), 327 llvm::ConstantInt::get(llvm::Type::Int32Ty, 1)); 328 return RValue::get(Address); 329 } 330 case Builtin::BI__builtin_return_address: { 331 Value *F = CGM.getIntrinsic(Intrinsic::returnaddress, 0, 0); 332 return RValue::get(Builder.CreateCall(F, EmitScalarExpr(E->getArg(0)))); 333 } 334 case Builtin::BI__builtin_frame_address: { 335 Value *F = CGM.getIntrinsic(Intrinsic::frameaddress, 0, 0); 336 return RValue::get(Builder.CreateCall(F, EmitScalarExpr(E->getArg(0)))); 337 } 338 case Builtin::BI__sync_fetch_and_add: 339 return EmitBinaryAtomic(*this, Intrinsic::atomic_load_add, E); 340 case Builtin::BI__sync_fetch_and_sub: 341 return EmitBinaryAtomic(*this, Intrinsic::atomic_load_sub, E); 342 case Builtin::BI__sync_fetch_and_min: 343 return EmitBinaryAtomic(*this, Intrinsic::atomic_load_min, E); 344 case Builtin::BI__sync_fetch_and_max: 345 return EmitBinaryAtomic(*this, Intrinsic::atomic_load_max, E); 346 case Builtin::BI__sync_fetch_and_umin: 347 return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umin, E); 348 case Builtin::BI__sync_fetch_and_umax: 349 return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umax, E); 350 case Builtin::BI__sync_fetch_and_and: 351 return EmitBinaryAtomic(*this, Intrinsic::atomic_load_and, E); 352 case Builtin::BI__sync_fetch_and_or: 353 return EmitBinaryAtomic(*this, Intrinsic::atomic_load_or, E); 354 case Builtin::BI__sync_fetch_and_xor: 355 return EmitBinaryAtomic(*this, Intrinsic::atomic_load_xor, E); 356 case Builtin::BI__sync_val_compare_and_swap: { 357 Value *Args[3]; 358 Args[0]= EmitScalarExpr(E->getArg(0)); 359 Args[1] = EmitScalarExpr(E->getArg(1)); 360 Args[2] = EmitScalarExpr(E->getArg(2)); 361 const llvm::Type *ResType[2]; 362 ResType[0]= ConvertType(E->getType()); 363 ResType[1] = ConvertType(E->getArg(0)->getType()); 364 Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap, ResType, 2); 365 return RValue::get(Builder.CreateCall(AtomF, &Args[0], &Args[1]+2)); 366 } 367 case Builtin::BI__sync_lock_test_and_set: 368 return EmitBinaryAtomic(*this, Intrinsic::atomic_swap, E); 369 } 370 371 // If this is an alias for a libm function (e.g. __builtin_sin) turn it into 372 // that function. 373 if (getContext().BuiltinInfo.isLibFunction(BuiltinID)) 374 return EmitCallExpr(CGM.getBuiltinLibFunction(BuiltinID), 375 E->getCallee()->getType(), E->arg_begin(), 376 E->arg_end()); 377 378 // See if we have a target specific intrinsic. 379 Intrinsic::ID IntrinsicID; 380 const char *TargetPrefix = Target.getTargetPrefix(); 381 const char *BuiltinName = getContext().BuiltinInfo.GetName(BuiltinID); 382#define GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN 383#include "llvm/Intrinsics.gen" 384#undef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN 385 386 if (IntrinsicID != Intrinsic::not_intrinsic) { 387 SmallVector<Value*, 16> Args; 388 389 Function *F = CGM.getIntrinsic(IntrinsicID); 390 const llvm::FunctionType *FTy = F->getFunctionType(); 391 392 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 393 Value *ArgValue = EmitScalarExpr(E->getArg(i)); 394 395 // If the intrinsic arg type is different from the builtin arg type 396 // we need to do a bit cast. 397 const llvm::Type *PTy = FTy->getParamType(i); 398 if (PTy != ArgValue->getType()) { 399 assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) && 400 "Must be able to losslessly bit cast to param"); 401 ArgValue = Builder.CreateBitCast(ArgValue, PTy); 402 } 403 404 Args.push_back(ArgValue); 405 } 406 407 Value *V = Builder.CreateCall(F, &Args[0], &Args[0] + Args.size()); 408 QualType BuiltinRetType = E->getType(); 409 410 const llvm::Type *RetTy = llvm::Type::VoidTy; 411 if (!BuiltinRetType->isVoidType()) RetTy = ConvertType(BuiltinRetType); 412 413 if (RetTy != V->getType()) { 414 assert(V->getType()->canLosslesslyBitCastTo(RetTy) && 415 "Must be able to losslessly bit cast result type"); 416 V = Builder.CreateBitCast(V, RetTy); 417 } 418 419 return RValue::get(V); 420 } 421 422 // See if we have a target specific builtin that needs to be lowered. 423 Value *V = 0; 424 425 if (strcmp(TargetPrefix, "x86") == 0) 426 V = EmitX86BuiltinExpr(BuiltinID, E); 427 else if (strcmp(TargetPrefix, "ppc") == 0) 428 V = EmitPPCBuiltinExpr(BuiltinID, E); 429 430 if (V) 431 return RValue::get(V); 432 433 WarnUnsupported(E, "builtin function"); 434 435 // Unknown builtin, for now just dump it out and return undef. 436 if (hasAggregateLLVMType(E->getType())) 437 return RValue::getAggregate(CreateTempAlloca(ConvertType(E->getType()))); 438 return RValue::get(UndefValue::get(ConvertType(E->getType()))); 439} 440 441Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, 442 const CallExpr *E) { 443 444 llvm::SmallVector<Value*, 4> Ops; 445 446 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) 447 Ops.push_back(EmitScalarExpr(E->getArg(i))); 448 449 switch (BuiltinID) { 450 default: return 0; 451 case X86::BI__builtin_ia32_mulps: 452 return Builder.CreateMul(Ops[0], Ops[1], "mulps"); 453 case X86::BI__builtin_ia32_mulpd: 454 return Builder.CreateMul(Ops[0], Ops[1], "mulpd"); 455 case X86::BI__builtin_ia32_pand: 456 case X86::BI__builtin_ia32_pand128: 457 return Builder.CreateAnd(Ops[0], Ops[1], "pand"); 458 case X86::BI__builtin_ia32_por: 459 case X86::BI__builtin_ia32_por128: 460 return Builder.CreateOr(Ops[0], Ops[1], "por"); 461 case X86::BI__builtin_ia32_pxor: 462 case X86::BI__builtin_ia32_pxor128: 463 return Builder.CreateXor(Ops[0], Ops[1], "pxor"); 464 case X86::BI__builtin_ia32_pandn: 465 case X86::BI__builtin_ia32_pandn128: 466 Ops[0] = Builder.CreateNot(Ops[0], "tmp"); 467 return Builder.CreateAnd(Ops[0], Ops[1], "pandn"); 468 case X86::BI__builtin_ia32_paddb: 469 case X86::BI__builtin_ia32_paddb128: 470 case X86::BI__builtin_ia32_paddd: 471 case X86::BI__builtin_ia32_paddd128: 472 case X86::BI__builtin_ia32_paddq: 473 case X86::BI__builtin_ia32_paddq128: 474 case X86::BI__builtin_ia32_paddw: 475 case X86::BI__builtin_ia32_paddw128: 476 case X86::BI__builtin_ia32_addps: 477 case X86::BI__builtin_ia32_addpd: 478 return Builder.CreateAdd(Ops[0], Ops[1], "add"); 479 case X86::BI__builtin_ia32_psubb: 480 case X86::BI__builtin_ia32_psubb128: 481 case X86::BI__builtin_ia32_psubd: 482 case X86::BI__builtin_ia32_psubd128: 483 case X86::BI__builtin_ia32_psubq: 484 case X86::BI__builtin_ia32_psubq128: 485 case X86::BI__builtin_ia32_psubw: 486 case X86::BI__builtin_ia32_psubw128: 487 case X86::BI__builtin_ia32_subps: 488 case X86::BI__builtin_ia32_subpd: 489 return Builder.CreateSub(Ops[0], Ops[1], "sub"); 490 case X86::BI__builtin_ia32_divps: 491 return Builder.CreateFDiv(Ops[0], Ops[1], "divps"); 492 case X86::BI__builtin_ia32_divpd: 493 return Builder.CreateFDiv(Ops[0], Ops[1], "divpd"); 494 case X86::BI__builtin_ia32_pmullw: 495 case X86::BI__builtin_ia32_pmullw128: 496 return Builder.CreateMul(Ops[0], Ops[1], "pmul"); 497 case X86::BI__builtin_ia32_punpckhbw: 498 return EmitShuffleVector(Ops[0], Ops[1], 4, 12, 5, 13, 6, 14, 7, 15, 499 "punpckhbw"); 500 case X86::BI__builtin_ia32_punpckhbw128: 501 return EmitShuffleVector(Ops[0], Ops[1], 8, 24, 9, 25, 10, 26, 11, 27, 502 12, 28, 13, 29, 14, 30, 15, 31, 503 "punpckhbw"); 504 case X86::BI__builtin_ia32_punpckhwd: 505 return EmitShuffleVector(Ops[0], Ops[1], 2, 6, 3, 7, "punpckhwd"); 506 case X86::BI__builtin_ia32_punpckhwd128: 507 return EmitShuffleVector(Ops[0], Ops[1], 4, 12, 5, 13, 6, 14, 7, 15, 508 "punpckhwd"); 509 case X86::BI__builtin_ia32_punpckhdq: 510 return EmitShuffleVector(Ops[0], Ops[1], 1, 3, "punpckhdq"); 511 case X86::BI__builtin_ia32_punpckhdq128: 512 return EmitShuffleVector(Ops[0], Ops[1], 2, 6, 3, 7, "punpckhdq"); 513 case X86::BI__builtin_ia32_punpckhqdq128: 514 return EmitShuffleVector(Ops[0], Ops[1], 1, 3, "punpckhqdq"); 515 case X86::BI__builtin_ia32_punpcklbw: 516 return EmitShuffleVector(Ops[0], Ops[1], 0, 8, 1, 9, 2, 10, 3, 11, 517 "punpcklbw"); 518 case X86::BI__builtin_ia32_punpcklwd: 519 return EmitShuffleVector(Ops[0], Ops[1], 0, 4, 1, 5, "punpcklwd"); 520 case X86::BI__builtin_ia32_punpckldq: 521 return EmitShuffleVector(Ops[0], Ops[1], 0, 2, "punpckldq"); 522 case X86::BI__builtin_ia32_punpckldq128: 523 return EmitShuffleVector(Ops[0], Ops[1], 0, 4, 1, 5, "punpckldq"); 524 case X86::BI__builtin_ia32_punpcklqdq128: 525 return EmitShuffleVector(Ops[0], Ops[1], 0, 2, "punpcklqdq"); 526 case X86::BI__builtin_ia32_pslldi128: 527 case X86::BI__builtin_ia32_psllqi128: 528 case X86::BI__builtin_ia32_psllwi128: 529 case X86::BI__builtin_ia32_psradi128: 530 case X86::BI__builtin_ia32_psrawi128: 531 case X86::BI__builtin_ia32_psrldi128: 532 case X86::BI__builtin_ia32_psrlqi128: 533 case X86::BI__builtin_ia32_psrlwi128: { 534 Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::Int64Ty, "zext"); 535 const llvm::Type *Ty = llvm::VectorType::get(llvm::Type::Int64Ty, 2); 536 llvm::Value *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0); 537 Ops[1] = Builder.CreateInsertElement(llvm::UndefValue::get(Ty), 538 Ops[1], Zero, "insert"); 539 Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType(), "bitcast"); 540 const char *name = 0; 541 Intrinsic::ID ID = Intrinsic::not_intrinsic; 542 543 switch (BuiltinID) { 544 default: assert(0 && "Unsupported shift intrinsic!"); 545 case X86::BI__builtin_ia32_pslldi128: 546 name = "pslldi"; 547 ID = Intrinsic::x86_sse2_psll_d; 548 break; 549 case X86::BI__builtin_ia32_psllqi128: 550 name = "psllqi"; 551 ID = Intrinsic::x86_sse2_psll_q; 552 break; 553 case X86::BI__builtin_ia32_psllwi128: 554 name = "psllwi"; 555 ID = Intrinsic::x86_sse2_psll_w; 556 break; 557 case X86::BI__builtin_ia32_psradi128: 558 name = "psradi"; 559 ID = Intrinsic::x86_sse2_psra_d; 560 break; 561 case X86::BI__builtin_ia32_psrawi128: 562 name = "psrawi"; 563 ID = Intrinsic::x86_sse2_psra_w; 564 break; 565 case X86::BI__builtin_ia32_psrldi128: 566 name = "psrldi"; 567 ID = Intrinsic::x86_sse2_psrl_d; 568 break; 569 case X86::BI__builtin_ia32_psrlqi128: 570 name = "psrlqi"; 571 ID = Intrinsic::x86_sse2_psrl_q; 572 break; 573 case X86::BI__builtin_ia32_psrlwi128: 574 name = "psrlwi"; 575 ID = Intrinsic::x86_sse2_psrl_w; 576 break; 577 } 578 llvm::Function *F = CGM.getIntrinsic(ID); 579 return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name); 580 } 581 case X86::BI__builtin_ia32_pslldi: 582 case X86::BI__builtin_ia32_psllqi: 583 case X86::BI__builtin_ia32_psllwi: 584 case X86::BI__builtin_ia32_psradi: 585 case X86::BI__builtin_ia32_psrawi: 586 case X86::BI__builtin_ia32_psrldi: 587 case X86::BI__builtin_ia32_psrlqi: 588 case X86::BI__builtin_ia32_psrlwi: { 589 Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::Int64Ty, "zext"); 590 const llvm::Type *Ty = llvm::VectorType::get(llvm::Type::Int64Ty, 1); 591 Ops[1] = Builder.CreateBitCast(Ops[1], Ty, "bitcast"); 592 const char *name = 0; 593 Intrinsic::ID ID = Intrinsic::not_intrinsic; 594 595 switch (BuiltinID) { 596 default: assert(0 && "Unsupported shift intrinsic!"); 597 case X86::BI__builtin_ia32_pslldi: 598 name = "pslldi"; 599 ID = Intrinsic::x86_mmx_psll_d; 600 break; 601 case X86::BI__builtin_ia32_psllqi: 602 name = "psllqi"; 603 ID = Intrinsic::x86_mmx_psll_q; 604 break; 605 case X86::BI__builtin_ia32_psllwi: 606 name = "psllwi"; 607 ID = Intrinsic::x86_mmx_psll_w; 608 break; 609 case X86::BI__builtin_ia32_psradi: 610 name = "psradi"; 611 ID = Intrinsic::x86_mmx_psra_d; 612 break; 613 case X86::BI__builtin_ia32_psrawi: 614 name = "psrawi"; 615 ID = Intrinsic::x86_mmx_psra_w; 616 break; 617 case X86::BI__builtin_ia32_psrldi: 618 name = "psrldi"; 619 ID = Intrinsic::x86_mmx_psrl_d; 620 break; 621 case X86::BI__builtin_ia32_psrlqi: 622 name = "psrlqi"; 623 ID = Intrinsic::x86_mmx_psrl_q; 624 break; 625 case X86::BI__builtin_ia32_psrlwi: 626 name = "psrlwi"; 627 ID = Intrinsic::x86_mmx_psrl_w; 628 break; 629 } 630 llvm::Function *F = CGM.getIntrinsic(ID); 631 return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name); 632 } 633 case X86::BI__builtin_ia32_pshuflw: { 634 unsigned i = cast<ConstantInt>(Ops[1])->getZExtValue(); 635 return EmitShuffleVector(Ops[0], Ops[0], 636 i & 0x3, (i & 0xc) >> 2, 637 (i & 0x30) >> 4, (i & 0xc0) >> 6, 4, 5, 6, 7, 638 "pshuflw"); 639 } 640 case X86::BI__builtin_ia32_pshufhw: { 641 unsigned i = cast<ConstantInt>(Ops[1])->getZExtValue(); 642 return EmitShuffleVector(Ops[0], Ops[0], 0, 1, 2, 3, 643 4 + (i & 0x3), 4 + ((i & 0xc) >> 2), 644 4 + ((i & 0x30) >> 4), 4 + ((i & 0xc0) >> 6), 645 "pshufhw"); 646 } 647 case X86::BI__builtin_ia32_pshufd: { 648 unsigned i = cast<ConstantInt>(Ops[1])->getZExtValue(); 649 return EmitShuffleVector(Ops[0], Ops[0], 650 i & 0x3, (i & 0xc) >> 2, 651 (i & 0x30) >> 4, (i & 0xc0) >> 6, 652 "pshufd"); 653 } 654 case X86::BI__builtin_ia32_vec_init_v4hi: 655 case X86::BI__builtin_ia32_vec_init_v8qi: 656 case X86::BI__builtin_ia32_vec_init_v2si: 657 return EmitVector(&Ops[0], Ops.size()); 658 case X86::BI__builtin_ia32_vec_ext_v2si: 659 case X86::BI__builtin_ia32_vec_ext_v2di: 660 case X86::BI__builtin_ia32_vec_ext_v4sf: 661 case X86::BI__builtin_ia32_vec_ext_v4si: 662 case X86::BI__builtin_ia32_vec_ext_v2df: 663 return Builder.CreateExtractElement(Ops[0], Ops[1], "result"); 664 case X86::BI__builtin_ia32_cmpordss: 665 case X86::BI__builtin_ia32_cmpordsd: 666 case X86::BI__builtin_ia32_cmpunordss: 667 case X86::BI__builtin_ia32_cmpunordsd: 668 case X86::BI__builtin_ia32_cmpeqss: 669 case X86::BI__builtin_ia32_cmpeqsd: 670 case X86::BI__builtin_ia32_cmpltss: 671 case X86::BI__builtin_ia32_cmpltsd: 672 case X86::BI__builtin_ia32_cmpless: 673 case X86::BI__builtin_ia32_cmplesd: 674 case X86::BI__builtin_ia32_cmpneqss: 675 case X86::BI__builtin_ia32_cmpneqsd: 676 case X86::BI__builtin_ia32_cmpnltss: 677 case X86::BI__builtin_ia32_cmpnltsd: 678 case X86::BI__builtin_ia32_cmpnless: 679 case X86::BI__builtin_ia32_cmpnlesd: { 680 unsigned i = 0; 681 const char *name = 0; 682 switch (BuiltinID) { 683 default: assert(0 && "Unknown compare builtin!"); 684 case X86::BI__builtin_ia32_cmpeqss: 685 case X86::BI__builtin_ia32_cmpeqsd: 686 i = 0; 687 name = "cmpeq"; 688 break; 689 case X86::BI__builtin_ia32_cmpltss: 690 case X86::BI__builtin_ia32_cmpltsd: 691 i = 1; 692 name = "cmplt"; 693 break; 694 case X86::BI__builtin_ia32_cmpless: 695 case X86::BI__builtin_ia32_cmplesd: 696 i = 2; 697 name = "cmple"; 698 break; 699 case X86::BI__builtin_ia32_cmpunordss: 700 case X86::BI__builtin_ia32_cmpunordsd: 701 i = 3; 702 name = "cmpunord"; 703 break; 704 case X86::BI__builtin_ia32_cmpneqss: 705 case X86::BI__builtin_ia32_cmpneqsd: 706 i = 4; 707 name = "cmpneq"; 708 break; 709 case X86::BI__builtin_ia32_cmpnltss: 710 case X86::BI__builtin_ia32_cmpnltsd: 711 i = 5; 712 name = "cmpntl"; 713 break; 714 case X86::BI__builtin_ia32_cmpnless: 715 case X86::BI__builtin_ia32_cmpnlesd: 716 i = 6; 717 name = "cmpnle"; 718 break; 719 case X86::BI__builtin_ia32_cmpordss: 720 case X86::BI__builtin_ia32_cmpordsd: 721 i = 7; 722 name = "cmpord"; 723 break; 724 } 725 726 llvm::Function *F; 727 if (cast<llvm::VectorType>(Ops[0]->getType())->getElementType() == 728 llvm::Type::FloatTy) 729 F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ss); 730 else 731 F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_sd); 732 733 Ops.push_back(llvm::ConstantInt::get(llvm::Type::Int8Ty, i)); 734 return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name); 735 } 736 case X86::BI__builtin_ia32_ldmxcsr: { 737 llvm::Type *PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 738 Value *One = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1); 739 Value *Tmp = Builder.CreateAlloca(llvm::Type::Int32Ty, One, "tmp"); 740 Builder.CreateStore(Ops[0], Tmp); 741 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr), 742 Builder.CreateBitCast(Tmp, PtrTy)); 743 } 744 case X86::BI__builtin_ia32_stmxcsr: { 745 llvm::Type *PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 746 Value *One = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1); 747 Value *Tmp = Builder.CreateAlloca(llvm::Type::Int32Ty, One, "tmp"); 748 One = Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr), 749 Builder.CreateBitCast(Tmp, PtrTy)); 750 return Builder.CreateLoad(Tmp, "stmxcsr"); 751 } 752 case X86::BI__builtin_ia32_cmpordps: 753 case X86::BI__builtin_ia32_cmpordpd: 754 case X86::BI__builtin_ia32_cmpunordps: 755 case X86::BI__builtin_ia32_cmpunordpd: 756 case X86::BI__builtin_ia32_cmpeqps: 757 case X86::BI__builtin_ia32_cmpeqpd: 758 case X86::BI__builtin_ia32_cmpltps: 759 case X86::BI__builtin_ia32_cmpltpd: 760 case X86::BI__builtin_ia32_cmpleps: 761 case X86::BI__builtin_ia32_cmplepd: 762 case X86::BI__builtin_ia32_cmpneqps: 763 case X86::BI__builtin_ia32_cmpneqpd: 764 case X86::BI__builtin_ia32_cmpngtps: 765 case X86::BI__builtin_ia32_cmpngtpd: 766 case X86::BI__builtin_ia32_cmpnltps: 767 case X86::BI__builtin_ia32_cmpnltpd: 768 case X86::BI__builtin_ia32_cmpgtps: 769 case X86::BI__builtin_ia32_cmpgtpd: 770 case X86::BI__builtin_ia32_cmpgeps: 771 case X86::BI__builtin_ia32_cmpgepd: 772 case X86::BI__builtin_ia32_cmpngeps: 773 case X86::BI__builtin_ia32_cmpngepd: 774 case X86::BI__builtin_ia32_cmpnleps: 775 case X86::BI__builtin_ia32_cmpnlepd: { 776 unsigned i = 0; 777 const char *name = 0; 778 bool ShouldSwap = false; 779 switch (BuiltinID) { 780 default: assert(0 && "Unknown compare builtin!"); 781 case X86::BI__builtin_ia32_cmpeqps: 782 case X86::BI__builtin_ia32_cmpeqpd: i = 0; name = "cmpeq"; break; 783 case X86::BI__builtin_ia32_cmpltps: 784 case X86::BI__builtin_ia32_cmpltpd: i = 1; name = "cmplt"; break; 785 case X86::BI__builtin_ia32_cmpleps: 786 case X86::BI__builtin_ia32_cmplepd: i = 2; name = "cmple"; break; 787 case X86::BI__builtin_ia32_cmpunordps: 788 case X86::BI__builtin_ia32_cmpunordpd: i = 3; name = "cmpunord"; break; 789 case X86::BI__builtin_ia32_cmpneqps: 790 case X86::BI__builtin_ia32_cmpneqpd: i = 4; name = "cmpneq"; break; 791 case X86::BI__builtin_ia32_cmpnltps: 792 case X86::BI__builtin_ia32_cmpnltpd: i = 5; name = "cmpntl"; break; 793 case X86::BI__builtin_ia32_cmpnleps: 794 case X86::BI__builtin_ia32_cmpnlepd: i = 6; name = "cmpnle"; break; 795 case X86::BI__builtin_ia32_cmpordps: 796 case X86::BI__builtin_ia32_cmpordpd: i = 7; name = "cmpord"; break; 797 case X86::BI__builtin_ia32_cmpgtps: 798 case X86::BI__builtin_ia32_cmpgtpd: 799 ShouldSwap = true; 800 i = 1; 801 name = "cmpgt"; 802 break; 803 case X86::BI__builtin_ia32_cmpgeps: 804 case X86::BI__builtin_ia32_cmpgepd: 805 i = 2; 806 name = "cmpge"; 807 ShouldSwap = true; 808 break; 809 case X86::BI__builtin_ia32_cmpngtps: 810 case X86::BI__builtin_ia32_cmpngtpd: 811 i = 5; 812 name = "cmpngt"; 813 ShouldSwap = true; 814 break; 815 case X86::BI__builtin_ia32_cmpngeps: 816 case X86::BI__builtin_ia32_cmpngepd: 817 i = 6; 818 name = "cmpnge"; 819 ShouldSwap = true; 820 break; 821 } 822 823 if (ShouldSwap) 824 std::swap(Ops[0], Ops[1]); 825 826 llvm::Function *F; 827 if (cast<llvm::VectorType>(Ops[0]->getType())->getElementType() == 828 llvm::Type::FloatTy) 829 F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ps); 830 else 831 F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_pd); 832 833 Ops.push_back(llvm::ConstantInt::get(llvm::Type::Int8Ty, i)); 834 return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name); 835 } 836 case X86::BI__builtin_ia32_movss: 837 return EmitShuffleVector(Ops[0], Ops[1], 4, 1, 2, 3, "movss"); 838 case X86::BI__builtin_ia32_shufps: { 839 unsigned i = cast<ConstantInt>(Ops[2])->getZExtValue(); 840 return EmitShuffleVector(Ops[0], Ops[1], 841 i & 0x3, (i & 0xc) >> 2, 842 ((i & 0x30) >> 4) + 4, 843 ((i & 0xc0) >> 6) + 4, "shufps"); 844 } 845 case X86::BI__builtin_ia32_shufpd: { 846 unsigned i = cast<ConstantInt>(Ops[2])->getZExtValue(); 847 return EmitShuffleVector(Ops[0], Ops[1], i & 1, (i & 2) + 2, "shufpd"); 848 } 849 case X86::BI__builtin_ia32_punpcklbw128: 850 return EmitShuffleVector(Ops[0], Ops[1], 0, 16, 1, 17, 2, 18, 3, 19, 851 4, 20, 5, 21, 6, 22, 7, 23, 852 "punpcklbw"); 853 case X86::BI__builtin_ia32_punpcklwd128: 854 return EmitShuffleVector(Ops[0], Ops[1], 0, 8, 1, 9, 2, 10, 3, 11, 855 "punpcklwd"); 856 case X86::BI__builtin_ia32_movlhps: 857 return EmitShuffleVector(Ops[0], Ops[1], 0, 1, 4, 5, "movlhps"); 858 case X86::BI__builtin_ia32_movhlps: 859 return EmitShuffleVector(Ops[0], Ops[1], 6, 7, 2, 3, "movhlps"); 860 case X86::BI__builtin_ia32_unpckhps: 861 return EmitShuffleVector(Ops[0], Ops[1], 2, 6, 3, 7, "unpckhps"); 862 case X86::BI__builtin_ia32_unpcklps: 863 return EmitShuffleVector(Ops[0], Ops[1], 0, 4, 1, 5, "unpcklps"); 864 case X86::BI__builtin_ia32_unpckhpd: 865 return EmitShuffleVector(Ops[0], Ops[1], 1, 3, "unpckhpd"); 866 case X86::BI__builtin_ia32_unpcklpd: 867 return EmitShuffleVector(Ops[0], Ops[1], 0, 2, "unpcklpd"); 868 case X86::BI__builtin_ia32_movsd: 869 return EmitShuffleVector(Ops[0], Ops[1], 2, 1, "movsd"); 870 case X86::BI__builtin_ia32_movqv4si: { 871 llvm::Type *Ty = llvm::VectorType::get(llvm::Type::Int64Ty, 2); 872 return Builder.CreateBitCast(Ops[0], Ty); 873 } 874 case X86::BI__builtin_ia32_loadlps: 875 case X86::BI__builtin_ia32_loadhps: { 876 // FIXME: This should probably be represented as 877 // shuffle (dst, (v4f32 (insert undef, (load i64), 0)), shuf mask hi/lo) 878 const llvm::Type *EltTy = llvm::Type::DoubleTy; 879 const llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2); 880 const llvm::Type *OrigTy = Ops[0]->getType(); 881 unsigned Index = BuiltinID == X86::BI__builtin_ia32_loadlps ? 0 : 1; 882 llvm::Value *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, Index); 883 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::PointerType::getUnqual(EltTy)); 884 Ops[1] = Builder.CreateLoad(Ops[1], "tmp"); 885 Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 886 Ops[0] = Builder.CreateInsertElement(Ops[0], Ops[1], Idx, "loadps"); 887 return Builder.CreateBitCast(Ops[0], OrigTy, "loadps"); 888 } 889 case X86::BI__builtin_ia32_storehps: 890 case X86::BI__builtin_ia32_storelps: { 891 const llvm::Type *EltTy = llvm::Type::Int64Ty; 892 llvm::Type *PtrTy = llvm::PointerType::getUnqual(EltTy); 893 llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2); 894 895 // cast val v2i64 896 Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast"); 897 898 // extract (0, 1) 899 unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1; 900 llvm::Value *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, Index); 901 Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract"); 902 903 // cast pointer to i64 & store 904 Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy); 905 return Builder.CreateStore(Ops[1], Ops[0]); 906 } 907 case X86::BI__builtin_ia32_loadlv4si: { 908 // load i64 909 const llvm::Type *EltTy = llvm::Type::Int64Ty; 910 llvm::Type *PtrTy = llvm::PointerType::getUnqual(EltTy); 911 Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy); 912 Ops[0] = Builder.CreateLoad(Ops[0], "load"); 913 914 // scalar to vector: insert i64 into 2 x i64 undef 915 llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2); 916 llvm::Value *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0); 917 Ops[0] = Builder.CreateInsertElement(llvm::UndefValue::get(VecTy), 918 Ops[0], Zero, "s2v"); 919 920 // shuffle into zero vector. 921 std::vector<llvm::Constant *>Elts; 922 Elts.resize(2, llvm::ConstantInt::get(EltTy, 0)); 923 llvm::Value *ZV = ConstantVector::get(Elts); 924 Ops[0] = EmitShuffleVector(ZV, Ops[0], 2, 1, "loadl"); 925 926 // bitcast to result. 927 return Builder.CreateBitCast(Ops[0], 928 llvm::VectorType::get(llvm::Type::Int32Ty, 4)); 929 } 930 case X86::BI__builtin_ia32_vec_set_v4hi: 931 case X86::BI__builtin_ia32_vec_set_v8hi: 932 return Builder.CreateInsertElement(Ops[0], Ops[1], Ops[2], "pinsrw"); 933 case X86::BI__builtin_ia32_andps: 934 case X86::BI__builtin_ia32_andpd: 935 case X86::BI__builtin_ia32_andnps: 936 case X86::BI__builtin_ia32_andnpd: 937 case X86::BI__builtin_ia32_orps: 938 case X86::BI__builtin_ia32_orpd: 939 case X86::BI__builtin_ia32_xorpd: 940 case X86::BI__builtin_ia32_xorps: { 941 const llvm::Type *ITy = llvm::VectorType::get(llvm::Type::Int32Ty, 4); 942 const llvm::Type *FTy = Ops[0]->getType(); 943 Ops[0] = Builder.CreateBitCast(Ops[0], ITy, "bitcast"); 944 Ops[1] = Builder.CreateBitCast(Ops[1], ITy, "bitcast"); 945 switch (BuiltinID) { 946 case X86::BI__builtin_ia32_andps: 947 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1], "andps"); 948 break; 949 case X86::BI__builtin_ia32_andpd: 950 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1], "andpd"); 951 break; 952 case X86::BI__builtin_ia32_andnps: 953 Ops[0] = Builder.CreateNot(Ops[0], "not"); 954 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1], "andnps"); 955 break; 956 case X86::BI__builtin_ia32_andnpd: 957 Ops[0] = Builder.CreateNot(Ops[0], "not"); 958 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1], "andnpd"); 959 break; 960 case X86::BI__builtin_ia32_orps: 961 Ops[0] = Builder.CreateOr(Ops[0], Ops[1], "orps"); 962 break; 963 case X86::BI__builtin_ia32_orpd: 964 Ops[0] = Builder.CreateOr(Ops[0], Ops[1], "orpd"); 965 break; 966 case X86::BI__builtin_ia32_xorps: 967 Ops[0] = Builder.CreateXor(Ops[0], Ops[1], "xorps"); 968 break; 969 case X86::BI__builtin_ia32_xorpd: 970 Ops[0] = Builder.CreateXor(Ops[0], Ops[1], "xorpd"); 971 break; 972 } 973 return Builder.CreateBitCast(Ops[0], FTy, "bitcast"); 974 } 975 } 976} 977 978Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, 979 const CallExpr *E) { 980 switch (BuiltinID) { 981 default: return 0; 982 } 983} 984