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 "CGObjCRuntime.h" 16 #include "CodeGenModule.h" 17 #include "TargetInfo.h" 18 #include "clang/AST/ASTContext.h" 19 #include "clang/AST/Decl.h" 20 #include "clang/Basic/TargetBuiltins.h" 21 #include "clang/Basic/TargetInfo.h" 22 #include "clang/CodeGen/CGFunctionInfo.h" 23 #include "llvm/IR/DataLayout.h" 24 #include "llvm/IR/Intrinsics.h" 25 26 using namespace clang; 27 using namespace CodeGen; 28 using namespace llvm; 29 30 /// getBuiltinLibFunction - Given a builtin id for a function like 31 /// "__builtin_fabsf", return a Function* for "fabsf". 32 llvm::Value *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD, 33 unsigned BuiltinID) { 34 assert(Context.BuiltinInfo.isLibFunction(BuiltinID)); 35 36 // Get the name, skip over the __builtin_ prefix (if necessary). 37 StringRef Name; 38 GlobalDecl D(FD); 39 40 // If the builtin has been declared explicitly with an assembler label, 41 // use the mangled name. This differs from the plain label on platforms 42 // that prefix labels. 43 if (FD->hasAttr<AsmLabelAttr>()) 44 Name = getMangledName(D); 45 else 46 Name = Context.BuiltinInfo.GetName(BuiltinID) + 10; 47 48 llvm::FunctionType *Ty = 49 cast<llvm::FunctionType>(getTypes().ConvertType(FD->getType())); 50 51 return GetOrCreateLLVMFunction(Name, Ty, D, /*ForVTable=*/false); 52 } 53 54 /// Emit the conversions required to turn the given value into an 55 /// integer of the given size. 56 static Value *EmitToInt(CodeGenFunction &CGF, llvm::Value *V, 57 QualType T, llvm::IntegerType *IntType) { 58 V = CGF.EmitToMemory(V, T); 59 60 if (V->getType()->isPointerTy()) 61 return CGF.Builder.CreatePtrToInt(V, IntType); 62 63 assert(V->getType() == IntType); 64 return V; 65 } 66 67 static Value *EmitFromInt(CodeGenFunction &CGF, llvm::Value *V, 68 QualType T, llvm::Type *ResultType) { 69 V = CGF.EmitFromMemory(V, T); 70 71 if (ResultType->isPointerTy()) 72 return CGF.Builder.CreateIntToPtr(V, ResultType); 73 74 assert(V->getType() == ResultType); 75 return V; 76 } 77 78 /// Utility to insert an atomic instruction based on Instrinsic::ID 79 /// and the expression node. 80 static RValue EmitBinaryAtomic(CodeGenFunction &CGF, 81 llvm::AtomicRMWInst::BinOp Kind, 82 const CallExpr *E) { 83 QualType T = E->getType(); 84 assert(E->getArg(0)->getType()->isPointerType()); 85 assert(CGF.getContext().hasSameUnqualifiedType(T, 86 E->getArg(0)->getType()->getPointeeType())); 87 assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType())); 88 89 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); 90 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); 91 92 llvm::IntegerType *IntType = 93 llvm::IntegerType::get(CGF.getLLVMContext(), 94 CGF.getContext().getTypeSize(T)); 95 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 96 97 llvm::Value *Args[2]; 98 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType); 99 Args[1] = CGF.EmitScalarExpr(E->getArg(1)); 100 llvm::Type *ValueType = Args[1]->getType(); 101 Args[1] = EmitToInt(CGF, Args[1], T, IntType); 102 103 llvm::Value *Result = 104 CGF.Builder.CreateAtomicRMW(Kind, Args[0], Args[1], 105 llvm::SequentiallyConsistent); 106 Result = EmitFromInt(CGF, Result, T, ValueType); 107 return RValue::get(Result); 108 } 109 110 /// Utility to insert an atomic instruction based Instrinsic::ID and 111 /// the expression node, where the return value is the result of the 112 /// operation. 113 static RValue EmitBinaryAtomicPost(CodeGenFunction &CGF, 114 llvm::AtomicRMWInst::BinOp Kind, 115 const CallExpr *E, 116 Instruction::BinaryOps Op) { 117 QualType T = E->getType(); 118 assert(E->getArg(0)->getType()->isPointerType()); 119 assert(CGF.getContext().hasSameUnqualifiedType(T, 120 E->getArg(0)->getType()->getPointeeType())); 121 assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType())); 122 123 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); 124 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); 125 126 llvm::IntegerType *IntType = 127 llvm::IntegerType::get(CGF.getLLVMContext(), 128 CGF.getContext().getTypeSize(T)); 129 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 130 131 llvm::Value *Args[2]; 132 Args[1] = CGF.EmitScalarExpr(E->getArg(1)); 133 llvm::Type *ValueType = Args[1]->getType(); 134 Args[1] = EmitToInt(CGF, Args[1], T, IntType); 135 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType); 136 137 llvm::Value *Result = 138 CGF.Builder.CreateAtomicRMW(Kind, Args[0], Args[1], 139 llvm::SequentiallyConsistent); 140 Result = CGF.Builder.CreateBinOp(Op, Result, Args[1]); 141 Result = EmitFromInt(CGF, Result, T, ValueType); 142 return RValue::get(Result); 143 } 144 145 /// EmitFAbs - Emit a call to fabs/fabsf/fabsl, depending on the type of ValTy, 146 /// which must be a scalar floating point type. 147 static Value *EmitFAbs(CodeGenFunction &CGF, Value *V, QualType ValTy) { 148 const BuiltinType *ValTyP = ValTy->getAs<BuiltinType>(); 149 assert(ValTyP && "isn't scalar fp type!"); 150 151 StringRef FnName; 152 switch (ValTyP->getKind()) { 153 default: llvm_unreachable("Isn't a scalar fp type!"); 154 case BuiltinType::Float: FnName = "fabsf"; break; 155 case BuiltinType::Double: FnName = "fabs"; break; 156 case BuiltinType::LongDouble: FnName = "fabsl"; break; 157 } 158 159 // The prototype is something that takes and returns whatever V's type is. 160 llvm::FunctionType *FT = llvm::FunctionType::get(V->getType(), V->getType(), 161 false); 162 llvm::Value *Fn = CGF.CGM.CreateRuntimeFunction(FT, FnName); 163 164 return CGF.EmitNounwindRuntimeCall(Fn, V, "abs"); 165 } 166 167 static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *Fn, 168 const CallExpr *E, llvm::Value *calleeValue) { 169 return CGF.EmitCall(E->getCallee()->getType(), calleeValue, E->getLocStart(), 170 ReturnValueSlot(), E->arg_begin(), E->arg_end(), Fn); 171 } 172 173 /// \brief Emit a call to llvm.{sadd,uadd,ssub,usub,smul,umul}.with.overflow.* 174 /// depending on IntrinsicID. 175 /// 176 /// \arg CGF The current codegen function. 177 /// \arg IntrinsicID The ID for the Intrinsic we wish to generate. 178 /// \arg X The first argument to the llvm.*.with.overflow.*. 179 /// \arg Y The second argument to the llvm.*.with.overflow.*. 180 /// \arg Carry The carry returned by the llvm.*.with.overflow.*. 181 /// \returns The result (i.e. sum/product) returned by the intrinsic. 182 static llvm::Value *EmitOverflowIntrinsic(CodeGenFunction &CGF, 183 const llvm::Intrinsic::ID IntrinsicID, 184 llvm::Value *X, llvm::Value *Y, 185 llvm::Value *&Carry) { 186 // Make sure we have integers of the same width. 187 assert(X->getType() == Y->getType() && 188 "Arguments must be the same type. (Did you forget to make sure both " 189 "arguments have the same integer width?)"); 190 191 llvm::Value *Callee = CGF.CGM.getIntrinsic(IntrinsicID, X->getType()); 192 llvm::Value *Tmp = CGF.Builder.CreateCall2(Callee, X, Y); 193 Carry = CGF.Builder.CreateExtractValue(Tmp, 1); 194 return CGF.Builder.CreateExtractValue(Tmp, 0); 195 } 196 197 RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, 198 unsigned BuiltinID, const CallExpr *E) { 199 // See if we can constant fold this builtin. If so, don't emit it at all. 200 Expr::EvalResult Result; 201 if (E->EvaluateAsRValue(Result, CGM.getContext()) && 202 !Result.hasSideEffects()) { 203 if (Result.Val.isInt()) 204 return RValue::get(llvm::ConstantInt::get(getLLVMContext(), 205 Result.Val.getInt())); 206 if (Result.Val.isFloat()) 207 return RValue::get(llvm::ConstantFP::get(getLLVMContext(), 208 Result.Val.getFloat())); 209 } 210 211 switch (BuiltinID) { 212 default: break; // Handle intrinsics and libm functions below. 213 case Builtin::BI__builtin___CFStringMakeConstantString: 214 case Builtin::BI__builtin___NSStringMakeConstantString: 215 return RValue::get(CGM.EmitConstantExpr(E, E->getType(), 0)); 216 case Builtin::BI__builtin_stdarg_start: 217 case Builtin::BI__builtin_va_start: 218 case Builtin::BI__va_start: 219 case Builtin::BI__builtin_va_end: { 220 Value *ArgValue = (BuiltinID == Builtin::BI__va_start) 221 ? EmitScalarExpr(E->getArg(0)) 222 : EmitVAListRef(E->getArg(0)); 223 llvm::Type *DestType = Int8PtrTy; 224 if (ArgValue->getType() != DestType) 225 ArgValue = Builder.CreateBitCast(ArgValue, DestType, 226 ArgValue->getName().data()); 227 228 Intrinsic::ID inst = (BuiltinID == Builtin::BI__builtin_va_end) ? 229 Intrinsic::vaend : Intrinsic::vastart; 230 return RValue::get(Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue)); 231 } 232 case Builtin::BI__builtin_va_copy: { 233 Value *DstPtr = EmitVAListRef(E->getArg(0)); 234 Value *SrcPtr = EmitVAListRef(E->getArg(1)); 235 236 llvm::Type *Type = Int8PtrTy; 237 238 DstPtr = Builder.CreateBitCast(DstPtr, Type); 239 SrcPtr = Builder.CreateBitCast(SrcPtr, Type); 240 return RValue::get(Builder.CreateCall2(CGM.getIntrinsic(Intrinsic::vacopy), 241 DstPtr, SrcPtr)); 242 } 243 case Builtin::BI__builtin_abs: 244 case Builtin::BI__builtin_labs: 245 case Builtin::BI__builtin_llabs: { 246 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 247 248 Value *NegOp = Builder.CreateNeg(ArgValue, "neg"); 249 Value *CmpResult = 250 Builder.CreateICmpSGE(ArgValue, 251 llvm::Constant::getNullValue(ArgValue->getType()), 252 "abscond"); 253 Value *Result = 254 Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs"); 255 256 return RValue::get(Result); 257 } 258 259 case Builtin::BI__builtin_conj: 260 case Builtin::BI__builtin_conjf: 261 case Builtin::BI__builtin_conjl: { 262 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); 263 Value *Real = ComplexVal.first; 264 Value *Imag = ComplexVal.second; 265 Value *Zero = 266 Imag->getType()->isFPOrFPVectorTy() 267 ? llvm::ConstantFP::getZeroValueForNegation(Imag->getType()) 268 : llvm::Constant::getNullValue(Imag->getType()); 269 270 Imag = Builder.CreateFSub(Zero, Imag, "sub"); 271 return RValue::getComplex(std::make_pair(Real, Imag)); 272 } 273 case Builtin::BI__builtin_creal: 274 case Builtin::BI__builtin_crealf: 275 case Builtin::BI__builtin_creall: 276 case Builtin::BIcreal: 277 case Builtin::BIcrealf: 278 case Builtin::BIcreall: { 279 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); 280 return RValue::get(ComplexVal.first); 281 } 282 283 case Builtin::BI__builtin_cimag: 284 case Builtin::BI__builtin_cimagf: 285 case Builtin::BI__builtin_cimagl: 286 case Builtin::BIcimag: 287 case Builtin::BIcimagf: 288 case Builtin::BIcimagl: { 289 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); 290 return RValue::get(ComplexVal.second); 291 } 292 293 case Builtin::BI__builtin_ctzs: 294 case Builtin::BI__builtin_ctz: 295 case Builtin::BI__builtin_ctzl: 296 case Builtin::BI__builtin_ctzll: { 297 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 298 299 llvm::Type *ArgType = ArgValue->getType(); 300 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType); 301 302 llvm::Type *ResultType = ConvertType(E->getType()); 303 Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef()); 304 Value *Result = Builder.CreateCall2(F, ArgValue, ZeroUndef); 305 if (Result->getType() != ResultType) 306 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 307 "cast"); 308 return RValue::get(Result); 309 } 310 case Builtin::BI__builtin_clzs: 311 case Builtin::BI__builtin_clz: 312 case Builtin::BI__builtin_clzl: 313 case Builtin::BI__builtin_clzll: { 314 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 315 316 llvm::Type *ArgType = ArgValue->getType(); 317 Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType); 318 319 llvm::Type *ResultType = ConvertType(E->getType()); 320 Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef()); 321 Value *Result = Builder.CreateCall2(F, ArgValue, ZeroUndef); 322 if (Result->getType() != ResultType) 323 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 324 "cast"); 325 return RValue::get(Result); 326 } 327 case Builtin::BI__builtin_ffs: 328 case Builtin::BI__builtin_ffsl: 329 case Builtin::BI__builtin_ffsll: { 330 // ffs(x) -> x ? cttz(x) + 1 : 0 331 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 332 333 llvm::Type *ArgType = ArgValue->getType(); 334 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType); 335 336 llvm::Type *ResultType = ConvertType(E->getType()); 337 Value *Tmp = Builder.CreateAdd(Builder.CreateCall2(F, ArgValue, 338 Builder.getTrue()), 339 llvm::ConstantInt::get(ArgType, 1)); 340 Value *Zero = llvm::Constant::getNullValue(ArgType); 341 Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero"); 342 Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp, "ffs"); 343 if (Result->getType() != ResultType) 344 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 345 "cast"); 346 return RValue::get(Result); 347 } 348 case Builtin::BI__builtin_parity: 349 case Builtin::BI__builtin_parityl: 350 case Builtin::BI__builtin_parityll: { 351 // parity(x) -> ctpop(x) & 1 352 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 353 354 llvm::Type *ArgType = ArgValue->getType(); 355 Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType); 356 357 llvm::Type *ResultType = ConvertType(E->getType()); 358 Value *Tmp = Builder.CreateCall(F, ArgValue); 359 Value *Result = Builder.CreateAnd(Tmp, llvm::ConstantInt::get(ArgType, 1)); 360 if (Result->getType() != ResultType) 361 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 362 "cast"); 363 return RValue::get(Result); 364 } 365 case Builtin::BI__builtin_popcount: 366 case Builtin::BI__builtin_popcountl: 367 case Builtin::BI__builtin_popcountll: { 368 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 369 370 llvm::Type *ArgType = ArgValue->getType(); 371 Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType); 372 373 llvm::Type *ResultType = ConvertType(E->getType()); 374 Value *Result = Builder.CreateCall(F, ArgValue); 375 if (Result->getType() != ResultType) 376 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 377 "cast"); 378 return RValue::get(Result); 379 } 380 case Builtin::BI__builtin_expect: { 381 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 382 llvm::Type *ArgType = ArgValue->getType(); 383 384 Value *FnExpect = CGM.getIntrinsic(Intrinsic::expect, ArgType); 385 Value *ExpectedValue = EmitScalarExpr(E->getArg(1)); 386 387 Value *Result = Builder.CreateCall2(FnExpect, ArgValue, ExpectedValue, 388 "expval"); 389 return RValue::get(Result); 390 } 391 case Builtin::BI__builtin_bswap16: 392 case Builtin::BI__builtin_bswap32: 393 case Builtin::BI__builtin_bswap64: { 394 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 395 llvm::Type *ArgType = ArgValue->getType(); 396 Value *F = CGM.getIntrinsic(Intrinsic::bswap, ArgType); 397 return RValue::get(Builder.CreateCall(F, ArgValue)); 398 } 399 case Builtin::BI__builtin_object_size: { 400 // We rely on constant folding to deal with expressions with side effects. 401 assert(!E->getArg(0)->HasSideEffects(getContext()) && 402 "should have been constant folded"); 403 404 // We pass this builtin onto the optimizer so that it can 405 // figure out the object size in more complex cases. 406 llvm::Type *ResType = ConvertType(E->getType()); 407 408 // LLVM only supports 0 and 2, make sure that we pass along that 409 // as a boolean. 410 Value *Ty = EmitScalarExpr(E->getArg(1)); 411 ConstantInt *CI = dyn_cast<ConstantInt>(Ty); 412 assert(CI); 413 uint64_t val = CI->getZExtValue(); 414 CI = ConstantInt::get(Builder.getInt1Ty(), (val & 0x2) >> 1); 415 // FIXME: Get right address space. 416 llvm::Type *Tys[] = { ResType, Builder.getInt8PtrTy(0) }; 417 Value *F = CGM.getIntrinsic(Intrinsic::objectsize, Tys); 418 return RValue::get(Builder.CreateCall2(F, EmitScalarExpr(E->getArg(0)),CI)); 419 } 420 case Builtin::BI__builtin_prefetch: { 421 Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0)); 422 // FIXME: Technically these constants should of type 'int', yes? 423 RW = (E->getNumArgs() > 1) ? EmitScalarExpr(E->getArg(1)) : 424 llvm::ConstantInt::get(Int32Ty, 0); 425 Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : 426 llvm::ConstantInt::get(Int32Ty, 3); 427 Value *Data = llvm::ConstantInt::get(Int32Ty, 1); 428 Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 429 return RValue::get(Builder.CreateCall4(F, Address, RW, Locality, Data)); 430 } 431 case Builtin::BI__builtin_readcyclecounter: { 432 Value *F = CGM.getIntrinsic(Intrinsic::readcyclecounter); 433 return RValue::get(Builder.CreateCall(F)); 434 } 435 case Builtin::BI__builtin___clear_cache: { 436 Value *Begin = EmitScalarExpr(E->getArg(0)); 437 Value *End = EmitScalarExpr(E->getArg(1)); 438 Value *F = CGM.getIntrinsic(Intrinsic::clear_cache); 439 return RValue::get(Builder.CreateCall2(F, Begin, End)); 440 } 441 case Builtin::BI__builtin_trap: { 442 Value *F = CGM.getIntrinsic(Intrinsic::trap); 443 return RValue::get(Builder.CreateCall(F)); 444 } 445 case Builtin::BI__debugbreak: { 446 Value *F = CGM.getIntrinsic(Intrinsic::debugtrap); 447 return RValue::get(Builder.CreateCall(F)); 448 } 449 case Builtin::BI__builtin_unreachable: { 450 if (SanOpts->Unreachable) 451 EmitCheck(Builder.getFalse(), "builtin_unreachable", 452 EmitCheckSourceLocation(E->getExprLoc()), 453 ArrayRef<llvm::Value *>(), CRK_Unrecoverable); 454 else 455 Builder.CreateUnreachable(); 456 457 // We do need to preserve an insertion point. 458 EmitBlock(createBasicBlock("unreachable.cont")); 459 460 return RValue::get(0); 461 } 462 463 case Builtin::BI__builtin_powi: 464 case Builtin::BI__builtin_powif: 465 case Builtin::BI__builtin_powil: { 466 Value *Base = EmitScalarExpr(E->getArg(0)); 467 Value *Exponent = EmitScalarExpr(E->getArg(1)); 468 llvm::Type *ArgType = Base->getType(); 469 Value *F = CGM.getIntrinsic(Intrinsic::powi, ArgType); 470 return RValue::get(Builder.CreateCall2(F, Base, Exponent)); 471 } 472 473 case Builtin::BI__builtin_isgreater: 474 case Builtin::BI__builtin_isgreaterequal: 475 case Builtin::BI__builtin_isless: 476 case Builtin::BI__builtin_islessequal: 477 case Builtin::BI__builtin_islessgreater: 478 case Builtin::BI__builtin_isunordered: { 479 // Ordered comparisons: we know the arguments to these are matching scalar 480 // floating point values. 481 Value *LHS = EmitScalarExpr(E->getArg(0)); 482 Value *RHS = EmitScalarExpr(E->getArg(1)); 483 484 switch (BuiltinID) { 485 default: llvm_unreachable("Unknown ordered comparison"); 486 case Builtin::BI__builtin_isgreater: 487 LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp"); 488 break; 489 case Builtin::BI__builtin_isgreaterequal: 490 LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp"); 491 break; 492 case Builtin::BI__builtin_isless: 493 LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp"); 494 break; 495 case Builtin::BI__builtin_islessequal: 496 LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp"); 497 break; 498 case Builtin::BI__builtin_islessgreater: 499 LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp"); 500 break; 501 case Builtin::BI__builtin_isunordered: 502 LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp"); 503 break; 504 } 505 // ZExt bool to int type. 506 return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType()))); 507 } 508 case Builtin::BI__builtin_isnan: { 509 Value *V = EmitScalarExpr(E->getArg(0)); 510 V = Builder.CreateFCmpUNO(V, V, "cmp"); 511 return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 512 } 513 514 case Builtin::BI__builtin_isinf: { 515 // isinf(x) --> fabs(x) == infinity 516 Value *V = EmitScalarExpr(E->getArg(0)); 517 V = EmitFAbs(*this, V, E->getArg(0)->getType()); 518 519 V = Builder.CreateFCmpOEQ(V, ConstantFP::getInfinity(V->getType()),"isinf"); 520 return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 521 } 522 523 // TODO: BI__builtin_isinf_sign 524 // isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0 525 526 case Builtin::BI__builtin_isnormal: { 527 // isnormal(x) --> x == x && fabsf(x) < infinity && fabsf(x) >= float_min 528 Value *V = EmitScalarExpr(E->getArg(0)); 529 Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq"); 530 531 Value *Abs = EmitFAbs(*this, V, E->getArg(0)->getType()); 532 Value *IsLessThanInf = 533 Builder.CreateFCmpULT(Abs, ConstantFP::getInfinity(V->getType()),"isinf"); 534 APFloat Smallest = APFloat::getSmallestNormalized( 535 getContext().getFloatTypeSemantics(E->getArg(0)->getType())); 536 Value *IsNormal = 537 Builder.CreateFCmpUGE(Abs, ConstantFP::get(V->getContext(), Smallest), 538 "isnormal"); 539 V = Builder.CreateAnd(Eq, IsLessThanInf, "and"); 540 V = Builder.CreateAnd(V, IsNormal, "and"); 541 return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 542 } 543 544 case Builtin::BI__builtin_isfinite: { 545 // isfinite(x) --> x == x && fabs(x) != infinity; 546 Value *V = EmitScalarExpr(E->getArg(0)); 547 Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq"); 548 549 Value *Abs = EmitFAbs(*this, V, E->getArg(0)->getType()); 550 Value *IsNotInf = 551 Builder.CreateFCmpUNE(Abs, ConstantFP::getInfinity(V->getType()),"isinf"); 552 553 V = Builder.CreateAnd(Eq, IsNotInf, "and"); 554 return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 555 } 556 557 case Builtin::BI__builtin_fpclassify: { 558 Value *V = EmitScalarExpr(E->getArg(5)); 559 llvm::Type *Ty = ConvertType(E->getArg(5)->getType()); 560 561 // Create Result 562 BasicBlock *Begin = Builder.GetInsertBlock(); 563 BasicBlock *End = createBasicBlock("fpclassify_end", this->CurFn); 564 Builder.SetInsertPoint(End); 565 PHINode *Result = 566 Builder.CreatePHI(ConvertType(E->getArg(0)->getType()), 4, 567 "fpclassify_result"); 568 569 // if (V==0) return FP_ZERO 570 Builder.SetInsertPoint(Begin); 571 Value *IsZero = Builder.CreateFCmpOEQ(V, Constant::getNullValue(Ty), 572 "iszero"); 573 Value *ZeroLiteral = EmitScalarExpr(E->getArg(4)); 574 BasicBlock *NotZero = createBasicBlock("fpclassify_not_zero", this->CurFn); 575 Builder.CreateCondBr(IsZero, End, NotZero); 576 Result->addIncoming(ZeroLiteral, Begin); 577 578 // if (V != V) return FP_NAN 579 Builder.SetInsertPoint(NotZero); 580 Value *IsNan = Builder.CreateFCmpUNO(V, V, "cmp"); 581 Value *NanLiteral = EmitScalarExpr(E->getArg(0)); 582 BasicBlock *NotNan = createBasicBlock("fpclassify_not_nan", this->CurFn); 583 Builder.CreateCondBr(IsNan, End, NotNan); 584 Result->addIncoming(NanLiteral, NotZero); 585 586 // if (fabs(V) == infinity) return FP_INFINITY 587 Builder.SetInsertPoint(NotNan); 588 Value *VAbs = EmitFAbs(*this, V, E->getArg(5)->getType()); 589 Value *IsInf = 590 Builder.CreateFCmpOEQ(VAbs, ConstantFP::getInfinity(V->getType()), 591 "isinf"); 592 Value *InfLiteral = EmitScalarExpr(E->getArg(1)); 593 BasicBlock *NotInf = createBasicBlock("fpclassify_not_inf", this->CurFn); 594 Builder.CreateCondBr(IsInf, End, NotInf); 595 Result->addIncoming(InfLiteral, NotNan); 596 597 // if (fabs(V) >= MIN_NORMAL) return FP_NORMAL else FP_SUBNORMAL 598 Builder.SetInsertPoint(NotInf); 599 APFloat Smallest = APFloat::getSmallestNormalized( 600 getContext().getFloatTypeSemantics(E->getArg(5)->getType())); 601 Value *IsNormal = 602 Builder.CreateFCmpUGE(VAbs, ConstantFP::get(V->getContext(), Smallest), 603 "isnormal"); 604 Value *NormalResult = 605 Builder.CreateSelect(IsNormal, EmitScalarExpr(E->getArg(2)), 606 EmitScalarExpr(E->getArg(3))); 607 Builder.CreateBr(End); 608 Result->addIncoming(NormalResult, NotInf); 609 610 // return Result 611 Builder.SetInsertPoint(End); 612 return RValue::get(Result); 613 } 614 615 case Builtin::BIalloca: 616 case Builtin::BI_alloca: 617 case Builtin::BI__builtin_alloca: { 618 Value *Size = EmitScalarExpr(E->getArg(0)); 619 return RValue::get(Builder.CreateAlloca(Builder.getInt8Ty(), Size)); 620 } 621 case Builtin::BIbzero: 622 case Builtin::BI__builtin_bzero: { 623 std::pair<llvm::Value*, unsigned> Dest = 624 EmitPointerWithAlignment(E->getArg(0)); 625 Value *SizeVal = EmitScalarExpr(E->getArg(1)); 626 Builder.CreateMemSet(Dest.first, Builder.getInt8(0), SizeVal, 627 Dest.second, false); 628 return RValue::get(Dest.first); 629 } 630 case Builtin::BImemcpy: 631 case Builtin::BI__builtin_memcpy: { 632 std::pair<llvm::Value*, unsigned> Dest = 633 EmitPointerWithAlignment(E->getArg(0)); 634 std::pair<llvm::Value*, unsigned> Src = 635 EmitPointerWithAlignment(E->getArg(1)); 636 Value *SizeVal = EmitScalarExpr(E->getArg(2)); 637 unsigned Align = std::min(Dest.second, Src.second); 638 Builder.CreateMemCpy(Dest.first, Src.first, SizeVal, Align, false); 639 return RValue::get(Dest.first); 640 } 641 642 case Builtin::BI__builtin___memcpy_chk: { 643 // fold __builtin_memcpy_chk(x, y, cst1, cst2) to memcpy iff cst1<=cst2. 644 llvm::APSInt Size, DstSize; 645 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || 646 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) 647 break; 648 if (Size.ugt(DstSize)) 649 break; 650 std::pair<llvm::Value*, unsigned> Dest = 651 EmitPointerWithAlignment(E->getArg(0)); 652 std::pair<llvm::Value*, unsigned> Src = 653 EmitPointerWithAlignment(E->getArg(1)); 654 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); 655 unsigned Align = std::min(Dest.second, Src.second); 656 Builder.CreateMemCpy(Dest.first, Src.first, SizeVal, Align, false); 657 return RValue::get(Dest.first); 658 } 659 660 case Builtin::BI__builtin_objc_memmove_collectable: { 661 Value *Address = EmitScalarExpr(E->getArg(0)); 662 Value *SrcAddr = EmitScalarExpr(E->getArg(1)); 663 Value *SizeVal = EmitScalarExpr(E->getArg(2)); 664 CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, 665 Address, SrcAddr, SizeVal); 666 return RValue::get(Address); 667 } 668 669 case Builtin::BI__builtin___memmove_chk: { 670 // fold __builtin_memmove_chk(x, y, cst1, cst2) to memmove iff cst1<=cst2. 671 llvm::APSInt Size, DstSize; 672 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || 673 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) 674 break; 675 if (Size.ugt(DstSize)) 676 break; 677 std::pair<llvm::Value*, unsigned> Dest = 678 EmitPointerWithAlignment(E->getArg(0)); 679 std::pair<llvm::Value*, unsigned> Src = 680 EmitPointerWithAlignment(E->getArg(1)); 681 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); 682 unsigned Align = std::min(Dest.second, Src.second); 683 Builder.CreateMemMove(Dest.first, Src.first, SizeVal, Align, false); 684 return RValue::get(Dest.first); 685 } 686 687 case Builtin::BImemmove: 688 case Builtin::BI__builtin_memmove: { 689 std::pair<llvm::Value*, unsigned> Dest = 690 EmitPointerWithAlignment(E->getArg(0)); 691 std::pair<llvm::Value*, unsigned> Src = 692 EmitPointerWithAlignment(E->getArg(1)); 693 Value *SizeVal = EmitScalarExpr(E->getArg(2)); 694 unsigned Align = std::min(Dest.second, Src.second); 695 Builder.CreateMemMove(Dest.first, Src.first, SizeVal, Align, false); 696 return RValue::get(Dest.first); 697 } 698 case Builtin::BImemset: 699 case Builtin::BI__builtin_memset: { 700 std::pair<llvm::Value*, unsigned> Dest = 701 EmitPointerWithAlignment(E->getArg(0)); 702 Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), 703 Builder.getInt8Ty()); 704 Value *SizeVal = EmitScalarExpr(E->getArg(2)); 705 Builder.CreateMemSet(Dest.first, ByteVal, SizeVal, Dest.second, false); 706 return RValue::get(Dest.first); 707 } 708 case Builtin::BI__builtin___memset_chk: { 709 // fold __builtin_memset_chk(x, y, cst1, cst2) to memset iff cst1<=cst2. 710 llvm::APSInt Size, DstSize; 711 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || 712 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) 713 break; 714 if (Size.ugt(DstSize)) 715 break; 716 std::pair<llvm::Value*, unsigned> Dest = 717 EmitPointerWithAlignment(E->getArg(0)); 718 Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), 719 Builder.getInt8Ty()); 720 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); 721 Builder.CreateMemSet(Dest.first, ByteVal, SizeVal, Dest.second, false); 722 return RValue::get(Dest.first); 723 } 724 case Builtin::BI__builtin_dwarf_cfa: { 725 // The offset in bytes from the first argument to the CFA. 726 // 727 // Why on earth is this in the frontend? Is there any reason at 728 // all that the backend can't reasonably determine this while 729 // lowering llvm.eh.dwarf.cfa()? 730 // 731 // TODO: If there's a satisfactory reason, add a target hook for 732 // this instead of hard-coding 0, which is correct for most targets. 733 int32_t Offset = 0; 734 735 Value *F = CGM.getIntrinsic(Intrinsic::eh_dwarf_cfa); 736 return RValue::get(Builder.CreateCall(F, 737 llvm::ConstantInt::get(Int32Ty, Offset))); 738 } 739 case Builtin::BI__builtin_return_address: { 740 Value *Depth = EmitScalarExpr(E->getArg(0)); 741 Depth = Builder.CreateIntCast(Depth, Int32Ty, false); 742 Value *F = CGM.getIntrinsic(Intrinsic::returnaddress); 743 return RValue::get(Builder.CreateCall(F, Depth)); 744 } 745 case Builtin::BI__builtin_frame_address: { 746 Value *Depth = EmitScalarExpr(E->getArg(0)); 747 Depth = Builder.CreateIntCast(Depth, Int32Ty, false); 748 Value *F = CGM.getIntrinsic(Intrinsic::frameaddress); 749 return RValue::get(Builder.CreateCall(F, Depth)); 750 } 751 case Builtin::BI__builtin_extract_return_addr: { 752 Value *Address = EmitScalarExpr(E->getArg(0)); 753 Value *Result = getTargetHooks().decodeReturnAddress(*this, Address); 754 return RValue::get(Result); 755 } 756 case Builtin::BI__builtin_frob_return_addr: { 757 Value *Address = EmitScalarExpr(E->getArg(0)); 758 Value *Result = getTargetHooks().encodeReturnAddress(*this, Address); 759 return RValue::get(Result); 760 } 761 case Builtin::BI__builtin_dwarf_sp_column: { 762 llvm::IntegerType *Ty 763 = cast<llvm::IntegerType>(ConvertType(E->getType())); 764 int Column = getTargetHooks().getDwarfEHStackPointer(CGM); 765 if (Column == -1) { 766 CGM.ErrorUnsupported(E, "__builtin_dwarf_sp_column"); 767 return RValue::get(llvm::UndefValue::get(Ty)); 768 } 769 return RValue::get(llvm::ConstantInt::get(Ty, Column, true)); 770 } 771 case Builtin::BI__builtin_init_dwarf_reg_size_table: { 772 Value *Address = EmitScalarExpr(E->getArg(0)); 773 if (getTargetHooks().initDwarfEHRegSizeTable(*this, Address)) 774 CGM.ErrorUnsupported(E, "__builtin_init_dwarf_reg_size_table"); 775 return RValue::get(llvm::UndefValue::get(ConvertType(E->getType()))); 776 } 777 case Builtin::BI__builtin_eh_return: { 778 Value *Int = EmitScalarExpr(E->getArg(0)); 779 Value *Ptr = EmitScalarExpr(E->getArg(1)); 780 781 llvm::IntegerType *IntTy = cast<llvm::IntegerType>(Int->getType()); 782 assert((IntTy->getBitWidth() == 32 || IntTy->getBitWidth() == 64) && 783 "LLVM's __builtin_eh_return only supports 32- and 64-bit variants"); 784 Value *F = CGM.getIntrinsic(IntTy->getBitWidth() == 32 785 ? Intrinsic::eh_return_i32 786 : Intrinsic::eh_return_i64); 787 Builder.CreateCall2(F, Int, Ptr); 788 Builder.CreateUnreachable(); 789 790 // We do need to preserve an insertion point. 791 EmitBlock(createBasicBlock("builtin_eh_return.cont")); 792 793 return RValue::get(0); 794 } 795 case Builtin::BI__builtin_unwind_init: { 796 Value *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init); 797 return RValue::get(Builder.CreateCall(F)); 798 } 799 case Builtin::BI__builtin_extend_pointer: { 800 // Extends a pointer to the size of an _Unwind_Word, which is 801 // uint64_t on all platforms. Generally this gets poked into a 802 // register and eventually used as an address, so if the 803 // addressing registers are wider than pointers and the platform 804 // doesn't implicitly ignore high-order bits when doing 805 // addressing, we need to make sure we zext / sext based on 806 // the platform's expectations. 807 // 808 // See: http://gcc.gnu.org/ml/gcc-bugs/2002-02/msg00237.html 809 810 // Cast the pointer to intptr_t. 811 Value *Ptr = EmitScalarExpr(E->getArg(0)); 812 Value *Result = Builder.CreatePtrToInt(Ptr, IntPtrTy, "extend.cast"); 813 814 // If that's 64 bits, we're done. 815 if (IntPtrTy->getBitWidth() == 64) 816 return RValue::get(Result); 817 818 // Otherwise, ask the codegen data what to do. 819 if (getTargetHooks().extendPointerWithSExt()) 820 return RValue::get(Builder.CreateSExt(Result, Int64Ty, "extend.sext")); 821 else 822 return RValue::get(Builder.CreateZExt(Result, Int64Ty, "extend.zext")); 823 } 824 case Builtin::BI__builtin_setjmp: { 825 // Buffer is a void**. 826 Value *Buf = EmitScalarExpr(E->getArg(0)); 827 828 // Store the frame pointer to the setjmp buffer. 829 Value *FrameAddr = 830 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress), 831 ConstantInt::get(Int32Ty, 0)); 832 Builder.CreateStore(FrameAddr, Buf); 833 834 // Store the stack pointer to the setjmp buffer. 835 Value *StackAddr = 836 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::stacksave)); 837 Value *StackSaveSlot = 838 Builder.CreateGEP(Buf, ConstantInt::get(Int32Ty, 2)); 839 Builder.CreateStore(StackAddr, StackSaveSlot); 840 841 // Call LLVM's EH setjmp, which is lightweight. 842 Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp); 843 Buf = Builder.CreateBitCast(Buf, Int8PtrTy); 844 return RValue::get(Builder.CreateCall(F, Buf)); 845 } 846 case Builtin::BI__builtin_longjmp: { 847 Value *Buf = EmitScalarExpr(E->getArg(0)); 848 Buf = Builder.CreateBitCast(Buf, Int8PtrTy); 849 850 // Call LLVM's EH longjmp, which is lightweight. 851 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp), Buf); 852 853 // longjmp doesn't return; mark this as unreachable. 854 Builder.CreateUnreachable(); 855 856 // We do need to preserve an insertion point. 857 EmitBlock(createBasicBlock("longjmp.cont")); 858 859 return RValue::get(0); 860 } 861 case Builtin::BI__sync_fetch_and_add: 862 case Builtin::BI__sync_fetch_and_sub: 863 case Builtin::BI__sync_fetch_and_or: 864 case Builtin::BI__sync_fetch_and_and: 865 case Builtin::BI__sync_fetch_and_xor: 866 case Builtin::BI__sync_add_and_fetch: 867 case Builtin::BI__sync_sub_and_fetch: 868 case Builtin::BI__sync_and_and_fetch: 869 case Builtin::BI__sync_or_and_fetch: 870 case Builtin::BI__sync_xor_and_fetch: 871 case Builtin::BI__sync_val_compare_and_swap: 872 case Builtin::BI__sync_bool_compare_and_swap: 873 case Builtin::BI__sync_lock_test_and_set: 874 case Builtin::BI__sync_lock_release: 875 case Builtin::BI__sync_swap: 876 llvm_unreachable("Shouldn't make it through sema"); 877 case Builtin::BI__sync_fetch_and_add_1: 878 case Builtin::BI__sync_fetch_and_add_2: 879 case Builtin::BI__sync_fetch_and_add_4: 880 case Builtin::BI__sync_fetch_and_add_8: 881 case Builtin::BI__sync_fetch_and_add_16: 882 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Add, E); 883 case Builtin::BI__sync_fetch_and_sub_1: 884 case Builtin::BI__sync_fetch_and_sub_2: 885 case Builtin::BI__sync_fetch_and_sub_4: 886 case Builtin::BI__sync_fetch_and_sub_8: 887 case Builtin::BI__sync_fetch_and_sub_16: 888 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Sub, E); 889 case Builtin::BI__sync_fetch_and_or_1: 890 case Builtin::BI__sync_fetch_and_or_2: 891 case Builtin::BI__sync_fetch_and_or_4: 892 case Builtin::BI__sync_fetch_and_or_8: 893 case Builtin::BI__sync_fetch_and_or_16: 894 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Or, E); 895 case Builtin::BI__sync_fetch_and_and_1: 896 case Builtin::BI__sync_fetch_and_and_2: 897 case Builtin::BI__sync_fetch_and_and_4: 898 case Builtin::BI__sync_fetch_and_and_8: 899 case Builtin::BI__sync_fetch_and_and_16: 900 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::And, E); 901 case Builtin::BI__sync_fetch_and_xor_1: 902 case Builtin::BI__sync_fetch_and_xor_2: 903 case Builtin::BI__sync_fetch_and_xor_4: 904 case Builtin::BI__sync_fetch_and_xor_8: 905 case Builtin::BI__sync_fetch_and_xor_16: 906 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xor, E); 907 908 // Clang extensions: not overloaded yet. 909 case Builtin::BI__sync_fetch_and_min: 910 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Min, E); 911 case Builtin::BI__sync_fetch_and_max: 912 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Max, E); 913 case Builtin::BI__sync_fetch_and_umin: 914 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::UMin, E); 915 case Builtin::BI__sync_fetch_and_umax: 916 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::UMax, E); 917 918 case Builtin::BI__sync_add_and_fetch_1: 919 case Builtin::BI__sync_add_and_fetch_2: 920 case Builtin::BI__sync_add_and_fetch_4: 921 case Builtin::BI__sync_add_and_fetch_8: 922 case Builtin::BI__sync_add_and_fetch_16: 923 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Add, E, 924 llvm::Instruction::Add); 925 case Builtin::BI__sync_sub_and_fetch_1: 926 case Builtin::BI__sync_sub_and_fetch_2: 927 case Builtin::BI__sync_sub_and_fetch_4: 928 case Builtin::BI__sync_sub_and_fetch_8: 929 case Builtin::BI__sync_sub_and_fetch_16: 930 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Sub, E, 931 llvm::Instruction::Sub); 932 case Builtin::BI__sync_and_and_fetch_1: 933 case Builtin::BI__sync_and_and_fetch_2: 934 case Builtin::BI__sync_and_and_fetch_4: 935 case Builtin::BI__sync_and_and_fetch_8: 936 case Builtin::BI__sync_and_and_fetch_16: 937 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::And, E, 938 llvm::Instruction::And); 939 case Builtin::BI__sync_or_and_fetch_1: 940 case Builtin::BI__sync_or_and_fetch_2: 941 case Builtin::BI__sync_or_and_fetch_4: 942 case Builtin::BI__sync_or_and_fetch_8: 943 case Builtin::BI__sync_or_and_fetch_16: 944 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Or, E, 945 llvm::Instruction::Or); 946 case Builtin::BI__sync_xor_and_fetch_1: 947 case Builtin::BI__sync_xor_and_fetch_2: 948 case Builtin::BI__sync_xor_and_fetch_4: 949 case Builtin::BI__sync_xor_and_fetch_8: 950 case Builtin::BI__sync_xor_and_fetch_16: 951 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Xor, E, 952 llvm::Instruction::Xor); 953 954 case Builtin::BI__sync_val_compare_and_swap_1: 955 case Builtin::BI__sync_val_compare_and_swap_2: 956 case Builtin::BI__sync_val_compare_and_swap_4: 957 case Builtin::BI__sync_val_compare_and_swap_8: 958 case Builtin::BI__sync_val_compare_and_swap_16: { 959 QualType T = E->getType(); 960 llvm::Value *DestPtr = EmitScalarExpr(E->getArg(0)); 961 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); 962 963 llvm::IntegerType *IntType = 964 llvm::IntegerType::get(getLLVMContext(), 965 getContext().getTypeSize(T)); 966 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 967 968 Value *Args[3]; 969 Args[0] = Builder.CreateBitCast(DestPtr, IntPtrType); 970 Args[1] = EmitScalarExpr(E->getArg(1)); 971 llvm::Type *ValueType = Args[1]->getType(); 972 Args[1] = EmitToInt(*this, Args[1], T, IntType); 973 Args[2] = EmitToInt(*this, EmitScalarExpr(E->getArg(2)), T, IntType); 974 975 Value *Result = Builder.CreateAtomicCmpXchg(Args[0], Args[1], Args[2], 976 llvm::SequentiallyConsistent, 977 llvm::SequentiallyConsistent); 978 Result = EmitFromInt(*this, Result, T, ValueType); 979 return RValue::get(Result); 980 } 981 982 case Builtin::BI__sync_bool_compare_and_swap_1: 983 case Builtin::BI__sync_bool_compare_and_swap_2: 984 case Builtin::BI__sync_bool_compare_and_swap_4: 985 case Builtin::BI__sync_bool_compare_and_swap_8: 986 case Builtin::BI__sync_bool_compare_and_swap_16: { 987 QualType T = E->getArg(1)->getType(); 988 llvm::Value *DestPtr = EmitScalarExpr(E->getArg(0)); 989 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); 990 991 llvm::IntegerType *IntType = 992 llvm::IntegerType::get(getLLVMContext(), 993 getContext().getTypeSize(T)); 994 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 995 996 Value *Args[3]; 997 Args[0] = Builder.CreateBitCast(DestPtr, IntPtrType); 998 Args[1] = EmitToInt(*this, EmitScalarExpr(E->getArg(1)), T, IntType); 999 Args[2] = EmitToInt(*this, EmitScalarExpr(E->getArg(2)), T, IntType); 1000 1001 Value *OldVal = Args[1]; 1002 Value *PrevVal = Builder.CreateAtomicCmpXchg(Args[0], Args[1], Args[2], 1003 llvm::SequentiallyConsistent, 1004 llvm::SequentiallyConsistent); 1005 Value *Result = Builder.CreateICmpEQ(PrevVal, OldVal); 1006 // zext bool to int. 1007 Result = Builder.CreateZExt(Result, ConvertType(E->getType())); 1008 return RValue::get(Result); 1009 } 1010 1011 case Builtin::BI__sync_swap_1: 1012 case Builtin::BI__sync_swap_2: 1013 case Builtin::BI__sync_swap_4: 1014 case Builtin::BI__sync_swap_8: 1015 case Builtin::BI__sync_swap_16: 1016 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E); 1017 1018 case Builtin::BI__sync_lock_test_and_set_1: 1019 case Builtin::BI__sync_lock_test_and_set_2: 1020 case Builtin::BI__sync_lock_test_and_set_4: 1021 case Builtin::BI__sync_lock_test_and_set_8: 1022 case Builtin::BI__sync_lock_test_and_set_16: 1023 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E); 1024 1025 case Builtin::BI__sync_lock_release_1: 1026 case Builtin::BI__sync_lock_release_2: 1027 case Builtin::BI__sync_lock_release_4: 1028 case Builtin::BI__sync_lock_release_8: 1029 case Builtin::BI__sync_lock_release_16: { 1030 Value *Ptr = EmitScalarExpr(E->getArg(0)); 1031 QualType ElTy = E->getArg(0)->getType()->getPointeeType(); 1032 CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy); 1033 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), 1034 StoreSize.getQuantity() * 8); 1035 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); 1036 llvm::StoreInst *Store = 1037 Builder.CreateStore(llvm::Constant::getNullValue(ITy), Ptr); 1038 Store->setAlignment(StoreSize.getQuantity()); 1039 Store->setAtomic(llvm::Release); 1040 return RValue::get(0); 1041 } 1042 1043 case Builtin::BI__sync_synchronize: { 1044 // We assume this is supposed to correspond to a C++0x-style 1045 // sequentially-consistent fence (i.e. this is only usable for 1046 // synchonization, not device I/O or anything like that). This intrinsic 1047 // is really badly designed in the sense that in theory, there isn't 1048 // any way to safely use it... but in practice, it mostly works 1049 // to use it with non-atomic loads and stores to get acquire/release 1050 // semantics. 1051 Builder.CreateFence(llvm::SequentiallyConsistent); 1052 return RValue::get(0); 1053 } 1054 1055 case Builtin::BI__c11_atomic_is_lock_free: 1056 case Builtin::BI__atomic_is_lock_free: { 1057 // Call "bool __atomic_is_lock_free(size_t size, void *ptr)". For the 1058 // __c11 builtin, ptr is 0 (indicating a properly-aligned object), since 1059 // _Atomic(T) is always properly-aligned. 1060 const char *LibCallName = "__atomic_is_lock_free"; 1061 CallArgList Args; 1062 Args.add(RValue::get(EmitScalarExpr(E->getArg(0))), 1063 getContext().getSizeType()); 1064 if (BuiltinID == Builtin::BI__atomic_is_lock_free) 1065 Args.add(RValue::get(EmitScalarExpr(E->getArg(1))), 1066 getContext().VoidPtrTy); 1067 else 1068 Args.add(RValue::get(llvm::Constant::getNullValue(VoidPtrTy)), 1069 getContext().VoidPtrTy); 1070 const CGFunctionInfo &FuncInfo = 1071 CGM.getTypes().arrangeFreeFunctionCall(E->getType(), Args, 1072 FunctionType::ExtInfo(), 1073 RequiredArgs::All); 1074 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo); 1075 llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName); 1076 return EmitCall(FuncInfo, Func, ReturnValueSlot(), Args); 1077 } 1078 1079 case Builtin::BI__atomic_test_and_set: { 1080 // Look at the argument type to determine whether this is a volatile 1081 // operation. The parameter type is always volatile. 1082 QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType(); 1083 bool Volatile = 1084 PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified(); 1085 1086 Value *Ptr = EmitScalarExpr(E->getArg(0)); 1087 unsigned AddrSpace = Ptr->getType()->getPointerAddressSpace(); 1088 Ptr = Builder.CreateBitCast(Ptr, Int8Ty->getPointerTo(AddrSpace)); 1089 Value *NewVal = Builder.getInt8(1); 1090 Value *Order = EmitScalarExpr(E->getArg(1)); 1091 if (isa<llvm::ConstantInt>(Order)) { 1092 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 1093 AtomicRMWInst *Result = 0; 1094 switch (ord) { 1095 case 0: // memory_order_relaxed 1096 default: // invalid order 1097 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, 1098 Ptr, NewVal, 1099 llvm::Monotonic); 1100 break; 1101 case 1: // memory_order_consume 1102 case 2: // memory_order_acquire 1103 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, 1104 Ptr, NewVal, 1105 llvm::Acquire); 1106 break; 1107 case 3: // memory_order_release 1108 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, 1109 Ptr, NewVal, 1110 llvm::Release); 1111 break; 1112 case 4: // memory_order_acq_rel 1113 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, 1114 Ptr, NewVal, 1115 llvm::AcquireRelease); 1116 break; 1117 case 5: // memory_order_seq_cst 1118 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, 1119 Ptr, NewVal, 1120 llvm::SequentiallyConsistent); 1121 break; 1122 } 1123 Result->setVolatile(Volatile); 1124 return RValue::get(Builder.CreateIsNotNull(Result, "tobool")); 1125 } 1126 1127 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 1128 1129 llvm::BasicBlock *BBs[5] = { 1130 createBasicBlock("monotonic", CurFn), 1131 createBasicBlock("acquire", CurFn), 1132 createBasicBlock("release", CurFn), 1133 createBasicBlock("acqrel", CurFn), 1134 createBasicBlock("seqcst", CurFn) 1135 }; 1136 llvm::AtomicOrdering Orders[5] = { 1137 llvm::Monotonic, llvm::Acquire, llvm::Release, 1138 llvm::AcquireRelease, llvm::SequentiallyConsistent 1139 }; 1140 1141 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 1142 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, BBs[0]); 1143 1144 Builder.SetInsertPoint(ContBB); 1145 PHINode *Result = Builder.CreatePHI(Int8Ty, 5, "was_set"); 1146 1147 for (unsigned i = 0; i < 5; ++i) { 1148 Builder.SetInsertPoint(BBs[i]); 1149 AtomicRMWInst *RMW = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, 1150 Ptr, NewVal, Orders[i]); 1151 RMW->setVolatile(Volatile); 1152 Result->addIncoming(RMW, BBs[i]); 1153 Builder.CreateBr(ContBB); 1154 } 1155 1156 SI->addCase(Builder.getInt32(0), BBs[0]); 1157 SI->addCase(Builder.getInt32(1), BBs[1]); 1158 SI->addCase(Builder.getInt32(2), BBs[1]); 1159 SI->addCase(Builder.getInt32(3), BBs[2]); 1160 SI->addCase(Builder.getInt32(4), BBs[3]); 1161 SI->addCase(Builder.getInt32(5), BBs[4]); 1162 1163 Builder.SetInsertPoint(ContBB); 1164 return RValue::get(Builder.CreateIsNotNull(Result, "tobool")); 1165 } 1166 1167 case Builtin::BI__atomic_clear: { 1168 QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType(); 1169 bool Volatile = 1170 PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified(); 1171 1172 Value *Ptr = EmitScalarExpr(E->getArg(0)); 1173 unsigned AddrSpace = Ptr->getType()->getPointerAddressSpace(); 1174 Ptr = Builder.CreateBitCast(Ptr, Int8Ty->getPointerTo(AddrSpace)); 1175 Value *NewVal = Builder.getInt8(0); 1176 Value *Order = EmitScalarExpr(E->getArg(1)); 1177 if (isa<llvm::ConstantInt>(Order)) { 1178 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 1179 StoreInst *Store = Builder.CreateStore(NewVal, Ptr, Volatile); 1180 Store->setAlignment(1); 1181 switch (ord) { 1182 case 0: // memory_order_relaxed 1183 default: // invalid order 1184 Store->setOrdering(llvm::Monotonic); 1185 break; 1186 case 3: // memory_order_release 1187 Store->setOrdering(llvm::Release); 1188 break; 1189 case 5: // memory_order_seq_cst 1190 Store->setOrdering(llvm::SequentiallyConsistent); 1191 break; 1192 } 1193 return RValue::get(0); 1194 } 1195 1196 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 1197 1198 llvm::BasicBlock *BBs[3] = { 1199 createBasicBlock("monotonic", CurFn), 1200 createBasicBlock("release", CurFn), 1201 createBasicBlock("seqcst", CurFn) 1202 }; 1203 llvm::AtomicOrdering Orders[3] = { 1204 llvm::Monotonic, llvm::Release, llvm::SequentiallyConsistent 1205 }; 1206 1207 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 1208 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, BBs[0]); 1209 1210 for (unsigned i = 0; i < 3; ++i) { 1211 Builder.SetInsertPoint(BBs[i]); 1212 StoreInst *Store = Builder.CreateStore(NewVal, Ptr, Volatile); 1213 Store->setAlignment(1); 1214 Store->setOrdering(Orders[i]); 1215 Builder.CreateBr(ContBB); 1216 } 1217 1218 SI->addCase(Builder.getInt32(0), BBs[0]); 1219 SI->addCase(Builder.getInt32(3), BBs[1]); 1220 SI->addCase(Builder.getInt32(5), BBs[2]); 1221 1222 Builder.SetInsertPoint(ContBB); 1223 return RValue::get(0); 1224 } 1225 1226 case Builtin::BI__atomic_thread_fence: 1227 case Builtin::BI__atomic_signal_fence: 1228 case Builtin::BI__c11_atomic_thread_fence: 1229 case Builtin::BI__c11_atomic_signal_fence: { 1230 llvm::SynchronizationScope Scope; 1231 if (BuiltinID == Builtin::BI__atomic_signal_fence || 1232 BuiltinID == Builtin::BI__c11_atomic_signal_fence) 1233 Scope = llvm::SingleThread; 1234 else 1235 Scope = llvm::CrossThread; 1236 Value *Order = EmitScalarExpr(E->getArg(0)); 1237 if (isa<llvm::ConstantInt>(Order)) { 1238 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 1239 switch (ord) { 1240 case 0: // memory_order_relaxed 1241 default: // invalid order 1242 break; 1243 case 1: // memory_order_consume 1244 case 2: // memory_order_acquire 1245 Builder.CreateFence(llvm::Acquire, Scope); 1246 break; 1247 case 3: // memory_order_release 1248 Builder.CreateFence(llvm::Release, Scope); 1249 break; 1250 case 4: // memory_order_acq_rel 1251 Builder.CreateFence(llvm::AcquireRelease, Scope); 1252 break; 1253 case 5: // memory_order_seq_cst 1254 Builder.CreateFence(llvm::SequentiallyConsistent, Scope); 1255 break; 1256 } 1257 return RValue::get(0); 1258 } 1259 1260 llvm::BasicBlock *AcquireBB, *ReleaseBB, *AcqRelBB, *SeqCstBB; 1261 AcquireBB = createBasicBlock("acquire", CurFn); 1262 ReleaseBB = createBasicBlock("release", CurFn); 1263 AcqRelBB = createBasicBlock("acqrel", CurFn); 1264 SeqCstBB = createBasicBlock("seqcst", CurFn); 1265 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 1266 1267 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 1268 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, ContBB); 1269 1270 Builder.SetInsertPoint(AcquireBB); 1271 Builder.CreateFence(llvm::Acquire, Scope); 1272 Builder.CreateBr(ContBB); 1273 SI->addCase(Builder.getInt32(1), AcquireBB); 1274 SI->addCase(Builder.getInt32(2), AcquireBB); 1275 1276 Builder.SetInsertPoint(ReleaseBB); 1277 Builder.CreateFence(llvm::Release, Scope); 1278 Builder.CreateBr(ContBB); 1279 SI->addCase(Builder.getInt32(3), ReleaseBB); 1280 1281 Builder.SetInsertPoint(AcqRelBB); 1282 Builder.CreateFence(llvm::AcquireRelease, Scope); 1283 Builder.CreateBr(ContBB); 1284 SI->addCase(Builder.getInt32(4), AcqRelBB); 1285 1286 Builder.SetInsertPoint(SeqCstBB); 1287 Builder.CreateFence(llvm::SequentiallyConsistent, Scope); 1288 Builder.CreateBr(ContBB); 1289 SI->addCase(Builder.getInt32(5), SeqCstBB); 1290 1291 Builder.SetInsertPoint(ContBB); 1292 return RValue::get(0); 1293 } 1294 1295 // Library functions with special handling. 1296 case Builtin::BIsqrt: 1297 case Builtin::BIsqrtf: 1298 case Builtin::BIsqrtl: { 1299 // Transform a call to sqrt* into a @llvm.sqrt.* intrinsic call, but only 1300 // in finite- or unsafe-math mode (the intrinsic has different semantics 1301 // for handling negative numbers compared to the library function, so 1302 // -fmath-errno=0 is not enough). 1303 if (!FD->hasAttr<ConstAttr>()) 1304 break; 1305 if (!(CGM.getCodeGenOpts().UnsafeFPMath || 1306 CGM.getCodeGenOpts().NoNaNsFPMath)) 1307 break; 1308 Value *Arg0 = EmitScalarExpr(E->getArg(0)); 1309 llvm::Type *ArgType = Arg0->getType(); 1310 Value *F = CGM.getIntrinsic(Intrinsic::sqrt, ArgType); 1311 return RValue::get(Builder.CreateCall(F, Arg0)); 1312 } 1313 1314 case Builtin::BIpow: 1315 case Builtin::BIpowf: 1316 case Builtin::BIpowl: { 1317 // Transform a call to pow* into a @llvm.pow.* intrinsic call. 1318 if (!FD->hasAttr<ConstAttr>()) 1319 break; 1320 Value *Base = EmitScalarExpr(E->getArg(0)); 1321 Value *Exponent = EmitScalarExpr(E->getArg(1)); 1322 llvm::Type *ArgType = Base->getType(); 1323 Value *F = CGM.getIntrinsic(Intrinsic::pow, ArgType); 1324 return RValue::get(Builder.CreateCall2(F, Base, Exponent)); 1325 } 1326 1327 case Builtin::BIfma: 1328 case Builtin::BIfmaf: 1329 case Builtin::BIfmal: 1330 case Builtin::BI__builtin_fma: 1331 case Builtin::BI__builtin_fmaf: 1332 case Builtin::BI__builtin_fmal: { 1333 // Rewrite fma to intrinsic. 1334 Value *FirstArg = EmitScalarExpr(E->getArg(0)); 1335 llvm::Type *ArgType = FirstArg->getType(); 1336 Value *F = CGM.getIntrinsic(Intrinsic::fma, ArgType); 1337 return RValue::get(Builder.CreateCall3(F, FirstArg, 1338 EmitScalarExpr(E->getArg(1)), 1339 EmitScalarExpr(E->getArg(2)))); 1340 } 1341 1342 case Builtin::BI__builtin_signbit: 1343 case Builtin::BI__builtin_signbitf: 1344 case Builtin::BI__builtin_signbitl: { 1345 LLVMContext &C = CGM.getLLVMContext(); 1346 1347 Value *Arg = EmitScalarExpr(E->getArg(0)); 1348 llvm::Type *ArgTy = Arg->getType(); 1349 if (ArgTy->isPPC_FP128Ty()) 1350 break; // FIXME: I'm not sure what the right implementation is here. 1351 int ArgWidth = ArgTy->getPrimitiveSizeInBits(); 1352 llvm::Type *ArgIntTy = llvm::IntegerType::get(C, ArgWidth); 1353 Value *BCArg = Builder.CreateBitCast(Arg, ArgIntTy); 1354 Value *ZeroCmp = llvm::Constant::getNullValue(ArgIntTy); 1355 Value *Result = Builder.CreateICmpSLT(BCArg, ZeroCmp); 1356 return RValue::get(Builder.CreateZExt(Result, ConvertType(E->getType()))); 1357 } 1358 case Builtin::BI__builtin_annotation: { 1359 llvm::Value *AnnVal = EmitScalarExpr(E->getArg(0)); 1360 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::annotation, 1361 AnnVal->getType()); 1362 1363 // Get the annotation string, go through casts. Sema requires this to be a 1364 // non-wide string literal, potentially casted, so the cast<> is safe. 1365 const Expr *AnnotationStrExpr = E->getArg(1)->IgnoreParenCasts(); 1366 StringRef Str = cast<StringLiteral>(AnnotationStrExpr)->getString(); 1367 return RValue::get(EmitAnnotationCall(F, AnnVal, Str, E->getExprLoc())); 1368 } 1369 case Builtin::BI__builtin_addcb: 1370 case Builtin::BI__builtin_addcs: 1371 case Builtin::BI__builtin_addc: 1372 case Builtin::BI__builtin_addcl: 1373 case Builtin::BI__builtin_addcll: 1374 case Builtin::BI__builtin_subcb: 1375 case Builtin::BI__builtin_subcs: 1376 case Builtin::BI__builtin_subc: 1377 case Builtin::BI__builtin_subcl: 1378 case Builtin::BI__builtin_subcll: { 1379 1380 // We translate all of these builtins from expressions of the form: 1381 // int x = ..., y = ..., carryin = ..., carryout, result; 1382 // result = __builtin_addc(x, y, carryin, &carryout); 1383 // 1384 // to LLVM IR of the form: 1385 // 1386 // %tmp1 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x, i32 %y) 1387 // %tmpsum1 = extractvalue {i32, i1} %tmp1, 0 1388 // %carry1 = extractvalue {i32, i1} %tmp1, 1 1389 // %tmp2 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %tmpsum1, 1390 // i32 %carryin) 1391 // %result = extractvalue {i32, i1} %tmp2, 0 1392 // %carry2 = extractvalue {i32, i1} %tmp2, 1 1393 // %tmp3 = or i1 %carry1, %carry2 1394 // %tmp4 = zext i1 %tmp3 to i32 1395 // store i32 %tmp4, i32* %carryout 1396 1397 // Scalarize our inputs. 1398 llvm::Value *X = EmitScalarExpr(E->getArg(0)); 1399 llvm::Value *Y = EmitScalarExpr(E->getArg(1)); 1400 llvm::Value *Carryin = EmitScalarExpr(E->getArg(2)); 1401 std::pair<llvm::Value*, unsigned> CarryOutPtr = 1402 EmitPointerWithAlignment(E->getArg(3)); 1403 1404 // Decide if we are lowering to a uadd.with.overflow or usub.with.overflow. 1405 llvm::Intrinsic::ID IntrinsicId; 1406 switch (BuiltinID) { 1407 default: llvm_unreachable("Unknown multiprecision builtin id."); 1408 case Builtin::BI__builtin_addcb: 1409 case Builtin::BI__builtin_addcs: 1410 case Builtin::BI__builtin_addc: 1411 case Builtin::BI__builtin_addcl: 1412 case Builtin::BI__builtin_addcll: 1413 IntrinsicId = llvm::Intrinsic::uadd_with_overflow; 1414 break; 1415 case Builtin::BI__builtin_subcb: 1416 case Builtin::BI__builtin_subcs: 1417 case Builtin::BI__builtin_subc: 1418 case Builtin::BI__builtin_subcl: 1419 case Builtin::BI__builtin_subcll: 1420 IntrinsicId = llvm::Intrinsic::usub_with_overflow; 1421 break; 1422 } 1423 1424 // Construct our resulting LLVM IR expression. 1425 llvm::Value *Carry1; 1426 llvm::Value *Sum1 = EmitOverflowIntrinsic(*this, IntrinsicId, 1427 X, Y, Carry1); 1428 llvm::Value *Carry2; 1429 llvm::Value *Sum2 = EmitOverflowIntrinsic(*this, IntrinsicId, 1430 Sum1, Carryin, Carry2); 1431 llvm::Value *CarryOut = Builder.CreateZExt(Builder.CreateOr(Carry1, Carry2), 1432 X->getType()); 1433 llvm::StoreInst *CarryOutStore = Builder.CreateStore(CarryOut, 1434 CarryOutPtr.first); 1435 CarryOutStore->setAlignment(CarryOutPtr.second); 1436 return RValue::get(Sum2); 1437 } 1438 case Builtin::BI__builtin_uadd_overflow: 1439 case Builtin::BI__builtin_uaddl_overflow: 1440 case Builtin::BI__builtin_uaddll_overflow: 1441 case Builtin::BI__builtin_usub_overflow: 1442 case Builtin::BI__builtin_usubl_overflow: 1443 case Builtin::BI__builtin_usubll_overflow: 1444 case Builtin::BI__builtin_umul_overflow: 1445 case Builtin::BI__builtin_umull_overflow: 1446 case Builtin::BI__builtin_umulll_overflow: 1447 case Builtin::BI__builtin_sadd_overflow: 1448 case Builtin::BI__builtin_saddl_overflow: 1449 case Builtin::BI__builtin_saddll_overflow: 1450 case Builtin::BI__builtin_ssub_overflow: 1451 case Builtin::BI__builtin_ssubl_overflow: 1452 case Builtin::BI__builtin_ssubll_overflow: 1453 case Builtin::BI__builtin_smul_overflow: 1454 case Builtin::BI__builtin_smull_overflow: 1455 case Builtin::BI__builtin_smulll_overflow: { 1456 1457 // We translate all of these builtins directly to the relevant llvm IR node. 1458 1459 // Scalarize our inputs. 1460 llvm::Value *X = EmitScalarExpr(E->getArg(0)); 1461 llvm::Value *Y = EmitScalarExpr(E->getArg(1)); 1462 std::pair<llvm::Value *, unsigned> SumOutPtr = 1463 EmitPointerWithAlignment(E->getArg(2)); 1464 1465 // Decide which of the overflow intrinsics we are lowering to: 1466 llvm::Intrinsic::ID IntrinsicId; 1467 switch (BuiltinID) { 1468 default: llvm_unreachable("Unknown security overflow builtin id."); 1469 case Builtin::BI__builtin_uadd_overflow: 1470 case Builtin::BI__builtin_uaddl_overflow: 1471 case Builtin::BI__builtin_uaddll_overflow: 1472 IntrinsicId = llvm::Intrinsic::uadd_with_overflow; 1473 break; 1474 case Builtin::BI__builtin_usub_overflow: 1475 case Builtin::BI__builtin_usubl_overflow: 1476 case Builtin::BI__builtin_usubll_overflow: 1477 IntrinsicId = llvm::Intrinsic::usub_with_overflow; 1478 break; 1479 case Builtin::BI__builtin_umul_overflow: 1480 case Builtin::BI__builtin_umull_overflow: 1481 case Builtin::BI__builtin_umulll_overflow: 1482 IntrinsicId = llvm::Intrinsic::umul_with_overflow; 1483 break; 1484 case Builtin::BI__builtin_sadd_overflow: 1485 case Builtin::BI__builtin_saddl_overflow: 1486 case Builtin::BI__builtin_saddll_overflow: 1487 IntrinsicId = llvm::Intrinsic::sadd_with_overflow; 1488 break; 1489 case Builtin::BI__builtin_ssub_overflow: 1490 case Builtin::BI__builtin_ssubl_overflow: 1491 case Builtin::BI__builtin_ssubll_overflow: 1492 IntrinsicId = llvm::Intrinsic::ssub_with_overflow; 1493 break; 1494 case Builtin::BI__builtin_smul_overflow: 1495 case Builtin::BI__builtin_smull_overflow: 1496 case Builtin::BI__builtin_smulll_overflow: 1497 IntrinsicId = llvm::Intrinsic::smul_with_overflow; 1498 break; 1499 } 1500 1501 1502 llvm::Value *Carry; 1503 llvm::Value *Sum = EmitOverflowIntrinsic(*this, IntrinsicId, X, Y, Carry); 1504 llvm::StoreInst *SumOutStore = Builder.CreateStore(Sum, SumOutPtr.first); 1505 SumOutStore->setAlignment(SumOutPtr.second); 1506 1507 return RValue::get(Carry); 1508 } 1509 case Builtin::BI__builtin_addressof: 1510 return RValue::get(EmitLValue(E->getArg(0)).getAddress()); 1511 case Builtin::BI__noop: 1512 return RValue::get(0); 1513 case Builtin::BI_InterlockedCompareExchange: { 1514 AtomicCmpXchgInst *CXI = Builder.CreateAtomicCmpXchg( 1515 EmitScalarExpr(E->getArg(0)), 1516 EmitScalarExpr(E->getArg(2)), 1517 EmitScalarExpr(E->getArg(1)), 1518 SequentiallyConsistent, 1519 SequentiallyConsistent); 1520 CXI->setVolatile(true); 1521 return RValue::get(CXI); 1522 } 1523 case Builtin::BI_InterlockedIncrement: { 1524 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW( 1525 AtomicRMWInst::Add, 1526 EmitScalarExpr(E->getArg(0)), 1527 ConstantInt::get(Int32Ty, 1), 1528 llvm::SequentiallyConsistent); 1529 RMWI->setVolatile(true); 1530 return RValue::get(Builder.CreateAdd(RMWI, ConstantInt::get(Int32Ty, 1))); 1531 } 1532 case Builtin::BI_InterlockedDecrement: { 1533 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW( 1534 AtomicRMWInst::Sub, 1535 EmitScalarExpr(E->getArg(0)), 1536 ConstantInt::get(Int32Ty, 1), 1537 llvm::SequentiallyConsistent); 1538 RMWI->setVolatile(true); 1539 return RValue::get(Builder.CreateSub(RMWI, ConstantInt::get(Int32Ty, 1))); 1540 } 1541 case Builtin::BI_InterlockedExchangeAdd: { 1542 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW( 1543 AtomicRMWInst::Add, 1544 EmitScalarExpr(E->getArg(0)), 1545 EmitScalarExpr(E->getArg(1)), 1546 llvm::SequentiallyConsistent); 1547 RMWI->setVolatile(true); 1548 return RValue::get(RMWI); 1549 } 1550 } 1551 1552 // If this is an alias for a lib function (e.g. __builtin_sin), emit 1553 // the call using the normal call path, but using the unmangled 1554 // version of the function name. 1555 if (getContext().BuiltinInfo.isLibFunction(BuiltinID)) 1556 return emitLibraryCall(*this, FD, E, 1557 CGM.getBuiltinLibFunction(FD, BuiltinID)); 1558 1559 // If this is a predefined lib function (e.g. malloc), emit the call 1560 // using exactly the normal call path. 1561 if (getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID)) 1562 return emitLibraryCall(*this, FD, E, EmitScalarExpr(E->getCallee())); 1563 1564 // See if we have a target specific intrinsic. 1565 const char *Name = getContext().BuiltinInfo.GetName(BuiltinID); 1566 Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic; 1567 if (const char *Prefix = 1568 llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch())) 1569 IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix, Name); 1570 1571 if (IntrinsicID != Intrinsic::not_intrinsic) { 1572 SmallVector<Value*, 16> Args; 1573 1574 // Find out if any arguments are required to be integer constant 1575 // expressions. 1576 unsigned ICEArguments = 0; 1577 ASTContext::GetBuiltinTypeError Error; 1578 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 1579 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 1580 1581 Function *F = CGM.getIntrinsic(IntrinsicID); 1582 llvm::FunctionType *FTy = F->getFunctionType(); 1583 1584 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 1585 Value *ArgValue; 1586 // If this is a normal argument, just emit it as a scalar. 1587 if ((ICEArguments & (1 << i)) == 0) { 1588 ArgValue = EmitScalarExpr(E->getArg(i)); 1589 } else { 1590 // If this is required to be a constant, constant fold it so that we 1591 // know that the generated intrinsic gets a ConstantInt. 1592 llvm::APSInt Result; 1593 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result,getContext()); 1594 assert(IsConst && "Constant arg isn't actually constant?"); 1595 (void)IsConst; 1596 ArgValue = llvm::ConstantInt::get(getLLVMContext(), Result); 1597 } 1598 1599 // If the intrinsic arg type is different from the builtin arg type 1600 // we need to do a bit cast. 1601 llvm::Type *PTy = FTy->getParamType(i); 1602 if (PTy != ArgValue->getType()) { 1603 assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) && 1604 "Must be able to losslessly bit cast to param"); 1605 ArgValue = Builder.CreateBitCast(ArgValue, PTy); 1606 } 1607 1608 Args.push_back(ArgValue); 1609 } 1610 1611 Value *V = Builder.CreateCall(F, Args); 1612 QualType BuiltinRetType = E->getType(); 1613 1614 llvm::Type *RetTy = VoidTy; 1615 if (!BuiltinRetType->isVoidType()) 1616 RetTy = ConvertType(BuiltinRetType); 1617 1618 if (RetTy != V->getType()) { 1619 assert(V->getType()->canLosslesslyBitCastTo(RetTy) && 1620 "Must be able to losslessly bit cast result type"); 1621 V = Builder.CreateBitCast(V, RetTy); 1622 } 1623 1624 return RValue::get(V); 1625 } 1626 1627 // See if we have a target specific builtin that needs to be lowered. 1628 if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E)) 1629 return RValue::get(V); 1630 1631 ErrorUnsupported(E, "builtin function"); 1632 1633 // Unknown builtin, for now just dump it out and return undef. 1634 return GetUndefRValue(E->getType()); 1635 } 1636 1637 Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, 1638 const CallExpr *E) { 1639 switch (getTarget().getTriple().getArch()) { 1640 case llvm::Triple::aarch64: 1641 case llvm::Triple::aarch64_be: 1642 return EmitAArch64BuiltinExpr(BuiltinID, E); 1643 case llvm::Triple::arm: 1644 case llvm::Triple::armeb: 1645 case llvm::Triple::thumb: 1646 case llvm::Triple::thumbeb: 1647 return EmitARMBuiltinExpr(BuiltinID, E); 1648 case llvm::Triple::x86: 1649 case llvm::Triple::x86_64: 1650 return EmitX86BuiltinExpr(BuiltinID, E); 1651 case llvm::Triple::ppc: 1652 case llvm::Triple::ppc64: 1653 case llvm::Triple::ppc64le: 1654 return EmitPPCBuiltinExpr(BuiltinID, E); 1655 default: 1656 return 0; 1657 } 1658 } 1659 1660 static llvm::VectorType *GetNeonType(CodeGenFunction *CGF, 1661 NeonTypeFlags TypeFlags, 1662 bool V1Ty=false) { 1663 int IsQuad = TypeFlags.isQuad(); 1664 switch (TypeFlags.getEltType()) { 1665 case NeonTypeFlags::Int8: 1666 case NeonTypeFlags::Poly8: 1667 return llvm::VectorType::get(CGF->Int8Ty, V1Ty ? 1 : (8 << IsQuad)); 1668 case NeonTypeFlags::Int16: 1669 case NeonTypeFlags::Poly16: 1670 case NeonTypeFlags::Float16: 1671 return llvm::VectorType::get(CGF->Int16Ty, V1Ty ? 1 : (4 << IsQuad)); 1672 case NeonTypeFlags::Int32: 1673 return llvm::VectorType::get(CGF->Int32Ty, V1Ty ? 1 : (2 << IsQuad)); 1674 case NeonTypeFlags::Int64: 1675 case NeonTypeFlags::Poly64: 1676 return llvm::VectorType::get(CGF->Int64Ty, V1Ty ? 1 : (1 << IsQuad)); 1677 case NeonTypeFlags::Poly128: 1678 // FIXME: i128 and f128 doesn't get fully support in Clang and llvm. 1679 // There is a lot of i128 and f128 API missing. 1680 // so we use v16i8 to represent poly128 and get pattern matched. 1681 return llvm::VectorType::get(CGF->Int8Ty, 16); 1682 case NeonTypeFlags::Float32: 1683 return llvm::VectorType::get(CGF->FloatTy, V1Ty ? 1 : (2 << IsQuad)); 1684 case NeonTypeFlags::Float64: 1685 return llvm::VectorType::get(CGF->DoubleTy, V1Ty ? 1 : (1 << IsQuad)); 1686 } 1687 llvm_unreachable("Unknown vector element type!"); 1688 } 1689 1690 Value *CodeGenFunction::EmitNeonSplat(Value *V, Constant *C) { 1691 unsigned nElts = cast<llvm::VectorType>(V->getType())->getNumElements(); 1692 Value* SV = llvm::ConstantVector::getSplat(nElts, C); 1693 return Builder.CreateShuffleVector(V, V, SV, "lane"); 1694 } 1695 1696 Value *CodeGenFunction::EmitNeonCall(Function *F, SmallVectorImpl<Value*> &Ops, 1697 const char *name, 1698 unsigned shift, bool rightshift) { 1699 unsigned j = 0; 1700 for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end(); 1701 ai != ae; ++ai, ++j) 1702 if (shift > 0 && shift == j) 1703 Ops[j] = EmitNeonShiftVector(Ops[j], ai->getType(), rightshift); 1704 else 1705 Ops[j] = Builder.CreateBitCast(Ops[j], ai->getType(), name); 1706 1707 return Builder.CreateCall(F, Ops, name); 1708 } 1709 1710 Value *CodeGenFunction::EmitNeonShiftVector(Value *V, llvm::Type *Ty, 1711 bool neg) { 1712 int SV = cast<ConstantInt>(V)->getSExtValue(); 1713 1714 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 1715 llvm::Constant *C = ConstantInt::get(VTy->getElementType(), neg ? -SV : SV); 1716 return llvm::ConstantVector::getSplat(VTy->getNumElements(), C); 1717 } 1718 1719 // \brief Right-shift a vector by a constant. 1720 Value *CodeGenFunction::EmitNeonRShiftImm(Value *Vec, Value *Shift, 1721 llvm::Type *Ty, bool usgn, 1722 const char *name) { 1723 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 1724 1725 int ShiftAmt = cast<ConstantInt>(Shift)->getSExtValue(); 1726 int EltSize = VTy->getScalarSizeInBits(); 1727 1728 Vec = Builder.CreateBitCast(Vec, Ty); 1729 1730 // lshr/ashr are undefined when the shift amount is equal to the vector 1731 // element size. 1732 if (ShiftAmt == EltSize) { 1733 if (usgn) { 1734 // Right-shifting an unsigned value by its size yields 0. 1735 llvm::Constant *Zero = ConstantInt::get(VTy->getElementType(), 0); 1736 return llvm::ConstantVector::getSplat(VTy->getNumElements(), Zero); 1737 } else { 1738 // Right-shifting a signed value by its size is equivalent 1739 // to a shift of size-1. 1740 --ShiftAmt; 1741 Shift = ConstantInt::get(VTy->getElementType(), ShiftAmt); 1742 } 1743 } 1744 1745 Shift = EmitNeonShiftVector(Shift, Ty, false); 1746 if (usgn) 1747 return Builder.CreateLShr(Vec, Shift, name); 1748 else 1749 return Builder.CreateAShr(Vec, Shift, name); 1750 } 1751 1752 /// GetPointeeAlignment - Given an expression with a pointer type, find the 1753 /// alignment of the type referenced by the pointer. Skip over implicit 1754 /// casts. 1755 std::pair<llvm::Value*, unsigned> 1756 CodeGenFunction::EmitPointerWithAlignment(const Expr *Addr) { 1757 assert(Addr->getType()->isPointerType()); 1758 Addr = Addr->IgnoreParens(); 1759 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Addr)) { 1760 if ((ICE->getCastKind() == CK_BitCast || ICE->getCastKind() == CK_NoOp) && 1761 ICE->getSubExpr()->getType()->isPointerType()) { 1762 std::pair<llvm::Value*, unsigned> Ptr = 1763 EmitPointerWithAlignment(ICE->getSubExpr()); 1764 Ptr.first = Builder.CreateBitCast(Ptr.first, 1765 ConvertType(Addr->getType())); 1766 return Ptr; 1767 } else if (ICE->getCastKind() == CK_ArrayToPointerDecay) { 1768 LValue LV = EmitLValue(ICE->getSubExpr()); 1769 unsigned Align = LV.getAlignment().getQuantity(); 1770 if (!Align) { 1771 // FIXME: Once LValues are fixed to always set alignment, 1772 // zap this code. 1773 QualType PtTy = ICE->getSubExpr()->getType(); 1774 if (!PtTy->isIncompleteType()) 1775 Align = getContext().getTypeAlignInChars(PtTy).getQuantity(); 1776 else 1777 Align = 1; 1778 } 1779 return std::make_pair(LV.getAddress(), Align); 1780 } 1781 } 1782 if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(Addr)) { 1783 if (UO->getOpcode() == UO_AddrOf) { 1784 LValue LV = EmitLValue(UO->getSubExpr()); 1785 unsigned Align = LV.getAlignment().getQuantity(); 1786 if (!Align) { 1787 // FIXME: Once LValues are fixed to always set alignment, 1788 // zap this code. 1789 QualType PtTy = UO->getSubExpr()->getType(); 1790 if (!PtTy->isIncompleteType()) 1791 Align = getContext().getTypeAlignInChars(PtTy).getQuantity(); 1792 else 1793 Align = 1; 1794 } 1795 return std::make_pair(LV.getAddress(), Align); 1796 } 1797 } 1798 1799 unsigned Align = 1; 1800 QualType PtTy = Addr->getType()->getPointeeType(); 1801 if (!PtTy->isIncompleteType()) 1802 Align = getContext().getTypeAlignInChars(PtTy).getQuantity(); 1803 1804 return std::make_pair(EmitScalarExpr(Addr), Align); 1805 } 1806 1807 enum { 1808 AddRetType = (1 << 0), 1809 Add1ArgType = (1 << 1), 1810 Add2ArgTypes = (1 << 2), 1811 1812 VectorizeRetType = (1 << 3), 1813 VectorizeArgTypes = (1 << 4), 1814 1815 InventFloatType = (1 << 5), 1816 UnsignedAlts = (1 << 6), 1817 1818 Vectorize1ArgType = Add1ArgType | VectorizeArgTypes, 1819 VectorRet = AddRetType | VectorizeRetType, 1820 VectorRetGetArgs01 = 1821 AddRetType | Add2ArgTypes | VectorizeRetType | VectorizeArgTypes, 1822 FpCmpzModifiers = 1823 AddRetType | VectorizeRetType | Add1ArgType | InventFloatType 1824 }; 1825 1826 struct NeonIntrinsicInfo { 1827 unsigned BuiltinID; 1828 unsigned LLVMIntrinsic; 1829 unsigned AltLLVMIntrinsic; 1830 const char *NameHint; 1831 unsigned TypeModifier; 1832 1833 bool operator<(unsigned RHSBuiltinID) const { 1834 return BuiltinID < RHSBuiltinID; 1835 } 1836 }; 1837 1838 #define NEONMAP0(NameBase) \ 1839 { NEON::BI__builtin_neon_ ## NameBase, 0, 0, #NameBase, 0 } 1840 1841 #define NEONMAP1(NameBase, LLVMIntrinsic, TypeModifier) \ 1842 { NEON:: BI__builtin_neon_ ## NameBase, \ 1843 Intrinsic::LLVMIntrinsic, 0, #NameBase, TypeModifier } 1844 1845 #define NEONMAP2(NameBase, LLVMIntrinsic, AltLLVMIntrinsic, TypeModifier) \ 1846 { NEON:: BI__builtin_neon_ ## NameBase, \ 1847 Intrinsic::LLVMIntrinsic, Intrinsic::AltLLVMIntrinsic, \ 1848 #NameBase, TypeModifier } 1849 1850 static const NeonIntrinsicInfo AArch64SISDIntrinsicInfo[] = { 1851 NEONMAP1(vabdd_f64, aarch64_neon_vabd, AddRetType), 1852 NEONMAP1(vabds_f32, aarch64_neon_vabd, AddRetType), 1853 NEONMAP1(vabsd_s64, aarch64_neon_vabs, 0), 1854 NEONMAP1(vaddd_s64, aarch64_neon_vaddds, 0), 1855 NEONMAP1(vaddd_u64, aarch64_neon_vadddu, 0), 1856 NEONMAP1(vaddlv_s16, aarch64_neon_saddlv, VectorRet | Add1ArgType), 1857 NEONMAP1(vaddlv_s32, aarch64_neon_saddlv, VectorRet | Add1ArgType), 1858 NEONMAP1(vaddlv_s8, aarch64_neon_saddlv, VectorRet | Add1ArgType), 1859 NEONMAP1(vaddlv_u16, aarch64_neon_uaddlv, VectorRet | Add1ArgType), 1860 NEONMAP1(vaddlv_u32, aarch64_neon_uaddlv, VectorRet | Add1ArgType), 1861 NEONMAP1(vaddlv_u8, aarch64_neon_uaddlv, VectorRet | Add1ArgType), 1862 NEONMAP1(vaddlvq_s16, aarch64_neon_saddlv, VectorRet | Add1ArgType), 1863 NEONMAP1(vaddlvq_s32, aarch64_neon_saddlv, VectorRet | Add1ArgType), 1864 NEONMAP1(vaddlvq_s8, aarch64_neon_saddlv, VectorRet | Add1ArgType), 1865 NEONMAP1(vaddlvq_u16, aarch64_neon_uaddlv, VectorRet | Add1ArgType), 1866 NEONMAP1(vaddlvq_u32, aarch64_neon_uaddlv, VectorRet | Add1ArgType), 1867 NEONMAP1(vaddlvq_u8, aarch64_neon_uaddlv, VectorRet | Add1ArgType), 1868 NEONMAP1(vaddv_f32, aarch64_neon_vpfadd, AddRetType | Add1ArgType), 1869 NEONMAP1(vaddv_s16, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1870 NEONMAP1(vaddv_s32, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1871 NEONMAP1(vaddv_s8, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1872 NEONMAP1(vaddv_u16, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1873 NEONMAP1(vaddv_u32, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1874 NEONMAP1(vaddv_u8, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1875 NEONMAP1(vaddvq_f32, aarch64_neon_vpfadd, AddRetType | Add1ArgType), 1876 NEONMAP1(vaddvq_f64, aarch64_neon_vpfadd, AddRetType | Add1ArgType), 1877 NEONMAP1(vaddvq_s16, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1878 NEONMAP1(vaddvq_s32, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1879 NEONMAP1(vaddvq_s64, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1880 NEONMAP1(vaddvq_s8, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1881 NEONMAP1(vaddvq_u16, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1882 NEONMAP1(vaddvq_u32, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1883 NEONMAP1(vaddvq_u64, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1884 NEONMAP1(vaddvq_u8, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1885 NEONMAP1(vcaged_f64, aarch64_neon_fcage, VectorRet | Add2ArgTypes), 1886 NEONMAP1(vcages_f32, aarch64_neon_fcage, VectorRet | Add2ArgTypes), 1887 NEONMAP1(vcagtd_f64, aarch64_neon_fcagt, VectorRet | Add2ArgTypes), 1888 NEONMAP1(vcagts_f32, aarch64_neon_fcagt, VectorRet | Add2ArgTypes), 1889 NEONMAP1(vcaled_f64, aarch64_neon_fcage, VectorRet | Add2ArgTypes), 1890 NEONMAP1(vcales_f32, aarch64_neon_fcage, VectorRet | Add2ArgTypes), 1891 NEONMAP1(vcaltd_f64, aarch64_neon_fcagt, VectorRet | Add2ArgTypes), 1892 NEONMAP1(vcalts_f32, aarch64_neon_fcagt, VectorRet | Add2ArgTypes), 1893 NEONMAP1(vceqd_f64, aarch64_neon_fceq, VectorRet | Add2ArgTypes), 1894 NEONMAP1(vceqd_s64, aarch64_neon_vceq, VectorRetGetArgs01), 1895 NEONMAP1(vceqd_u64, aarch64_neon_vceq, VectorRetGetArgs01), 1896 NEONMAP1(vceqs_f32, aarch64_neon_fceq, VectorRet | Add2ArgTypes), 1897 NEONMAP1(vceqzd_f64, aarch64_neon_fceq, FpCmpzModifiers), 1898 NEONMAP1(vceqzd_s64, aarch64_neon_vceq, VectorRetGetArgs01), 1899 NEONMAP1(vceqzd_u64, aarch64_neon_vceq, VectorRetGetArgs01), 1900 NEONMAP1(vceqzs_f32, aarch64_neon_fceq, FpCmpzModifiers), 1901 NEONMAP1(vcged_f64, aarch64_neon_fcge, VectorRet | Add2ArgTypes), 1902 NEONMAP1(vcged_s64, aarch64_neon_vcge, VectorRetGetArgs01), 1903 NEONMAP1(vcged_u64, aarch64_neon_vchs, VectorRetGetArgs01), 1904 NEONMAP1(vcges_f32, aarch64_neon_fcge, VectorRet | Add2ArgTypes), 1905 NEONMAP1(vcgezd_f64, aarch64_neon_fcge, FpCmpzModifiers), 1906 NEONMAP1(vcgezd_s64, aarch64_neon_vcge, VectorRetGetArgs01), 1907 NEONMAP1(vcgezs_f32, aarch64_neon_fcge, FpCmpzModifiers), 1908 NEONMAP1(vcgtd_f64, aarch64_neon_fcgt, VectorRet | Add2ArgTypes), 1909 NEONMAP1(vcgtd_s64, aarch64_neon_vcgt, VectorRetGetArgs01), 1910 NEONMAP1(vcgtd_u64, aarch64_neon_vchi, VectorRetGetArgs01), 1911 NEONMAP1(vcgts_f32, aarch64_neon_fcgt, VectorRet | Add2ArgTypes), 1912 NEONMAP1(vcgtzd_f64, aarch64_neon_fcgt, FpCmpzModifiers), 1913 NEONMAP1(vcgtzd_s64, aarch64_neon_vcgt, VectorRetGetArgs01), 1914 NEONMAP1(vcgtzs_f32, aarch64_neon_fcgt, FpCmpzModifiers), 1915 NEONMAP1(vcled_f64, aarch64_neon_fcge, VectorRet | Add2ArgTypes), 1916 NEONMAP1(vcled_s64, aarch64_neon_vcge, VectorRetGetArgs01), 1917 NEONMAP1(vcled_u64, aarch64_neon_vchs, VectorRetGetArgs01), 1918 NEONMAP1(vcles_f32, aarch64_neon_fcge, VectorRet | Add2ArgTypes), 1919 NEONMAP1(vclezd_f64, aarch64_neon_fclez, FpCmpzModifiers), 1920 NEONMAP1(vclezd_s64, aarch64_neon_vclez, VectorRetGetArgs01), 1921 NEONMAP1(vclezs_f32, aarch64_neon_fclez, FpCmpzModifiers), 1922 NEONMAP1(vcltd_f64, aarch64_neon_fcgt, VectorRet | Add2ArgTypes), 1923 NEONMAP1(vcltd_s64, aarch64_neon_vcgt, VectorRetGetArgs01), 1924 NEONMAP1(vcltd_u64, aarch64_neon_vchi, VectorRetGetArgs01), 1925 NEONMAP1(vclts_f32, aarch64_neon_fcgt, VectorRet | Add2ArgTypes), 1926 NEONMAP1(vcltzd_f64, aarch64_neon_fcltz, FpCmpzModifiers), 1927 NEONMAP1(vcltzd_s64, aarch64_neon_vcltz, VectorRetGetArgs01), 1928 NEONMAP1(vcltzs_f32, aarch64_neon_fcltz, FpCmpzModifiers), 1929 NEONMAP1(vcvtad_s64_f64, aarch64_neon_fcvtas, VectorRet | Add1ArgType), 1930 NEONMAP1(vcvtad_u64_f64, aarch64_neon_fcvtau, VectorRet | Add1ArgType), 1931 NEONMAP1(vcvtas_s32_f32, aarch64_neon_fcvtas, VectorRet | Add1ArgType), 1932 NEONMAP1(vcvtas_u32_f32, aarch64_neon_fcvtau, VectorRet | Add1ArgType), 1933 NEONMAP1(vcvtd_f64_s64, aarch64_neon_vcvtint2fps, AddRetType | Vectorize1ArgType), 1934 NEONMAP1(vcvtd_f64_u64, aarch64_neon_vcvtint2fpu, AddRetType | Vectorize1ArgType), 1935 NEONMAP1(vcvtd_n_f64_s64, aarch64_neon_vcvtfxs2fp_n, AddRetType | Vectorize1ArgType), 1936 NEONMAP1(vcvtd_n_f64_u64, aarch64_neon_vcvtfxu2fp_n, AddRetType | Vectorize1ArgType), 1937 NEONMAP1(vcvtd_n_s64_f64, aarch64_neon_vcvtfp2fxs_n, VectorRet | Add1ArgType), 1938 NEONMAP1(vcvtd_n_u64_f64, aarch64_neon_vcvtfp2fxu_n, VectorRet | Add1ArgType), 1939 NEONMAP1(vcvtd_s64_f64, aarch64_neon_fcvtzs, VectorRet | Add1ArgType), 1940 NEONMAP1(vcvtd_u64_f64, aarch64_neon_fcvtzu, VectorRet | Add1ArgType), 1941 NEONMAP1(vcvtmd_s64_f64, aarch64_neon_fcvtms, VectorRet | Add1ArgType), 1942 NEONMAP1(vcvtmd_u64_f64, aarch64_neon_fcvtmu, VectorRet | Add1ArgType), 1943 NEONMAP1(vcvtms_s32_f32, aarch64_neon_fcvtms, VectorRet | Add1ArgType), 1944 NEONMAP1(vcvtms_u32_f32, aarch64_neon_fcvtmu, VectorRet | Add1ArgType), 1945 NEONMAP1(vcvtnd_s64_f64, aarch64_neon_fcvtns, VectorRet | Add1ArgType), 1946 NEONMAP1(vcvtnd_u64_f64, aarch64_neon_fcvtnu, VectorRet | Add1ArgType), 1947 NEONMAP1(vcvtns_s32_f32, aarch64_neon_fcvtns, VectorRet | Add1ArgType), 1948 NEONMAP1(vcvtns_u32_f32, aarch64_neon_fcvtnu, VectorRet | Add1ArgType), 1949 NEONMAP1(vcvtpd_s64_f64, aarch64_neon_fcvtps, VectorRet | Add1ArgType), 1950 NEONMAP1(vcvtpd_u64_f64, aarch64_neon_fcvtpu, VectorRet | Add1ArgType), 1951 NEONMAP1(vcvtps_s32_f32, aarch64_neon_fcvtps, VectorRet | Add1ArgType), 1952 NEONMAP1(vcvtps_u32_f32, aarch64_neon_fcvtpu, VectorRet | Add1ArgType), 1953 NEONMAP1(vcvts_f32_s32, aarch64_neon_vcvtint2fps, AddRetType | Vectorize1ArgType), 1954 NEONMAP1(vcvts_f32_u32, aarch64_neon_vcvtint2fpu, AddRetType | Vectorize1ArgType), 1955 NEONMAP1(vcvts_n_f32_s32, aarch64_neon_vcvtfxs2fp_n, AddRetType | Vectorize1ArgType), 1956 NEONMAP1(vcvts_n_f32_u32, aarch64_neon_vcvtfxu2fp_n, AddRetType | Vectorize1ArgType), 1957 NEONMAP1(vcvts_n_s32_f32, aarch64_neon_vcvtfp2fxs_n, VectorRet | Add1ArgType), 1958 NEONMAP1(vcvts_n_u32_f32, aarch64_neon_vcvtfp2fxu_n, VectorRet | Add1ArgType), 1959 NEONMAP1(vcvts_s32_f32, aarch64_neon_fcvtzs, VectorRet | Add1ArgType), 1960 NEONMAP1(vcvts_u32_f32, aarch64_neon_fcvtzu, VectorRet | Add1ArgType), 1961 NEONMAP1(vcvtxd_f32_f64, aarch64_neon_fcvtxn, 0), 1962 NEONMAP0(vdupb_lane_i8), 1963 NEONMAP0(vdupb_laneq_i8), 1964 NEONMAP0(vdupd_lane_f64), 1965 NEONMAP0(vdupd_lane_i64), 1966 NEONMAP0(vdupd_laneq_f64), 1967 NEONMAP0(vdupd_laneq_i64), 1968 NEONMAP0(vduph_lane_i16), 1969 NEONMAP0(vduph_laneq_i16), 1970 NEONMAP0(vdups_lane_f32), 1971 NEONMAP0(vdups_lane_i32), 1972 NEONMAP0(vdups_laneq_f32), 1973 NEONMAP0(vdups_laneq_i32), 1974 NEONMAP0(vfmad_lane_f64), 1975 NEONMAP0(vfmad_laneq_f64), 1976 NEONMAP0(vfmas_lane_f32), 1977 NEONMAP0(vfmas_laneq_f32), 1978 NEONMAP0(vget_lane_f32), 1979 NEONMAP0(vget_lane_f64), 1980 NEONMAP0(vget_lane_i16), 1981 NEONMAP0(vget_lane_i32), 1982 NEONMAP0(vget_lane_i64), 1983 NEONMAP0(vget_lane_i8), 1984 NEONMAP0(vgetq_lane_f32), 1985 NEONMAP0(vgetq_lane_f64), 1986 NEONMAP0(vgetq_lane_i16), 1987 NEONMAP0(vgetq_lane_i32), 1988 NEONMAP0(vgetq_lane_i64), 1989 NEONMAP0(vgetq_lane_i8), 1990 NEONMAP1(vmaxnmv_f32, aarch64_neon_vpfmaxnm, AddRetType | Add1ArgType), 1991 NEONMAP1(vmaxnmvq_f32, aarch64_neon_vmaxnmv, 0), 1992 NEONMAP1(vmaxnmvq_f64, aarch64_neon_vpfmaxnm, AddRetType | Add1ArgType), 1993 NEONMAP1(vmaxv_f32, aarch64_neon_vpmax, AddRetType | Add1ArgType), 1994 NEONMAP1(vmaxv_s16, aarch64_neon_smaxv, VectorRet | Add1ArgType), 1995 NEONMAP1(vmaxv_s32, aarch64_neon_smaxv, VectorRet | Add1ArgType), 1996 NEONMAP1(vmaxv_s8, aarch64_neon_smaxv, VectorRet | Add1ArgType), 1997 NEONMAP1(vmaxv_u16, aarch64_neon_umaxv, VectorRet | Add1ArgType), 1998 NEONMAP1(vmaxv_u32, aarch64_neon_umaxv, VectorRet | Add1ArgType), 1999 NEONMAP1(vmaxv_u8, aarch64_neon_umaxv, VectorRet | Add1ArgType), 2000 NEONMAP1(vmaxvq_f32, aarch64_neon_vmaxv, 0), 2001 NEONMAP1(vmaxvq_f64, aarch64_neon_vpmax, AddRetType | Add1ArgType), 2002 NEONMAP1(vmaxvq_s16, aarch64_neon_smaxv, VectorRet | Add1ArgType), 2003 NEONMAP1(vmaxvq_s32, aarch64_neon_smaxv, VectorRet | Add1ArgType), 2004 NEONMAP1(vmaxvq_s8, aarch64_neon_smaxv, VectorRet | Add1ArgType), 2005 NEONMAP1(vmaxvq_u16, aarch64_neon_umaxv, VectorRet | Add1ArgType), 2006 NEONMAP1(vmaxvq_u32, aarch64_neon_umaxv, VectorRet | Add1ArgType), 2007 NEONMAP1(vmaxvq_u8, aarch64_neon_umaxv, VectorRet | Add1ArgType), 2008 NEONMAP1(vminnmv_f32, aarch64_neon_vpfminnm, AddRetType | Add1ArgType), 2009 NEONMAP1(vminnmvq_f32, aarch64_neon_vminnmv, 0), 2010 NEONMAP1(vminnmvq_f64, aarch64_neon_vpfminnm, AddRetType | Add1ArgType), 2011 NEONMAP1(vminv_f32, aarch64_neon_vpmin, AddRetType | Add1ArgType), 2012 NEONMAP1(vminv_s16, aarch64_neon_sminv, VectorRet | Add1ArgType), 2013 NEONMAP1(vminv_s32, aarch64_neon_sminv, VectorRet | Add1ArgType), 2014 NEONMAP1(vminv_s8, aarch64_neon_sminv, VectorRet | Add1ArgType), 2015 NEONMAP1(vminv_u16, aarch64_neon_uminv, VectorRet | Add1ArgType), 2016 NEONMAP1(vminv_u32, aarch64_neon_uminv, VectorRet | Add1ArgType), 2017 NEONMAP1(vminv_u8, aarch64_neon_uminv, VectorRet | Add1ArgType), 2018 NEONMAP1(vminvq_f32, aarch64_neon_vminv, 0), 2019 NEONMAP1(vminvq_f64, aarch64_neon_vpmin, AddRetType | Add1ArgType), 2020 NEONMAP1(vminvq_s16, aarch64_neon_sminv, VectorRet | Add1ArgType), 2021 NEONMAP1(vminvq_s32, aarch64_neon_sminv, VectorRet | Add1ArgType), 2022 NEONMAP1(vminvq_s8, aarch64_neon_sminv, VectorRet | Add1ArgType), 2023 NEONMAP1(vminvq_u16, aarch64_neon_uminv, VectorRet | Add1ArgType), 2024 NEONMAP1(vminvq_u32, aarch64_neon_uminv, VectorRet | Add1ArgType), 2025 NEONMAP1(vminvq_u8, aarch64_neon_uminv, VectorRet | Add1ArgType), 2026 NEONMAP0(vmul_n_f64), 2027 NEONMAP1(vmull_p64, aarch64_neon_vmull_p64, 0), 2028 NEONMAP0(vmulxd_f64), 2029 NEONMAP0(vmulxs_f32), 2030 NEONMAP1(vnegd_s64, aarch64_neon_vneg, 0), 2031 NEONMAP1(vpaddd_f64, aarch64_neon_vpfadd, AddRetType | Add1ArgType), 2032 NEONMAP1(vpaddd_s64, aarch64_neon_vpadd, 0), 2033 NEONMAP1(vpaddd_u64, aarch64_neon_vpadd, 0), 2034 NEONMAP1(vpadds_f32, aarch64_neon_vpfadd, AddRetType | Add1ArgType), 2035 NEONMAP1(vpmaxnmqd_f64, aarch64_neon_vpfmaxnm, AddRetType | Add1ArgType), 2036 NEONMAP1(vpmaxnms_f32, aarch64_neon_vpfmaxnm, AddRetType | Add1ArgType), 2037 NEONMAP1(vpmaxqd_f64, aarch64_neon_vpmax, AddRetType | Add1ArgType), 2038 NEONMAP1(vpmaxs_f32, aarch64_neon_vpmax, AddRetType | Add1ArgType), 2039 NEONMAP1(vpminnmqd_f64, aarch64_neon_vpfminnm, AddRetType | Add1ArgType), 2040 NEONMAP1(vpminnms_f32, aarch64_neon_vpfminnm, AddRetType | Add1ArgType), 2041 NEONMAP1(vpminqd_f64, aarch64_neon_vpmin, AddRetType | Add1ArgType), 2042 NEONMAP1(vpmins_f32, aarch64_neon_vpmin, AddRetType | Add1ArgType), 2043 NEONMAP1(vqabsb_s8, arm_neon_vqabs, VectorRet), 2044 NEONMAP1(vqabsd_s64, arm_neon_vqabs, VectorRet), 2045 NEONMAP1(vqabsh_s16, arm_neon_vqabs, VectorRet), 2046 NEONMAP1(vqabss_s32, arm_neon_vqabs, VectorRet), 2047 NEONMAP1(vqaddb_s8, arm_neon_vqadds, VectorRet), 2048 NEONMAP1(vqaddb_u8, arm_neon_vqaddu, VectorRet), 2049 NEONMAP1(vqaddd_s64, arm_neon_vqadds, VectorRet), 2050 NEONMAP1(vqaddd_u64, arm_neon_vqaddu, VectorRet), 2051 NEONMAP1(vqaddh_s16, arm_neon_vqadds, VectorRet), 2052 NEONMAP1(vqaddh_u16, arm_neon_vqaddu, VectorRet), 2053 NEONMAP1(vqadds_s32, arm_neon_vqadds, VectorRet), 2054 NEONMAP1(vqadds_u32, arm_neon_vqaddu, VectorRet), 2055 NEONMAP0(vqdmlalh_lane_s16), 2056 NEONMAP0(vqdmlalh_laneq_s16), 2057 NEONMAP1(vqdmlalh_s16, aarch64_neon_vqdmlal, VectorRet), 2058 NEONMAP0(vqdmlals_lane_s32), 2059 NEONMAP0(vqdmlals_laneq_s32), 2060 NEONMAP1(vqdmlals_s32, aarch64_neon_vqdmlal, VectorRet), 2061 NEONMAP0(vqdmlslh_lane_s16), 2062 NEONMAP0(vqdmlslh_laneq_s16), 2063 NEONMAP1(vqdmlslh_s16, aarch64_neon_vqdmlsl, VectorRet), 2064 NEONMAP0(vqdmlsls_lane_s32), 2065 NEONMAP0(vqdmlsls_laneq_s32), 2066 NEONMAP1(vqdmlsls_s32, aarch64_neon_vqdmlsl, VectorRet), 2067 NEONMAP1(vqdmulhh_s16, arm_neon_vqdmulh, VectorRet), 2068 NEONMAP1(vqdmulhs_s32, arm_neon_vqdmulh, VectorRet), 2069 NEONMAP1(vqdmullh_s16, arm_neon_vqdmull, VectorRet), 2070 NEONMAP1(vqdmulls_s32, arm_neon_vqdmull, VectorRet), 2071 NEONMAP1(vqmovnd_s64, arm_neon_vqmovns, VectorRet), 2072 NEONMAP1(vqmovnd_u64, arm_neon_vqmovnu, VectorRet), 2073 NEONMAP1(vqmovnh_s16, arm_neon_vqmovns, VectorRet), 2074 NEONMAP1(vqmovnh_u16, arm_neon_vqmovnu, VectorRet), 2075 NEONMAP1(vqmovns_s32, arm_neon_vqmovns, VectorRet), 2076 NEONMAP1(vqmovns_u32, arm_neon_vqmovnu, VectorRet), 2077 NEONMAP1(vqmovund_s64, arm_neon_vqmovnsu, VectorRet), 2078 NEONMAP1(vqmovunh_s16, arm_neon_vqmovnsu, VectorRet), 2079 NEONMAP1(vqmovuns_s32, arm_neon_vqmovnsu, VectorRet), 2080 NEONMAP1(vqnegb_s8, arm_neon_vqneg, VectorRet), 2081 NEONMAP1(vqnegd_s64, arm_neon_vqneg, VectorRet), 2082 NEONMAP1(vqnegh_s16, arm_neon_vqneg, VectorRet), 2083 NEONMAP1(vqnegs_s32, arm_neon_vqneg, VectorRet), 2084 NEONMAP1(vqrdmulhh_s16, arm_neon_vqrdmulh, VectorRet), 2085 NEONMAP1(vqrdmulhs_s32, arm_neon_vqrdmulh, VectorRet), 2086 NEONMAP1(vqrshlb_s8, aarch64_neon_vqrshls, VectorRet), 2087 NEONMAP1(vqrshlb_u8, aarch64_neon_vqrshlu, VectorRet), 2088 NEONMAP1(vqrshld_s64, aarch64_neon_vqrshls, VectorRet), 2089 NEONMAP1(vqrshld_u64, aarch64_neon_vqrshlu, VectorRet), 2090 NEONMAP1(vqrshlh_s16, aarch64_neon_vqrshls, VectorRet), 2091 NEONMAP1(vqrshlh_u16, aarch64_neon_vqrshlu, VectorRet), 2092 NEONMAP1(vqrshls_s32, aarch64_neon_vqrshls, VectorRet), 2093 NEONMAP1(vqrshls_u32, aarch64_neon_vqrshlu, VectorRet), 2094 NEONMAP1(vqrshrnd_n_s64, aarch64_neon_vsqrshrn, VectorRet), 2095 NEONMAP1(vqrshrnd_n_u64, aarch64_neon_vuqrshrn, VectorRet), 2096 NEONMAP1(vqrshrnh_n_s16, aarch64_neon_vsqrshrn, VectorRet), 2097 NEONMAP1(vqrshrnh_n_u16, aarch64_neon_vuqrshrn, VectorRet), 2098 NEONMAP1(vqrshrns_n_s32, aarch64_neon_vsqrshrn, VectorRet), 2099 NEONMAP1(vqrshrns_n_u32, aarch64_neon_vuqrshrn, VectorRet), 2100 NEONMAP1(vqrshrund_n_s64, aarch64_neon_vsqrshrun, VectorRet), 2101 NEONMAP1(vqrshrunh_n_s16, aarch64_neon_vsqrshrun, VectorRet), 2102 NEONMAP1(vqrshruns_n_s32, aarch64_neon_vsqrshrun, VectorRet), 2103 NEONMAP1(vqshlb_n_s8, aarch64_neon_vqshls_n, VectorRet), 2104 NEONMAP1(vqshlb_n_u8, aarch64_neon_vqshlu_n, VectorRet), 2105 NEONMAP1(vqshlb_s8, aarch64_neon_vqshls, VectorRet), 2106 NEONMAP1(vqshlb_u8, aarch64_neon_vqshlu, VectorRet), 2107 NEONMAP1(vqshld_n_s64, aarch64_neon_vqshls_n, VectorRet), 2108 NEONMAP1(vqshld_n_u64, aarch64_neon_vqshlu_n, VectorRet), 2109 NEONMAP1(vqshld_s64, aarch64_neon_vqshls, VectorRet), 2110 NEONMAP1(vqshld_u64, aarch64_neon_vqshlu, VectorRet), 2111 NEONMAP1(vqshlh_n_s16, aarch64_neon_vqshls_n, VectorRet), 2112 NEONMAP1(vqshlh_n_u16, aarch64_neon_vqshlu_n, VectorRet), 2113 NEONMAP1(vqshlh_s16, aarch64_neon_vqshls, VectorRet), 2114 NEONMAP1(vqshlh_u16, aarch64_neon_vqshlu, VectorRet), 2115 NEONMAP1(vqshls_n_s32, aarch64_neon_vqshls_n, VectorRet), 2116 NEONMAP1(vqshls_n_u32, aarch64_neon_vqshlu_n, VectorRet), 2117 NEONMAP1(vqshls_s32, aarch64_neon_vqshls, VectorRet), 2118 NEONMAP1(vqshls_u32, aarch64_neon_vqshlu, VectorRet), 2119 NEONMAP1(vqshlub_n_s8, aarch64_neon_vsqshlu, VectorRet), 2120 NEONMAP1(vqshlud_n_s64, aarch64_neon_vsqshlu, VectorRet), 2121 NEONMAP1(vqshluh_n_s16, aarch64_neon_vsqshlu, VectorRet), 2122 NEONMAP1(vqshlus_n_s32, aarch64_neon_vsqshlu, VectorRet), 2123 NEONMAP1(vqshrnd_n_s64, aarch64_neon_vsqshrn, VectorRet), 2124 NEONMAP1(vqshrnd_n_u64, aarch64_neon_vuqshrn, VectorRet), 2125 NEONMAP1(vqshrnh_n_s16, aarch64_neon_vsqshrn, VectorRet), 2126 NEONMAP1(vqshrnh_n_u16, aarch64_neon_vuqshrn, VectorRet), 2127 NEONMAP1(vqshrns_n_s32, aarch64_neon_vsqshrn, VectorRet), 2128 NEONMAP1(vqshrns_n_u32, aarch64_neon_vuqshrn, VectorRet), 2129 NEONMAP1(vqshrund_n_s64, aarch64_neon_vsqshrun, VectorRet), 2130 NEONMAP1(vqshrunh_n_s16, aarch64_neon_vsqshrun, VectorRet), 2131 NEONMAP1(vqshruns_n_s32, aarch64_neon_vsqshrun, VectorRet), 2132 NEONMAP1(vqsubb_s8, arm_neon_vqsubs, VectorRet), 2133 NEONMAP1(vqsubb_u8, arm_neon_vqsubu, VectorRet), 2134 NEONMAP1(vqsubd_s64, arm_neon_vqsubs, VectorRet), 2135 NEONMAP1(vqsubd_u64, arm_neon_vqsubu, VectorRet), 2136 NEONMAP1(vqsubh_s16, arm_neon_vqsubs, VectorRet), 2137 NEONMAP1(vqsubh_u16, arm_neon_vqsubu, VectorRet), 2138 NEONMAP1(vqsubs_s32, arm_neon_vqsubs, VectorRet), 2139 NEONMAP1(vqsubs_u32, arm_neon_vqsubu, VectorRet), 2140 NEONMAP1(vrecped_f64, aarch64_neon_vrecpe, AddRetType), 2141 NEONMAP1(vrecpes_f32, aarch64_neon_vrecpe, AddRetType), 2142 NEONMAP1(vrecpsd_f64, aarch64_neon_vrecps, AddRetType), 2143 NEONMAP1(vrecpss_f32, aarch64_neon_vrecps, AddRetType), 2144 NEONMAP1(vrecpxd_f64, aarch64_neon_vrecpx, AddRetType), 2145 NEONMAP1(vrecpxs_f32, aarch64_neon_vrecpx, AddRetType), 2146 NEONMAP1(vrshld_s64, aarch64_neon_vrshlds, 0), 2147 NEONMAP1(vrshld_u64, aarch64_neon_vrshldu, 0), 2148 NEONMAP1(vrshrd_n_s64, aarch64_neon_vsrshr, VectorRet), 2149 NEONMAP1(vrshrd_n_u64, aarch64_neon_vurshr, VectorRet), 2150 NEONMAP1(vrsqrted_f64, aarch64_neon_vrsqrte, AddRetType), 2151 NEONMAP1(vrsqrtes_f32, aarch64_neon_vrsqrte, AddRetType), 2152 NEONMAP1(vrsqrtsd_f64, aarch64_neon_vrsqrts, AddRetType), 2153 NEONMAP1(vrsqrtss_f32, aarch64_neon_vrsqrts, AddRetType), 2154 NEONMAP1(vrsrad_n_s64, aarch64_neon_vrsrads_n, 0), 2155 NEONMAP1(vrsrad_n_u64, aarch64_neon_vrsradu_n, 0), 2156 NEONMAP0(vset_lane_f32), 2157 NEONMAP0(vset_lane_f64), 2158 NEONMAP0(vset_lane_i16), 2159 NEONMAP0(vset_lane_i32), 2160 NEONMAP0(vset_lane_i64), 2161 NEONMAP0(vset_lane_i8), 2162 NEONMAP0(vsetq_lane_f32), 2163 NEONMAP0(vsetq_lane_f64), 2164 NEONMAP0(vsetq_lane_i16), 2165 NEONMAP0(vsetq_lane_i32), 2166 NEONMAP0(vsetq_lane_i64), 2167 NEONMAP0(vsetq_lane_i8), 2168 NEONMAP1(vsha1cq_u32, arm_neon_sha1c, 0), 2169 NEONMAP1(vsha1h_u32, arm_neon_sha1h, 0), 2170 NEONMAP1(vsha1mq_u32, arm_neon_sha1m, 0), 2171 NEONMAP1(vsha1pq_u32, arm_neon_sha1p, 0), 2172 NEONMAP1(vshld_n_s64, aarch64_neon_vshld_n, 0), 2173 NEONMAP1(vshld_n_u64, aarch64_neon_vshld_n, 0), 2174 NEONMAP1(vshld_s64, aarch64_neon_vshlds, 0), 2175 NEONMAP1(vshld_u64, aarch64_neon_vshldu, 0), 2176 NEONMAP1(vshrd_n_s64, aarch64_neon_vshrds_n, 0), 2177 NEONMAP1(vshrd_n_u64, aarch64_neon_vshrdu_n, 0), 2178 NEONMAP1(vslid_n_s64, aarch64_neon_vsli, VectorRet), 2179 NEONMAP1(vslid_n_u64, aarch64_neon_vsli, VectorRet), 2180 NEONMAP1(vsqaddb_u8, aarch64_neon_vsqadd, VectorRet), 2181 NEONMAP1(vsqaddd_u64, aarch64_neon_vsqadd, VectorRet), 2182 NEONMAP1(vsqaddh_u16, aarch64_neon_vsqadd, VectorRet), 2183 NEONMAP1(vsqadds_u32, aarch64_neon_vsqadd, VectorRet), 2184 NEONMAP1(vsrad_n_s64, aarch64_neon_vsrads_n, 0), 2185 NEONMAP1(vsrad_n_u64, aarch64_neon_vsradu_n, 0), 2186 NEONMAP1(vsrid_n_s64, aarch64_neon_vsri, VectorRet), 2187 NEONMAP1(vsrid_n_u64, aarch64_neon_vsri, VectorRet), 2188 NEONMAP1(vsubd_s64, aarch64_neon_vsubds, 0), 2189 NEONMAP1(vsubd_u64, aarch64_neon_vsubdu, 0), 2190 NEONMAP1(vtstd_s64, aarch64_neon_vtstd, VectorRetGetArgs01), 2191 NEONMAP1(vtstd_u64, aarch64_neon_vtstd, VectorRetGetArgs01), 2192 NEONMAP1(vuqaddb_s8, aarch64_neon_vuqadd, VectorRet), 2193 NEONMAP1(vuqaddd_s64, aarch64_neon_vuqadd, VectorRet), 2194 NEONMAP1(vuqaddh_s16, aarch64_neon_vuqadd, VectorRet), 2195 NEONMAP1(vuqadds_s32, aarch64_neon_vuqadd, VectorRet) 2196 }; 2197 2198 static NeonIntrinsicInfo ARMSIMDIntrinsicMap [] = { 2199 NEONMAP2(vabd_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts), 2200 NEONMAP2(vabdq_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts), 2201 NEONMAP1(vabs_v, arm_neon_vabs, 0), 2202 NEONMAP1(vabsq_v, arm_neon_vabs, 0), 2203 NEONMAP0(vaddhn_v), 2204 NEONMAP1(vaesdq_v, arm_neon_aesd, 0), 2205 NEONMAP1(vaeseq_v, arm_neon_aese, 0), 2206 NEONMAP1(vaesimcq_v, arm_neon_aesimc, 0), 2207 NEONMAP1(vaesmcq_v, arm_neon_aesmc, 0), 2208 NEONMAP1(vbsl_v, arm_neon_vbsl, AddRetType), 2209 NEONMAP1(vbslq_v, arm_neon_vbsl, AddRetType), 2210 NEONMAP1(vcage_v, arm_neon_vacge, 0), 2211 NEONMAP1(vcageq_v, arm_neon_vacge, 0), 2212 NEONMAP1(vcagt_v, arm_neon_vacgt, 0), 2213 NEONMAP1(vcagtq_v, arm_neon_vacgt, 0), 2214 NEONMAP1(vcale_v, arm_neon_vacge, 0), 2215 NEONMAP1(vcaleq_v, arm_neon_vacge, 0), 2216 NEONMAP1(vcalt_v, arm_neon_vacgt, 0), 2217 NEONMAP1(vcaltq_v, arm_neon_vacgt, 0), 2218 NEONMAP1(vcls_v, arm_neon_vcls, Add1ArgType), 2219 NEONMAP1(vclsq_v, arm_neon_vcls, Add1ArgType), 2220 NEONMAP1(vclz_v, ctlz, Add1ArgType), 2221 NEONMAP1(vclzq_v, ctlz, Add1ArgType), 2222 NEONMAP1(vcnt_v, ctpop, Add1ArgType), 2223 NEONMAP1(vcntq_v, ctpop, Add1ArgType), 2224 NEONMAP1(vcvt_f16_v, arm_neon_vcvtfp2hf, 0), 2225 NEONMAP1(vcvt_f32_f16, arm_neon_vcvthf2fp, 0), 2226 NEONMAP0(vcvt_f32_v), 2227 NEONMAP2(vcvt_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0), 2228 NEONMAP1(vcvt_n_s32_v, arm_neon_vcvtfp2fxs, 0), 2229 NEONMAP1(vcvt_n_s64_v, arm_neon_vcvtfp2fxs, 0), 2230 NEONMAP1(vcvt_n_u32_v, arm_neon_vcvtfp2fxu, 0), 2231 NEONMAP1(vcvt_n_u64_v, arm_neon_vcvtfp2fxu, 0), 2232 NEONMAP0(vcvt_s32_v), 2233 NEONMAP0(vcvt_s64_v), 2234 NEONMAP0(vcvt_u32_v), 2235 NEONMAP0(vcvt_u64_v), 2236 NEONMAP1(vcvta_s32_v, arm_neon_vcvtas, 0), 2237 NEONMAP1(vcvta_s64_v, arm_neon_vcvtas, 0), 2238 NEONMAP1(vcvta_u32_v, arm_neon_vcvtau, 0), 2239 NEONMAP1(vcvta_u64_v, arm_neon_vcvtau, 0), 2240 NEONMAP1(vcvtaq_s32_v, arm_neon_vcvtas, 0), 2241 NEONMAP1(vcvtaq_s64_v, arm_neon_vcvtas, 0), 2242 NEONMAP1(vcvtaq_u32_v, arm_neon_vcvtau, 0), 2243 NEONMAP1(vcvtaq_u64_v, arm_neon_vcvtau, 0), 2244 NEONMAP1(vcvtm_s32_v, arm_neon_vcvtms, 0), 2245 NEONMAP1(vcvtm_s64_v, arm_neon_vcvtms, 0), 2246 NEONMAP1(vcvtm_u32_v, arm_neon_vcvtmu, 0), 2247 NEONMAP1(vcvtm_u64_v, arm_neon_vcvtmu, 0), 2248 NEONMAP1(vcvtmq_s32_v, arm_neon_vcvtms, 0), 2249 NEONMAP1(vcvtmq_s64_v, arm_neon_vcvtms, 0), 2250 NEONMAP1(vcvtmq_u32_v, arm_neon_vcvtmu, 0), 2251 NEONMAP1(vcvtmq_u64_v, arm_neon_vcvtmu, 0), 2252 NEONMAP1(vcvtn_s32_v, arm_neon_vcvtns, 0), 2253 NEONMAP1(vcvtn_s64_v, arm_neon_vcvtns, 0), 2254 NEONMAP1(vcvtn_u32_v, arm_neon_vcvtnu, 0), 2255 NEONMAP1(vcvtn_u64_v, arm_neon_vcvtnu, 0), 2256 NEONMAP1(vcvtnq_s32_v, arm_neon_vcvtns, 0), 2257 NEONMAP1(vcvtnq_s64_v, arm_neon_vcvtns, 0), 2258 NEONMAP1(vcvtnq_u32_v, arm_neon_vcvtnu, 0), 2259 NEONMAP1(vcvtnq_u64_v, arm_neon_vcvtnu, 0), 2260 NEONMAP1(vcvtp_s32_v, arm_neon_vcvtps, 0), 2261 NEONMAP1(vcvtp_s64_v, arm_neon_vcvtps, 0), 2262 NEONMAP1(vcvtp_u32_v, arm_neon_vcvtpu, 0), 2263 NEONMAP1(vcvtp_u64_v, arm_neon_vcvtpu, 0), 2264 NEONMAP1(vcvtpq_s32_v, arm_neon_vcvtps, 0), 2265 NEONMAP1(vcvtpq_s64_v, arm_neon_vcvtps, 0), 2266 NEONMAP1(vcvtpq_u32_v, arm_neon_vcvtpu, 0), 2267 NEONMAP1(vcvtpq_u64_v, arm_neon_vcvtpu, 0), 2268 NEONMAP0(vcvtq_f32_v), 2269 NEONMAP2(vcvtq_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0), 2270 NEONMAP1(vcvtq_n_s32_v, arm_neon_vcvtfp2fxs, 0), 2271 NEONMAP1(vcvtq_n_s64_v, arm_neon_vcvtfp2fxs, 0), 2272 NEONMAP1(vcvtq_n_u32_v, arm_neon_vcvtfp2fxu, 0), 2273 NEONMAP1(vcvtq_n_u64_v, arm_neon_vcvtfp2fxu, 0), 2274 NEONMAP0(vcvtq_s32_v), 2275 NEONMAP0(vcvtq_s64_v), 2276 NEONMAP0(vcvtq_u32_v), 2277 NEONMAP0(vcvtq_u64_v), 2278 NEONMAP0(vext_v), 2279 NEONMAP0(vextq_v), 2280 NEONMAP0(vfma_v), 2281 NEONMAP0(vfmaq_v), 2282 NEONMAP2(vhadd_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts), 2283 NEONMAP2(vhaddq_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts), 2284 NEONMAP2(vhsub_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts), 2285 NEONMAP2(vhsubq_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts), 2286 NEONMAP0(vld1_dup_v), 2287 NEONMAP1(vld1_v, arm_neon_vld1, 0), 2288 NEONMAP0(vld1q_dup_v), 2289 NEONMAP1(vld1q_v, arm_neon_vld1, 0), 2290 NEONMAP1(vld2_lane_v, arm_neon_vld2lane, 0), 2291 NEONMAP1(vld2_v, arm_neon_vld2, 0), 2292 NEONMAP1(vld2q_lane_v, arm_neon_vld2lane, 0), 2293 NEONMAP1(vld2q_v, arm_neon_vld2, 0), 2294 NEONMAP1(vld3_lane_v, arm_neon_vld3lane, 0), 2295 NEONMAP1(vld3_v, arm_neon_vld3, 0), 2296 NEONMAP1(vld3q_lane_v, arm_neon_vld3lane, 0), 2297 NEONMAP1(vld3q_v, arm_neon_vld3, 0), 2298 NEONMAP1(vld4_lane_v, arm_neon_vld4lane, 0), 2299 NEONMAP1(vld4_v, arm_neon_vld4, 0), 2300 NEONMAP1(vld4q_lane_v, arm_neon_vld4lane, 0), 2301 NEONMAP1(vld4q_v, arm_neon_vld4, 0), 2302 NEONMAP2(vmax_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts), 2303 NEONMAP2(vmaxq_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts), 2304 NEONMAP2(vmin_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts), 2305 NEONMAP2(vminq_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts), 2306 NEONMAP0(vmovl_v), 2307 NEONMAP0(vmovn_v), 2308 NEONMAP1(vmul_v, arm_neon_vmulp, Add1ArgType), 2309 NEONMAP0(vmull_v), 2310 NEONMAP1(vmulq_v, arm_neon_vmulp, Add1ArgType), 2311 NEONMAP2(vpadal_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts), 2312 NEONMAP2(vpadalq_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts), 2313 NEONMAP1(vpadd_v, arm_neon_vpadd, Add1ArgType), 2314 NEONMAP2(vpaddl_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts), 2315 NEONMAP2(vpaddlq_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts), 2316 NEONMAP1(vpaddq_v, arm_neon_vpadd, Add1ArgType), 2317 NEONMAP2(vpmax_v, arm_neon_vpmaxu, arm_neon_vpmaxs, Add1ArgType | UnsignedAlts), 2318 NEONMAP2(vpmin_v, arm_neon_vpminu, arm_neon_vpmins, Add1ArgType | UnsignedAlts), 2319 NEONMAP1(vqabs_v, arm_neon_vqabs, Add1ArgType), 2320 NEONMAP1(vqabsq_v, arm_neon_vqabs, Add1ArgType), 2321 NEONMAP2(vqadd_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts), 2322 NEONMAP2(vqaddq_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts), 2323 NEONMAP2(vqdmlal_v, arm_neon_vqdmull, arm_neon_vqadds, 0), 2324 NEONMAP2(vqdmlsl_v, arm_neon_vqdmull, arm_neon_vqsubs, 0), 2325 NEONMAP1(vqdmulh_v, arm_neon_vqdmulh, Add1ArgType), 2326 NEONMAP1(vqdmulhq_v, arm_neon_vqdmulh, Add1ArgType), 2327 NEONMAP1(vqdmull_v, arm_neon_vqdmull, Add1ArgType), 2328 NEONMAP2(vqmovn_v, arm_neon_vqmovnu, arm_neon_vqmovns, Add1ArgType | UnsignedAlts), 2329 NEONMAP1(vqmovun_v, arm_neon_vqmovnsu, Add1ArgType), 2330 NEONMAP1(vqneg_v, arm_neon_vqneg, Add1ArgType), 2331 NEONMAP1(vqnegq_v, arm_neon_vqneg, Add1ArgType), 2332 NEONMAP1(vqrdmulh_v, arm_neon_vqrdmulh, Add1ArgType), 2333 NEONMAP1(vqrdmulhq_v, arm_neon_vqrdmulh, Add1ArgType), 2334 NEONMAP2(vqrshl_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts), 2335 NEONMAP2(vqrshlq_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts), 2336 NEONMAP2(vqshl_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts), 2337 NEONMAP2(vqshl_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts), 2338 NEONMAP2(vqshlq_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts), 2339 NEONMAP2(vqshlq_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts), 2340 NEONMAP2(vqsub_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts), 2341 NEONMAP2(vqsubq_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts), 2342 NEONMAP1(vraddhn_v, arm_neon_vraddhn, Add1ArgType), 2343 NEONMAP2(vrecpe_v, arm_neon_vrecpe, arm_neon_vrecpe, 0), 2344 NEONMAP2(vrecpeq_v, arm_neon_vrecpe, arm_neon_vrecpe, 0), 2345 NEONMAP1(vrecps_v, arm_neon_vrecps, Add1ArgType), 2346 NEONMAP1(vrecpsq_v, arm_neon_vrecps, Add1ArgType), 2347 NEONMAP2(vrhadd_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts), 2348 NEONMAP2(vrhaddq_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts), 2349 NEONMAP2(vrshl_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts), 2350 NEONMAP2(vrshlq_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts), 2351 NEONMAP2(vrsqrte_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0), 2352 NEONMAP2(vrsqrteq_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0), 2353 NEONMAP1(vrsqrts_v, arm_neon_vrsqrts, Add1ArgType), 2354 NEONMAP1(vrsqrtsq_v, arm_neon_vrsqrts, Add1ArgType), 2355 NEONMAP1(vrsubhn_v, arm_neon_vrsubhn, Add1ArgType), 2356 NEONMAP1(vsha1su0q_v, arm_neon_sha1su0, 0), 2357 NEONMAP1(vsha1su1q_v, arm_neon_sha1su1, 0), 2358 NEONMAP1(vsha256h2q_v, arm_neon_sha256h2, 0), 2359 NEONMAP1(vsha256hq_v, arm_neon_sha256h, 0), 2360 NEONMAP1(vsha256su0q_v, arm_neon_sha256su0, 0), 2361 NEONMAP1(vsha256su1q_v, arm_neon_sha256su1, 0), 2362 NEONMAP0(vshl_n_v), 2363 NEONMAP2(vshl_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts), 2364 NEONMAP0(vshll_n_v), 2365 NEONMAP0(vshlq_n_v), 2366 NEONMAP2(vshlq_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts), 2367 NEONMAP0(vshr_n_v), 2368 NEONMAP0(vshrn_n_v), 2369 NEONMAP0(vshrq_n_v), 2370 NEONMAP1(vst1_v, arm_neon_vst1, 0), 2371 NEONMAP1(vst1q_v, arm_neon_vst1, 0), 2372 NEONMAP1(vst2_lane_v, arm_neon_vst2lane, 0), 2373 NEONMAP1(vst2_v, arm_neon_vst2, 0), 2374 NEONMAP1(vst2q_lane_v, arm_neon_vst2lane, 0), 2375 NEONMAP1(vst2q_v, arm_neon_vst2, 0), 2376 NEONMAP1(vst3_lane_v, arm_neon_vst3lane, 0), 2377 NEONMAP1(vst3_v, arm_neon_vst3, 0), 2378 NEONMAP1(vst3q_lane_v, arm_neon_vst3lane, 0), 2379 NEONMAP1(vst3q_v, arm_neon_vst3, 0), 2380 NEONMAP1(vst4_lane_v, arm_neon_vst4lane, 0), 2381 NEONMAP1(vst4_v, arm_neon_vst4, 0), 2382 NEONMAP1(vst4q_lane_v, arm_neon_vst4lane, 0), 2383 NEONMAP1(vst4q_v, arm_neon_vst4, 0), 2384 NEONMAP0(vsubhn_v), 2385 NEONMAP0(vtrn_v), 2386 NEONMAP0(vtrnq_v), 2387 NEONMAP0(vtst_v), 2388 NEONMAP0(vtstq_v), 2389 NEONMAP0(vuzp_v), 2390 NEONMAP0(vuzpq_v), 2391 NEONMAP0(vzip_v), 2392 NEONMAP0(vzipq_v) 2393 }; 2394 2395 #undef NEONMAP0 2396 #undef NEONMAP1 2397 #undef NEONMAP2 2398 2399 static bool NEONSIMDIntrinsicsProvenSorted = false; 2400 2401 static bool AArch64SISDIntrinsicInfoProvenSorted = false; 2402 2403 static const NeonIntrinsicInfo * 2404 findNeonIntrinsicInMap(llvm::ArrayRef<NeonIntrinsicInfo> IntrinsicMap, 2405 unsigned BuiltinID, bool &MapProvenSorted) { 2406 2407 #ifndef NDEBUG 2408 if (!MapProvenSorted) { 2409 // FIXME: use std::is_sorted once C++11 is allowed 2410 for (unsigned i = 0; i < IntrinsicMap.size() - 1; ++i) 2411 assert(IntrinsicMap[i].BuiltinID <= IntrinsicMap[i + 1].BuiltinID); 2412 MapProvenSorted = true; 2413 } 2414 #endif 2415 2416 const NeonIntrinsicInfo *Builtin = 2417 std::lower_bound(IntrinsicMap.begin(), IntrinsicMap.end(), BuiltinID); 2418 2419 if (Builtin != IntrinsicMap.end() && Builtin->BuiltinID == BuiltinID) 2420 return Builtin; 2421 2422 return 0; 2423 } 2424 2425 Function *CodeGenFunction::LookupNeonLLVMIntrinsic(unsigned IntrinsicID, 2426 unsigned Modifier, 2427 llvm::Type *ArgType, 2428 const CallExpr *E) { 2429 // Return type. 2430 SmallVector<llvm::Type *, 3> Tys; 2431 if (Modifier & AddRetType) { 2432 llvm::Type *Ty = ConvertType(E->getCallReturnType()); 2433 if (Modifier & VectorizeRetType) 2434 Ty = llvm::VectorType::get(Ty, 1); 2435 2436 Tys.push_back(Ty); 2437 } 2438 2439 // Arguments. 2440 if (Modifier & VectorizeArgTypes) 2441 ArgType = llvm::VectorType::get(ArgType, 1); 2442 2443 if (Modifier & (Add1ArgType | Add2ArgTypes)) 2444 Tys.push_back(ArgType); 2445 2446 if (Modifier & Add2ArgTypes) 2447 Tys.push_back(ArgType); 2448 2449 if (Modifier & InventFloatType) 2450 Tys.push_back(FloatTy); 2451 2452 return CGM.getIntrinsic(IntrinsicID, Tys); 2453 } 2454 2455 2456 static Value *EmitAArch64ScalarBuiltinExpr(CodeGenFunction &CGF, 2457 const NeonIntrinsicInfo &SISDInfo, 2458 const CallExpr *E) { 2459 unsigned BuiltinID = SISDInfo.BuiltinID; 2460 unsigned int Int = SISDInfo.LLVMIntrinsic; 2461 unsigned IntTypes = SISDInfo.TypeModifier; 2462 const char *s = SISDInfo.NameHint; 2463 2464 SmallVector<Value *, 4> Ops; 2465 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) { 2466 Ops.push_back(CGF.EmitScalarExpr(E->getArg(i))); 2467 } 2468 2469 // AArch64 scalar builtins are not overloaded, they do not have an extra 2470 // argument that specifies the vector type, need to handle each case. 2471 switch (BuiltinID) { 2472 default: break; 2473 case NEON::BI__builtin_neon_vdups_lane_f32: 2474 case NEON::BI__builtin_neon_vdupd_lane_f64: 2475 case NEON::BI__builtin_neon_vdups_laneq_f32: 2476 case NEON::BI__builtin_neon_vdupd_laneq_f64: { 2477 return CGF.Builder.CreateExtractElement(Ops[0], Ops[1], "vdup_lane"); 2478 } 2479 case NEON::BI__builtin_neon_vdupb_lane_i8: 2480 case NEON::BI__builtin_neon_vduph_lane_i16: 2481 case NEON::BI__builtin_neon_vdups_lane_i32: 2482 case NEON::BI__builtin_neon_vdupd_lane_i64: 2483 case NEON::BI__builtin_neon_vdupb_laneq_i8: 2484 case NEON::BI__builtin_neon_vduph_laneq_i16: 2485 case NEON::BI__builtin_neon_vdups_laneq_i32: 2486 case NEON::BI__builtin_neon_vdupd_laneq_i64: { 2487 // The backend treats Neon scalar types as v1ix types 2488 // So we want to dup lane from any vector to v1ix vector 2489 // with shufflevector 2490 s = "vdup_lane"; 2491 Value* SV = llvm::ConstantVector::getSplat(1, cast<ConstantInt>(Ops[1])); 2492 Value *Result = CGF.Builder.CreateShuffleVector(Ops[0], Ops[0], SV, s); 2493 llvm::Type *Ty = CGF.ConvertType(E->getCallReturnType()); 2494 // AArch64 intrinsic one-element vector type cast to 2495 // scalar type expected by the builtin 2496 return CGF.Builder.CreateBitCast(Result, Ty, s); 2497 } 2498 case NEON::BI__builtin_neon_vqdmlalh_lane_s16 : 2499 case NEON::BI__builtin_neon_vqdmlalh_laneq_s16 : 2500 case NEON::BI__builtin_neon_vqdmlals_lane_s32 : 2501 case NEON::BI__builtin_neon_vqdmlals_laneq_s32 : 2502 case NEON::BI__builtin_neon_vqdmlslh_lane_s16 : 2503 case NEON::BI__builtin_neon_vqdmlslh_laneq_s16 : 2504 case NEON::BI__builtin_neon_vqdmlsls_lane_s32 : 2505 case NEON::BI__builtin_neon_vqdmlsls_laneq_s32 : { 2506 Int = Intrinsic::arm_neon_vqadds; 2507 if (BuiltinID == NEON::BI__builtin_neon_vqdmlslh_lane_s16 || 2508 BuiltinID == NEON::BI__builtin_neon_vqdmlslh_laneq_s16 || 2509 BuiltinID == NEON::BI__builtin_neon_vqdmlsls_lane_s32 || 2510 BuiltinID == NEON::BI__builtin_neon_vqdmlsls_laneq_s32) { 2511 Int = Intrinsic::arm_neon_vqsubs; 2512 } 2513 // create vqdmull call with b * c[i] 2514 llvm::Type *Ty = CGF.ConvertType(E->getArg(1)->getType()); 2515 llvm::VectorType *OpVTy = llvm::VectorType::get(Ty, 1); 2516 Ty = CGF.ConvertType(E->getArg(0)->getType()); 2517 llvm::VectorType *ResVTy = llvm::VectorType::get(Ty, 1); 2518 Value *F = CGF.CGM.getIntrinsic(Intrinsic::arm_neon_vqdmull, ResVTy); 2519 Value *V = UndefValue::get(OpVTy); 2520 llvm::Constant *CI = ConstantInt::get(CGF.Int32Ty, 0); 2521 SmallVector<Value *, 2> MulOps; 2522 MulOps.push_back(Ops[1]); 2523 MulOps.push_back(Ops[2]); 2524 MulOps[0] = CGF.Builder.CreateInsertElement(V, MulOps[0], CI); 2525 MulOps[1] = CGF.Builder.CreateExtractElement(MulOps[1], Ops[3], "extract"); 2526 MulOps[1] = CGF.Builder.CreateInsertElement(V, MulOps[1], CI); 2527 Value *MulRes = CGF.Builder.CreateCall2(F, MulOps[0], MulOps[1]); 2528 // create vqadds call with a +/- vqdmull result 2529 F = CGF.CGM.getIntrinsic(Int, ResVTy); 2530 SmallVector<Value *, 2> AddOps; 2531 AddOps.push_back(Ops[0]); 2532 AddOps.push_back(MulRes); 2533 V = UndefValue::get(ResVTy); 2534 AddOps[0] = CGF.Builder.CreateInsertElement(V, AddOps[0], CI); 2535 Value *AddRes = CGF.Builder.CreateCall2(F, AddOps[0], AddOps[1]); 2536 return CGF.Builder.CreateBitCast(AddRes, Ty); 2537 } 2538 case NEON::BI__builtin_neon_vfmas_lane_f32: 2539 case NEON::BI__builtin_neon_vfmas_laneq_f32: 2540 case NEON::BI__builtin_neon_vfmad_lane_f64: 2541 case NEON::BI__builtin_neon_vfmad_laneq_f64: { 2542 llvm::Type *Ty = CGF.ConvertType(E->getCallReturnType()); 2543 Value *F = CGF.CGM.getIntrinsic(Intrinsic::fma, Ty); 2544 Ops[2] = CGF.Builder.CreateExtractElement(Ops[2], Ops[3], "extract"); 2545 return CGF.Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]); 2546 } 2547 // Scalar Floating-point Multiply Extended 2548 case NEON::BI__builtin_neon_vmulxs_f32: 2549 case NEON::BI__builtin_neon_vmulxd_f64: { 2550 Int = Intrinsic::aarch64_neon_vmulx; 2551 llvm::Type *Ty = CGF.ConvertType(E->getCallReturnType()); 2552 return CGF.EmitNeonCall(CGF.CGM.getIntrinsic(Int, Ty), Ops, "vmulx"); 2553 } 2554 case NEON::BI__builtin_neon_vmul_n_f64: { 2555 // v1f64 vmul_n_f64 should be mapped to Neon scalar mul lane 2556 llvm::Type *VTy = GetNeonType(&CGF, 2557 NeonTypeFlags(NeonTypeFlags::Float64, false, false)); 2558 Ops[0] = CGF.Builder.CreateBitCast(Ops[0], VTy); 2559 llvm::Value *Idx = llvm::ConstantInt::get(CGF.Int32Ty, 0); 2560 Ops[0] = CGF.Builder.CreateExtractElement(Ops[0], Idx, "extract"); 2561 Value *Result = CGF.Builder.CreateFMul(Ops[0], Ops[1]); 2562 return CGF.Builder.CreateBitCast(Result, VTy); 2563 } 2564 case NEON::BI__builtin_neon_vget_lane_i8: 2565 case NEON::BI__builtin_neon_vget_lane_i16: 2566 case NEON::BI__builtin_neon_vget_lane_i32: 2567 case NEON::BI__builtin_neon_vget_lane_i64: 2568 case NEON::BI__builtin_neon_vget_lane_f32: 2569 case NEON::BI__builtin_neon_vget_lane_f64: 2570 case NEON::BI__builtin_neon_vgetq_lane_i8: 2571 case NEON::BI__builtin_neon_vgetq_lane_i16: 2572 case NEON::BI__builtin_neon_vgetq_lane_i32: 2573 case NEON::BI__builtin_neon_vgetq_lane_i64: 2574 case NEON::BI__builtin_neon_vgetq_lane_f32: 2575 case NEON::BI__builtin_neon_vgetq_lane_f64: 2576 return CGF.EmitARMBuiltinExpr(NEON::BI__builtin_neon_vget_lane_i8, E); 2577 case NEON::BI__builtin_neon_vset_lane_i8: 2578 case NEON::BI__builtin_neon_vset_lane_i16: 2579 case NEON::BI__builtin_neon_vset_lane_i32: 2580 case NEON::BI__builtin_neon_vset_lane_i64: 2581 case NEON::BI__builtin_neon_vset_lane_f32: 2582 case NEON::BI__builtin_neon_vset_lane_f64: 2583 case NEON::BI__builtin_neon_vsetq_lane_i8: 2584 case NEON::BI__builtin_neon_vsetq_lane_i16: 2585 case NEON::BI__builtin_neon_vsetq_lane_i32: 2586 case NEON::BI__builtin_neon_vsetq_lane_i64: 2587 case NEON::BI__builtin_neon_vsetq_lane_f32: 2588 case NEON::BI__builtin_neon_vsetq_lane_f64: 2589 return CGF.EmitARMBuiltinExpr(NEON::BI__builtin_neon_vset_lane_i8, E); 2590 2591 case NEON::BI__builtin_neon_vcled_s64: 2592 case NEON::BI__builtin_neon_vcled_u64: 2593 case NEON::BI__builtin_neon_vcles_f32: 2594 case NEON::BI__builtin_neon_vcled_f64: 2595 case NEON::BI__builtin_neon_vcltd_s64: 2596 case NEON::BI__builtin_neon_vcltd_u64: 2597 case NEON::BI__builtin_neon_vclts_f32: 2598 case NEON::BI__builtin_neon_vcltd_f64: 2599 case NEON::BI__builtin_neon_vcales_f32: 2600 case NEON::BI__builtin_neon_vcaled_f64: 2601 case NEON::BI__builtin_neon_vcalts_f32: 2602 case NEON::BI__builtin_neon_vcaltd_f64: 2603 // Only one direction of comparisons actually exist, cmle is actually a cmge 2604 // with swapped operands. The table gives us the right intrinsic but we 2605 // still need to do the swap. 2606 std::swap(Ops[0], Ops[1]); 2607 break; 2608 case NEON::BI__builtin_neon_vceqzd_s64: 2609 case NEON::BI__builtin_neon_vceqzd_u64: 2610 case NEON::BI__builtin_neon_vcgezd_s64: 2611 case NEON::BI__builtin_neon_vcgtzd_s64: 2612 case NEON::BI__builtin_neon_vclezd_s64: 2613 case NEON::BI__builtin_neon_vcltzd_s64: 2614 // Add implicit zero operand. 2615 Ops.push_back(llvm::Constant::getNullValue(Ops[0]->getType())); 2616 break; 2617 case NEON::BI__builtin_neon_vceqzs_f32: 2618 case NEON::BI__builtin_neon_vceqzd_f64: 2619 case NEON::BI__builtin_neon_vcgezs_f32: 2620 case NEON::BI__builtin_neon_vcgezd_f64: 2621 case NEON::BI__builtin_neon_vcgtzs_f32: 2622 case NEON::BI__builtin_neon_vcgtzd_f64: 2623 case NEON::BI__builtin_neon_vclezs_f32: 2624 case NEON::BI__builtin_neon_vclezd_f64: 2625 case NEON::BI__builtin_neon_vcltzs_f32: 2626 case NEON::BI__builtin_neon_vcltzd_f64: 2627 // Add implicit zero operand. 2628 Ops.push_back(llvm::Constant::getNullValue(CGF.FloatTy)); 2629 break; 2630 } 2631 2632 2633 assert(Int && "Generic code assumes a valid intrinsic"); 2634 2635 // Determine the type(s) of this overloaded AArch64 intrinsic. 2636 const Expr *Arg = E->getArg(0); 2637 llvm::Type *ArgTy = CGF.ConvertType(Arg->getType()); 2638 Function *F = CGF.LookupNeonLLVMIntrinsic(Int, IntTypes, ArgTy, E); 2639 2640 Value *Result = CGF.EmitNeonCall(F, Ops, s); 2641 llvm::Type *ResultType = CGF.ConvertType(E->getType()); 2642 // AArch64 intrinsic one-element vector type cast to 2643 // scalar type expected by the builtin 2644 return CGF.Builder.CreateBitCast(Result, ResultType, s); 2645 } 2646 2647 Value *CodeGenFunction::EmitCommonNeonBuiltinExpr( 2648 unsigned BuiltinID, unsigned LLVMIntrinsic, unsigned AltLLVMIntrinsic, 2649 const char *NameHint, unsigned Modifier, const CallExpr *E, 2650 SmallVectorImpl<llvm::Value *> &Ops, llvm::Value *Align) { 2651 // Get the last argument, which specifies the vector type. 2652 llvm::APSInt NeonTypeConst; 2653 const Expr *Arg = E->getArg(E->getNumArgs() - 1); 2654 if (!Arg->isIntegerConstantExpr(NeonTypeConst, getContext())) 2655 return 0; 2656 2657 // Determine the type of this overloaded NEON intrinsic. 2658 NeonTypeFlags Type(NeonTypeConst.getZExtValue()); 2659 bool Usgn = Type.isUnsigned(); 2660 bool Quad = Type.isQuad(); 2661 2662 llvm::VectorType *VTy = GetNeonType(this, Type); 2663 llvm::Type *Ty = VTy; 2664 if (!Ty) 2665 return 0; 2666 2667 unsigned Int = LLVMIntrinsic; 2668 if ((Modifier & UnsignedAlts) && !Usgn) 2669 Int = AltLLVMIntrinsic; 2670 2671 switch (BuiltinID) { 2672 default: break; 2673 case NEON::BI__builtin_neon_vabs_v: 2674 case NEON::BI__builtin_neon_vabsq_v: 2675 if (VTy->getElementType()->isFloatingPointTy()) 2676 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::fabs, Ty), Ops, "vabs"); 2677 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), Ops, "vabs"); 2678 case NEON::BI__builtin_neon_vaddhn_v: { 2679 llvm::VectorType *SrcTy = 2680 llvm::VectorType::getExtendedElementVectorType(VTy); 2681 2682 // %sum = add <4 x i32> %lhs, %rhs 2683 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 2684 Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy); 2685 Ops[0] = Builder.CreateAdd(Ops[0], Ops[1], "vaddhn"); 2686 2687 // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16> 2688 Constant *ShiftAmt = ConstantInt::get(SrcTy->getElementType(), 2689 SrcTy->getScalarSizeInBits() / 2); 2690 ShiftAmt = ConstantVector::getSplat(VTy->getNumElements(), ShiftAmt); 2691 Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vaddhn"); 2692 2693 // %res = trunc <4 x i32> %high to <4 x i16> 2694 return Builder.CreateTrunc(Ops[0], VTy, "vaddhn"); 2695 } 2696 case NEON::BI__builtin_neon_vcale_v: 2697 case NEON::BI__builtin_neon_vcaleq_v: 2698 case NEON::BI__builtin_neon_vcalt_v: 2699 case NEON::BI__builtin_neon_vcaltq_v: 2700 std::swap(Ops[0], Ops[1]); 2701 case NEON::BI__builtin_neon_vcage_v: 2702 case NEON::BI__builtin_neon_vcageq_v: 2703 case NEON::BI__builtin_neon_vcagt_v: 2704 case NEON::BI__builtin_neon_vcagtq_v: { 2705 llvm::Type *VecFlt = llvm::VectorType::get( 2706 VTy->getScalarSizeInBits() == 32 ? FloatTy : DoubleTy, 2707 VTy->getNumElements()); 2708 llvm::Type *Tys[] = { VTy, VecFlt }; 2709 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 2710 return EmitNeonCall(F, Ops, NameHint); 2711 } 2712 case NEON::BI__builtin_neon_vclz_v: 2713 case NEON::BI__builtin_neon_vclzq_v: 2714 // We generate target-independent intrinsic, which needs a second argument 2715 // for whether or not clz of zero is undefined; on ARM it isn't. 2716 Ops.push_back(Builder.getInt1(getTarget().isCLZForZeroUndef())); 2717 break; 2718 case NEON::BI__builtin_neon_vcvt_f32_v: 2719 case NEON::BI__builtin_neon_vcvtq_f32_v: 2720 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2721 Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, Quad)); 2722 return Usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") 2723 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); 2724 case NEON::BI__builtin_neon_vcvt_n_f32_v: 2725 case NEON::BI__builtin_neon_vcvtq_n_f32_v: { 2726 bool Double = 2727 (cast<llvm::IntegerType>(VTy->getElementType())->getBitWidth() == 64); 2728 llvm::Type *FloatTy = 2729 GetNeonType(this, NeonTypeFlags(Double ? NeonTypeFlags::Float64 2730 : NeonTypeFlags::Float32, 2731 false, Quad)); 2732 llvm::Type *Tys[2] = { FloatTy, Ty }; 2733 Int = Usgn ? LLVMIntrinsic : AltLLVMIntrinsic; 2734 Function *F = CGM.getIntrinsic(Int, Tys); 2735 return EmitNeonCall(F, Ops, "vcvt_n"); 2736 } 2737 case NEON::BI__builtin_neon_vcvt_n_s32_v: 2738 case NEON::BI__builtin_neon_vcvt_n_u32_v: 2739 case NEON::BI__builtin_neon_vcvt_n_s64_v: 2740 case NEON::BI__builtin_neon_vcvt_n_u64_v: 2741 case NEON::BI__builtin_neon_vcvtq_n_s32_v: 2742 case NEON::BI__builtin_neon_vcvtq_n_u32_v: 2743 case NEON::BI__builtin_neon_vcvtq_n_s64_v: 2744 case NEON::BI__builtin_neon_vcvtq_n_u64_v: { 2745 bool Double = 2746 (cast<llvm::IntegerType>(VTy->getElementType())->getBitWidth() == 64); 2747 llvm::Type *FloatTy = 2748 GetNeonType(this, NeonTypeFlags(Double ? NeonTypeFlags::Float64 2749 : NeonTypeFlags::Float32, 2750 false, Quad)); 2751 llvm::Type *Tys[2] = { Ty, FloatTy }; 2752 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 2753 return EmitNeonCall(F, Ops, "vcvt_n"); 2754 } 2755 case NEON::BI__builtin_neon_vcvt_s32_v: 2756 case NEON::BI__builtin_neon_vcvt_u32_v: 2757 case NEON::BI__builtin_neon_vcvt_s64_v: 2758 case NEON::BI__builtin_neon_vcvt_u64_v: 2759 case NEON::BI__builtin_neon_vcvtq_s32_v: 2760 case NEON::BI__builtin_neon_vcvtq_u32_v: 2761 case NEON::BI__builtin_neon_vcvtq_s64_v: 2762 case NEON::BI__builtin_neon_vcvtq_u64_v: { 2763 bool Double = 2764 (cast<llvm::IntegerType>(VTy->getElementType())->getBitWidth() == 64); 2765 llvm::Type *FloatTy = 2766 GetNeonType(this, NeonTypeFlags(Double ? NeonTypeFlags::Float64 2767 : NeonTypeFlags::Float32, 2768 false, Quad)); 2769 Ops[0] = Builder.CreateBitCast(Ops[0], FloatTy); 2770 return Usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt") 2771 : Builder.CreateFPToSI(Ops[0], Ty, "vcvt"); 2772 } 2773 case NEON::BI__builtin_neon_vcvta_s32_v: 2774 case NEON::BI__builtin_neon_vcvta_s64_v: 2775 case NEON::BI__builtin_neon_vcvta_u32_v: 2776 case NEON::BI__builtin_neon_vcvta_u64_v: 2777 case NEON::BI__builtin_neon_vcvtaq_s32_v: 2778 case NEON::BI__builtin_neon_vcvtaq_s64_v: 2779 case NEON::BI__builtin_neon_vcvtaq_u32_v: 2780 case NEON::BI__builtin_neon_vcvtaq_u64_v: 2781 case NEON::BI__builtin_neon_vcvtn_s32_v: 2782 case NEON::BI__builtin_neon_vcvtn_s64_v: 2783 case NEON::BI__builtin_neon_vcvtn_u32_v: 2784 case NEON::BI__builtin_neon_vcvtn_u64_v: 2785 case NEON::BI__builtin_neon_vcvtnq_s32_v: 2786 case NEON::BI__builtin_neon_vcvtnq_s64_v: 2787 case NEON::BI__builtin_neon_vcvtnq_u32_v: 2788 case NEON::BI__builtin_neon_vcvtnq_u64_v: 2789 case NEON::BI__builtin_neon_vcvtp_s32_v: 2790 case NEON::BI__builtin_neon_vcvtp_s64_v: 2791 case NEON::BI__builtin_neon_vcvtp_u32_v: 2792 case NEON::BI__builtin_neon_vcvtp_u64_v: 2793 case NEON::BI__builtin_neon_vcvtpq_s32_v: 2794 case NEON::BI__builtin_neon_vcvtpq_s64_v: 2795 case NEON::BI__builtin_neon_vcvtpq_u32_v: 2796 case NEON::BI__builtin_neon_vcvtpq_u64_v: 2797 case NEON::BI__builtin_neon_vcvtm_s32_v: 2798 case NEON::BI__builtin_neon_vcvtm_s64_v: 2799 case NEON::BI__builtin_neon_vcvtm_u32_v: 2800 case NEON::BI__builtin_neon_vcvtm_u64_v: 2801 case NEON::BI__builtin_neon_vcvtmq_s32_v: 2802 case NEON::BI__builtin_neon_vcvtmq_s64_v: 2803 case NEON::BI__builtin_neon_vcvtmq_u32_v: 2804 case NEON::BI__builtin_neon_vcvtmq_u64_v: { 2805 bool Double = 2806 (cast<llvm::IntegerType>(VTy->getElementType())->getBitWidth() == 64); 2807 llvm::Type *InTy = 2808 GetNeonType(this, 2809 NeonTypeFlags(Double ? NeonTypeFlags::Float64 2810 : NeonTypeFlags::Float32, false, Quad)); 2811 llvm::Type *Tys[2] = { Ty, InTy }; 2812 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, NameHint); 2813 } 2814 case NEON::BI__builtin_neon_vext_v: 2815 case NEON::BI__builtin_neon_vextq_v: { 2816 int CV = cast<ConstantInt>(Ops[2])->getSExtValue(); 2817 SmallVector<Constant*, 16> Indices; 2818 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 2819 Indices.push_back(ConstantInt::get(Int32Ty, i+CV)); 2820 2821 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2822 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 2823 Value *SV = llvm::ConstantVector::get(Indices); 2824 return Builder.CreateShuffleVector(Ops[0], Ops[1], SV, "vext"); 2825 } 2826 case NEON::BI__builtin_neon_vfma_v: 2827 case NEON::BI__builtin_neon_vfmaq_v: { 2828 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 2829 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2830 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 2831 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 2832 2833 // NEON intrinsic puts accumulator first, unlike the LLVM fma. 2834 return Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]); 2835 } 2836 case NEON::BI__builtin_neon_vld1_v: 2837 case NEON::BI__builtin_neon_vld1q_v: 2838 Ops.push_back(Align); 2839 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), Ops, "vld1"); 2840 case NEON::BI__builtin_neon_vld2_v: 2841 case NEON::BI__builtin_neon_vld2q_v: 2842 case NEON::BI__builtin_neon_vld3_v: 2843 case NEON::BI__builtin_neon_vld3q_v: 2844 case NEON::BI__builtin_neon_vld4_v: 2845 case NEON::BI__builtin_neon_vld4q_v: { 2846 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Ty); 2847 Ops[1] = Builder.CreateCall2(F, Ops[1], Align, NameHint); 2848 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 2849 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2850 return Builder.CreateStore(Ops[1], Ops[0]); 2851 } 2852 case NEON::BI__builtin_neon_vld1_dup_v: 2853 case NEON::BI__builtin_neon_vld1q_dup_v: { 2854 Value *V = UndefValue::get(Ty); 2855 Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 2856 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2857 LoadInst *Ld = Builder.CreateLoad(Ops[0]); 2858 Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); 2859 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 2860 Ops[0] = Builder.CreateInsertElement(V, Ld, CI); 2861 return EmitNeonSplat(Ops[0], CI); 2862 } 2863 case NEON::BI__builtin_neon_vld2_lane_v: 2864 case NEON::BI__builtin_neon_vld2q_lane_v: 2865 case NEON::BI__builtin_neon_vld3_lane_v: 2866 case NEON::BI__builtin_neon_vld3q_lane_v: 2867 case NEON::BI__builtin_neon_vld4_lane_v: 2868 case NEON::BI__builtin_neon_vld4q_lane_v: { 2869 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Ty); 2870 for (unsigned I = 2; I < Ops.size() - 1; ++I) 2871 Ops[I] = Builder.CreateBitCast(Ops[I], Ty); 2872 Ops.push_back(Align); 2873 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), NameHint); 2874 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 2875 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2876 return Builder.CreateStore(Ops[1], Ops[0]); 2877 } 2878 case NEON::BI__builtin_neon_vmovl_v: { 2879 llvm::Type *DTy =llvm::VectorType::getTruncatedElementVectorType(VTy); 2880 Ops[0] = Builder.CreateBitCast(Ops[0], DTy); 2881 if (Usgn) 2882 return Builder.CreateZExt(Ops[0], Ty, "vmovl"); 2883 return Builder.CreateSExt(Ops[0], Ty, "vmovl"); 2884 } 2885 case NEON::BI__builtin_neon_vmovn_v: { 2886 llvm::Type *QTy = llvm::VectorType::getExtendedElementVectorType(VTy); 2887 Ops[0] = Builder.CreateBitCast(Ops[0], QTy); 2888 return Builder.CreateTrunc(Ops[0], Ty, "vmovn"); 2889 } 2890 case NEON::BI__builtin_neon_vmull_v: 2891 // FIXME: the integer vmull operations could be emitted in terms of pure 2892 // LLVM IR (2 exts followed by a mul). Unfortunately LLVM has a habit of 2893 // hoisting the exts outside loops. Until global ISel comes along that can 2894 // see through such movement this leads to bad CodeGen. So we need an 2895 // intrinsic for now. 2896 Int = Usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls; 2897 Int = Type.isPoly() ? (unsigned)Intrinsic::arm_neon_vmullp : Int; 2898 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull"); 2899 case NEON::BI__builtin_neon_vpadal_v: 2900 case NEON::BI__builtin_neon_vpadalq_v: { 2901 // The source operand type has twice as many elements of half the size. 2902 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 2903 llvm::Type *EltTy = 2904 llvm::IntegerType::get(getLLVMContext(), EltBits / 2); 2905 llvm::Type *NarrowTy = 2906 llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); 2907 llvm::Type *Tys[2] = { Ty, NarrowTy }; 2908 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, NameHint); 2909 } 2910 case NEON::BI__builtin_neon_vpaddl_v: 2911 case NEON::BI__builtin_neon_vpaddlq_v: { 2912 // The source operand type has twice as many elements of half the size. 2913 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 2914 llvm::Type *EltTy = llvm::IntegerType::get(getLLVMContext(), EltBits / 2); 2915 llvm::Type *NarrowTy = 2916 llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); 2917 llvm::Type *Tys[2] = { Ty, NarrowTy }; 2918 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vpaddl"); 2919 } 2920 case NEON::BI__builtin_neon_vqdmlal_v: 2921 case NEON::BI__builtin_neon_vqdmlsl_v: { 2922 SmallVector<Value *, 2> MulOps(Ops.begin() + 1, Ops.end()); 2923 Value *Mul = EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), 2924 MulOps, "vqdmlal"); 2925 2926 SmallVector<Value *, 2> AccumOps; 2927 AccumOps.push_back(Ops[0]); 2928 AccumOps.push_back(Mul); 2929 return EmitNeonCall(CGM.getIntrinsic(AltLLVMIntrinsic, Ty), 2930 AccumOps, NameHint); 2931 } 2932 case NEON::BI__builtin_neon_vqshl_n_v: 2933 case NEON::BI__builtin_neon_vqshlq_n_v: 2934 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshl_n", 2935 1, false); 2936 case NEON::BI__builtin_neon_vrecpe_v: 2937 case NEON::BI__builtin_neon_vrecpeq_v: 2938 case NEON::BI__builtin_neon_vrsqrte_v: 2939 case NEON::BI__builtin_neon_vrsqrteq_v: 2940 Int = Ty->isFPOrFPVectorTy() ? LLVMIntrinsic : AltLLVMIntrinsic; 2941 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, NameHint); 2942 2943 case NEON::BI__builtin_neon_vshl_n_v: 2944 case NEON::BI__builtin_neon_vshlq_n_v: 2945 Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false); 2946 return Builder.CreateShl(Builder.CreateBitCast(Ops[0],Ty), Ops[1], 2947 "vshl_n"); 2948 case NEON::BI__builtin_neon_vshll_n_v: { 2949 llvm::Type *SrcTy = llvm::VectorType::getTruncatedElementVectorType(VTy); 2950 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 2951 if (Usgn) 2952 Ops[0] = Builder.CreateZExt(Ops[0], VTy); 2953 else 2954 Ops[0] = Builder.CreateSExt(Ops[0], VTy); 2955 Ops[1] = EmitNeonShiftVector(Ops[1], VTy, false); 2956 return Builder.CreateShl(Ops[0], Ops[1], "vshll_n"); 2957 } 2958 case NEON::BI__builtin_neon_vshrn_n_v: { 2959 llvm::Type *SrcTy = llvm::VectorType::getExtendedElementVectorType(VTy); 2960 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 2961 Ops[1] = EmitNeonShiftVector(Ops[1], SrcTy, false); 2962 if (Usgn) 2963 Ops[0] = Builder.CreateLShr(Ops[0], Ops[1]); 2964 else 2965 Ops[0] = Builder.CreateAShr(Ops[0], Ops[1]); 2966 return Builder.CreateTrunc(Ops[0], Ty, "vshrn_n"); 2967 } 2968 case NEON::BI__builtin_neon_vshr_n_v: 2969 case NEON::BI__builtin_neon_vshrq_n_v: 2970 return EmitNeonRShiftImm(Ops[0], Ops[1], Ty, Usgn, "vshr_n"); 2971 case NEON::BI__builtin_neon_vst1_v: 2972 case NEON::BI__builtin_neon_vst1q_v: 2973 case NEON::BI__builtin_neon_vst2_v: 2974 case NEON::BI__builtin_neon_vst2q_v: 2975 case NEON::BI__builtin_neon_vst3_v: 2976 case NEON::BI__builtin_neon_vst3q_v: 2977 case NEON::BI__builtin_neon_vst4_v: 2978 case NEON::BI__builtin_neon_vst4q_v: 2979 case NEON::BI__builtin_neon_vst2_lane_v: 2980 case NEON::BI__builtin_neon_vst2q_lane_v: 2981 case NEON::BI__builtin_neon_vst3_lane_v: 2982 case NEON::BI__builtin_neon_vst3q_lane_v: 2983 case NEON::BI__builtin_neon_vst4_lane_v: 2984 case NEON::BI__builtin_neon_vst4q_lane_v: 2985 Ops.push_back(Align); 2986 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, ""); 2987 case NEON::BI__builtin_neon_vsubhn_v: { 2988 llvm::VectorType *SrcTy = 2989 llvm::VectorType::getExtendedElementVectorType(VTy); 2990 2991 // %sum = add <4 x i32> %lhs, %rhs 2992 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 2993 Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy); 2994 Ops[0] = Builder.CreateSub(Ops[0], Ops[1], "vsubhn"); 2995 2996 // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16> 2997 Constant *ShiftAmt = ConstantInt::get(SrcTy->getElementType(), 2998 SrcTy->getScalarSizeInBits() / 2); 2999 ShiftAmt = ConstantVector::getSplat(VTy->getNumElements(), ShiftAmt); 3000 Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vsubhn"); 3001 3002 // %res = trunc <4 x i32> %high to <4 x i16> 3003 return Builder.CreateTrunc(Ops[0], VTy, "vsubhn"); 3004 } 3005 case NEON::BI__builtin_neon_vtrn_v: 3006 case NEON::BI__builtin_neon_vtrnq_v: { 3007 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 3008 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3009 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 3010 Value *SV = 0; 3011 3012 for (unsigned vi = 0; vi != 2; ++vi) { 3013 SmallVector<Constant*, 16> Indices; 3014 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 3015 Indices.push_back(Builder.getInt32(i+vi)); 3016 Indices.push_back(Builder.getInt32(i+e+vi)); 3017 } 3018 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi); 3019 SV = llvm::ConstantVector::get(Indices); 3020 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vtrn"); 3021 SV = Builder.CreateStore(SV, Addr); 3022 } 3023 return SV; 3024 } 3025 case NEON::BI__builtin_neon_vtst_v: 3026 case NEON::BI__builtin_neon_vtstq_v: { 3027 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3028 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3029 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]); 3030 Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0], 3031 ConstantAggregateZero::get(Ty)); 3032 return Builder.CreateSExt(Ops[0], Ty, "vtst"); 3033 } 3034 case NEON::BI__builtin_neon_vuzp_v: 3035 case NEON::BI__builtin_neon_vuzpq_v: { 3036 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 3037 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3038 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 3039 Value *SV = 0; 3040 3041 for (unsigned vi = 0; vi != 2; ++vi) { 3042 SmallVector<Constant*, 16> Indices; 3043 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 3044 Indices.push_back(ConstantInt::get(Int32Ty, 2*i+vi)); 3045 3046 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi); 3047 SV = llvm::ConstantVector::get(Indices); 3048 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vuzp"); 3049 SV = Builder.CreateStore(SV, Addr); 3050 } 3051 return SV; 3052 } 3053 case NEON::BI__builtin_neon_vzip_v: 3054 case NEON::BI__builtin_neon_vzipq_v: { 3055 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 3056 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3057 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 3058 Value *SV = 0; 3059 3060 for (unsigned vi = 0; vi != 2; ++vi) { 3061 SmallVector<Constant*, 16> Indices; 3062 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 3063 Indices.push_back(ConstantInt::get(Int32Ty, (i + vi*e) >> 1)); 3064 Indices.push_back(ConstantInt::get(Int32Ty, ((i + vi*e) >> 1)+e)); 3065 } 3066 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi); 3067 SV = llvm::ConstantVector::get(Indices); 3068 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vzip"); 3069 SV = Builder.CreateStore(SV, Addr); 3070 } 3071 return SV; 3072 } 3073 } 3074 3075 assert(Int && "Expected valid intrinsic number"); 3076 3077 // Determine the type(s) of this overloaded AArch64 intrinsic. 3078 Function *F = LookupNeonLLVMIntrinsic(Int, Modifier, Ty, E); 3079 3080 Value *Result = EmitNeonCall(F, Ops, NameHint); 3081 llvm::Type *ResultType = ConvertType(E->getType()); 3082 // AArch64 intrinsic one-element vector type cast to 3083 // scalar type expected by the builtin 3084 return Builder.CreateBitCast(Result, ResultType, NameHint); 3085 } 3086 3087 Value *CodeGenFunction::EmitAArch64CompareBuiltinExpr( 3088 Value *Op, llvm::Type *Ty, const CmpInst::Predicate Fp, 3089 const CmpInst::Predicate Ip, const Twine &Name) { 3090 llvm::Type *OTy = ((llvm::User *)Op)->getOperand(0)->getType(); 3091 if (OTy->isPointerTy()) 3092 OTy = Ty; 3093 Op = Builder.CreateBitCast(Op, OTy); 3094 if (((llvm::VectorType *)OTy)->getElementType()->isFloatingPointTy()) { 3095 Op = Builder.CreateFCmp(Fp, Op, ConstantAggregateZero::get(OTy)); 3096 } else { 3097 Op = Builder.CreateICmp(Ip, Op, ConstantAggregateZero::get(OTy)); 3098 } 3099 return Builder.CreateSExt(Op, Ty, Name); 3100 } 3101 3102 static Value *packTBLDVectorList(CodeGenFunction &CGF, ArrayRef<Value *> Ops, 3103 Value *ExtOp, Value *IndexOp, 3104 llvm::Type *ResTy, unsigned IntID, 3105 const char *Name) { 3106 SmallVector<Value *, 2> TblOps; 3107 if (ExtOp) 3108 TblOps.push_back(ExtOp); 3109 3110 // Build a vector containing sequential number like (0, 1, 2, ..., 15) 3111 SmallVector<Constant*, 16> Indices; 3112 llvm::VectorType *TblTy = cast<llvm::VectorType>(Ops[0]->getType()); 3113 for (unsigned i = 0, e = TblTy->getNumElements(); i != e; ++i) { 3114 Indices.push_back(ConstantInt::get(CGF.Int32Ty, 2*i)); 3115 Indices.push_back(ConstantInt::get(CGF.Int32Ty, 2*i+1)); 3116 } 3117 Value *SV = llvm::ConstantVector::get(Indices); 3118 3119 int PairPos = 0, End = Ops.size() - 1; 3120 while (PairPos < End) { 3121 TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos], 3122 Ops[PairPos+1], SV, Name)); 3123 PairPos += 2; 3124 } 3125 3126 // If there's an odd number of 64-bit lookup table, fill the high 64-bit 3127 // of the 128-bit lookup table with zero. 3128 if (PairPos == End) { 3129 Value *ZeroTbl = ConstantAggregateZero::get(TblTy); 3130 TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos], 3131 ZeroTbl, SV, Name)); 3132 } 3133 3134 Function *TblF; 3135 TblOps.push_back(IndexOp); 3136 TblF = CGF.CGM.getIntrinsic(IntID, ResTy); 3137 3138 return CGF.EmitNeonCall(TblF, TblOps, Name); 3139 } 3140 3141 static Value *EmitAArch64TblBuiltinExpr(CodeGenFunction &CGF, 3142 unsigned BuiltinID, 3143 const CallExpr *E) { 3144 unsigned int Int = 0; 3145 const char *s = NULL; 3146 3147 switch (BuiltinID) { 3148 default: 3149 return 0; 3150 case NEON::BI__builtin_neon_vtbl1_v: 3151 case NEON::BI__builtin_neon_vqtbl1_v: 3152 case NEON::BI__builtin_neon_vqtbl1q_v: 3153 case NEON::BI__builtin_neon_vtbl2_v: 3154 case NEON::BI__builtin_neon_vqtbl2_v: 3155 case NEON::BI__builtin_neon_vqtbl2q_v: 3156 case NEON::BI__builtin_neon_vtbl3_v: 3157 case NEON::BI__builtin_neon_vqtbl3_v: 3158 case NEON::BI__builtin_neon_vqtbl3q_v: 3159 case NEON::BI__builtin_neon_vtbl4_v: 3160 case NEON::BI__builtin_neon_vqtbl4_v: 3161 case NEON::BI__builtin_neon_vqtbl4q_v: 3162 case NEON::BI__builtin_neon_vtbx1_v: 3163 case NEON::BI__builtin_neon_vqtbx1_v: 3164 case NEON::BI__builtin_neon_vqtbx1q_v: 3165 case NEON::BI__builtin_neon_vtbx2_v: 3166 case NEON::BI__builtin_neon_vqtbx2_v: 3167 case NEON::BI__builtin_neon_vqtbx2q_v: 3168 case NEON::BI__builtin_neon_vtbx3_v: 3169 case NEON::BI__builtin_neon_vqtbx3_v: 3170 case NEON::BI__builtin_neon_vqtbx3q_v: 3171 case NEON::BI__builtin_neon_vtbx4_v: 3172 case NEON::BI__builtin_neon_vqtbx4_v: 3173 case NEON::BI__builtin_neon_vqtbx4q_v: 3174 break; 3175 } 3176 3177 assert(E->getNumArgs() >= 3); 3178 3179 // Get the last argument, which specifies the vector type. 3180 llvm::APSInt Result; 3181 const Expr *Arg = E->getArg(E->getNumArgs() - 1); 3182 if (!Arg->isIntegerConstantExpr(Result, CGF.getContext())) 3183 return 0; 3184 3185 // Determine the type of this overloaded NEON intrinsic. 3186 NeonTypeFlags Type(Result.getZExtValue()); 3187 llvm::VectorType *VTy = GetNeonType(&CGF, Type); 3188 llvm::Type *Ty = VTy; 3189 if (!Ty) 3190 return 0; 3191 3192 SmallVector<Value *, 4> Ops; 3193 for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) { 3194 Ops.push_back(CGF.EmitScalarExpr(E->getArg(i))); 3195 } 3196 3197 unsigned nElts = VTy->getNumElements(); 3198 3199 // AArch64 scalar builtins are not overloaded, they do not have an extra 3200 // argument that specifies the vector type, need to handle each case. 3201 SmallVector<Value *, 2> TblOps; 3202 switch (BuiltinID) { 3203 case NEON::BI__builtin_neon_vtbl1_v: { 3204 TblOps.push_back(Ops[0]); 3205 return packTBLDVectorList(CGF, TblOps, 0, Ops[1], Ty, 3206 Intrinsic::aarch64_neon_vtbl1, "vtbl1"); 3207 } 3208 case NEON::BI__builtin_neon_vtbl2_v: { 3209 TblOps.push_back(Ops[0]); 3210 TblOps.push_back(Ops[1]); 3211 return packTBLDVectorList(CGF, TblOps, 0, Ops[2], Ty, 3212 Intrinsic::aarch64_neon_vtbl1, "vtbl1"); 3213 } 3214 case NEON::BI__builtin_neon_vtbl3_v: { 3215 TblOps.push_back(Ops[0]); 3216 TblOps.push_back(Ops[1]); 3217 TblOps.push_back(Ops[2]); 3218 return packTBLDVectorList(CGF, TblOps, 0, Ops[3], Ty, 3219 Intrinsic::aarch64_neon_vtbl2, "vtbl2"); 3220 } 3221 case NEON::BI__builtin_neon_vtbl4_v: { 3222 TblOps.push_back(Ops[0]); 3223 TblOps.push_back(Ops[1]); 3224 TblOps.push_back(Ops[2]); 3225 TblOps.push_back(Ops[3]); 3226 return packTBLDVectorList(CGF, TblOps, 0, Ops[4], Ty, 3227 Intrinsic::aarch64_neon_vtbl2, "vtbl2"); 3228 } 3229 case NEON::BI__builtin_neon_vtbx1_v: { 3230 TblOps.push_back(Ops[1]); 3231 Value *TblRes = packTBLDVectorList(CGF, TblOps, 0, Ops[2], Ty, 3232 Intrinsic::aarch64_neon_vtbl1, "vtbl1"); 3233 3234 llvm::Constant *Eight = ConstantInt::get(VTy->getElementType(), 8); 3235 Value* EightV = llvm::ConstantVector::getSplat(nElts, Eight); 3236 Value *CmpRes = CGF.Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[2], EightV); 3237 CmpRes = CGF.Builder.CreateSExt(CmpRes, Ty); 3238 3239 SmallVector<Value *, 4> BslOps; 3240 BslOps.push_back(CmpRes); 3241 BslOps.push_back(Ops[0]); 3242 BslOps.push_back(TblRes); 3243 Function *BslF = CGF.CGM.getIntrinsic(Intrinsic::arm_neon_vbsl, Ty); 3244 return CGF.EmitNeonCall(BslF, BslOps, "vbsl"); 3245 } 3246 case NEON::BI__builtin_neon_vtbx2_v: { 3247 TblOps.push_back(Ops[1]); 3248 TblOps.push_back(Ops[2]); 3249 return packTBLDVectorList(CGF, TblOps, Ops[0], Ops[3], Ty, 3250 Intrinsic::aarch64_neon_vtbx1, "vtbx1"); 3251 } 3252 case NEON::BI__builtin_neon_vtbx3_v: { 3253 TblOps.push_back(Ops[1]); 3254 TblOps.push_back(Ops[2]); 3255 TblOps.push_back(Ops[3]); 3256 Value *TblRes = packTBLDVectorList(CGF, TblOps, 0, Ops[4], Ty, 3257 Intrinsic::aarch64_neon_vtbl2, "vtbl2"); 3258 3259 llvm::Constant *TwentyFour = ConstantInt::get(VTy->getElementType(), 24); 3260 Value* TwentyFourV = llvm::ConstantVector::getSplat(nElts, TwentyFour); 3261 Value *CmpRes = CGF.Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[4], 3262 TwentyFourV); 3263 CmpRes = CGF.Builder.CreateSExt(CmpRes, Ty); 3264 3265 SmallVector<Value *, 4> BslOps; 3266 BslOps.push_back(CmpRes); 3267 BslOps.push_back(Ops[0]); 3268 BslOps.push_back(TblRes); 3269 Function *BslF = CGF.CGM.getIntrinsic(Intrinsic::arm_neon_vbsl, Ty); 3270 return CGF.EmitNeonCall(BslF, BslOps, "vbsl"); 3271 } 3272 case NEON::BI__builtin_neon_vtbx4_v: { 3273 TblOps.push_back(Ops[1]); 3274 TblOps.push_back(Ops[2]); 3275 TblOps.push_back(Ops[3]); 3276 TblOps.push_back(Ops[4]); 3277 return packTBLDVectorList(CGF, TblOps, Ops[0], Ops[5], Ty, 3278 Intrinsic::aarch64_neon_vtbx2, "vtbx2"); 3279 } 3280 case NEON::BI__builtin_neon_vqtbl1_v: 3281 case NEON::BI__builtin_neon_vqtbl1q_v: 3282 Int = Intrinsic::aarch64_neon_vtbl1; s = "vtbl1"; break; 3283 case NEON::BI__builtin_neon_vqtbl2_v: 3284 case NEON::BI__builtin_neon_vqtbl2q_v: { 3285 Int = Intrinsic::aarch64_neon_vtbl2; s = "vtbl2"; break; 3286 case NEON::BI__builtin_neon_vqtbl3_v: 3287 case NEON::BI__builtin_neon_vqtbl3q_v: 3288 Int = Intrinsic::aarch64_neon_vtbl3; s = "vtbl3"; break; 3289 case NEON::BI__builtin_neon_vqtbl4_v: 3290 case NEON::BI__builtin_neon_vqtbl4q_v: 3291 Int = Intrinsic::aarch64_neon_vtbl4; s = "vtbl4"; break; 3292 case NEON::BI__builtin_neon_vqtbx1_v: 3293 case NEON::BI__builtin_neon_vqtbx1q_v: 3294 Int = Intrinsic::aarch64_neon_vtbx1; s = "vtbx1"; break; 3295 case NEON::BI__builtin_neon_vqtbx2_v: 3296 case NEON::BI__builtin_neon_vqtbx2q_v: 3297 Int = Intrinsic::aarch64_neon_vtbx2; s = "vtbx2"; break; 3298 case NEON::BI__builtin_neon_vqtbx3_v: 3299 case NEON::BI__builtin_neon_vqtbx3q_v: 3300 Int = Intrinsic::aarch64_neon_vtbx3; s = "vtbx3"; break; 3301 case NEON::BI__builtin_neon_vqtbx4_v: 3302 case NEON::BI__builtin_neon_vqtbx4q_v: 3303 Int = Intrinsic::aarch64_neon_vtbx4; s = "vtbx4"; break; 3304 } 3305 } 3306 3307 if (!Int) 3308 return 0; 3309 3310 Function *F = CGF.CGM.getIntrinsic(Int, Ty); 3311 return CGF.EmitNeonCall(F, Ops, s); 3312 } 3313 3314 Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, 3315 const CallExpr *E) { 3316 3317 // Process AArch64 scalar builtins 3318 llvm::ArrayRef<NeonIntrinsicInfo> SISDInfo(AArch64SISDIntrinsicInfo); 3319 const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap( 3320 SISDInfo, BuiltinID, AArch64SISDIntrinsicInfoProvenSorted); 3321 3322 if (Builtin) { 3323 Value *Result = EmitAArch64ScalarBuiltinExpr(*this, *Builtin, E); 3324 assert(Result && "SISD intrinsic should have been handled"); 3325 return Result; 3326 } 3327 3328 // Process AArch64 table lookup builtins 3329 if (Value *Result = EmitAArch64TblBuiltinExpr(*this, BuiltinID, E)) 3330 return Result; 3331 3332 if (BuiltinID == AArch64::BI__clear_cache) { 3333 assert(E->getNumArgs() == 2 && 3334 "Variadic __clear_cache slipped through on AArch64"); 3335 3336 const FunctionDecl *FD = E->getDirectCallee(); 3337 SmallVector<Value *, 2> Ops; 3338 for (unsigned i = 0; i < E->getNumArgs(); i++) 3339 Ops.push_back(EmitScalarExpr(E->getArg(i))); 3340 llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); 3341 llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); 3342 StringRef Name = FD->getName(); 3343 return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); 3344 } 3345 3346 SmallVector<Value *, 4> Ops; 3347 llvm::Value *Align = 0; // Alignment for load/store 3348 3349 if (BuiltinID == NEON::BI__builtin_neon_vldrq_p128) { 3350 Value *Op = EmitScalarExpr(E->getArg(0)); 3351 unsigned addressSpace = 3352 cast<llvm::PointerType>(Op->getType())->getAddressSpace(); 3353 llvm::Type *Ty = llvm::Type::getFP128PtrTy(getLLVMContext(), addressSpace); 3354 Op = Builder.CreateBitCast(Op, Ty); 3355 Op = Builder.CreateLoad(Op); 3356 Ty = llvm::Type::getIntNTy(getLLVMContext(), 128); 3357 return Builder.CreateBitCast(Op, Ty); 3358 } 3359 if (BuiltinID == NEON::BI__builtin_neon_vstrq_p128) { 3360 Value *Op0 = EmitScalarExpr(E->getArg(0)); 3361 unsigned addressSpace = 3362 cast<llvm::PointerType>(Op0->getType())->getAddressSpace(); 3363 llvm::Type *PTy = llvm::Type::getFP128PtrTy(getLLVMContext(), addressSpace); 3364 Op0 = Builder.CreateBitCast(Op0, PTy); 3365 Value *Op1 = EmitScalarExpr(E->getArg(1)); 3366 llvm::Type *Ty = llvm::Type::getFP128Ty(getLLVMContext()); 3367 Op1 = Builder.CreateBitCast(Op1, Ty); 3368 return Builder.CreateStore(Op1, Op0); 3369 } 3370 for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) { 3371 if (i == 0) { 3372 switch (BuiltinID) { 3373 case NEON::BI__builtin_neon_vld1_v: 3374 case NEON::BI__builtin_neon_vld1q_v: 3375 case NEON::BI__builtin_neon_vst1_v: 3376 case NEON::BI__builtin_neon_vst1q_v: 3377 case NEON::BI__builtin_neon_vst2_v: 3378 case NEON::BI__builtin_neon_vst2q_v: 3379 case NEON::BI__builtin_neon_vst3_v: 3380 case NEON::BI__builtin_neon_vst3q_v: 3381 case NEON::BI__builtin_neon_vst4_v: 3382 case NEON::BI__builtin_neon_vst4q_v: 3383 case NEON::BI__builtin_neon_vst1_x2_v: 3384 case NEON::BI__builtin_neon_vst1q_x2_v: 3385 case NEON::BI__builtin_neon_vst1_x3_v: 3386 case NEON::BI__builtin_neon_vst1q_x3_v: 3387 case NEON::BI__builtin_neon_vst1_x4_v: 3388 case NEON::BI__builtin_neon_vst1q_x4_v: 3389 // Handle ld1/st1 lane in this function a little different from ARM. 3390 case NEON::BI__builtin_neon_vld1_lane_v: 3391 case NEON::BI__builtin_neon_vld1q_lane_v: 3392 case NEON::BI__builtin_neon_vst1_lane_v: 3393 case NEON::BI__builtin_neon_vst1q_lane_v: 3394 case NEON::BI__builtin_neon_vst2_lane_v: 3395 case NEON::BI__builtin_neon_vst2q_lane_v: 3396 case NEON::BI__builtin_neon_vst3_lane_v: 3397 case NEON::BI__builtin_neon_vst3q_lane_v: 3398 case NEON::BI__builtin_neon_vst4_lane_v: 3399 case NEON::BI__builtin_neon_vst4q_lane_v: 3400 case NEON::BI__builtin_neon_vld1_dup_v: 3401 case NEON::BI__builtin_neon_vld1q_dup_v: 3402 // Get the alignment for the argument in addition to the value; 3403 // we'll use it later. 3404 std::pair<llvm::Value *, unsigned> Src = 3405 EmitPointerWithAlignment(E->getArg(0)); 3406 Ops.push_back(Src.first); 3407 Align = Builder.getInt32(Src.second); 3408 continue; 3409 } 3410 } 3411 if (i == 1) { 3412 switch (BuiltinID) { 3413 case NEON::BI__builtin_neon_vld2_v: 3414 case NEON::BI__builtin_neon_vld2q_v: 3415 case NEON::BI__builtin_neon_vld3_v: 3416 case NEON::BI__builtin_neon_vld3q_v: 3417 case NEON::BI__builtin_neon_vld4_v: 3418 case NEON::BI__builtin_neon_vld4q_v: 3419 case NEON::BI__builtin_neon_vld1_x2_v: 3420 case NEON::BI__builtin_neon_vld1q_x2_v: 3421 case NEON::BI__builtin_neon_vld1_x3_v: 3422 case NEON::BI__builtin_neon_vld1q_x3_v: 3423 case NEON::BI__builtin_neon_vld1_x4_v: 3424 case NEON::BI__builtin_neon_vld1q_x4_v: 3425 // Handle ld1/st1 dup lane in this function a little different from ARM. 3426 case NEON::BI__builtin_neon_vld2_dup_v: 3427 case NEON::BI__builtin_neon_vld2q_dup_v: 3428 case NEON::BI__builtin_neon_vld3_dup_v: 3429 case NEON::BI__builtin_neon_vld3q_dup_v: 3430 case NEON::BI__builtin_neon_vld4_dup_v: 3431 case NEON::BI__builtin_neon_vld4q_dup_v: 3432 case NEON::BI__builtin_neon_vld2_lane_v: 3433 case NEON::BI__builtin_neon_vld2q_lane_v: 3434 case NEON::BI__builtin_neon_vld3_lane_v: 3435 case NEON::BI__builtin_neon_vld3q_lane_v: 3436 case NEON::BI__builtin_neon_vld4_lane_v: 3437 case NEON::BI__builtin_neon_vld4q_lane_v: 3438 // Get the alignment for the argument in addition to the value; 3439 // we'll use it later. 3440 std::pair<llvm::Value *, unsigned> Src = 3441 EmitPointerWithAlignment(E->getArg(1)); 3442 Ops.push_back(Src.first); 3443 Align = Builder.getInt32(Src.second); 3444 continue; 3445 } 3446 } 3447 Ops.push_back(EmitScalarExpr(E->getArg(i))); 3448 } 3449 3450 // Get the last argument, which specifies the vector type. 3451 llvm::APSInt Result; 3452 const Expr *Arg = E->getArg(E->getNumArgs() - 1); 3453 if (!Arg->isIntegerConstantExpr(Result, getContext())) 3454 return 0; 3455 3456 // Determine the type of this overloaded NEON intrinsic. 3457 NeonTypeFlags Type(Result.getZExtValue()); 3458 bool usgn = Type.isUnsigned(); 3459 bool quad = Type.isQuad(); 3460 3461 llvm::VectorType *VTy = GetNeonType(this, Type); 3462 llvm::Type *Ty = VTy; 3463 if (!Ty) 3464 return 0; 3465 3466 3467 // Many NEON builtins have identical semantics and uses in ARM and 3468 // AArch64. Emit these in a single function. 3469 llvm::ArrayRef<NeonIntrinsicInfo> IntrinsicMap(ARMSIMDIntrinsicMap); 3470 Builtin = findNeonIntrinsicInMap(IntrinsicMap, BuiltinID, 3471 NEONSIMDIntrinsicsProvenSorted); 3472 if (Builtin) 3473 return EmitCommonNeonBuiltinExpr( 3474 Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic, 3475 Builtin->NameHint, Builtin->TypeModifier, E, Ops, Align); 3476 3477 unsigned Int; 3478 switch (BuiltinID) { 3479 default: 3480 return 0; 3481 3482 // AArch64 builtins mapping to legacy ARM v7 builtins. 3483 // FIXME: the mapped builtins listed correspond to what has been tested 3484 // in aarch64-neon-intrinsics.c so far. 3485 3486 // Shift by immediate 3487 case NEON::BI__builtin_neon_vrshr_n_v: 3488 case NEON::BI__builtin_neon_vrshrq_n_v: 3489 Int = usgn ? Intrinsic::aarch64_neon_vurshr 3490 : Intrinsic::aarch64_neon_vsrshr; 3491 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshr_n"); 3492 case NEON::BI__builtin_neon_vsra_n_v: 3493 if (VTy->getElementType()->isIntegerTy(64)) { 3494 Int = usgn ? Intrinsic::aarch64_neon_vsradu_n 3495 : Intrinsic::aarch64_neon_vsrads_n; 3496 return EmitNeonCall(CGM.getIntrinsic(Int), Ops, "vsra_n"); 3497 } 3498 return EmitARMBuiltinExpr(NEON::BI__builtin_neon_vsra_n_v, E); 3499 case NEON::BI__builtin_neon_vsraq_n_v: 3500 return EmitARMBuiltinExpr(NEON::BI__builtin_neon_vsraq_n_v, E); 3501 case NEON::BI__builtin_neon_vrsra_n_v: 3502 if (VTy->getElementType()->isIntegerTy(64)) { 3503 Int = usgn ? Intrinsic::aarch64_neon_vrsradu_n 3504 : Intrinsic::aarch64_neon_vrsrads_n; 3505 return EmitNeonCall(CGM.getIntrinsic(Int), Ops, "vrsra_n"); 3506 } 3507 // fall through 3508 case NEON::BI__builtin_neon_vrsraq_n_v: { 3509 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3510 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3511 Int = usgn ? Intrinsic::aarch64_neon_vurshr 3512 : Intrinsic::aarch64_neon_vsrshr; 3513 Ops[1] = Builder.CreateCall2(CGM.getIntrinsic(Int, Ty), Ops[1], Ops[2]); 3514 return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n"); 3515 } 3516 case NEON::BI__builtin_neon_vqshlu_n_v: 3517 case NEON::BI__builtin_neon_vqshluq_n_v: 3518 Int = Intrinsic::aarch64_neon_vsqshlu; 3519 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshlu_n"); 3520 case NEON::BI__builtin_neon_vsri_n_v: 3521 case NEON::BI__builtin_neon_vsriq_n_v: 3522 Int = Intrinsic::aarch64_neon_vsri; 3523 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsri_n"); 3524 case NEON::BI__builtin_neon_vsli_n_v: 3525 case NEON::BI__builtin_neon_vsliq_n_v: 3526 Int = Intrinsic::aarch64_neon_vsli; 3527 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsli_n"); 3528 case NEON::BI__builtin_neon_vqshrun_n_v: 3529 Int = Intrinsic::aarch64_neon_vsqshrun; 3530 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrun_n"); 3531 case NEON::BI__builtin_neon_vrshrn_n_v: 3532 Int = Intrinsic::aarch64_neon_vrshrn; 3533 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshrn_n"); 3534 case NEON::BI__builtin_neon_vqrshrun_n_v: 3535 Int = Intrinsic::aarch64_neon_vsqrshrun; 3536 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrun_n"); 3537 case NEON::BI__builtin_neon_vqshrn_n_v: 3538 Int = usgn ? Intrinsic::aarch64_neon_vuqshrn 3539 : Intrinsic::aarch64_neon_vsqshrn; 3540 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n"); 3541 case NEON::BI__builtin_neon_vqrshrn_n_v: 3542 Int = usgn ? Intrinsic::aarch64_neon_vuqrshrn 3543 : Intrinsic::aarch64_neon_vsqrshrn; 3544 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n"); 3545 3546 // Convert 3547 case NEON::BI__builtin_neon_vcvt_n_f64_v: 3548 case NEON::BI__builtin_neon_vcvtq_n_f64_v: { 3549 llvm::Type *FloatTy = 3550 GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, quad)); 3551 llvm::Type *Tys[2] = { FloatTy, Ty }; 3552 Int = usgn ? Intrinsic::arm_neon_vcvtfxu2fp 3553 : Intrinsic::arm_neon_vcvtfxs2fp; 3554 Function *F = CGM.getIntrinsic(Int, Tys); 3555 return EmitNeonCall(F, Ops, "vcvt_n"); 3556 } 3557 3558 // Load/Store 3559 case NEON::BI__builtin_neon_vld1_x2_v: 3560 case NEON::BI__builtin_neon_vld1q_x2_v: 3561 case NEON::BI__builtin_neon_vld1_x3_v: 3562 case NEON::BI__builtin_neon_vld1q_x3_v: 3563 case NEON::BI__builtin_neon_vld1_x4_v: 3564 case NEON::BI__builtin_neon_vld1q_x4_v: { 3565 unsigned Int; 3566 switch (BuiltinID) { 3567 case NEON::BI__builtin_neon_vld1_x2_v: 3568 case NEON::BI__builtin_neon_vld1q_x2_v: 3569 Int = Intrinsic::aarch64_neon_vld1x2; 3570 break; 3571 case NEON::BI__builtin_neon_vld1_x3_v: 3572 case NEON::BI__builtin_neon_vld1q_x3_v: 3573 Int = Intrinsic::aarch64_neon_vld1x3; 3574 break; 3575 case NEON::BI__builtin_neon_vld1_x4_v: 3576 case NEON::BI__builtin_neon_vld1q_x4_v: 3577 Int = Intrinsic::aarch64_neon_vld1x4; 3578 break; 3579 } 3580 Function *F = CGM.getIntrinsic(Int, Ty); 3581 Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld1xN"); 3582 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 3583 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3584 return Builder.CreateStore(Ops[1], Ops[0]); 3585 } 3586 case NEON::BI__builtin_neon_vst1_x2_v: 3587 case NEON::BI__builtin_neon_vst1q_x2_v: 3588 case NEON::BI__builtin_neon_vst1_x3_v: 3589 case NEON::BI__builtin_neon_vst1q_x3_v: 3590 case NEON::BI__builtin_neon_vst1_x4_v: 3591 case NEON::BI__builtin_neon_vst1q_x4_v: { 3592 Ops.push_back(Align); 3593 unsigned Int; 3594 switch (BuiltinID) { 3595 case NEON::BI__builtin_neon_vst1_x2_v: 3596 case NEON::BI__builtin_neon_vst1q_x2_v: 3597 Int = Intrinsic::aarch64_neon_vst1x2; 3598 break; 3599 case NEON::BI__builtin_neon_vst1_x3_v: 3600 case NEON::BI__builtin_neon_vst1q_x3_v: 3601 Int = Intrinsic::aarch64_neon_vst1x3; 3602 break; 3603 case NEON::BI__builtin_neon_vst1_x4_v: 3604 case NEON::BI__builtin_neon_vst1q_x4_v: 3605 Int = Intrinsic::aarch64_neon_vst1x4; 3606 break; 3607 } 3608 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, ""); 3609 } 3610 case NEON::BI__builtin_neon_vld1_lane_v: 3611 case NEON::BI__builtin_neon_vld1q_lane_v: { 3612 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3613 Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 3614 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3615 LoadInst *Ld = Builder.CreateLoad(Ops[0]); 3616 Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); 3617 return Builder.CreateInsertElement(Ops[1], Ld, Ops[2], "vld1_lane"); 3618 } 3619 case NEON::BI__builtin_neon_vst1_lane_v: 3620 case NEON::BI__builtin_neon_vst1q_lane_v: { 3621 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3622 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); 3623 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 3624 StoreInst *St = 3625 Builder.CreateStore(Ops[1], Builder.CreateBitCast(Ops[0], Ty)); 3626 St->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); 3627 return St; 3628 } 3629 case NEON::BI__builtin_neon_vld2_dup_v: 3630 case NEON::BI__builtin_neon_vld2q_dup_v: 3631 case NEON::BI__builtin_neon_vld3_dup_v: 3632 case NEON::BI__builtin_neon_vld3q_dup_v: 3633 case NEON::BI__builtin_neon_vld4_dup_v: 3634 case NEON::BI__builtin_neon_vld4q_dup_v: { 3635 // Handle 64-bit x 1 elements as a special-case. There is no "dup" needed. 3636 if (VTy->getElementType()->getPrimitiveSizeInBits() == 64 && 3637 VTy->getNumElements() == 1) { 3638 switch (BuiltinID) { 3639 case NEON::BI__builtin_neon_vld2_dup_v: 3640 Int = Intrinsic::arm_neon_vld2; 3641 break; 3642 case NEON::BI__builtin_neon_vld3_dup_v: 3643 Int = Intrinsic::arm_neon_vld3; 3644 break; 3645 case NEON::BI__builtin_neon_vld4_dup_v: 3646 Int = Intrinsic::arm_neon_vld4; 3647 break; 3648 default: 3649 llvm_unreachable("unknown vld_dup intrinsic?"); 3650 } 3651 Function *F = CGM.getIntrinsic(Int, Ty); 3652 Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld_dup"); 3653 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 3654 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3655 return Builder.CreateStore(Ops[1], Ops[0]); 3656 } 3657 switch (BuiltinID) { 3658 case NEON::BI__builtin_neon_vld2_dup_v: 3659 case NEON::BI__builtin_neon_vld2q_dup_v: 3660 Int = Intrinsic::arm_neon_vld2lane; 3661 break; 3662 case NEON::BI__builtin_neon_vld3_dup_v: 3663 case NEON::BI__builtin_neon_vld3q_dup_v: 3664 Int = Intrinsic::arm_neon_vld3lane; 3665 break; 3666 case NEON::BI__builtin_neon_vld4_dup_v: 3667 case NEON::BI__builtin_neon_vld4q_dup_v: 3668 Int = Intrinsic::arm_neon_vld4lane; 3669 break; 3670 } 3671 Function *F = CGM.getIntrinsic(Int, Ty); 3672 llvm::StructType *STy = cast<llvm::StructType>(F->getReturnType()); 3673 3674 SmallVector<Value *, 6> Args; 3675 Args.push_back(Ops[1]); 3676 Args.append(STy->getNumElements(), UndefValue::get(Ty)); 3677 3678 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 3679 Args.push_back(CI); 3680 Args.push_back(Align); 3681 3682 Ops[1] = Builder.CreateCall(F, Args, "vld_dup"); 3683 // splat lane 0 to all elts in each vector of the result. 3684 for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { 3685 Value *Val = Builder.CreateExtractValue(Ops[1], i); 3686 Value *Elt = Builder.CreateBitCast(Val, Ty); 3687 Elt = EmitNeonSplat(Elt, CI); 3688 Elt = Builder.CreateBitCast(Elt, Val->getType()); 3689 Ops[1] = Builder.CreateInsertValue(Ops[1], Elt, i); 3690 } 3691 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 3692 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3693 return Builder.CreateStore(Ops[1], Ops[0]); 3694 } 3695 3696 case NEON::BI__builtin_neon_vmul_lane_v: 3697 case NEON::BI__builtin_neon_vmul_laneq_v: { 3698 // v1f64 vmul_lane should be mapped to Neon scalar mul lane 3699 bool Quad = false; 3700 if (BuiltinID == NEON::BI__builtin_neon_vmul_laneq_v) 3701 Quad = true; 3702 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 3703 llvm::Type *VTy = GetNeonType(this, 3704 NeonTypeFlags(NeonTypeFlags::Float64, false, Quad)); 3705 Ops[1] = Builder.CreateBitCast(Ops[1], VTy); 3706 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2], "extract"); 3707 Value *Result = Builder.CreateFMul(Ops[0], Ops[1]); 3708 return Builder.CreateBitCast(Result, Ty); 3709 } 3710 3711 // AArch64-only builtins 3712 case NEON::BI__builtin_neon_vfmaq_laneq_v: { 3713 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 3714 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3715 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3716 3717 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 3718 Ops[2] = EmitNeonSplat(Ops[2], cast<ConstantInt>(Ops[3])); 3719 return Builder.CreateCall3(F, Ops[2], Ops[1], Ops[0]); 3720 } 3721 case NEON::BI__builtin_neon_vfmaq_lane_v: { 3722 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 3723 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3724 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3725 3726 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 3727 llvm::Type *STy = llvm::VectorType::get(VTy->getElementType(), 3728 VTy->getNumElements() / 2); 3729 Ops[2] = Builder.CreateBitCast(Ops[2], STy); 3730 Value* SV = llvm::ConstantVector::getSplat(VTy->getNumElements(), 3731 cast<ConstantInt>(Ops[3])); 3732 Ops[2] = Builder.CreateShuffleVector(Ops[2], Ops[2], SV, "lane"); 3733 3734 return Builder.CreateCall3(F, Ops[2], Ops[1], Ops[0]); 3735 } 3736 case NEON::BI__builtin_neon_vfma_lane_v: { 3737 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 3738 // v1f64 fma should be mapped to Neon scalar f64 fma 3739 if (VTy && VTy->getElementType() == DoubleTy) { 3740 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 3741 Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy); 3742 llvm::Type *VTy = GetNeonType(this, 3743 NeonTypeFlags(NeonTypeFlags::Float64, false, false)); 3744 Ops[2] = Builder.CreateBitCast(Ops[2], VTy); 3745 Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract"); 3746 Value *F = CGM.getIntrinsic(Intrinsic::fma, DoubleTy); 3747 Value *Result = Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]); 3748 return Builder.CreateBitCast(Result, Ty); 3749 } 3750 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 3751 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3752 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3753 3754 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 3755 Ops[2] = EmitNeonSplat(Ops[2], cast<ConstantInt>(Ops[3])); 3756 return Builder.CreateCall3(F, Ops[2], Ops[1], Ops[0]); 3757 } 3758 case NEON::BI__builtin_neon_vfma_laneq_v: { 3759 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 3760 // v1f64 fma should be mapped to Neon scalar f64 fma 3761 if (VTy && VTy->getElementType() == DoubleTy) { 3762 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 3763 Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy); 3764 llvm::Type *VTy = GetNeonType(this, 3765 NeonTypeFlags(NeonTypeFlags::Float64, false, true)); 3766 Ops[2] = Builder.CreateBitCast(Ops[2], VTy); 3767 Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract"); 3768 Value *F = CGM.getIntrinsic(Intrinsic::fma, DoubleTy); 3769 Value *Result = Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]); 3770 return Builder.CreateBitCast(Result, Ty); 3771 } 3772 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 3773 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3774 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3775 3776 llvm::Type *STy = llvm::VectorType::get(VTy->getElementType(), 3777 VTy->getNumElements() * 2); 3778 Ops[2] = Builder.CreateBitCast(Ops[2], STy); 3779 Value* SV = llvm::ConstantVector::getSplat(VTy->getNumElements(), 3780 cast<ConstantInt>(Ops[3])); 3781 Ops[2] = Builder.CreateShuffleVector(Ops[2], Ops[2], SV, "lane"); 3782 3783 return Builder.CreateCall3(F, Ops[2], Ops[1], Ops[0]); 3784 } 3785 case NEON::BI__builtin_neon_vfms_v: 3786 case NEON::BI__builtin_neon_vfmsq_v: { 3787 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 3788 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3789 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3790 Ops[1] = Builder.CreateFNeg(Ops[1]); 3791 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 3792 3793 // LLVM's fma intrinsic puts the accumulator in the last position, but the 3794 // AArch64 intrinsic has it first. 3795 return Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]); 3796 } 3797 case NEON::BI__builtin_neon_vmaxnm_v: 3798 case NEON::BI__builtin_neon_vmaxnmq_v: { 3799 Int = Intrinsic::aarch64_neon_vmaxnm; 3800 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmaxnm"); 3801 } 3802 case NEON::BI__builtin_neon_vminnm_v: 3803 case NEON::BI__builtin_neon_vminnmq_v: { 3804 Int = Intrinsic::aarch64_neon_vminnm; 3805 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vminnm"); 3806 } 3807 case NEON::BI__builtin_neon_vpmaxnm_v: 3808 case NEON::BI__builtin_neon_vpmaxnmq_v: { 3809 Int = Intrinsic::aarch64_neon_vpmaxnm; 3810 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmaxnm"); 3811 } 3812 case NEON::BI__builtin_neon_vpminnm_v: 3813 case NEON::BI__builtin_neon_vpminnmq_v: { 3814 Int = Intrinsic::aarch64_neon_vpminnm; 3815 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpminnm"); 3816 } 3817 case NEON::BI__builtin_neon_vpmaxq_v: { 3818 Int = usgn ? Intrinsic::arm_neon_vpmaxu : Intrinsic::arm_neon_vpmaxs; 3819 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmax"); 3820 } 3821 case NEON::BI__builtin_neon_vpminq_v: { 3822 Int = usgn ? Intrinsic::arm_neon_vpminu : Intrinsic::arm_neon_vpmins; 3823 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmin"); 3824 } 3825 case NEON::BI__builtin_neon_vmulx_v: 3826 case NEON::BI__builtin_neon_vmulxq_v: { 3827 Int = Intrinsic::aarch64_neon_vmulx; 3828 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmulx"); 3829 } 3830 case NEON::BI__builtin_neon_vsqadd_v: 3831 case NEON::BI__builtin_neon_vsqaddq_v: { 3832 Int = Intrinsic::aarch64_neon_usqadd; 3833 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqadd"); 3834 } 3835 case NEON::BI__builtin_neon_vuqadd_v: 3836 case NEON::BI__builtin_neon_vuqaddq_v: { 3837 Int = Intrinsic::aarch64_neon_suqadd; 3838 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vuqadd"); 3839 } 3840 case NEON::BI__builtin_neon_vrbit_v: 3841 case NEON::BI__builtin_neon_vrbitq_v: 3842 Int = Intrinsic::aarch64_neon_rbit; 3843 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrbit"); 3844 case NEON::BI__builtin_neon_vcvt_f32_f64: { 3845 NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float64, false, true); 3846 Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag)); 3847 return Builder.CreateFPTrunc(Ops[0], Ty, "vcvt"); 3848 } 3849 case NEON::BI__builtin_neon_vcvtx_f32_v: { 3850 llvm::Type *EltTy = FloatTy; 3851 llvm::Type *ResTy = llvm::VectorType::get(EltTy, 2); 3852 llvm::Type *Tys[2] = { ResTy, Ty }; 3853 Int = Intrinsic::aarch64_neon_vcvtxn; 3854 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtx_f32_f64"); 3855 } 3856 case NEON::BI__builtin_neon_vcvt_f64_f32: { 3857 llvm::Type *OpTy = 3858 GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, false)); 3859 Ops[0] = Builder.CreateBitCast(Ops[0], OpTy); 3860 return Builder.CreateFPExt(Ops[0], Ty, "vcvt"); 3861 } 3862 case NEON::BI__builtin_neon_vcvt_f64_v: 3863 case NEON::BI__builtin_neon_vcvtq_f64_v: { 3864 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3865 Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, quad)); 3866 return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") 3867 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); 3868 } 3869 case NEON::BI__builtin_neon_vrndn_v: 3870 case NEON::BI__builtin_neon_vrndnq_v: { 3871 Int = Intrinsic::aarch64_neon_frintn; 3872 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndn"); 3873 } 3874 case NEON::BI__builtin_neon_vrnda_v: 3875 case NEON::BI__builtin_neon_vrndaq_v: { 3876 Int = Intrinsic::round; 3877 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrnda"); 3878 } 3879 case NEON::BI__builtin_neon_vrndp_v: 3880 case NEON::BI__builtin_neon_vrndpq_v: { 3881 Int = Intrinsic::ceil; 3882 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndp"); 3883 } 3884 case NEON::BI__builtin_neon_vrndm_v: 3885 case NEON::BI__builtin_neon_vrndmq_v: { 3886 Int = Intrinsic::floor; 3887 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndm"); 3888 } 3889 case NEON::BI__builtin_neon_vrndx_v: 3890 case NEON::BI__builtin_neon_vrndxq_v: { 3891 Int = Intrinsic::rint; 3892 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndx"); 3893 } 3894 case NEON::BI__builtin_neon_vrnd_v: 3895 case NEON::BI__builtin_neon_vrndq_v: { 3896 Int = Intrinsic::trunc; 3897 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrnd"); 3898 } 3899 case NEON::BI__builtin_neon_vrndi_v: 3900 case NEON::BI__builtin_neon_vrndiq_v: { 3901 Int = Intrinsic::nearbyint; 3902 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndi"); 3903 } 3904 case NEON::BI__builtin_neon_vsqrt_v: 3905 case NEON::BI__builtin_neon_vsqrtq_v: { 3906 Int = Intrinsic::sqrt; 3907 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqrt"); 3908 } 3909 case NEON::BI__builtin_neon_vceqz_v: 3910 case NEON::BI__builtin_neon_vceqzq_v: 3911 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OEQ, 3912 ICmpInst::ICMP_EQ, "vceqz"); 3913 case NEON::BI__builtin_neon_vcgez_v: 3914 case NEON::BI__builtin_neon_vcgezq_v: 3915 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGE, 3916 ICmpInst::ICMP_SGE, "vcgez"); 3917 case NEON::BI__builtin_neon_vclez_v: 3918 case NEON::BI__builtin_neon_vclezq_v: 3919 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLE, 3920 ICmpInst::ICMP_SLE, "vclez"); 3921 case NEON::BI__builtin_neon_vcgtz_v: 3922 case NEON::BI__builtin_neon_vcgtzq_v: 3923 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGT, 3924 ICmpInst::ICMP_SGT, "vcgtz"); 3925 case NEON::BI__builtin_neon_vcltz_v: 3926 case NEON::BI__builtin_neon_vcltzq_v: 3927 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLT, 3928 ICmpInst::ICMP_SLT, "vcltz"); 3929 } 3930 } 3931 3932 Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, 3933 const CallExpr *E) { 3934 if (BuiltinID == ARM::BI__clear_cache) { 3935 assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments"); 3936 const FunctionDecl *FD = E->getDirectCallee(); 3937 SmallVector<Value*, 2> Ops; 3938 for (unsigned i = 0; i < 2; i++) 3939 Ops.push_back(EmitScalarExpr(E->getArg(i))); 3940 llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); 3941 llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); 3942 StringRef Name = FD->getName(); 3943 return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); 3944 } 3945 3946 if (BuiltinID == ARM::BI__builtin_arm_ldrexd || 3947 (BuiltinID == ARM::BI__builtin_arm_ldrex && 3948 getContext().getTypeSize(E->getType()) == 64)) { 3949 Function *F = CGM.getIntrinsic(Intrinsic::arm_ldrexd); 3950 3951 Value *LdPtr = EmitScalarExpr(E->getArg(0)); 3952 Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy), 3953 "ldrexd"); 3954 3955 Value *Val0 = Builder.CreateExtractValue(Val, 1); 3956 Value *Val1 = Builder.CreateExtractValue(Val, 0); 3957 Val0 = Builder.CreateZExt(Val0, Int64Ty); 3958 Val1 = Builder.CreateZExt(Val1, Int64Ty); 3959 3960 Value *ShiftCst = llvm::ConstantInt::get(Int64Ty, 32); 3961 Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */); 3962 Val = Builder.CreateOr(Val, Val1); 3963 return Builder.CreateBitCast(Val, ConvertType(E->getType())); 3964 } 3965 3966 if (BuiltinID == ARM::BI__builtin_arm_ldrex) { 3967 Value *LoadAddr = EmitScalarExpr(E->getArg(0)); 3968 3969 QualType Ty = E->getType(); 3970 llvm::Type *RealResTy = ConvertType(Ty); 3971 llvm::Type *IntResTy = llvm::IntegerType::get(getLLVMContext(), 3972 getContext().getTypeSize(Ty)); 3973 LoadAddr = Builder.CreateBitCast(LoadAddr, IntResTy->getPointerTo()); 3974 3975 Function *F = CGM.getIntrinsic(Intrinsic::arm_ldrex, LoadAddr->getType()); 3976 Value *Val = Builder.CreateCall(F, LoadAddr, "ldrex"); 3977 3978 if (RealResTy->isPointerTy()) 3979 return Builder.CreateIntToPtr(Val, RealResTy); 3980 else { 3981 Val = Builder.CreateTruncOrBitCast(Val, IntResTy); 3982 return Builder.CreateBitCast(Val, RealResTy); 3983 } 3984 } 3985 3986 if (BuiltinID == ARM::BI__builtin_arm_strexd || 3987 (BuiltinID == ARM::BI__builtin_arm_strex && 3988 getContext().getTypeSize(E->getArg(0)->getType()) == 64)) { 3989 Function *F = CGM.getIntrinsic(Intrinsic::arm_strexd); 3990 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, NULL); 3991 3992 Value *Tmp = CreateMemTemp(E->getArg(0)->getType()); 3993 Value *Val = EmitScalarExpr(E->getArg(0)); 3994 Builder.CreateStore(Val, Tmp); 3995 3996 Value *LdPtr = Builder.CreateBitCast(Tmp,llvm::PointerType::getUnqual(STy)); 3997 Val = Builder.CreateLoad(LdPtr); 3998 3999 Value *Arg0 = Builder.CreateExtractValue(Val, 0); 4000 Value *Arg1 = Builder.CreateExtractValue(Val, 1); 4001 Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), Int8PtrTy); 4002 return Builder.CreateCall3(F, Arg0, Arg1, StPtr, "strexd"); 4003 } 4004 4005 if (BuiltinID == ARM::BI__builtin_arm_strex) { 4006 Value *StoreVal = EmitScalarExpr(E->getArg(0)); 4007 Value *StoreAddr = EmitScalarExpr(E->getArg(1)); 4008 4009 QualType Ty = E->getArg(0)->getType(); 4010 llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(), 4011 getContext().getTypeSize(Ty)); 4012 StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo()); 4013 4014 if (StoreVal->getType()->isPointerTy()) 4015 StoreVal = Builder.CreatePtrToInt(StoreVal, Int32Ty); 4016 else { 4017 StoreVal = Builder.CreateBitCast(StoreVal, StoreTy); 4018 StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int32Ty); 4019 } 4020 4021 Function *F = CGM.getIntrinsic(Intrinsic::arm_strex, StoreAddr->getType()); 4022 return Builder.CreateCall2(F, StoreVal, StoreAddr, "strex"); 4023 } 4024 4025 if (BuiltinID == ARM::BI__builtin_arm_clrex) { 4026 Function *F = CGM.getIntrinsic(Intrinsic::arm_clrex); 4027 return Builder.CreateCall(F); 4028 } 4029 4030 if (BuiltinID == ARM::BI__builtin_arm_sevl) { 4031 Function *F = CGM.getIntrinsic(Intrinsic::arm_sevl); 4032 return Builder.CreateCall(F); 4033 } 4034 4035 // CRC32 4036 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic; 4037 switch (BuiltinID) { 4038 case ARM::BI__builtin_arm_crc32b: 4039 CRCIntrinsicID = Intrinsic::arm_crc32b; break; 4040 case ARM::BI__builtin_arm_crc32cb: 4041 CRCIntrinsicID = Intrinsic::arm_crc32cb; break; 4042 case ARM::BI__builtin_arm_crc32h: 4043 CRCIntrinsicID = Intrinsic::arm_crc32h; break; 4044 case ARM::BI__builtin_arm_crc32ch: 4045 CRCIntrinsicID = Intrinsic::arm_crc32ch; break; 4046 case ARM::BI__builtin_arm_crc32w: 4047 case ARM::BI__builtin_arm_crc32d: 4048 CRCIntrinsicID = Intrinsic::arm_crc32w; break; 4049 case ARM::BI__builtin_arm_crc32cw: 4050 case ARM::BI__builtin_arm_crc32cd: 4051 CRCIntrinsicID = Intrinsic::arm_crc32cw; break; 4052 } 4053 4054 if (CRCIntrinsicID != Intrinsic::not_intrinsic) { 4055 Value *Arg0 = EmitScalarExpr(E->getArg(0)); 4056 Value *Arg1 = EmitScalarExpr(E->getArg(1)); 4057 4058 // crc32{c,}d intrinsics are implemnted as two calls to crc32{c,}w 4059 // intrinsics, hence we need different codegen for these cases. 4060 if (BuiltinID == ARM::BI__builtin_arm_crc32d || 4061 BuiltinID == ARM::BI__builtin_arm_crc32cd) { 4062 Value *C1 = llvm::ConstantInt::get(Int64Ty, 32); 4063 Value *Arg1a = Builder.CreateTruncOrBitCast(Arg1, Int32Ty); 4064 Value *Arg1b = Builder.CreateLShr(Arg1, C1); 4065 Arg1b = Builder.CreateTruncOrBitCast(Arg1b, Int32Ty); 4066 4067 Function *F = CGM.getIntrinsic(CRCIntrinsicID); 4068 Value *Res = Builder.CreateCall2(F, Arg0, Arg1a); 4069 return Builder.CreateCall2(F, Res, Arg1b); 4070 } else { 4071 Arg1 = Builder.CreateZExtOrBitCast(Arg1, Int32Ty); 4072 4073 Function *F = CGM.getIntrinsic(CRCIntrinsicID); 4074 return Builder.CreateCall2(F, Arg0, Arg1); 4075 } 4076 } 4077 4078 SmallVector<Value*, 4> Ops; 4079 llvm::Value *Align = 0; 4080 for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) { 4081 if (i == 0) { 4082 switch (BuiltinID) { 4083 case NEON::BI__builtin_neon_vld1_v: 4084 case NEON::BI__builtin_neon_vld1q_v: 4085 case NEON::BI__builtin_neon_vld1q_lane_v: 4086 case NEON::BI__builtin_neon_vld1_lane_v: 4087 case NEON::BI__builtin_neon_vld1_dup_v: 4088 case NEON::BI__builtin_neon_vld1q_dup_v: 4089 case NEON::BI__builtin_neon_vst1_v: 4090 case NEON::BI__builtin_neon_vst1q_v: 4091 case NEON::BI__builtin_neon_vst1q_lane_v: 4092 case NEON::BI__builtin_neon_vst1_lane_v: 4093 case NEON::BI__builtin_neon_vst2_v: 4094 case NEON::BI__builtin_neon_vst2q_v: 4095 case NEON::BI__builtin_neon_vst2_lane_v: 4096 case NEON::BI__builtin_neon_vst2q_lane_v: 4097 case NEON::BI__builtin_neon_vst3_v: 4098 case NEON::BI__builtin_neon_vst3q_v: 4099 case NEON::BI__builtin_neon_vst3_lane_v: 4100 case NEON::BI__builtin_neon_vst3q_lane_v: 4101 case NEON::BI__builtin_neon_vst4_v: 4102 case NEON::BI__builtin_neon_vst4q_v: 4103 case NEON::BI__builtin_neon_vst4_lane_v: 4104 case NEON::BI__builtin_neon_vst4q_lane_v: 4105 // Get the alignment for the argument in addition to the value; 4106 // we'll use it later. 4107 std::pair<llvm::Value*, unsigned> Src = 4108 EmitPointerWithAlignment(E->getArg(0)); 4109 Ops.push_back(Src.first); 4110 Align = Builder.getInt32(Src.second); 4111 continue; 4112 } 4113 } 4114 if (i == 1) { 4115 switch (BuiltinID) { 4116 case NEON::BI__builtin_neon_vld2_v: 4117 case NEON::BI__builtin_neon_vld2q_v: 4118 case NEON::BI__builtin_neon_vld3_v: 4119 case NEON::BI__builtin_neon_vld3q_v: 4120 case NEON::BI__builtin_neon_vld4_v: 4121 case NEON::BI__builtin_neon_vld4q_v: 4122 case NEON::BI__builtin_neon_vld2_lane_v: 4123 case NEON::BI__builtin_neon_vld2q_lane_v: 4124 case NEON::BI__builtin_neon_vld3_lane_v: 4125 case NEON::BI__builtin_neon_vld3q_lane_v: 4126 case NEON::BI__builtin_neon_vld4_lane_v: 4127 case NEON::BI__builtin_neon_vld4q_lane_v: 4128 case NEON::BI__builtin_neon_vld2_dup_v: 4129 case NEON::BI__builtin_neon_vld3_dup_v: 4130 case NEON::BI__builtin_neon_vld4_dup_v: 4131 // Get the alignment for the argument in addition to the value; 4132 // we'll use it later. 4133 std::pair<llvm::Value*, unsigned> Src = 4134 EmitPointerWithAlignment(E->getArg(1)); 4135 Ops.push_back(Src.first); 4136 Align = Builder.getInt32(Src.second); 4137 continue; 4138 } 4139 } 4140 Ops.push_back(EmitScalarExpr(E->getArg(i))); 4141 } 4142 4143 switch (BuiltinID) { 4144 default: break; 4145 // vget_lane and vset_lane are not overloaded and do not have an extra 4146 // argument that specifies the vector type. 4147 case NEON::BI__builtin_neon_vget_lane_i8: 4148 case NEON::BI__builtin_neon_vget_lane_i16: 4149 case NEON::BI__builtin_neon_vget_lane_i32: 4150 case NEON::BI__builtin_neon_vget_lane_i64: 4151 case NEON::BI__builtin_neon_vget_lane_f32: 4152 case NEON::BI__builtin_neon_vgetq_lane_i8: 4153 case NEON::BI__builtin_neon_vgetq_lane_i16: 4154 case NEON::BI__builtin_neon_vgetq_lane_i32: 4155 case NEON::BI__builtin_neon_vgetq_lane_i64: 4156 case NEON::BI__builtin_neon_vgetq_lane_f32: 4157 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 4158 "vget_lane"); 4159 case NEON::BI__builtin_neon_vset_lane_i8: 4160 case NEON::BI__builtin_neon_vset_lane_i16: 4161 case NEON::BI__builtin_neon_vset_lane_i32: 4162 case NEON::BI__builtin_neon_vset_lane_i64: 4163 case NEON::BI__builtin_neon_vset_lane_f32: 4164 case NEON::BI__builtin_neon_vsetq_lane_i8: 4165 case NEON::BI__builtin_neon_vsetq_lane_i16: 4166 case NEON::BI__builtin_neon_vsetq_lane_i32: 4167 case NEON::BI__builtin_neon_vsetq_lane_i64: 4168 case NEON::BI__builtin_neon_vsetq_lane_f32: 4169 Ops.push_back(EmitScalarExpr(E->getArg(2))); 4170 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 4171 4172 // Non-polymorphic crypto instructions also not overloaded 4173 case NEON::BI__builtin_neon_vsha1h_u32: 4174 Ops.push_back(EmitScalarExpr(E->getArg(0))); 4175 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1h), Ops, 4176 "vsha1h"); 4177 case NEON::BI__builtin_neon_vsha1cq_u32: 4178 Ops.push_back(EmitScalarExpr(E->getArg(2))); 4179 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1c), Ops, 4180 "vsha1h"); 4181 case NEON::BI__builtin_neon_vsha1pq_u32: 4182 Ops.push_back(EmitScalarExpr(E->getArg(2))); 4183 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1p), Ops, 4184 "vsha1h"); 4185 case NEON::BI__builtin_neon_vsha1mq_u32: 4186 Ops.push_back(EmitScalarExpr(E->getArg(2))); 4187 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1m), Ops, 4188 "vsha1h"); 4189 } 4190 4191 // Get the last argument, which specifies the vector type. 4192 llvm::APSInt Result; 4193 const Expr *Arg = E->getArg(E->getNumArgs()-1); 4194 if (!Arg->isIntegerConstantExpr(Result, getContext())) 4195 return 0; 4196 4197 if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f || 4198 BuiltinID == ARM::BI__builtin_arm_vcvtr_d) { 4199 // Determine the overloaded type of this builtin. 4200 llvm::Type *Ty; 4201 if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f) 4202 Ty = FloatTy; 4203 else 4204 Ty = DoubleTy; 4205 4206 // Determine whether this is an unsigned conversion or not. 4207 bool usgn = Result.getZExtValue() == 1; 4208 unsigned Int = usgn ? Intrinsic::arm_vcvtru : Intrinsic::arm_vcvtr; 4209 4210 // Call the appropriate intrinsic. 4211 Function *F = CGM.getIntrinsic(Int, Ty); 4212 return Builder.CreateCall(F, Ops, "vcvtr"); 4213 } 4214 4215 // Determine the type of this overloaded NEON intrinsic. 4216 NeonTypeFlags Type(Result.getZExtValue()); 4217 bool usgn = Type.isUnsigned(); 4218 bool rightShift = false; 4219 4220 llvm::VectorType *VTy = GetNeonType(this, Type); 4221 llvm::Type *Ty = VTy; 4222 if (!Ty) 4223 return 0; 4224 4225 // Many NEON builtins have identical semantics and uses in ARM and 4226 // AArch64. Emit these in a single function. 4227 llvm::ArrayRef<NeonIntrinsicInfo> IntrinsicMap(ARMSIMDIntrinsicMap); 4228 const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap( 4229 IntrinsicMap, BuiltinID, NEONSIMDIntrinsicsProvenSorted); 4230 if (Builtin) 4231 return EmitCommonNeonBuiltinExpr( 4232 Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic, 4233 Builtin->NameHint, Builtin->TypeModifier, E, Ops, Align); 4234 4235 unsigned Int; 4236 switch (BuiltinID) { 4237 default: return 0; 4238 case NEON::BI__builtin_neon_vld1q_lane_v: 4239 // Handle 64-bit integer elements as a special case. Use shuffles of 4240 // one-element vectors to avoid poor code for i64 in the backend. 4241 if (VTy->getElementType()->isIntegerTy(64)) { 4242 // Extract the other lane. 4243 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4244 int Lane = cast<ConstantInt>(Ops[2])->getZExtValue(); 4245 Value *SV = llvm::ConstantVector::get(ConstantInt::get(Int32Ty, 1-Lane)); 4246 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); 4247 // Load the value as a one-element vector. 4248 Ty = llvm::VectorType::get(VTy->getElementType(), 1); 4249 Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Ty); 4250 Value *Ld = Builder.CreateCall2(F, Ops[0], Align); 4251 // Combine them. 4252 SmallVector<Constant*, 2> Indices; 4253 Indices.push_back(ConstantInt::get(Int32Ty, 1-Lane)); 4254 Indices.push_back(ConstantInt::get(Int32Ty, Lane)); 4255 SV = llvm::ConstantVector::get(Indices); 4256 return Builder.CreateShuffleVector(Ops[1], Ld, SV, "vld1q_lane"); 4257 } 4258 // fall through 4259 case NEON::BI__builtin_neon_vld1_lane_v: { 4260 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4261 Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 4262 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4263 LoadInst *Ld = Builder.CreateLoad(Ops[0]); 4264 Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); 4265 return Builder.CreateInsertElement(Ops[1], Ld, Ops[2], "vld1_lane"); 4266 } 4267 case NEON::BI__builtin_neon_vld2_dup_v: 4268 case NEON::BI__builtin_neon_vld3_dup_v: 4269 case NEON::BI__builtin_neon_vld4_dup_v: { 4270 // Handle 64-bit elements as a special-case. There is no "dup" needed. 4271 if (VTy->getElementType()->getPrimitiveSizeInBits() == 64) { 4272 switch (BuiltinID) { 4273 case NEON::BI__builtin_neon_vld2_dup_v: 4274 Int = Intrinsic::arm_neon_vld2; 4275 break; 4276 case NEON::BI__builtin_neon_vld3_dup_v: 4277 Int = Intrinsic::arm_neon_vld3; 4278 break; 4279 case NEON::BI__builtin_neon_vld4_dup_v: 4280 Int = Intrinsic::arm_neon_vld4; 4281 break; 4282 default: llvm_unreachable("unknown vld_dup intrinsic?"); 4283 } 4284 Function *F = CGM.getIntrinsic(Int, Ty); 4285 Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld_dup"); 4286 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 4287 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4288 return Builder.CreateStore(Ops[1], Ops[0]); 4289 } 4290 switch (BuiltinID) { 4291 case NEON::BI__builtin_neon_vld2_dup_v: 4292 Int = Intrinsic::arm_neon_vld2lane; 4293 break; 4294 case NEON::BI__builtin_neon_vld3_dup_v: 4295 Int = Intrinsic::arm_neon_vld3lane; 4296 break; 4297 case NEON::BI__builtin_neon_vld4_dup_v: 4298 Int = Intrinsic::arm_neon_vld4lane; 4299 break; 4300 default: llvm_unreachable("unknown vld_dup intrinsic?"); 4301 } 4302 Function *F = CGM.getIntrinsic(Int, Ty); 4303 llvm::StructType *STy = cast<llvm::StructType>(F->getReturnType()); 4304 4305 SmallVector<Value*, 6> Args; 4306 Args.push_back(Ops[1]); 4307 Args.append(STy->getNumElements(), UndefValue::get(Ty)); 4308 4309 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 4310 Args.push_back(CI); 4311 Args.push_back(Align); 4312 4313 Ops[1] = Builder.CreateCall(F, Args, "vld_dup"); 4314 // splat lane 0 to all elts in each vector of the result. 4315 for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { 4316 Value *Val = Builder.CreateExtractValue(Ops[1], i); 4317 Value *Elt = Builder.CreateBitCast(Val, Ty); 4318 Elt = EmitNeonSplat(Elt, CI); 4319 Elt = Builder.CreateBitCast(Elt, Val->getType()); 4320 Ops[1] = Builder.CreateInsertValue(Ops[1], Elt, i); 4321 } 4322 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 4323 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4324 return Builder.CreateStore(Ops[1], Ops[0]); 4325 } 4326 case NEON::BI__builtin_neon_vqrshrn_n_v: 4327 Int = 4328 usgn ? Intrinsic::arm_neon_vqrshiftnu : Intrinsic::arm_neon_vqrshiftns; 4329 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n", 4330 1, true); 4331 case NEON::BI__builtin_neon_vqrshrun_n_v: 4332 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrshiftnsu, Ty), 4333 Ops, "vqrshrun_n", 1, true); 4334 case NEON::BI__builtin_neon_vqshlu_n_v: 4335 case NEON::BI__builtin_neon_vqshluq_n_v: 4336 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftsu, Ty), 4337 Ops, "vqshlu", 1, false); 4338 case NEON::BI__builtin_neon_vqshrn_n_v: 4339 Int = usgn ? Intrinsic::arm_neon_vqshiftnu : Intrinsic::arm_neon_vqshiftns; 4340 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n", 4341 1, true); 4342 case NEON::BI__builtin_neon_vqshrun_n_v: 4343 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftnsu, Ty), 4344 Ops, "vqshrun_n", 1, true); 4345 case NEON::BI__builtin_neon_vrecpe_v: 4346 case NEON::BI__builtin_neon_vrecpeq_v: 4347 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecpe, Ty), 4348 Ops, "vrecpe"); 4349 case NEON::BI__builtin_neon_vrshrn_n_v: 4350 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrshiftn, Ty), 4351 Ops, "vrshrn_n", 1, true); 4352 case NEON::BI__builtin_neon_vrshr_n_v: 4353 case NEON::BI__builtin_neon_vrshrq_n_v: 4354 Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 4355 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshr_n", 1, true); 4356 case NEON::BI__builtin_neon_vrsra_n_v: 4357 case NEON::BI__builtin_neon_vrsraq_n_v: 4358 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4359 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4360 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, true); 4361 Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 4362 Ops[1] = Builder.CreateCall2(CGM.getIntrinsic(Int, Ty), Ops[1], Ops[2]); 4363 return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n"); 4364 case NEON::BI__builtin_neon_vsri_n_v: 4365 case NEON::BI__builtin_neon_vsriq_n_v: 4366 rightShift = true; 4367 case NEON::BI__builtin_neon_vsli_n_v: 4368 case NEON::BI__builtin_neon_vsliq_n_v: 4369 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, rightShift); 4370 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftins, Ty), 4371 Ops, "vsli_n"); 4372 case NEON::BI__builtin_neon_vsra_n_v: 4373 case NEON::BI__builtin_neon_vsraq_n_v: 4374 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4375 Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n"); 4376 return Builder.CreateAdd(Ops[0], Ops[1]); 4377 case NEON::BI__builtin_neon_vst1q_lane_v: 4378 // Handle 64-bit integer elements as a special case. Use a shuffle to get 4379 // a one-element vector and avoid poor code for i64 in the backend. 4380 if (VTy->getElementType()->isIntegerTy(64)) { 4381 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4382 Value *SV = llvm::ConstantVector::get(cast<llvm::Constant>(Ops[2])); 4383 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); 4384 Ops[2] = Align; 4385 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, 4386 Ops[1]->getType()), Ops); 4387 } 4388 // fall through 4389 case NEON::BI__builtin_neon_vst1_lane_v: { 4390 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4391 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); 4392 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 4393 StoreInst *St = Builder.CreateStore(Ops[1], 4394 Builder.CreateBitCast(Ops[0], Ty)); 4395 St->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); 4396 return St; 4397 } 4398 case NEON::BI__builtin_neon_vtbl1_v: 4399 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl1), 4400 Ops, "vtbl1"); 4401 case NEON::BI__builtin_neon_vtbl2_v: 4402 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl2), 4403 Ops, "vtbl2"); 4404 case NEON::BI__builtin_neon_vtbl3_v: 4405 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl3), 4406 Ops, "vtbl3"); 4407 case NEON::BI__builtin_neon_vtbl4_v: 4408 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl4), 4409 Ops, "vtbl4"); 4410 case NEON::BI__builtin_neon_vtbx1_v: 4411 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx1), 4412 Ops, "vtbx1"); 4413 case NEON::BI__builtin_neon_vtbx2_v: 4414 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx2), 4415 Ops, "vtbx2"); 4416 case NEON::BI__builtin_neon_vtbx3_v: 4417 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx3), 4418 Ops, "vtbx3"); 4419 case NEON::BI__builtin_neon_vtbx4_v: 4420 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx4), 4421 Ops, "vtbx4"); 4422 } 4423 } 4424 4425 llvm::Value *CodeGenFunction:: 4426 BuildVector(ArrayRef<llvm::Value*> Ops) { 4427 assert((Ops.size() & (Ops.size() - 1)) == 0 && 4428 "Not a power-of-two sized vector!"); 4429 bool AllConstants = true; 4430 for (unsigned i = 0, e = Ops.size(); i != e && AllConstants; ++i) 4431 AllConstants &= isa<Constant>(Ops[i]); 4432 4433 // If this is a constant vector, create a ConstantVector. 4434 if (AllConstants) { 4435 SmallVector<llvm::Constant*, 16> CstOps; 4436 for (unsigned i = 0, e = Ops.size(); i != e; ++i) 4437 CstOps.push_back(cast<Constant>(Ops[i])); 4438 return llvm::ConstantVector::get(CstOps); 4439 } 4440 4441 // Otherwise, insertelement the values to build the vector. 4442 Value *Result = 4443 llvm::UndefValue::get(llvm::VectorType::get(Ops[0]->getType(), Ops.size())); 4444 4445 for (unsigned i = 0, e = Ops.size(); i != e; ++i) 4446 Result = Builder.CreateInsertElement(Result, Ops[i], Builder.getInt32(i)); 4447 4448 return Result; 4449 } 4450 4451 Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, 4452 const CallExpr *E) { 4453 SmallVector<Value*, 4> Ops; 4454 4455 // Find out if any arguments are required to be integer constant expressions. 4456 unsigned ICEArguments = 0; 4457 ASTContext::GetBuiltinTypeError Error; 4458 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 4459 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 4460 4461 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) { 4462 // If this is a normal argument, just emit it as a scalar. 4463 if ((ICEArguments & (1 << i)) == 0) { 4464 Ops.push_back(EmitScalarExpr(E->getArg(i))); 4465 continue; 4466 } 4467 4468 // If this is required to be a constant, constant fold it so that we know 4469 // that the generated intrinsic gets a ConstantInt. 4470 llvm::APSInt Result; 4471 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext()); 4472 assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst; 4473 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result)); 4474 } 4475 4476 switch (BuiltinID) { 4477 default: return 0; 4478 case X86::BI_mm_prefetch: { 4479 Value *Address = EmitScalarExpr(E->getArg(0)); 4480 Value *RW = ConstantInt::get(Int32Ty, 0); 4481 Value *Locality = EmitScalarExpr(E->getArg(1)); 4482 Value *Data = ConstantInt::get(Int32Ty, 1); 4483 Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 4484 return Builder.CreateCall4(F, Address, RW, Locality, Data); 4485 } 4486 case X86::BI__builtin_ia32_vec_init_v8qi: 4487 case X86::BI__builtin_ia32_vec_init_v4hi: 4488 case X86::BI__builtin_ia32_vec_init_v2si: 4489 return Builder.CreateBitCast(BuildVector(Ops), 4490 llvm::Type::getX86_MMXTy(getLLVMContext())); 4491 case X86::BI__builtin_ia32_vec_ext_v2si: 4492 return Builder.CreateExtractElement(Ops[0], 4493 llvm::ConstantInt::get(Ops[1]->getType(), 0)); 4494 case X86::BI__builtin_ia32_ldmxcsr: { 4495 Value *Tmp = CreateMemTemp(E->getArg(0)->getType()); 4496 Builder.CreateStore(Ops[0], Tmp); 4497 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr), 4498 Builder.CreateBitCast(Tmp, Int8PtrTy)); 4499 } 4500 case X86::BI__builtin_ia32_stmxcsr: { 4501 Value *Tmp = CreateMemTemp(E->getType()); 4502 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr), 4503 Builder.CreateBitCast(Tmp, Int8PtrTy)); 4504 return Builder.CreateLoad(Tmp, "stmxcsr"); 4505 } 4506 case X86::BI__builtin_ia32_storehps: 4507 case X86::BI__builtin_ia32_storelps: { 4508 llvm::Type *PtrTy = llvm::PointerType::getUnqual(Int64Ty); 4509 llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2); 4510 4511 // cast val v2i64 4512 Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast"); 4513 4514 // extract (0, 1) 4515 unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1; 4516 llvm::Value *Idx = llvm::ConstantInt::get(Int32Ty, Index); 4517 Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract"); 4518 4519 // cast pointer to i64 & store 4520 Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy); 4521 return Builder.CreateStore(Ops[1], Ops[0]); 4522 } 4523 case X86::BI__builtin_ia32_palignr: { 4524 unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 4525 4526 // If palignr is shifting the pair of input vectors less than 9 bytes, 4527 // emit a shuffle instruction. 4528 if (shiftVal <= 8) { 4529 SmallVector<llvm::Constant*, 8> Indices; 4530 for (unsigned i = 0; i != 8; ++i) 4531 Indices.push_back(llvm::ConstantInt::get(Int32Ty, shiftVal + i)); 4532 4533 Value* SV = llvm::ConstantVector::get(Indices); 4534 return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 4535 } 4536 4537 // If palignr is shifting the pair of input vectors more than 8 but less 4538 // than 16 bytes, emit a logical right shift of the destination. 4539 if (shiftVal < 16) { 4540 // MMX has these as 1 x i64 vectors for some odd optimization reasons. 4541 llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 1); 4542 4543 Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 4544 Ops[1] = llvm::ConstantInt::get(VecTy, (shiftVal-8) * 8); 4545 4546 // create i32 constant 4547 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_mmx_psrl_q); 4548 return Builder.CreateCall(F, makeArrayRef(&Ops[0], 2), "palignr"); 4549 } 4550 4551 // If palignr is shifting the pair of vectors more than 16 bytes, emit zero. 4552 return llvm::Constant::getNullValue(ConvertType(E->getType())); 4553 } 4554 case X86::BI__builtin_ia32_palignr128: { 4555 unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 4556 4557 // If palignr is shifting the pair of input vectors less than 17 bytes, 4558 // emit a shuffle instruction. 4559 if (shiftVal <= 16) { 4560 SmallVector<llvm::Constant*, 16> Indices; 4561 for (unsigned i = 0; i != 16; ++i) 4562 Indices.push_back(llvm::ConstantInt::get(Int32Ty, shiftVal + i)); 4563 4564 Value* SV = llvm::ConstantVector::get(Indices); 4565 return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 4566 } 4567 4568 // If palignr is shifting the pair of input vectors more than 16 but less 4569 // than 32 bytes, emit a logical right shift of the destination. 4570 if (shiftVal < 32) { 4571 llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2); 4572 4573 Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 4574 Ops[1] = llvm::ConstantInt::get(Int32Ty, (shiftVal-16) * 8); 4575 4576 // create i32 constant 4577 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_psrl_dq); 4578 return Builder.CreateCall(F, makeArrayRef(&Ops[0], 2), "palignr"); 4579 } 4580 4581 // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 4582 return llvm::Constant::getNullValue(ConvertType(E->getType())); 4583 } 4584 case X86::BI__builtin_ia32_palignr256: { 4585 unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 4586 4587 // If palignr is shifting the pair of input vectors less than 17 bytes, 4588 // emit a shuffle instruction. 4589 if (shiftVal <= 16) { 4590 SmallVector<llvm::Constant*, 32> Indices; 4591 // 256-bit palignr operates on 128-bit lanes so we need to handle that 4592 for (unsigned l = 0; l != 2; ++l) { 4593 unsigned LaneStart = l * 16; 4594 unsigned LaneEnd = (l+1) * 16; 4595 for (unsigned i = 0; i != 16; ++i) { 4596 unsigned Idx = shiftVal + i + LaneStart; 4597 if (Idx >= LaneEnd) Idx += 16; // end of lane, switch operand 4598 Indices.push_back(llvm::ConstantInt::get(Int32Ty, Idx)); 4599 } 4600 } 4601 4602 Value* SV = llvm::ConstantVector::get(Indices); 4603 return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 4604 } 4605 4606 // If palignr is shifting the pair of input vectors more than 16 but less 4607 // than 32 bytes, emit a logical right shift of the destination. 4608 if (shiftVal < 32) { 4609 llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 4); 4610 4611 Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 4612 Ops[1] = llvm::ConstantInt::get(Int32Ty, (shiftVal-16) * 8); 4613 4614 // create i32 constant 4615 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_avx2_psrl_dq); 4616 return Builder.CreateCall(F, makeArrayRef(&Ops[0], 2), "palignr"); 4617 } 4618 4619 // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 4620 return llvm::Constant::getNullValue(ConvertType(E->getType())); 4621 } 4622 case X86::BI__builtin_ia32_movntps: 4623 case X86::BI__builtin_ia32_movntps256: 4624 case X86::BI__builtin_ia32_movntpd: 4625 case X86::BI__builtin_ia32_movntpd256: 4626 case X86::BI__builtin_ia32_movntdq: 4627 case X86::BI__builtin_ia32_movntdq256: 4628 case X86::BI__builtin_ia32_movnti: 4629 case X86::BI__builtin_ia32_movnti64: { 4630 llvm::MDNode *Node = llvm::MDNode::get(getLLVMContext(), 4631 Builder.getInt32(1)); 4632 4633 // Convert the type of the pointer to a pointer to the stored type. 4634 Value *BC = Builder.CreateBitCast(Ops[0], 4635 llvm::PointerType::getUnqual(Ops[1]->getType()), 4636 "cast"); 4637 StoreInst *SI = Builder.CreateStore(Ops[1], BC); 4638 SI->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); 4639 4640 // If the operand is an integer, we can't assume alignment. Otherwise, 4641 // assume natural alignment. 4642 QualType ArgTy = E->getArg(1)->getType(); 4643 unsigned Align; 4644 if (ArgTy->isIntegerType()) 4645 Align = 1; 4646 else 4647 Align = getContext().getTypeSizeInChars(ArgTy).getQuantity(); 4648 SI->setAlignment(Align); 4649 return SI; 4650 } 4651 // 3DNow! 4652 case X86::BI__builtin_ia32_pswapdsf: 4653 case X86::BI__builtin_ia32_pswapdsi: { 4654 const char *name = 0; 4655 Intrinsic::ID ID = Intrinsic::not_intrinsic; 4656 switch(BuiltinID) { 4657 default: llvm_unreachable("Unsupported intrinsic!"); 4658 case X86::BI__builtin_ia32_pswapdsf: 4659 case X86::BI__builtin_ia32_pswapdsi: 4660 name = "pswapd"; 4661 ID = Intrinsic::x86_3dnowa_pswapd; 4662 break; 4663 } 4664 llvm::Type *MMXTy = llvm::Type::getX86_MMXTy(getLLVMContext()); 4665 Ops[0] = Builder.CreateBitCast(Ops[0], MMXTy, "cast"); 4666 llvm::Function *F = CGM.getIntrinsic(ID); 4667 return Builder.CreateCall(F, Ops, name); 4668 } 4669 case X86::BI__builtin_ia32_rdrand16_step: 4670 case X86::BI__builtin_ia32_rdrand32_step: 4671 case X86::BI__builtin_ia32_rdrand64_step: 4672 case X86::BI__builtin_ia32_rdseed16_step: 4673 case X86::BI__builtin_ia32_rdseed32_step: 4674 case X86::BI__builtin_ia32_rdseed64_step: { 4675 Intrinsic::ID ID; 4676 switch (BuiltinID) { 4677 default: llvm_unreachable("Unsupported intrinsic!"); 4678 case X86::BI__builtin_ia32_rdrand16_step: 4679 ID = Intrinsic::x86_rdrand_16; 4680 break; 4681 case X86::BI__builtin_ia32_rdrand32_step: 4682 ID = Intrinsic::x86_rdrand_32; 4683 break; 4684 case X86::BI__builtin_ia32_rdrand64_step: 4685 ID = Intrinsic::x86_rdrand_64; 4686 break; 4687 case X86::BI__builtin_ia32_rdseed16_step: 4688 ID = Intrinsic::x86_rdseed_16; 4689 break; 4690 case X86::BI__builtin_ia32_rdseed32_step: 4691 ID = Intrinsic::x86_rdseed_32; 4692 break; 4693 case X86::BI__builtin_ia32_rdseed64_step: 4694 ID = Intrinsic::x86_rdseed_64; 4695 break; 4696 } 4697 4698 Value *Call = Builder.CreateCall(CGM.getIntrinsic(ID)); 4699 Builder.CreateStore(Builder.CreateExtractValue(Call, 0), Ops[0]); 4700 return Builder.CreateExtractValue(Call, 1); 4701 } 4702 // AVX2 broadcast 4703 case X86::BI__builtin_ia32_vbroadcastsi256: { 4704 Value *VecTmp = CreateMemTemp(E->getArg(0)->getType()); 4705 Builder.CreateStore(Ops[0], VecTmp); 4706 Value *F = CGM.getIntrinsic(Intrinsic::x86_avx2_vbroadcasti128); 4707 return Builder.CreateCall(F, Builder.CreateBitCast(VecTmp, Int8PtrTy)); 4708 } 4709 } 4710 } 4711 4712 4713 Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, 4714 const CallExpr *E) { 4715 SmallVector<Value*, 4> Ops; 4716 4717 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) 4718 Ops.push_back(EmitScalarExpr(E->getArg(i))); 4719 4720 Intrinsic::ID ID = Intrinsic::not_intrinsic; 4721 4722 switch (BuiltinID) { 4723 default: return 0; 4724 4725 // vec_ld, vec_lvsl, vec_lvsr 4726 case PPC::BI__builtin_altivec_lvx: 4727 case PPC::BI__builtin_altivec_lvxl: 4728 case PPC::BI__builtin_altivec_lvebx: 4729 case PPC::BI__builtin_altivec_lvehx: 4730 case PPC::BI__builtin_altivec_lvewx: 4731 case PPC::BI__builtin_altivec_lvsl: 4732 case PPC::BI__builtin_altivec_lvsr: 4733 { 4734 Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy); 4735 4736 Ops[0] = Builder.CreateGEP(Ops[1], Ops[0]); 4737 Ops.pop_back(); 4738 4739 switch (BuiltinID) { 4740 default: llvm_unreachable("Unsupported ld/lvsl/lvsr intrinsic!"); 4741 case PPC::BI__builtin_altivec_lvx: 4742 ID = Intrinsic::ppc_altivec_lvx; 4743 break; 4744 case PPC::BI__builtin_altivec_lvxl: 4745 ID = Intrinsic::ppc_altivec_lvxl; 4746 break; 4747 case PPC::BI__builtin_altivec_lvebx: 4748 ID = Intrinsic::ppc_altivec_lvebx; 4749 break; 4750 case PPC::BI__builtin_altivec_lvehx: 4751 ID = Intrinsic::ppc_altivec_lvehx; 4752 break; 4753 case PPC::BI__builtin_altivec_lvewx: 4754 ID = Intrinsic::ppc_altivec_lvewx; 4755 break; 4756 case PPC::BI__builtin_altivec_lvsl: 4757 ID = Intrinsic::ppc_altivec_lvsl; 4758 break; 4759 case PPC::BI__builtin_altivec_lvsr: 4760 ID = Intrinsic::ppc_altivec_lvsr; 4761 break; 4762 } 4763 llvm::Function *F = CGM.getIntrinsic(ID); 4764 return Builder.CreateCall(F, Ops, ""); 4765 } 4766 4767 // vec_st 4768 case PPC::BI__builtin_altivec_stvx: 4769 case PPC::BI__builtin_altivec_stvxl: 4770 case PPC::BI__builtin_altivec_stvebx: 4771 case PPC::BI__builtin_altivec_stvehx: 4772 case PPC::BI__builtin_altivec_stvewx: 4773 { 4774 Ops[2] = Builder.CreateBitCast(Ops[2], Int8PtrTy); 4775 Ops[1] = Builder.CreateGEP(Ops[2], Ops[1]); 4776 Ops.pop_back(); 4777 4778 switch (BuiltinID) { 4779 default: llvm_unreachable("Unsupported st intrinsic!"); 4780 case PPC::BI__builtin_altivec_stvx: 4781 ID = Intrinsic::ppc_altivec_stvx; 4782 break; 4783 case PPC::BI__builtin_altivec_stvxl: 4784 ID = Intrinsic::ppc_altivec_stvxl; 4785 break; 4786 case PPC::BI__builtin_altivec_stvebx: 4787 ID = Intrinsic::ppc_altivec_stvebx; 4788 break; 4789 case PPC::BI__builtin_altivec_stvehx: 4790 ID = Intrinsic::ppc_altivec_stvehx; 4791 break; 4792 case PPC::BI__builtin_altivec_stvewx: 4793 ID = Intrinsic::ppc_altivec_stvewx; 4794 break; 4795 } 4796 llvm::Function *F = CGM.getIntrinsic(ID); 4797 return Builder.CreateCall(F, Ops, ""); 4798 } 4799 } 4800 } 4801