CGBuiltin.cpp revision 5caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534
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/AST/TargetBuiltins.h" 21#include "llvm/Intrinsics.h" 22using namespace clang; 23using namespace CodeGen; 24using namespace llvm; 25 26/// Utility to insert an atomic instruction based on Instrinsic::ID 27/// and the expression node. 28static RValue EmitBinaryAtomic(CodeGenFunction& CGF, 29 Intrinsic::ID Id, const CallExpr *E) { 30 const llvm::Type *ResType[2]; 31 ResType[0] = CGF.ConvertType(E->getType()); 32 ResType[1] = CGF.ConvertType(E->getArg(0)->getType()); 33 Value *AtomF = CGF.CGM.getIntrinsic(Id, ResType, 2); 34 return RValue::get(CGF.Builder.CreateCall2(AtomF, 35 CGF.EmitScalarExpr(E->getArg(0)), 36 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. 42static RValue EmitBinaryAtomicPost(CodeGenFunction& CGF, 43 Intrinsic::ID Id, const CallExpr *E, 44 Instruction::BinaryOps Op) { 45 const llvm::Type *ResType[2]; 46 ResType[0] = CGF.ConvertType(E->getType()); 47 ResType[1] = CGF.ConvertType(E->getArg(0)->getType()); 48 Value *AtomF = CGF.CGM.getIntrinsic(Id, ResType, 2); 49 Value *Ptr = CGF.EmitScalarExpr(E->getArg(0)); 50 Value *Operand = CGF.EmitScalarExpr(E->getArg(1)); 51 Value *Result = CGF.Builder.CreateCall2(AtomF, Ptr, Operand); 52 return RValue::get(CGF.Builder.CreateBinOp(Op, Result, Operand)); 53} 54 55RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, 56 unsigned BuiltinID, const CallExpr *E) { 57 // See if we can constant fold this builtin. If so, don't emit it at all. 58 Expr::EvalResult Result; 59 if (E->Evaluate(Result, CGM.getContext())) { 60 if (Result.Val.isInt()) 61 return RValue::get(llvm::ConstantInt::get(Result.Val.getInt())); 62 else if (Result.Val.isFloat()) 63 return RValue::get(llvm::ConstantFP::get(Result.Val.getFloat())); 64 } 65 66 switch (BuiltinID) { 67 default: break; // Handle intrinsics and libm functions below. 68 case Builtin::BI__builtin___CFStringMakeConstantString: 69 return RValue::get(CGM.EmitConstantExpr(E, E->getType(), 0)); 70 case Builtin::BI__builtin_stdarg_start: 71 case Builtin::BI__builtin_va_start: 72 case Builtin::BI__builtin_va_end: { 73 Value *ArgValue = EmitVAListRef(E->getArg(0)); 74 const llvm::Type *DestType = 75 llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 76 if (ArgValue->getType() != DestType) 77 ArgValue = Builder.CreateBitCast(ArgValue, DestType, 78 ArgValue->getNameStart()); 79 80 Intrinsic::ID inst = (BuiltinID == Builtin::BI__builtin_va_end) ? 81 Intrinsic::vaend : Intrinsic::vastart; 82 return RValue::get(Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue)); 83 } 84 case Builtin::BI__builtin_va_copy: { 85 Value *DstPtr = EmitVAListRef(E->getArg(0)); 86 Value *SrcPtr = EmitVAListRef(E->getArg(1)); 87 88 const llvm::Type *Type = 89 llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 90 91 DstPtr = Builder.CreateBitCast(DstPtr, Type); 92 SrcPtr = Builder.CreateBitCast(SrcPtr, Type); 93 return RValue::get(Builder.CreateCall2(CGM.getIntrinsic(Intrinsic::vacopy), 94 DstPtr, SrcPtr)); 95 } 96 case Builtin::BI__builtin_abs: { 97 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 98 99 Value *NegOp = Builder.CreateNeg(ArgValue, "neg"); 100 Value *CmpResult = 101 Builder.CreateICmpSGE(ArgValue, Constant::getNullValue(ArgValue->getType()), 102 "abscond"); 103 Value *Result = 104 Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs"); 105 106 return RValue::get(Result); 107 } 108 case Builtin::BI__builtin_ctz: 109 case Builtin::BI__builtin_ctzl: 110 case Builtin::BI__builtin_ctzll: { 111 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 112 113 const llvm::Type *ArgType = ArgValue->getType(); 114 Value *F = CGM.getIntrinsic(Intrinsic::cttz, &ArgType, 1); 115 116 const llvm::Type *ResultType = ConvertType(E->getType()); 117 Value *Result = Builder.CreateCall(F, ArgValue, "tmp"); 118 if (Result->getType() != ResultType) 119 Result = Builder.CreateIntCast(Result, ResultType, "cast"); 120 return RValue::get(Result); 121 } 122 case Builtin::BI__builtin_clz: 123 case Builtin::BI__builtin_clzl: 124 case Builtin::BI__builtin_clzll: { 125 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 126 127 const llvm::Type *ArgType = ArgValue->getType(); 128 Value *F = CGM.getIntrinsic(Intrinsic::ctlz, &ArgType, 1); 129 130 const llvm::Type *ResultType = ConvertType(E->getType()); 131 Value *Result = Builder.CreateCall(F, ArgValue, "tmp"); 132 if (Result->getType() != ResultType) 133 Result = Builder.CreateIntCast(Result, ResultType, "cast"); 134 return RValue::get(Result); 135 } 136 case Builtin::BI__builtin_ffs: 137 case Builtin::BI__builtin_ffsl: 138 case Builtin::BI__builtin_ffsll: { 139 // ffs(x) -> x ? cttz(x) + 1 : 0 140 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 141 142 const llvm::Type *ArgType = ArgValue->getType(); 143 Value *F = CGM.getIntrinsic(Intrinsic::cttz, &ArgType, 1); 144 145 const llvm::Type *ResultType = ConvertType(E->getType()); 146 Value *Tmp = Builder.CreateAdd(Builder.CreateCall(F, ArgValue, "tmp"), 147 ConstantInt::get(ArgType, 1), "tmp"); 148 Value *Zero = llvm::Constant::getNullValue(ArgType); 149 Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero"); 150 Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp, "ffs"); 151 if (Result->getType() != ResultType) 152 Result = Builder.CreateIntCast(Result, ResultType, "cast"); 153 return RValue::get(Result); 154 } 155 case Builtin::BI__builtin_parity: 156 case Builtin::BI__builtin_parityl: 157 case Builtin::BI__builtin_parityll: { 158 // parity(x) -> ctpop(x) & 1 159 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 160 161 const llvm::Type *ArgType = ArgValue->getType(); 162 Value *F = CGM.getIntrinsic(Intrinsic::ctpop, &ArgType, 1); 163 164 const llvm::Type *ResultType = ConvertType(E->getType()); 165 Value *Tmp = Builder.CreateCall(F, ArgValue, "tmp"); 166 Value *Result = Builder.CreateAnd(Tmp, ConstantInt::get(ArgType, 1), 167 "tmp"); 168 if (Result->getType() != ResultType) 169 Result = Builder.CreateIntCast(Result, ResultType, "cast"); 170 return RValue::get(Result); 171 } 172 case Builtin::BI__builtin_popcount: 173 case Builtin::BI__builtin_popcountl: 174 case Builtin::BI__builtin_popcountll: { 175 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 176 177 const llvm::Type *ArgType = ArgValue->getType(); 178 Value *F = CGM.getIntrinsic(Intrinsic::ctpop, &ArgType, 1); 179 180 const llvm::Type *ResultType = ConvertType(E->getType()); 181 Value *Result = Builder.CreateCall(F, ArgValue, "tmp"); 182 if (Result->getType() != ResultType) 183 Result = Builder.CreateIntCast(Result, ResultType, "cast"); 184 return RValue::get(Result); 185 } 186 case Builtin::BI__builtin_expect: 187 // FIXME: pass expect through to LLVM 188 return RValue::get(EmitScalarExpr(E->getArg(0))); 189 case Builtin::BI__builtin_bswap32: 190 case Builtin::BI__builtin_bswap64: { 191 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 192 const llvm::Type *ArgType = ArgValue->getType(); 193 Value *F = CGM.getIntrinsic(Intrinsic::bswap, &ArgType, 1); 194 return RValue::get(Builder.CreateCall(F, ArgValue, "tmp")); 195 } 196 case Builtin::BI__builtin_object_size: { 197 // FIXME: Implement. For now we just always fail and pretend we 198 // don't know the object size. 199 llvm::APSInt TypeArg = E->getArg(1)->EvaluateAsInt(CGM.getContext()); 200 const llvm::Type *ResType = ConvertType(E->getType()); 201 // bool UseSubObject = TypeArg.getZExtValue() & 1; 202 bool UseMinimum = TypeArg.getZExtValue() & 2; 203 return RValue::get(ConstantInt::get(ResType, UseMinimum ? 0 : -1LL)); 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_powi: 221 case Builtin::BI__builtin_powif: 222 case Builtin::BI__builtin_powil: { 223 Value *Base = EmitScalarExpr(E->getArg(0)); 224 Value *Exponent = EmitScalarExpr(E->getArg(1)); 225 const llvm::Type *ArgType = Base->getType(); 226 Value *F = CGM.getIntrinsic(Intrinsic::powi, &ArgType, 1); 227 return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp")); 228 } 229 230 case Builtin::BI__builtin_isgreater: 231 case Builtin::BI__builtin_isgreaterequal: 232 case Builtin::BI__builtin_isless: 233 case Builtin::BI__builtin_islessequal: 234 case Builtin::BI__builtin_islessgreater: 235 case Builtin::BI__builtin_isunordered: { 236 // Ordered comparisons: we know the arguments to these are matching scalar 237 // floating point values. 238 Value *LHS = EmitScalarExpr(E->getArg(0)); 239 Value *RHS = EmitScalarExpr(E->getArg(1)); 240 241 switch (BuiltinID) { 242 default: assert(0 && "Unknown ordered comparison"); 243 case Builtin::BI__builtin_isgreater: 244 LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp"); 245 break; 246 case Builtin::BI__builtin_isgreaterequal: 247 LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp"); 248 break; 249 case Builtin::BI__builtin_isless: 250 LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp"); 251 break; 252 case Builtin::BI__builtin_islessequal: 253 LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp"); 254 break; 255 case Builtin::BI__builtin_islessgreater: 256 LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp"); 257 break; 258 case Builtin::BI__builtin_isunordered: 259 LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp"); 260 break; 261 } 262 // ZExt bool to int type. 263 return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType()), 264 "tmp")); 265 } 266 case Builtin::BI__builtin_alloca: { 267 // FIXME: LLVM IR Should allow alloca with an i64 size! 268 Value *Size = EmitScalarExpr(E->getArg(0)); 269 Size = Builder.CreateIntCast(Size, llvm::Type::Int32Ty, false, "tmp"); 270 return RValue::get(Builder.CreateAlloca(llvm::Type::Int8Ty, Size, "tmp")); 271 } 272 case Builtin::BI__builtin_bzero: { 273 Value *Address = EmitScalarExpr(E->getArg(0)); 274 Builder.CreateCall4(CGM.getMemSetFn(), Address, 275 llvm::ConstantInt::get(llvm::Type::Int8Ty, 0), 276 EmitScalarExpr(E->getArg(1)), 277 llvm::ConstantInt::get(llvm::Type::Int32Ty, 1)); 278 return RValue::get(Address); 279 } 280 case Builtin::BI__builtin_memcpy: { 281 Value *Address = EmitScalarExpr(E->getArg(0)); 282 Builder.CreateCall4(CGM.getMemCpyFn(), Address, 283 EmitScalarExpr(E->getArg(1)), 284 EmitScalarExpr(E->getArg(2)), 285 llvm::ConstantInt::get(llvm::Type::Int32Ty, 1)); 286 return RValue::get(Address); 287 } 288 case Builtin::BI__builtin_memmove: { 289 Value *Address = EmitScalarExpr(E->getArg(0)); 290 Builder.CreateCall4(CGM.getMemMoveFn(), Address, 291 EmitScalarExpr(E->getArg(1)), 292 EmitScalarExpr(E->getArg(2)), 293 llvm::ConstantInt::get(llvm::Type::Int32Ty, 1)); 294 return RValue::get(Address); 295 } 296 case Builtin::BI__builtin_memset: { 297 Value *Address = EmitScalarExpr(E->getArg(0)); 298 Builder.CreateCall4(CGM.getMemSetFn(), Address, 299 Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), 300 llvm::Type::Int8Ty), 301 EmitScalarExpr(E->getArg(2)), 302 llvm::ConstantInt::get(llvm::Type::Int32Ty, 1)); 303 return RValue::get(Address); 304 } 305 case Builtin::BI__builtin_return_address: { 306 Value *F = CGM.getIntrinsic(Intrinsic::returnaddress, 0, 0); 307 return RValue::get(Builder.CreateCall(F, EmitScalarExpr(E->getArg(0)))); 308 } 309 case Builtin::BI__builtin_frame_address: { 310 Value *F = CGM.getIntrinsic(Intrinsic::frameaddress, 0, 0); 311 return RValue::get(Builder.CreateCall(F, EmitScalarExpr(E->getArg(0)))); 312 } 313 case Builtin::BI__builtin_extract_return_addr: { 314 // FIXME: There should be a target hook for this 315 return RValue::get(EmitScalarExpr(E->getArg(0))); 316 } 317 case Builtin::BI__sync_fetch_and_add: 318 case Builtin::BI__sync_fetch_and_sub: 319 case Builtin::BI__sync_fetch_and_or: 320 case Builtin::BI__sync_fetch_and_and: 321 case Builtin::BI__sync_fetch_and_xor: 322 case Builtin::BI__sync_add_and_fetch: 323 case Builtin::BI__sync_sub_and_fetch: 324 case Builtin::BI__sync_and_and_fetch: 325 case Builtin::BI__sync_or_and_fetch: 326 case Builtin::BI__sync_xor_and_fetch: 327 case Builtin::BI__sync_val_compare_and_swap: 328 case Builtin::BI__sync_bool_compare_and_swap: 329 case Builtin::BI__sync_lock_test_and_set: 330 case Builtin::BI__sync_lock_release: 331 assert(0 && "Shouldn't make it through sema"); 332 case Builtin::BI__sync_fetch_and_add_1: 333 case Builtin::BI__sync_fetch_and_add_2: 334 case Builtin::BI__sync_fetch_and_add_4: 335 case Builtin::BI__sync_fetch_and_add_8: 336 case Builtin::BI__sync_fetch_and_add_16: 337 return EmitBinaryAtomic(*this, Intrinsic::atomic_load_add, E); 338 case Builtin::BI__sync_fetch_and_sub_1: 339 case Builtin::BI__sync_fetch_and_sub_2: 340 case Builtin::BI__sync_fetch_and_sub_4: 341 case Builtin::BI__sync_fetch_and_sub_8: 342 case Builtin::BI__sync_fetch_and_sub_16: 343 return EmitBinaryAtomic(*this, Intrinsic::atomic_load_sub, E); 344 case Builtin::BI__sync_fetch_and_or_1: 345 case Builtin::BI__sync_fetch_and_or_2: 346 case Builtin::BI__sync_fetch_and_or_4: 347 case Builtin::BI__sync_fetch_and_or_8: 348 case Builtin::BI__sync_fetch_and_or_16: 349 return EmitBinaryAtomic(*this, Intrinsic::atomic_load_or, E); 350 case Builtin::BI__sync_fetch_and_and_1: 351 case Builtin::BI__sync_fetch_and_and_2: 352 case Builtin::BI__sync_fetch_and_and_4: 353 case Builtin::BI__sync_fetch_and_and_8: 354 case Builtin::BI__sync_fetch_and_and_16: 355 return EmitBinaryAtomic(*this, Intrinsic::atomic_load_and, E); 356 case Builtin::BI__sync_fetch_and_xor_1: 357 case Builtin::BI__sync_fetch_and_xor_2: 358 case Builtin::BI__sync_fetch_and_xor_4: 359 case Builtin::BI__sync_fetch_and_xor_8: 360 case Builtin::BI__sync_fetch_and_xor_16: 361 return EmitBinaryAtomic(*this, Intrinsic::atomic_load_xor, E); 362 363 // Clang extensions: not overloaded yet. 364 case Builtin::BI__sync_fetch_and_min: 365 return EmitBinaryAtomic(*this, Intrinsic::atomic_load_min, E); 366 case Builtin::BI__sync_fetch_and_max: 367 return EmitBinaryAtomic(*this, Intrinsic::atomic_load_max, E); 368 case Builtin::BI__sync_fetch_and_umin: 369 return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umin, E); 370 case Builtin::BI__sync_fetch_and_umax: 371 return EmitBinaryAtomic(*this, Intrinsic::atomic_load_umax, E); 372 373 case Builtin::BI__sync_add_and_fetch_1: 374 case Builtin::BI__sync_add_and_fetch_2: 375 case Builtin::BI__sync_add_and_fetch_4: 376 case Builtin::BI__sync_add_and_fetch_8: 377 case Builtin::BI__sync_add_and_fetch_16: 378 return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_add, E, 379 llvm::Instruction::Add); 380 case Builtin::BI__sync_sub_and_fetch_1: 381 case Builtin::BI__sync_sub_and_fetch_2: 382 case Builtin::BI__sync_sub_and_fetch_4: 383 case Builtin::BI__sync_sub_and_fetch_8: 384 case Builtin::BI__sync_sub_and_fetch_16: 385 return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_sub, E, 386 llvm::Instruction::Sub); 387 case Builtin::BI__sync_and_and_fetch_1: 388 case Builtin::BI__sync_and_and_fetch_2: 389 case Builtin::BI__sync_and_and_fetch_4: 390 case Builtin::BI__sync_and_and_fetch_8: 391 case Builtin::BI__sync_and_and_fetch_16: 392 return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_and, E, 393 llvm::Instruction::And); 394 case Builtin::BI__sync_or_and_fetch_1: 395 case Builtin::BI__sync_or_and_fetch_2: 396 case Builtin::BI__sync_or_and_fetch_4: 397 case Builtin::BI__sync_or_and_fetch_8: 398 case Builtin::BI__sync_or_and_fetch_16: 399 return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_or, E, 400 llvm::Instruction::Or); 401 case Builtin::BI__sync_xor_and_fetch_1: 402 case Builtin::BI__sync_xor_and_fetch_2: 403 case Builtin::BI__sync_xor_and_fetch_4: 404 case Builtin::BI__sync_xor_and_fetch_8: 405 case Builtin::BI__sync_xor_and_fetch_16: 406 return EmitBinaryAtomicPost(*this, Intrinsic::atomic_load_xor, E, 407 llvm::Instruction::Xor); 408 409 case Builtin::BI__sync_val_compare_and_swap_1: 410 case Builtin::BI__sync_val_compare_and_swap_2: 411 case Builtin::BI__sync_val_compare_and_swap_4: 412 case Builtin::BI__sync_val_compare_and_swap_8: 413 case Builtin::BI__sync_val_compare_and_swap_16: 414 { 415 const llvm::Type *ResType[2]; 416 ResType[0]= ConvertType(E->getType()); 417 ResType[1] = ConvertType(E->getArg(0)->getType()); 418 Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap, ResType, 2); 419 return RValue::get(Builder.CreateCall3(AtomF, 420 EmitScalarExpr(E->getArg(0)), 421 EmitScalarExpr(E->getArg(1)), 422 EmitScalarExpr(E->getArg(2)))); 423 } 424 425 case Builtin::BI__sync_bool_compare_and_swap_1: 426 case Builtin::BI__sync_bool_compare_and_swap_2: 427 case Builtin::BI__sync_bool_compare_and_swap_4: 428 case Builtin::BI__sync_bool_compare_and_swap_8: 429 case Builtin::BI__sync_bool_compare_and_swap_16: 430 { 431 const llvm::Type *ResType[2]; 432 ResType[0]= ConvertType(E->getArg(1)->getType()); 433 ResType[1] = llvm::PointerType::getUnqual(ResType[0]); 434 Value *AtomF = CGM.getIntrinsic(Intrinsic::atomic_cmp_swap, ResType, 2); 435 Value *OldVal = EmitScalarExpr(E->getArg(1)); 436 Value *PrevVal = Builder.CreateCall3(AtomF, 437 EmitScalarExpr(E->getArg(0)), 438 OldVal, 439 EmitScalarExpr(E->getArg(2))); 440 Value *Result = Builder.CreateICmpEQ(PrevVal, OldVal); 441 // zext bool to int. 442 return RValue::get(Builder.CreateZExt(Result, ConvertType(E->getType()))); 443 } 444 445 case Builtin::BI__sync_lock_test_and_set_1: 446 case Builtin::BI__sync_lock_test_and_set_2: 447 case Builtin::BI__sync_lock_test_and_set_4: 448 case Builtin::BI__sync_lock_test_and_set_8: 449 case Builtin::BI__sync_lock_test_and_set_16: 450 return EmitBinaryAtomic(*this, Intrinsic::atomic_swap, E); 451 case Builtin::BI__sync_lock_release_1: 452 case Builtin::BI__sync_lock_release_2: 453 case Builtin::BI__sync_lock_release_4: 454 case Builtin::BI__sync_lock_release_8: 455 case Builtin::BI__sync_lock_release_16: 456 assert(0 && "FIXME: Implement"); 457 458 // Library functions with special handling. 459 460 case Builtin::BIsqrt: 461 case Builtin::BIsqrtf: 462 case Builtin::BIsqrtl: { 463 // Rewrite sqrt to intrinsic if allowed. 464 if (!FD->hasAttr<ConstAttr>()) 465 break; 466 Value *Arg0 = EmitScalarExpr(E->getArg(0)); 467 const llvm::Type *ArgType = Arg0->getType(); 468 Value *F = CGM.getIntrinsic(Intrinsic::sqrt, &ArgType, 1); 469 return RValue::get(Builder.CreateCall(F, Arg0, "tmp")); 470 } 471 472 case Builtin::BIpow: 473 case Builtin::BIpowf: 474 case Builtin::BIpowl: { 475 // Rewrite sqrt to intrinsic if allowed. 476 if (!FD->hasAttr<ConstAttr>()) 477 break; 478 Value *Base = EmitScalarExpr(E->getArg(0)); 479 Value *Exponent = EmitScalarExpr(E->getArg(1)); 480 const llvm::Type *ArgType = Base->getType(); 481 Value *F = CGM.getIntrinsic(Intrinsic::pow, &ArgType, 1); 482 return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp")); 483 } 484 } 485 486 // If this is an alias for a libm function (e.g. __builtin_sin) turn it into 487 // that function. 488 if (getContext().BuiltinInfo.isLibFunction(BuiltinID) || 489 getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID)) 490 return EmitCallExpr(CGM.getBuiltinLibFunction(BuiltinID), 491 E->getCallee()->getType(), E->arg_begin(), 492 E->arg_end()); 493 494 // See if we have a target specific intrinsic. 495 const char *Name = getContext().BuiltinInfo.GetName(BuiltinID); 496 Intrinsic::ID IntrinsicID = 497 Intrinsic::getIntrinsicForGCCBuiltin(Target.getTargetPrefix(), Name); 498 499 if (IntrinsicID != Intrinsic::not_intrinsic) { 500 SmallVector<Value*, 16> Args; 501 502 Function *F = CGM.getIntrinsic(IntrinsicID); 503 const llvm::FunctionType *FTy = F->getFunctionType(); 504 505 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 506 Value *ArgValue = EmitScalarExpr(E->getArg(i)); 507 508 // If the intrinsic arg type is different from the builtin arg type 509 // we need to do a bit cast. 510 const llvm::Type *PTy = FTy->getParamType(i); 511 if (PTy != ArgValue->getType()) { 512 assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) && 513 "Must be able to losslessly bit cast to param"); 514 ArgValue = Builder.CreateBitCast(ArgValue, PTy); 515 } 516 517 Args.push_back(ArgValue); 518 } 519 520 Value *V = Builder.CreateCall(F, &Args[0], &Args[0] + Args.size()); 521 QualType BuiltinRetType = E->getType(); 522 523 const llvm::Type *RetTy = llvm::Type::VoidTy; 524 if (!BuiltinRetType->isVoidType()) RetTy = ConvertType(BuiltinRetType); 525 526 if (RetTy != V->getType()) { 527 assert(V->getType()->canLosslesslyBitCastTo(RetTy) && 528 "Must be able to losslessly bit cast result type"); 529 V = Builder.CreateBitCast(V, RetTy); 530 } 531 532 return RValue::get(V); 533 } 534 535 // See if we have a target specific builtin that needs to be lowered. 536 if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E)) 537 return RValue::get(V); 538 539 ErrorUnsupported(E, "builtin function"); 540 541 // Unknown builtin, for now just dump it out and return undef. 542 if (hasAggregateLLVMType(E->getType())) 543 return RValue::getAggregate(CreateTempAlloca(ConvertType(E->getType()))); 544 return RValue::get(UndefValue::get(ConvertType(E->getType()))); 545} 546 547Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, 548 const CallExpr *E) { 549 const char *TargetPrefix = Target.getTargetPrefix(); 550 if (strcmp(TargetPrefix, "x86") == 0) 551 return EmitX86BuiltinExpr(BuiltinID, E); 552 else if (strcmp(TargetPrefix, "ppc") == 0) 553 return EmitPPCBuiltinExpr(BuiltinID, E); 554 return 0; 555} 556 557Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, 558 const CallExpr *E) { 559 560 llvm::SmallVector<Value*, 4> Ops; 561 562 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) 563 Ops.push_back(EmitScalarExpr(E->getArg(i))); 564 565 switch (BuiltinID) { 566 default: return 0; 567 case X86::BI__builtin_ia32_mulps: 568 return Builder.CreateMul(Ops[0], Ops[1], "mulps"); 569 case X86::BI__builtin_ia32_mulpd: 570 return Builder.CreateMul(Ops[0], Ops[1], "mulpd"); 571 case X86::BI__builtin_ia32_pand: 572 case X86::BI__builtin_ia32_pand128: 573 return Builder.CreateAnd(Ops[0], Ops[1], "pand"); 574 case X86::BI__builtin_ia32_por: 575 case X86::BI__builtin_ia32_por128: 576 return Builder.CreateOr(Ops[0], Ops[1], "por"); 577 case X86::BI__builtin_ia32_pxor: 578 case X86::BI__builtin_ia32_pxor128: 579 return Builder.CreateXor(Ops[0], Ops[1], "pxor"); 580 case X86::BI__builtin_ia32_pandn: 581 case X86::BI__builtin_ia32_pandn128: 582 Ops[0] = Builder.CreateNot(Ops[0], "tmp"); 583 return Builder.CreateAnd(Ops[0], Ops[1], "pandn"); 584 case X86::BI__builtin_ia32_paddb: 585 case X86::BI__builtin_ia32_paddb128: 586 case X86::BI__builtin_ia32_paddd: 587 case X86::BI__builtin_ia32_paddd128: 588 case X86::BI__builtin_ia32_paddq: 589 case X86::BI__builtin_ia32_paddq128: 590 case X86::BI__builtin_ia32_paddw: 591 case X86::BI__builtin_ia32_paddw128: 592 case X86::BI__builtin_ia32_addps: 593 case X86::BI__builtin_ia32_addpd: 594 return Builder.CreateAdd(Ops[0], Ops[1], "add"); 595 case X86::BI__builtin_ia32_psubb: 596 case X86::BI__builtin_ia32_psubb128: 597 case X86::BI__builtin_ia32_psubd: 598 case X86::BI__builtin_ia32_psubd128: 599 case X86::BI__builtin_ia32_psubq: 600 case X86::BI__builtin_ia32_psubq128: 601 case X86::BI__builtin_ia32_psubw: 602 case X86::BI__builtin_ia32_psubw128: 603 case X86::BI__builtin_ia32_subps: 604 case X86::BI__builtin_ia32_subpd: 605 return Builder.CreateSub(Ops[0], Ops[1], "sub"); 606 case X86::BI__builtin_ia32_divps: 607 return Builder.CreateFDiv(Ops[0], Ops[1], "divps"); 608 case X86::BI__builtin_ia32_divpd: 609 return Builder.CreateFDiv(Ops[0], Ops[1], "divpd"); 610 case X86::BI__builtin_ia32_pmullw: 611 case X86::BI__builtin_ia32_pmullw128: 612 return Builder.CreateMul(Ops[0], Ops[1], "pmul"); 613 case X86::BI__builtin_ia32_punpckhbw: 614 return EmitShuffleVector(Ops[0], Ops[1], 4, 12, 5, 13, 6, 14, 7, 15, 615 "punpckhbw"); 616 case X86::BI__builtin_ia32_punpckhbw128: 617 return EmitShuffleVector(Ops[0], Ops[1], 8, 24, 9, 25, 10, 26, 11, 27, 618 12, 28, 13, 29, 14, 30, 15, 31, 619 "punpckhbw"); 620 case X86::BI__builtin_ia32_punpckhwd: 621 return EmitShuffleVector(Ops[0], Ops[1], 2, 6, 3, 7, "punpckhwd"); 622 case X86::BI__builtin_ia32_punpckhwd128: 623 return EmitShuffleVector(Ops[0], Ops[1], 4, 12, 5, 13, 6, 14, 7, 15, 624 "punpckhwd"); 625 case X86::BI__builtin_ia32_punpckhdq: 626 return EmitShuffleVector(Ops[0], Ops[1], 1, 3, "punpckhdq"); 627 case X86::BI__builtin_ia32_punpckhdq128: 628 return EmitShuffleVector(Ops[0], Ops[1], 2, 6, 3, 7, "punpckhdq"); 629 case X86::BI__builtin_ia32_punpckhqdq128: 630 return EmitShuffleVector(Ops[0], Ops[1], 1, 3, "punpckhqdq"); 631 case X86::BI__builtin_ia32_punpcklbw: 632 return EmitShuffleVector(Ops[0], Ops[1], 0, 8, 1, 9, 2, 10, 3, 11, 633 "punpcklbw"); 634 case X86::BI__builtin_ia32_punpcklwd: 635 return EmitShuffleVector(Ops[0], Ops[1], 0, 4, 1, 5, "punpcklwd"); 636 case X86::BI__builtin_ia32_punpckldq: 637 return EmitShuffleVector(Ops[0], Ops[1], 0, 2, "punpckldq"); 638 case X86::BI__builtin_ia32_punpckldq128: 639 return EmitShuffleVector(Ops[0], Ops[1], 0, 4, 1, 5, "punpckldq"); 640 case X86::BI__builtin_ia32_punpcklqdq128: 641 return EmitShuffleVector(Ops[0], Ops[1], 0, 2, "punpcklqdq"); 642 case X86::BI__builtin_ia32_pslldi128: 643 case X86::BI__builtin_ia32_psllqi128: 644 case X86::BI__builtin_ia32_psllwi128: 645 case X86::BI__builtin_ia32_psradi128: 646 case X86::BI__builtin_ia32_psrawi128: 647 case X86::BI__builtin_ia32_psrldi128: 648 case X86::BI__builtin_ia32_psrlqi128: 649 case X86::BI__builtin_ia32_psrlwi128: { 650 Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::Int64Ty, "zext"); 651 const llvm::Type *Ty = llvm::VectorType::get(llvm::Type::Int64Ty, 2); 652 llvm::Value *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0); 653 Ops[1] = Builder.CreateInsertElement(llvm::UndefValue::get(Ty), 654 Ops[1], Zero, "insert"); 655 Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType(), "bitcast"); 656 const char *name = 0; 657 Intrinsic::ID ID = Intrinsic::not_intrinsic; 658 659 switch (BuiltinID) { 660 default: assert(0 && "Unsupported shift intrinsic!"); 661 case X86::BI__builtin_ia32_pslldi128: 662 name = "pslldi"; 663 ID = Intrinsic::x86_sse2_psll_d; 664 break; 665 case X86::BI__builtin_ia32_psllqi128: 666 name = "psllqi"; 667 ID = Intrinsic::x86_sse2_psll_q; 668 break; 669 case X86::BI__builtin_ia32_psllwi128: 670 name = "psllwi"; 671 ID = Intrinsic::x86_sse2_psll_w; 672 break; 673 case X86::BI__builtin_ia32_psradi128: 674 name = "psradi"; 675 ID = Intrinsic::x86_sse2_psra_d; 676 break; 677 case X86::BI__builtin_ia32_psrawi128: 678 name = "psrawi"; 679 ID = Intrinsic::x86_sse2_psra_w; 680 break; 681 case X86::BI__builtin_ia32_psrldi128: 682 name = "psrldi"; 683 ID = Intrinsic::x86_sse2_psrl_d; 684 break; 685 case X86::BI__builtin_ia32_psrlqi128: 686 name = "psrlqi"; 687 ID = Intrinsic::x86_sse2_psrl_q; 688 break; 689 case X86::BI__builtin_ia32_psrlwi128: 690 name = "psrlwi"; 691 ID = Intrinsic::x86_sse2_psrl_w; 692 break; 693 } 694 llvm::Function *F = CGM.getIntrinsic(ID); 695 return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name); 696 } 697 case X86::BI__builtin_ia32_pslldi: 698 case X86::BI__builtin_ia32_psllqi: 699 case X86::BI__builtin_ia32_psllwi: 700 case X86::BI__builtin_ia32_psradi: 701 case X86::BI__builtin_ia32_psrawi: 702 case X86::BI__builtin_ia32_psrldi: 703 case X86::BI__builtin_ia32_psrlqi: 704 case X86::BI__builtin_ia32_psrlwi: { 705 Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::Int64Ty, "zext"); 706 const llvm::Type *Ty = llvm::VectorType::get(llvm::Type::Int64Ty, 1); 707 Ops[1] = Builder.CreateBitCast(Ops[1], Ty, "bitcast"); 708 const char *name = 0; 709 Intrinsic::ID ID = Intrinsic::not_intrinsic; 710 711 switch (BuiltinID) { 712 default: assert(0 && "Unsupported shift intrinsic!"); 713 case X86::BI__builtin_ia32_pslldi: 714 name = "pslldi"; 715 ID = Intrinsic::x86_mmx_psll_d; 716 break; 717 case X86::BI__builtin_ia32_psllqi: 718 name = "psllqi"; 719 ID = Intrinsic::x86_mmx_psll_q; 720 break; 721 case X86::BI__builtin_ia32_psllwi: 722 name = "psllwi"; 723 ID = Intrinsic::x86_mmx_psll_w; 724 break; 725 case X86::BI__builtin_ia32_psradi: 726 name = "psradi"; 727 ID = Intrinsic::x86_mmx_psra_d; 728 break; 729 case X86::BI__builtin_ia32_psrawi: 730 name = "psrawi"; 731 ID = Intrinsic::x86_mmx_psra_w; 732 break; 733 case X86::BI__builtin_ia32_psrldi: 734 name = "psrldi"; 735 ID = Intrinsic::x86_mmx_psrl_d; 736 break; 737 case X86::BI__builtin_ia32_psrlqi: 738 name = "psrlqi"; 739 ID = Intrinsic::x86_mmx_psrl_q; 740 break; 741 case X86::BI__builtin_ia32_psrlwi: 742 name = "psrlwi"; 743 ID = Intrinsic::x86_mmx_psrl_w; 744 break; 745 } 746 llvm::Function *F = CGM.getIntrinsic(ID); 747 return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name); 748 } 749 case X86::BI__builtin_ia32_pshufw: { 750 unsigned i = cast<ConstantInt>(Ops[1])->getZExtValue(); 751 return EmitShuffleVector(Ops[0], Ops[0], 752 i & 0x3, (i & 0xc) >> 2, 753 (i & 0x30) >> 4, (i & 0xc0) >> 6, 754 "pshufw"); 755 } 756 case X86::BI__builtin_ia32_pshuflw: { 757 unsigned i = cast<ConstantInt>(Ops[1])->getZExtValue(); 758 return EmitShuffleVector(Ops[0], Ops[0], 759 i & 0x3, (i & 0xc) >> 2, 760 (i & 0x30) >> 4, (i & 0xc0) >> 6, 4, 5, 6, 7, 761 "pshuflw"); 762 } 763 case X86::BI__builtin_ia32_pshufhw: { 764 unsigned i = cast<ConstantInt>(Ops[1])->getZExtValue(); 765 return EmitShuffleVector(Ops[0], Ops[0], 0, 1, 2, 3, 766 4 + (i & 0x3), 4 + ((i & 0xc) >> 2), 767 4 + ((i & 0x30) >> 4), 4 + ((i & 0xc0) >> 6), 768 "pshufhw"); 769 } 770 case X86::BI__builtin_ia32_pshufd: { 771 unsigned i = cast<ConstantInt>(Ops[1])->getZExtValue(); 772 return EmitShuffleVector(Ops[0], Ops[0], 773 i & 0x3, (i & 0xc) >> 2, 774 (i & 0x30) >> 4, (i & 0xc0) >> 6, 775 "pshufd"); 776 } 777 case X86::BI__builtin_ia32_vec_init_v4hi: 778 case X86::BI__builtin_ia32_vec_init_v8qi: 779 case X86::BI__builtin_ia32_vec_init_v2si: 780 return EmitVector(&Ops[0], Ops.size()); 781 case X86::BI__builtin_ia32_vec_ext_v2si: 782 case X86::BI__builtin_ia32_vec_ext_v2di: 783 case X86::BI__builtin_ia32_vec_ext_v4sf: 784 case X86::BI__builtin_ia32_vec_ext_v4si: 785 case X86::BI__builtin_ia32_vec_ext_v8hi: 786 case X86::BI__builtin_ia32_vec_ext_v4hi: 787 case X86::BI__builtin_ia32_vec_ext_v2df: 788 return Builder.CreateExtractElement(Ops[0], Ops[1], "result"); 789 case X86::BI__builtin_ia32_cmpordss: 790 case X86::BI__builtin_ia32_cmpordsd: 791 case X86::BI__builtin_ia32_cmpunordss: 792 case X86::BI__builtin_ia32_cmpunordsd: 793 case X86::BI__builtin_ia32_cmpeqss: 794 case X86::BI__builtin_ia32_cmpeqsd: 795 case X86::BI__builtin_ia32_cmpltss: 796 case X86::BI__builtin_ia32_cmpltsd: 797 case X86::BI__builtin_ia32_cmpless: 798 case X86::BI__builtin_ia32_cmplesd: 799 case X86::BI__builtin_ia32_cmpneqss: 800 case X86::BI__builtin_ia32_cmpneqsd: 801 case X86::BI__builtin_ia32_cmpnltss: 802 case X86::BI__builtin_ia32_cmpnltsd: 803 case X86::BI__builtin_ia32_cmpnless: 804 case X86::BI__builtin_ia32_cmpnlesd: { 805 unsigned i = 0; 806 const char *name = 0; 807 switch (BuiltinID) { 808 default: assert(0 && "Unknown compare builtin!"); 809 case X86::BI__builtin_ia32_cmpeqss: 810 case X86::BI__builtin_ia32_cmpeqsd: 811 i = 0; 812 name = "cmpeq"; 813 break; 814 case X86::BI__builtin_ia32_cmpltss: 815 case X86::BI__builtin_ia32_cmpltsd: 816 i = 1; 817 name = "cmplt"; 818 break; 819 case X86::BI__builtin_ia32_cmpless: 820 case X86::BI__builtin_ia32_cmplesd: 821 i = 2; 822 name = "cmple"; 823 break; 824 case X86::BI__builtin_ia32_cmpunordss: 825 case X86::BI__builtin_ia32_cmpunordsd: 826 i = 3; 827 name = "cmpunord"; 828 break; 829 case X86::BI__builtin_ia32_cmpneqss: 830 case X86::BI__builtin_ia32_cmpneqsd: 831 i = 4; 832 name = "cmpneq"; 833 break; 834 case X86::BI__builtin_ia32_cmpnltss: 835 case X86::BI__builtin_ia32_cmpnltsd: 836 i = 5; 837 name = "cmpntl"; 838 break; 839 case X86::BI__builtin_ia32_cmpnless: 840 case X86::BI__builtin_ia32_cmpnlesd: 841 i = 6; 842 name = "cmpnle"; 843 break; 844 case X86::BI__builtin_ia32_cmpordss: 845 case X86::BI__builtin_ia32_cmpordsd: 846 i = 7; 847 name = "cmpord"; 848 break; 849 } 850 851 llvm::Function *F; 852 if (cast<llvm::VectorType>(Ops[0]->getType())->getElementType() == 853 llvm::Type::FloatTy) 854 F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ss); 855 else 856 F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_sd); 857 858 Ops.push_back(llvm::ConstantInt::get(llvm::Type::Int8Ty, i)); 859 return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name); 860 } 861 case X86::BI__builtin_ia32_ldmxcsr: { 862 llvm::Type *PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 863 Value *One = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1); 864 Value *Tmp = Builder.CreateAlloca(llvm::Type::Int32Ty, One, "tmp"); 865 Builder.CreateStore(Ops[0], Tmp); 866 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr), 867 Builder.CreateBitCast(Tmp, PtrTy)); 868 } 869 case X86::BI__builtin_ia32_stmxcsr: { 870 llvm::Type *PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 871 Value *One = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1); 872 Value *Tmp = Builder.CreateAlloca(llvm::Type::Int32Ty, One, "tmp"); 873 One = Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr), 874 Builder.CreateBitCast(Tmp, PtrTy)); 875 return Builder.CreateLoad(Tmp, "stmxcsr"); 876 } 877 case X86::BI__builtin_ia32_cmpordps: 878 case X86::BI__builtin_ia32_cmpordpd: 879 case X86::BI__builtin_ia32_cmpunordps: 880 case X86::BI__builtin_ia32_cmpunordpd: 881 case X86::BI__builtin_ia32_cmpeqps: 882 case X86::BI__builtin_ia32_cmpeqpd: 883 case X86::BI__builtin_ia32_cmpltps: 884 case X86::BI__builtin_ia32_cmpltpd: 885 case X86::BI__builtin_ia32_cmpleps: 886 case X86::BI__builtin_ia32_cmplepd: 887 case X86::BI__builtin_ia32_cmpneqps: 888 case X86::BI__builtin_ia32_cmpneqpd: 889 case X86::BI__builtin_ia32_cmpngtps: 890 case X86::BI__builtin_ia32_cmpngtpd: 891 case X86::BI__builtin_ia32_cmpnltps: 892 case X86::BI__builtin_ia32_cmpnltpd: 893 case X86::BI__builtin_ia32_cmpgtps: 894 case X86::BI__builtin_ia32_cmpgtpd: 895 case X86::BI__builtin_ia32_cmpgeps: 896 case X86::BI__builtin_ia32_cmpgepd: 897 case X86::BI__builtin_ia32_cmpngeps: 898 case X86::BI__builtin_ia32_cmpngepd: 899 case X86::BI__builtin_ia32_cmpnleps: 900 case X86::BI__builtin_ia32_cmpnlepd: { 901 unsigned i = 0; 902 const char *name = 0; 903 bool ShouldSwap = false; 904 switch (BuiltinID) { 905 default: assert(0 && "Unknown compare builtin!"); 906 case X86::BI__builtin_ia32_cmpeqps: 907 case X86::BI__builtin_ia32_cmpeqpd: i = 0; name = "cmpeq"; break; 908 case X86::BI__builtin_ia32_cmpltps: 909 case X86::BI__builtin_ia32_cmpltpd: i = 1; name = "cmplt"; break; 910 case X86::BI__builtin_ia32_cmpleps: 911 case X86::BI__builtin_ia32_cmplepd: i = 2; name = "cmple"; break; 912 case X86::BI__builtin_ia32_cmpunordps: 913 case X86::BI__builtin_ia32_cmpunordpd: i = 3; name = "cmpunord"; break; 914 case X86::BI__builtin_ia32_cmpneqps: 915 case X86::BI__builtin_ia32_cmpneqpd: i = 4; name = "cmpneq"; break; 916 case X86::BI__builtin_ia32_cmpnltps: 917 case X86::BI__builtin_ia32_cmpnltpd: i = 5; name = "cmpntl"; break; 918 case X86::BI__builtin_ia32_cmpnleps: 919 case X86::BI__builtin_ia32_cmpnlepd: i = 6; name = "cmpnle"; break; 920 case X86::BI__builtin_ia32_cmpordps: 921 case X86::BI__builtin_ia32_cmpordpd: i = 7; name = "cmpord"; break; 922 case X86::BI__builtin_ia32_cmpgtps: 923 case X86::BI__builtin_ia32_cmpgtpd: 924 ShouldSwap = true; 925 i = 1; 926 name = "cmpgt"; 927 break; 928 case X86::BI__builtin_ia32_cmpgeps: 929 case X86::BI__builtin_ia32_cmpgepd: 930 i = 2; 931 name = "cmpge"; 932 ShouldSwap = true; 933 break; 934 case X86::BI__builtin_ia32_cmpngtps: 935 case X86::BI__builtin_ia32_cmpngtpd: 936 i = 5; 937 name = "cmpngt"; 938 ShouldSwap = true; 939 break; 940 case X86::BI__builtin_ia32_cmpngeps: 941 case X86::BI__builtin_ia32_cmpngepd: 942 i = 6; 943 name = "cmpnge"; 944 ShouldSwap = true; 945 break; 946 } 947 948 if (ShouldSwap) 949 std::swap(Ops[0], Ops[1]); 950 951 llvm::Function *F; 952 if (cast<llvm::VectorType>(Ops[0]->getType())->getElementType() == 953 llvm::Type::FloatTy) 954 F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ps); 955 else 956 F = CGM.getIntrinsic(Intrinsic::x86_sse2_cmp_pd); 957 958 Ops.push_back(llvm::ConstantInt::get(llvm::Type::Int8Ty, i)); 959 return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name); 960 } 961 case X86::BI__builtin_ia32_movss: 962 return EmitShuffleVector(Ops[0], Ops[1], 4, 1, 2, 3, "movss"); 963 case X86::BI__builtin_ia32_shufps: { 964 unsigned i = cast<ConstantInt>(Ops[2])->getZExtValue(); 965 return EmitShuffleVector(Ops[0], Ops[1], 966 i & 0x3, (i & 0xc) >> 2, 967 ((i & 0x30) >> 4) + 4, 968 ((i & 0xc0) >> 6) + 4, "shufps"); 969 } 970 case X86::BI__builtin_ia32_shufpd: { 971 unsigned i = cast<ConstantInt>(Ops[2])->getZExtValue(); 972 return EmitShuffleVector(Ops[0], Ops[1], i & 1, 973 ((i & 2) >> 1)+2, "shufpd"); 974 } 975 case X86::BI__builtin_ia32_punpcklbw128: 976 return EmitShuffleVector(Ops[0], Ops[1], 0, 16, 1, 17, 2, 18, 3, 19, 977 4, 20, 5, 21, 6, 22, 7, 23, 978 "punpcklbw"); 979 case X86::BI__builtin_ia32_punpcklwd128: 980 return EmitShuffleVector(Ops[0], Ops[1], 0, 8, 1, 9, 2, 10, 3, 11, 981 "punpcklwd"); 982 case X86::BI__builtin_ia32_movlhps: 983 return EmitShuffleVector(Ops[0], Ops[1], 0, 1, 4, 5, "movlhps"); 984 case X86::BI__builtin_ia32_movhlps: 985 return EmitShuffleVector(Ops[0], Ops[1], 6, 7, 2, 3, "movhlps"); 986 case X86::BI__builtin_ia32_unpckhps: 987 return EmitShuffleVector(Ops[0], Ops[1], 2, 6, 3, 7, "unpckhps"); 988 case X86::BI__builtin_ia32_unpcklps: 989 return EmitShuffleVector(Ops[0], Ops[1], 0, 4, 1, 5, "unpcklps"); 990 case X86::BI__builtin_ia32_unpckhpd: 991 return EmitShuffleVector(Ops[0], Ops[1], 1, 3, "unpckhpd"); 992 case X86::BI__builtin_ia32_unpcklpd: 993 return EmitShuffleVector(Ops[0], Ops[1], 0, 2, "unpcklpd"); 994 case X86::BI__builtin_ia32_movsd: 995 return EmitShuffleVector(Ops[0], Ops[1], 2, 1, "movsd"); 996 case X86::BI__builtin_ia32_movqv4si: { 997 llvm::Type *Ty = llvm::VectorType::get(llvm::Type::Int64Ty, 2); 998 return Builder.CreateBitCast(Ops[0], Ty); 999 } 1000 case X86::BI__builtin_ia32_loadlps: 1001 case X86::BI__builtin_ia32_loadhps: { 1002 // FIXME: This should probably be represented as 1003 // shuffle (dst, (v4f32 (insert undef, (load i64), 0)), shuf mask hi/lo) 1004 const llvm::Type *EltTy = llvm::Type::DoubleTy; 1005 const llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2); 1006 const llvm::Type *OrigTy = Ops[0]->getType(); 1007 unsigned Index = BuiltinID == X86::BI__builtin_ia32_loadlps ? 0 : 1; 1008 llvm::Value *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, Index); 1009 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::PointerType::getUnqual(EltTy)); 1010 Ops[1] = Builder.CreateLoad(Ops[1], "tmp"); 1011 Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 1012 Ops[0] = Builder.CreateInsertElement(Ops[0], Ops[1], Idx, "loadps"); 1013 return Builder.CreateBitCast(Ops[0], OrigTy, "loadps"); 1014 } 1015 case X86::BI__builtin_ia32_loadlpd: 1016 case X86::BI__builtin_ia32_loadhpd: { 1017 Ops[1] = Builder.CreateLoad(Ops[1], "tmp"); 1018 unsigned Index = BuiltinID == X86::BI__builtin_ia32_loadlpd ? 0 : 1; 1019 llvm::Value *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, Index); 1020 return Builder.CreateInsertElement(Ops[0], Ops[1], Idx, "loadpd"); 1021 } 1022 case X86::BI__builtin_ia32_storehps: 1023 case X86::BI__builtin_ia32_storelps: { 1024 const llvm::Type *EltTy = llvm::Type::Int64Ty; 1025 llvm::Type *PtrTy = llvm::PointerType::getUnqual(EltTy); 1026 llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2); 1027 1028 // cast val v2i64 1029 Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast"); 1030 1031 // extract (0, 1) 1032 unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1; 1033 llvm::Value *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, Index); 1034 Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract"); 1035 1036 // cast pointer to i64 & store 1037 Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy); 1038 return Builder.CreateStore(Ops[1], Ops[0]); 1039 } 1040 case X86::BI__builtin_ia32_loadlv4si: { 1041 // load i64 1042 const llvm::Type *EltTy = llvm::Type::Int64Ty; 1043 llvm::Type *PtrTy = llvm::PointerType::getUnqual(EltTy); 1044 Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy); 1045 Ops[0] = Builder.CreateLoad(Ops[0], "load"); 1046 1047 // scalar to vector: insert i64 into 2 x i64 undef 1048 llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2); 1049 llvm::Value *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0); 1050 Ops[0] = Builder.CreateInsertElement(llvm::UndefValue::get(VecTy), 1051 Ops[0], Zero, "s2v"); 1052 1053 // shuffle into zero vector. 1054 std::vector<llvm::Constant *>Elts; 1055 Elts.resize(2, llvm::ConstantInt::get(EltTy, 0)); 1056 llvm::Value *ZV = ConstantVector::get(Elts); 1057 Ops[0] = EmitShuffleVector(ZV, Ops[0], 2, 1, "loadl"); 1058 1059 // bitcast to result. 1060 return Builder.CreateBitCast(Ops[0], 1061 llvm::VectorType::get(llvm::Type::Int32Ty, 4)); 1062 } 1063 case X86::BI__builtin_ia32_vec_set_v4hi: 1064 case X86::BI__builtin_ia32_vec_set_v8hi: 1065 return Builder.CreateInsertElement(Ops[0], Ops[1], Ops[2], "pinsrw"); 1066 case X86::BI__builtin_ia32_vec_set_v4si: 1067 return Builder.CreateInsertElement(Ops[0], Ops[1], Ops[2], "pinsrd"); 1068 case X86::BI__builtin_ia32_vec_set_v2di: 1069 return Builder.CreateInsertElement(Ops[0], Ops[1], Ops[2], "pinsrq"); 1070 case X86::BI__builtin_ia32_andps: 1071 case X86::BI__builtin_ia32_andpd: 1072 case X86::BI__builtin_ia32_andnps: 1073 case X86::BI__builtin_ia32_andnpd: 1074 case X86::BI__builtin_ia32_orps: 1075 case X86::BI__builtin_ia32_orpd: 1076 case X86::BI__builtin_ia32_xorpd: 1077 case X86::BI__builtin_ia32_xorps: { 1078 const llvm::Type *ITy = llvm::VectorType::get(llvm::Type::Int32Ty, 4); 1079 const llvm::Type *FTy = Ops[0]->getType(); 1080 Ops[0] = Builder.CreateBitCast(Ops[0], ITy, "bitcast"); 1081 Ops[1] = Builder.CreateBitCast(Ops[1], ITy, "bitcast"); 1082 switch (BuiltinID) { 1083 case X86::BI__builtin_ia32_andps: 1084 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1], "andps"); 1085 break; 1086 case X86::BI__builtin_ia32_andpd: 1087 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1], "andpd"); 1088 break; 1089 case X86::BI__builtin_ia32_andnps: 1090 Ops[0] = Builder.CreateNot(Ops[0], "not"); 1091 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1], "andnps"); 1092 break; 1093 case X86::BI__builtin_ia32_andnpd: 1094 Ops[0] = Builder.CreateNot(Ops[0], "not"); 1095 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1], "andnpd"); 1096 break; 1097 case X86::BI__builtin_ia32_orps: 1098 Ops[0] = Builder.CreateOr(Ops[0], Ops[1], "orps"); 1099 break; 1100 case X86::BI__builtin_ia32_orpd: 1101 Ops[0] = Builder.CreateOr(Ops[0], Ops[1], "orpd"); 1102 break; 1103 case X86::BI__builtin_ia32_xorps: 1104 Ops[0] = Builder.CreateXor(Ops[0], Ops[1], "xorps"); 1105 break; 1106 case X86::BI__builtin_ia32_xorpd: 1107 Ops[0] = Builder.CreateXor(Ops[0], Ops[1], "xorpd"); 1108 break; 1109 } 1110 return Builder.CreateBitCast(Ops[0], FTy, "bitcast"); 1111 } 1112 } 1113} 1114 1115Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, 1116 const CallExpr *E) { 1117 switch (BuiltinID) { 1118 default: return 0; 1119 } 1120} 1121