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