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::thumb: 1645 return EmitARMBuiltinExpr(BuiltinID, E); 1646 case llvm::Triple::x86: 1647 case llvm::Triple::x86_64: 1648 return EmitX86BuiltinExpr(BuiltinID, E); 1649 case llvm::Triple::ppc: 1650 case llvm::Triple::ppc64: 1651 case llvm::Triple::ppc64le: 1652 return EmitPPCBuiltinExpr(BuiltinID, E); 1653 default: 1654 return 0; 1655 } 1656 } 1657 1658 static llvm::VectorType *GetNeonType(CodeGenFunction *CGF, 1659 NeonTypeFlags TypeFlags, 1660 bool V1Ty=false) { 1661 int IsQuad = TypeFlags.isQuad(); 1662 switch (TypeFlags.getEltType()) { 1663 case NeonTypeFlags::Int8: 1664 case NeonTypeFlags::Poly8: 1665 return llvm::VectorType::get(CGF->Int8Ty, V1Ty ? 1 : (8 << IsQuad)); 1666 case NeonTypeFlags::Int16: 1667 case NeonTypeFlags::Poly16: 1668 case NeonTypeFlags::Float16: 1669 return llvm::VectorType::get(CGF->Int16Ty, V1Ty ? 1 : (4 << IsQuad)); 1670 case NeonTypeFlags::Int32: 1671 return llvm::VectorType::get(CGF->Int32Ty, V1Ty ? 1 : (2 << IsQuad)); 1672 case NeonTypeFlags::Int64: 1673 case NeonTypeFlags::Poly64: 1674 return llvm::VectorType::get(CGF->Int64Ty, V1Ty ? 1 : (1 << IsQuad)); 1675 case NeonTypeFlags::Poly128: 1676 // FIXME: i128 and f128 doesn't get fully support in Clang and llvm. 1677 // There is a lot of i128 and f128 API missing. 1678 // so we use v16i8 to represent poly128 and get pattern matched. 1679 return llvm::VectorType::get(CGF->Int8Ty, 16); 1680 case NeonTypeFlags::Float32: 1681 return llvm::VectorType::get(CGF->FloatTy, V1Ty ? 1 : (2 << IsQuad)); 1682 case NeonTypeFlags::Float64: 1683 return llvm::VectorType::get(CGF->DoubleTy, V1Ty ? 1 : (1 << IsQuad)); 1684 } 1685 llvm_unreachable("Unknown vector element type!"); 1686 } 1687 1688 Value *CodeGenFunction::EmitNeonSplat(Value *V, Constant *C) { 1689 unsigned nElts = cast<llvm::VectorType>(V->getType())->getNumElements(); 1690 Value* SV = llvm::ConstantVector::getSplat(nElts, C); 1691 return Builder.CreateShuffleVector(V, V, SV, "lane"); 1692 } 1693 1694 Value *CodeGenFunction::EmitNeonCall(Function *F, SmallVectorImpl<Value*> &Ops, 1695 const char *name, 1696 unsigned shift, bool rightshift) { 1697 unsigned j = 0; 1698 for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end(); 1699 ai != ae; ++ai, ++j) 1700 if (shift > 0 && shift == j) 1701 Ops[j] = EmitNeonShiftVector(Ops[j], ai->getType(), rightshift); 1702 else 1703 Ops[j] = Builder.CreateBitCast(Ops[j], ai->getType(), name); 1704 1705 return Builder.CreateCall(F, Ops, name); 1706 } 1707 1708 Value *CodeGenFunction::EmitNeonShiftVector(Value *V, llvm::Type *Ty, 1709 bool neg) { 1710 int SV = cast<ConstantInt>(V)->getSExtValue(); 1711 1712 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 1713 llvm::Constant *C = ConstantInt::get(VTy->getElementType(), neg ? -SV : SV); 1714 return llvm::ConstantVector::getSplat(VTy->getNumElements(), C); 1715 } 1716 1717 // \brief Right-shift a vector by a constant. 1718 Value *CodeGenFunction::EmitNeonRShiftImm(Value *Vec, Value *Shift, 1719 llvm::Type *Ty, bool usgn, 1720 const char *name) { 1721 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 1722 1723 int ShiftAmt = cast<ConstantInt>(Shift)->getSExtValue(); 1724 int EltSize = VTy->getScalarSizeInBits(); 1725 1726 Vec = Builder.CreateBitCast(Vec, Ty); 1727 1728 // lshr/ashr are undefined when the shift amount is equal to the vector 1729 // element size. 1730 if (ShiftAmt == EltSize) { 1731 if (usgn) { 1732 // Right-shifting an unsigned value by its size yields 0. 1733 llvm::Constant *Zero = ConstantInt::get(VTy->getElementType(), 0); 1734 return llvm::ConstantVector::getSplat(VTy->getNumElements(), Zero); 1735 } else { 1736 // Right-shifting a signed value by its size is equivalent 1737 // to a shift of size-1. 1738 --ShiftAmt; 1739 Shift = ConstantInt::get(VTy->getElementType(), ShiftAmt); 1740 } 1741 } 1742 1743 Shift = EmitNeonShiftVector(Shift, Ty, false); 1744 if (usgn) 1745 return Builder.CreateLShr(Vec, Shift, name); 1746 else 1747 return Builder.CreateAShr(Vec, Shift, name); 1748 } 1749 1750 /// GetPointeeAlignment - Given an expression with a pointer type, find the 1751 /// alignment of the type referenced by the pointer. Skip over implicit 1752 /// casts. 1753 std::pair<llvm::Value*, unsigned> 1754 CodeGenFunction::EmitPointerWithAlignment(const Expr *Addr) { 1755 assert(Addr->getType()->isPointerType()); 1756 Addr = Addr->IgnoreParens(); 1757 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Addr)) { 1758 if ((ICE->getCastKind() == CK_BitCast || ICE->getCastKind() == CK_NoOp) && 1759 ICE->getSubExpr()->getType()->isPointerType()) { 1760 std::pair<llvm::Value*, unsigned> Ptr = 1761 EmitPointerWithAlignment(ICE->getSubExpr()); 1762 Ptr.first = Builder.CreateBitCast(Ptr.first, 1763 ConvertType(Addr->getType())); 1764 return Ptr; 1765 } else if (ICE->getCastKind() == CK_ArrayToPointerDecay) { 1766 LValue LV = EmitLValue(ICE->getSubExpr()); 1767 unsigned Align = LV.getAlignment().getQuantity(); 1768 if (!Align) { 1769 // FIXME: Once LValues are fixed to always set alignment, 1770 // zap this code. 1771 QualType PtTy = ICE->getSubExpr()->getType(); 1772 if (!PtTy->isIncompleteType()) 1773 Align = getContext().getTypeAlignInChars(PtTy).getQuantity(); 1774 else 1775 Align = 1; 1776 } 1777 return std::make_pair(LV.getAddress(), Align); 1778 } 1779 } 1780 if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(Addr)) { 1781 if (UO->getOpcode() == UO_AddrOf) { 1782 LValue LV = EmitLValue(UO->getSubExpr()); 1783 unsigned Align = LV.getAlignment().getQuantity(); 1784 if (!Align) { 1785 // FIXME: Once LValues are fixed to always set alignment, 1786 // zap this code. 1787 QualType PtTy = UO->getSubExpr()->getType(); 1788 if (!PtTy->isIncompleteType()) 1789 Align = getContext().getTypeAlignInChars(PtTy).getQuantity(); 1790 else 1791 Align = 1; 1792 } 1793 return std::make_pair(LV.getAddress(), Align); 1794 } 1795 } 1796 1797 unsigned Align = 1; 1798 QualType PtTy = Addr->getType()->getPointeeType(); 1799 if (!PtTy->isIncompleteType()) 1800 Align = getContext().getTypeAlignInChars(PtTy).getQuantity(); 1801 1802 return std::make_pair(EmitScalarExpr(Addr), Align); 1803 } 1804 1805 enum { 1806 AddRetType = (1 << 0), 1807 Add1ArgType = (1 << 1), 1808 Add2ArgTypes = (1 << 2), 1809 1810 VectorizeRetType = (1 << 3), 1811 VectorizeArgTypes = (1 << 4), 1812 1813 InventFloatType = (1 << 5), 1814 UnsignedAlts = (1 << 6), 1815 1816 Vectorize1ArgType = Add1ArgType | VectorizeArgTypes, 1817 VectorRet = AddRetType | VectorizeRetType, 1818 VectorRetGetArgs01 = 1819 AddRetType | Add2ArgTypes | VectorizeRetType | VectorizeArgTypes, 1820 FpCmpzModifiers = 1821 AddRetType | VectorizeRetType | Add1ArgType | InventFloatType 1822 }; 1823 1824 struct NeonIntrinsicInfo { 1825 unsigned BuiltinID; 1826 unsigned LLVMIntrinsic; 1827 unsigned AltLLVMIntrinsic; 1828 const char *NameHint; 1829 unsigned TypeModifier; 1830 1831 bool operator<(unsigned RHSBuiltinID) const { 1832 return BuiltinID < RHSBuiltinID; 1833 } 1834 }; 1835 1836 #define NEONMAP0(NameBase) \ 1837 { NEON::BI__builtin_neon_ ## NameBase, 0, 0, #NameBase, 0 } 1838 1839 #define NEONMAP1(NameBase, LLVMIntrinsic, TypeModifier) \ 1840 { NEON:: BI__builtin_neon_ ## NameBase, \ 1841 Intrinsic::LLVMIntrinsic, 0, #NameBase, TypeModifier } 1842 1843 #define NEONMAP2(NameBase, LLVMIntrinsic, AltLLVMIntrinsic, TypeModifier) \ 1844 { NEON:: BI__builtin_neon_ ## NameBase, \ 1845 Intrinsic::LLVMIntrinsic, Intrinsic::AltLLVMIntrinsic, \ 1846 #NameBase, TypeModifier } 1847 1848 static const NeonIntrinsicInfo AArch64SISDIntrinsicInfo[] = { 1849 NEONMAP1(vabdd_f64, aarch64_neon_vabd, AddRetType), 1850 NEONMAP1(vabds_f32, aarch64_neon_vabd, AddRetType), 1851 NEONMAP1(vabsd_s64, aarch64_neon_vabs, 0), 1852 NEONMAP1(vaddd_s64, aarch64_neon_vaddds, 0), 1853 NEONMAP1(vaddd_u64, aarch64_neon_vadddu, 0), 1854 NEONMAP1(vaddlv_s16, aarch64_neon_saddlv, VectorRet | Add1ArgType), 1855 NEONMAP1(vaddlv_s32, aarch64_neon_saddlv, VectorRet | Add1ArgType), 1856 NEONMAP1(vaddlv_s8, aarch64_neon_saddlv, VectorRet | Add1ArgType), 1857 NEONMAP1(vaddlv_u16, aarch64_neon_uaddlv, VectorRet | Add1ArgType), 1858 NEONMAP1(vaddlv_u32, aarch64_neon_uaddlv, VectorRet | Add1ArgType), 1859 NEONMAP1(vaddlv_u8, aarch64_neon_uaddlv, VectorRet | Add1ArgType), 1860 NEONMAP1(vaddlvq_s16, aarch64_neon_saddlv, VectorRet | Add1ArgType), 1861 NEONMAP1(vaddlvq_s32, aarch64_neon_saddlv, VectorRet | Add1ArgType), 1862 NEONMAP1(vaddlvq_s8, aarch64_neon_saddlv, VectorRet | Add1ArgType), 1863 NEONMAP1(vaddlvq_u16, aarch64_neon_uaddlv, VectorRet | Add1ArgType), 1864 NEONMAP1(vaddlvq_u32, aarch64_neon_uaddlv, VectorRet | Add1ArgType), 1865 NEONMAP1(vaddlvq_u8, aarch64_neon_uaddlv, VectorRet | Add1ArgType), 1866 NEONMAP1(vaddv_f32, aarch64_neon_vpfadd, AddRetType | Add1ArgType), 1867 NEONMAP1(vaddv_s16, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1868 NEONMAP1(vaddv_s32, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1869 NEONMAP1(vaddv_s8, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1870 NEONMAP1(vaddv_u16, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1871 NEONMAP1(vaddv_u32, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1872 NEONMAP1(vaddv_u8, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1873 NEONMAP1(vaddvq_f32, aarch64_neon_vpfadd, AddRetType | Add1ArgType), 1874 NEONMAP1(vaddvq_f64, aarch64_neon_vpfadd, AddRetType | Add1ArgType), 1875 NEONMAP1(vaddvq_s16, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1876 NEONMAP1(vaddvq_s32, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1877 NEONMAP1(vaddvq_s64, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1878 NEONMAP1(vaddvq_s8, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1879 NEONMAP1(vaddvq_u16, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1880 NEONMAP1(vaddvq_u32, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1881 NEONMAP1(vaddvq_u64, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1882 NEONMAP1(vaddvq_u8, aarch64_neon_vaddv, VectorRet | Add1ArgType), 1883 NEONMAP1(vcaged_f64, aarch64_neon_fcage, VectorRet | Add2ArgTypes), 1884 NEONMAP1(vcages_f32, aarch64_neon_fcage, VectorRet | Add2ArgTypes), 1885 NEONMAP1(vcagtd_f64, aarch64_neon_fcagt, VectorRet | Add2ArgTypes), 1886 NEONMAP1(vcagts_f32, aarch64_neon_fcagt, VectorRet | Add2ArgTypes), 1887 NEONMAP1(vcaled_f64, aarch64_neon_fcage, VectorRet | Add2ArgTypes), 1888 NEONMAP1(vcales_f32, aarch64_neon_fcage, VectorRet | Add2ArgTypes), 1889 NEONMAP1(vcaltd_f64, aarch64_neon_fcagt, VectorRet | Add2ArgTypes), 1890 NEONMAP1(vcalts_f32, aarch64_neon_fcagt, VectorRet | Add2ArgTypes), 1891 NEONMAP1(vceqd_f64, aarch64_neon_fceq, VectorRet | Add2ArgTypes), 1892 NEONMAP1(vceqd_s64, aarch64_neon_vceq, VectorRetGetArgs01), 1893 NEONMAP1(vceqd_u64, aarch64_neon_vceq, VectorRetGetArgs01), 1894 NEONMAP1(vceqs_f32, aarch64_neon_fceq, VectorRet | Add2ArgTypes), 1895 NEONMAP1(vceqzd_f64, aarch64_neon_fceq, FpCmpzModifiers), 1896 NEONMAP1(vceqzd_s64, aarch64_neon_vceq, VectorRetGetArgs01), 1897 NEONMAP1(vceqzd_u64, aarch64_neon_vceq, VectorRetGetArgs01), 1898 NEONMAP1(vceqzs_f32, aarch64_neon_fceq, FpCmpzModifiers), 1899 NEONMAP1(vcged_f64, aarch64_neon_fcge, VectorRet | Add2ArgTypes), 1900 NEONMAP1(vcged_s64, aarch64_neon_vcge, VectorRetGetArgs01), 1901 NEONMAP1(vcged_u64, aarch64_neon_vchs, VectorRetGetArgs01), 1902 NEONMAP1(vcges_f32, aarch64_neon_fcge, VectorRet | Add2ArgTypes), 1903 NEONMAP1(vcgezd_f64, aarch64_neon_fcge, FpCmpzModifiers), 1904 NEONMAP1(vcgezd_s64, aarch64_neon_vcge, VectorRetGetArgs01), 1905 NEONMAP1(vcgezs_f32, aarch64_neon_fcge, FpCmpzModifiers), 1906 NEONMAP1(vcgtd_f64, aarch64_neon_fcgt, VectorRet | Add2ArgTypes), 1907 NEONMAP1(vcgtd_s64, aarch64_neon_vcgt, VectorRetGetArgs01), 1908 NEONMAP1(vcgtd_u64, aarch64_neon_vchi, VectorRetGetArgs01), 1909 NEONMAP1(vcgts_f32, aarch64_neon_fcgt, VectorRet | Add2ArgTypes), 1910 NEONMAP1(vcgtzd_f64, aarch64_neon_fcgt, FpCmpzModifiers), 1911 NEONMAP1(vcgtzd_s64, aarch64_neon_vcgt, VectorRetGetArgs01), 1912 NEONMAP1(vcgtzs_f32, aarch64_neon_fcgt, FpCmpzModifiers), 1913 NEONMAP1(vcled_f64, aarch64_neon_fcge, VectorRet | Add2ArgTypes), 1914 NEONMAP1(vcled_s64, aarch64_neon_vcge, VectorRetGetArgs01), 1915 NEONMAP1(vcled_u64, aarch64_neon_vchs, VectorRetGetArgs01), 1916 NEONMAP1(vcles_f32, aarch64_neon_fcge, VectorRet | Add2ArgTypes), 1917 NEONMAP1(vclezd_f64, aarch64_neon_fclez, FpCmpzModifiers), 1918 NEONMAP1(vclezd_s64, aarch64_neon_vclez, VectorRetGetArgs01), 1919 NEONMAP1(vclezs_f32, aarch64_neon_fclez, FpCmpzModifiers), 1920 NEONMAP1(vcltd_f64, aarch64_neon_fcgt, VectorRet | Add2ArgTypes), 1921 NEONMAP1(vcltd_s64, aarch64_neon_vcgt, VectorRetGetArgs01), 1922 NEONMAP1(vcltd_u64, aarch64_neon_vchi, VectorRetGetArgs01), 1923 NEONMAP1(vclts_f32, aarch64_neon_fcgt, VectorRet | Add2ArgTypes), 1924 NEONMAP1(vcltzd_f64, aarch64_neon_fcltz, FpCmpzModifiers), 1925 NEONMAP1(vcltzd_s64, aarch64_neon_vcltz, VectorRetGetArgs01), 1926 NEONMAP1(vcltzs_f32, aarch64_neon_fcltz, FpCmpzModifiers), 1927 NEONMAP1(vcvtad_s64_f64, aarch64_neon_fcvtas, VectorRet | Add1ArgType), 1928 NEONMAP1(vcvtad_u64_f64, aarch64_neon_fcvtau, VectorRet | Add1ArgType), 1929 NEONMAP1(vcvtas_s32_f32, aarch64_neon_fcvtas, VectorRet | Add1ArgType), 1930 NEONMAP1(vcvtas_u32_f32, aarch64_neon_fcvtau, VectorRet | Add1ArgType), 1931 NEONMAP1(vcvtd_f64_s64, aarch64_neon_vcvtint2fps, AddRetType | Vectorize1ArgType), 1932 NEONMAP1(vcvtd_f64_u64, aarch64_neon_vcvtint2fpu, AddRetType | Vectorize1ArgType), 1933 NEONMAP1(vcvtd_n_f64_s64, aarch64_neon_vcvtfxs2fp_n, AddRetType | Vectorize1ArgType), 1934 NEONMAP1(vcvtd_n_f64_u64, aarch64_neon_vcvtfxu2fp_n, AddRetType | Vectorize1ArgType), 1935 NEONMAP1(vcvtd_n_s64_f64, aarch64_neon_vcvtfp2fxs_n, VectorRet | Add1ArgType), 1936 NEONMAP1(vcvtd_n_u64_f64, aarch64_neon_vcvtfp2fxu_n, VectorRet | Add1ArgType), 1937 NEONMAP1(vcvtd_s64_f64, aarch64_neon_fcvtzs, VectorRet | Add1ArgType), 1938 NEONMAP1(vcvtd_u64_f64, aarch64_neon_fcvtzu, VectorRet | Add1ArgType), 1939 NEONMAP1(vcvtmd_s64_f64, aarch64_neon_fcvtms, VectorRet | Add1ArgType), 1940 NEONMAP1(vcvtmd_u64_f64, aarch64_neon_fcvtmu, VectorRet | Add1ArgType), 1941 NEONMAP1(vcvtms_s32_f32, aarch64_neon_fcvtms, VectorRet | Add1ArgType), 1942 NEONMAP1(vcvtms_u32_f32, aarch64_neon_fcvtmu, VectorRet | Add1ArgType), 1943 NEONMAP1(vcvtnd_s64_f64, aarch64_neon_fcvtns, VectorRet | Add1ArgType), 1944 NEONMAP1(vcvtnd_u64_f64, aarch64_neon_fcvtnu, VectorRet | Add1ArgType), 1945 NEONMAP1(vcvtns_s32_f32, aarch64_neon_fcvtns, VectorRet | Add1ArgType), 1946 NEONMAP1(vcvtns_u32_f32, aarch64_neon_fcvtnu, VectorRet | Add1ArgType), 1947 NEONMAP1(vcvtpd_s64_f64, aarch64_neon_fcvtps, VectorRet | Add1ArgType), 1948 NEONMAP1(vcvtpd_u64_f64, aarch64_neon_fcvtpu, VectorRet | Add1ArgType), 1949 NEONMAP1(vcvtps_s32_f32, aarch64_neon_fcvtps, VectorRet | Add1ArgType), 1950 NEONMAP1(vcvtps_u32_f32, aarch64_neon_fcvtpu, VectorRet | Add1ArgType), 1951 NEONMAP1(vcvts_f32_s32, aarch64_neon_vcvtint2fps, AddRetType | Vectorize1ArgType), 1952 NEONMAP1(vcvts_f32_u32, aarch64_neon_vcvtint2fpu, AddRetType | Vectorize1ArgType), 1953 NEONMAP1(vcvts_n_f32_s32, aarch64_neon_vcvtfxs2fp_n, AddRetType | Vectorize1ArgType), 1954 NEONMAP1(vcvts_n_f32_u32, aarch64_neon_vcvtfxu2fp_n, AddRetType | Vectorize1ArgType), 1955 NEONMAP1(vcvts_n_s32_f32, aarch64_neon_vcvtfp2fxs_n, VectorRet | Add1ArgType), 1956 NEONMAP1(vcvts_n_u32_f32, aarch64_neon_vcvtfp2fxu_n, VectorRet | Add1ArgType), 1957 NEONMAP1(vcvts_s32_f32, aarch64_neon_fcvtzs, VectorRet | Add1ArgType), 1958 NEONMAP1(vcvts_u32_f32, aarch64_neon_fcvtzu, VectorRet | Add1ArgType), 1959 NEONMAP1(vcvtxd_f32_f64, aarch64_neon_fcvtxn, 0), 1960 NEONMAP0(vdupb_lane_i8), 1961 NEONMAP0(vdupb_laneq_i8), 1962 NEONMAP0(vdupd_lane_f64), 1963 NEONMAP0(vdupd_lane_i64), 1964 NEONMAP0(vdupd_laneq_f64), 1965 NEONMAP0(vdupd_laneq_i64), 1966 NEONMAP0(vduph_lane_i16), 1967 NEONMAP0(vduph_laneq_i16), 1968 NEONMAP0(vdups_lane_f32), 1969 NEONMAP0(vdups_lane_i32), 1970 NEONMAP0(vdups_laneq_f32), 1971 NEONMAP0(vdups_laneq_i32), 1972 NEONMAP0(vfmad_lane_f64), 1973 NEONMAP0(vfmad_laneq_f64), 1974 NEONMAP0(vfmas_lane_f32), 1975 NEONMAP0(vfmas_laneq_f32), 1976 NEONMAP0(vget_lane_f32), 1977 NEONMAP0(vget_lane_f64), 1978 NEONMAP0(vget_lane_i16), 1979 NEONMAP0(vget_lane_i32), 1980 NEONMAP0(vget_lane_i64), 1981 NEONMAP0(vget_lane_i8), 1982 NEONMAP0(vgetq_lane_f32), 1983 NEONMAP0(vgetq_lane_f64), 1984 NEONMAP0(vgetq_lane_i16), 1985 NEONMAP0(vgetq_lane_i32), 1986 NEONMAP0(vgetq_lane_i64), 1987 NEONMAP0(vgetq_lane_i8), 1988 NEONMAP1(vmaxnmv_f32, aarch64_neon_vpfmaxnm, AddRetType | Add1ArgType), 1989 NEONMAP1(vmaxnmvq_f32, aarch64_neon_vmaxnmv, 0), 1990 NEONMAP1(vmaxnmvq_f64, aarch64_neon_vpfmaxnm, AddRetType | Add1ArgType), 1991 NEONMAP1(vmaxv_f32, aarch64_neon_vpmax, AddRetType | Add1ArgType), 1992 NEONMAP1(vmaxv_s16, aarch64_neon_smaxv, VectorRet | Add1ArgType), 1993 NEONMAP1(vmaxv_s32, aarch64_neon_smaxv, VectorRet | Add1ArgType), 1994 NEONMAP1(vmaxv_s8, aarch64_neon_smaxv, VectorRet | Add1ArgType), 1995 NEONMAP1(vmaxv_u16, aarch64_neon_umaxv, VectorRet | Add1ArgType), 1996 NEONMAP1(vmaxv_u32, aarch64_neon_umaxv, VectorRet | Add1ArgType), 1997 NEONMAP1(vmaxv_u8, aarch64_neon_umaxv, VectorRet | Add1ArgType), 1998 NEONMAP1(vmaxvq_f32, aarch64_neon_vmaxv, 0), 1999 NEONMAP1(vmaxvq_f64, aarch64_neon_vpmax, AddRetType | Add1ArgType), 2000 NEONMAP1(vmaxvq_s16, aarch64_neon_smaxv, VectorRet | Add1ArgType), 2001 NEONMAP1(vmaxvq_s32, aarch64_neon_smaxv, VectorRet | Add1ArgType), 2002 NEONMAP1(vmaxvq_s8, aarch64_neon_smaxv, VectorRet | Add1ArgType), 2003 NEONMAP1(vmaxvq_u16, aarch64_neon_umaxv, VectorRet | Add1ArgType), 2004 NEONMAP1(vmaxvq_u32, aarch64_neon_umaxv, VectorRet | Add1ArgType), 2005 NEONMAP1(vmaxvq_u8, aarch64_neon_umaxv, VectorRet | Add1ArgType), 2006 NEONMAP1(vminnmv_f32, aarch64_neon_vpfminnm, AddRetType | Add1ArgType), 2007 NEONMAP1(vminnmvq_f32, aarch64_neon_vminnmv, 0), 2008 NEONMAP1(vminnmvq_f64, aarch64_neon_vpfminnm, AddRetType | Add1ArgType), 2009 NEONMAP1(vminv_f32, aarch64_neon_vpmin, AddRetType | Add1ArgType), 2010 NEONMAP1(vminv_s16, aarch64_neon_sminv, VectorRet | Add1ArgType), 2011 NEONMAP1(vminv_s32, aarch64_neon_sminv, VectorRet | Add1ArgType), 2012 NEONMAP1(vminv_s8, aarch64_neon_sminv, VectorRet | Add1ArgType), 2013 NEONMAP1(vminv_u16, aarch64_neon_uminv, VectorRet | Add1ArgType), 2014 NEONMAP1(vminv_u32, aarch64_neon_uminv, VectorRet | Add1ArgType), 2015 NEONMAP1(vminv_u8, aarch64_neon_uminv, VectorRet | Add1ArgType), 2016 NEONMAP1(vminvq_f32, aarch64_neon_vminv, 0), 2017 NEONMAP1(vminvq_f64, aarch64_neon_vpmin, AddRetType | Add1ArgType), 2018 NEONMAP1(vminvq_s16, aarch64_neon_sminv, VectorRet | Add1ArgType), 2019 NEONMAP1(vminvq_s32, aarch64_neon_sminv, VectorRet | Add1ArgType), 2020 NEONMAP1(vminvq_s8, aarch64_neon_sminv, VectorRet | Add1ArgType), 2021 NEONMAP1(vminvq_u16, aarch64_neon_uminv, VectorRet | Add1ArgType), 2022 NEONMAP1(vminvq_u32, aarch64_neon_uminv, VectorRet | Add1ArgType), 2023 NEONMAP1(vminvq_u8, aarch64_neon_uminv, VectorRet | Add1ArgType), 2024 NEONMAP0(vmul_n_f64), 2025 NEONMAP1(vmull_p64, aarch64_neon_vmull_p64, 0), 2026 NEONMAP0(vmulxd_f64), 2027 NEONMAP0(vmulxs_f32), 2028 NEONMAP1(vnegd_s64, aarch64_neon_vneg, 0), 2029 NEONMAP1(vpaddd_f64, aarch64_neon_vpfadd, AddRetType | Add1ArgType), 2030 NEONMAP1(vpaddd_s64, aarch64_neon_vpadd, 0), 2031 NEONMAP1(vpaddd_u64, aarch64_neon_vpadd, 0), 2032 NEONMAP1(vpadds_f32, aarch64_neon_vpfadd, AddRetType | Add1ArgType), 2033 NEONMAP1(vpmaxnmqd_f64, aarch64_neon_vpfmaxnm, AddRetType | Add1ArgType), 2034 NEONMAP1(vpmaxnms_f32, aarch64_neon_vpfmaxnm, AddRetType | Add1ArgType), 2035 NEONMAP1(vpmaxqd_f64, aarch64_neon_vpmax, AddRetType | Add1ArgType), 2036 NEONMAP1(vpmaxs_f32, aarch64_neon_vpmax, AddRetType | Add1ArgType), 2037 NEONMAP1(vpminnmqd_f64, aarch64_neon_vpfminnm, AddRetType | Add1ArgType), 2038 NEONMAP1(vpminnms_f32, aarch64_neon_vpfminnm, AddRetType | Add1ArgType), 2039 NEONMAP1(vpminqd_f64, aarch64_neon_vpmin, AddRetType | Add1ArgType), 2040 NEONMAP1(vpmins_f32, aarch64_neon_vpmin, AddRetType | Add1ArgType), 2041 NEONMAP1(vqabsb_s8, arm_neon_vqabs, VectorRet), 2042 NEONMAP1(vqabsd_s64, arm_neon_vqabs, VectorRet), 2043 NEONMAP1(vqabsh_s16, arm_neon_vqabs, VectorRet), 2044 NEONMAP1(vqabss_s32, arm_neon_vqabs, VectorRet), 2045 NEONMAP1(vqaddb_s8, arm_neon_vqadds, VectorRet), 2046 NEONMAP1(vqaddb_u8, arm_neon_vqaddu, VectorRet), 2047 NEONMAP1(vqaddd_s64, arm_neon_vqadds, VectorRet), 2048 NEONMAP1(vqaddd_u64, arm_neon_vqaddu, VectorRet), 2049 NEONMAP1(vqaddh_s16, arm_neon_vqadds, VectorRet), 2050 NEONMAP1(vqaddh_u16, arm_neon_vqaddu, VectorRet), 2051 NEONMAP1(vqadds_s32, arm_neon_vqadds, VectorRet), 2052 NEONMAP1(vqadds_u32, arm_neon_vqaddu, VectorRet), 2053 NEONMAP0(vqdmlalh_lane_s16), 2054 NEONMAP0(vqdmlalh_laneq_s16), 2055 NEONMAP1(vqdmlalh_s16, aarch64_neon_vqdmlal, VectorRet), 2056 NEONMAP0(vqdmlals_lane_s32), 2057 NEONMAP0(vqdmlals_laneq_s32), 2058 NEONMAP1(vqdmlals_s32, aarch64_neon_vqdmlal, VectorRet), 2059 NEONMAP0(vqdmlslh_lane_s16), 2060 NEONMAP0(vqdmlslh_laneq_s16), 2061 NEONMAP1(vqdmlslh_s16, aarch64_neon_vqdmlsl, VectorRet), 2062 NEONMAP0(vqdmlsls_lane_s32), 2063 NEONMAP0(vqdmlsls_laneq_s32), 2064 NEONMAP1(vqdmlsls_s32, aarch64_neon_vqdmlsl, VectorRet), 2065 NEONMAP1(vqdmulhh_s16, arm_neon_vqdmulh, VectorRet), 2066 NEONMAP1(vqdmulhs_s32, arm_neon_vqdmulh, VectorRet), 2067 NEONMAP1(vqdmullh_s16, arm_neon_vqdmull, VectorRet), 2068 NEONMAP1(vqdmulls_s32, arm_neon_vqdmull, VectorRet), 2069 NEONMAP1(vqmovnd_s64, arm_neon_vqmovns, VectorRet), 2070 NEONMAP1(vqmovnd_u64, arm_neon_vqmovnu, VectorRet), 2071 NEONMAP1(vqmovnh_s16, arm_neon_vqmovns, VectorRet), 2072 NEONMAP1(vqmovnh_u16, arm_neon_vqmovnu, VectorRet), 2073 NEONMAP1(vqmovns_s32, arm_neon_vqmovns, VectorRet), 2074 NEONMAP1(vqmovns_u32, arm_neon_vqmovnu, VectorRet), 2075 NEONMAP1(vqmovund_s64, arm_neon_vqmovnsu, VectorRet), 2076 NEONMAP1(vqmovunh_s16, arm_neon_vqmovnsu, VectorRet), 2077 NEONMAP1(vqmovuns_s32, arm_neon_vqmovnsu, VectorRet), 2078 NEONMAP1(vqnegb_s8, arm_neon_vqneg, VectorRet), 2079 NEONMAP1(vqnegd_s64, arm_neon_vqneg, VectorRet), 2080 NEONMAP1(vqnegh_s16, arm_neon_vqneg, VectorRet), 2081 NEONMAP1(vqnegs_s32, arm_neon_vqneg, VectorRet), 2082 NEONMAP1(vqrdmulhh_s16, arm_neon_vqrdmulh, VectorRet), 2083 NEONMAP1(vqrdmulhs_s32, arm_neon_vqrdmulh, VectorRet), 2084 NEONMAP1(vqrshlb_s8, aarch64_neon_vqrshls, VectorRet), 2085 NEONMAP1(vqrshlb_u8, aarch64_neon_vqrshlu, VectorRet), 2086 NEONMAP1(vqrshld_s64, aarch64_neon_vqrshls, VectorRet), 2087 NEONMAP1(vqrshld_u64, aarch64_neon_vqrshlu, VectorRet), 2088 NEONMAP1(vqrshlh_s16, aarch64_neon_vqrshls, VectorRet), 2089 NEONMAP1(vqrshlh_u16, aarch64_neon_vqrshlu, VectorRet), 2090 NEONMAP1(vqrshls_s32, aarch64_neon_vqrshls, VectorRet), 2091 NEONMAP1(vqrshls_u32, aarch64_neon_vqrshlu, VectorRet), 2092 NEONMAP1(vqrshrnd_n_s64, aarch64_neon_vsqrshrn, VectorRet), 2093 NEONMAP1(vqrshrnd_n_u64, aarch64_neon_vuqrshrn, VectorRet), 2094 NEONMAP1(vqrshrnh_n_s16, aarch64_neon_vsqrshrn, VectorRet), 2095 NEONMAP1(vqrshrnh_n_u16, aarch64_neon_vuqrshrn, VectorRet), 2096 NEONMAP1(vqrshrns_n_s32, aarch64_neon_vsqrshrn, VectorRet), 2097 NEONMAP1(vqrshrns_n_u32, aarch64_neon_vuqrshrn, VectorRet), 2098 NEONMAP1(vqrshrund_n_s64, aarch64_neon_vsqrshrun, VectorRet), 2099 NEONMAP1(vqrshrunh_n_s16, aarch64_neon_vsqrshrun, VectorRet), 2100 NEONMAP1(vqrshruns_n_s32, aarch64_neon_vsqrshrun, VectorRet), 2101 NEONMAP1(vqshlb_n_s8, aarch64_neon_vqshls_n, VectorRet), 2102 NEONMAP1(vqshlb_n_u8, aarch64_neon_vqshlu_n, VectorRet), 2103 NEONMAP1(vqshlb_s8, aarch64_neon_vqshls, VectorRet), 2104 NEONMAP1(vqshlb_u8, aarch64_neon_vqshlu, VectorRet), 2105 NEONMAP1(vqshld_n_s64, aarch64_neon_vqshls_n, VectorRet), 2106 NEONMAP1(vqshld_n_u64, aarch64_neon_vqshlu_n, VectorRet), 2107 NEONMAP1(vqshld_s64, aarch64_neon_vqshls, VectorRet), 2108 NEONMAP1(vqshld_u64, aarch64_neon_vqshlu, VectorRet), 2109 NEONMAP1(vqshlh_n_s16, aarch64_neon_vqshls_n, VectorRet), 2110 NEONMAP1(vqshlh_n_u16, aarch64_neon_vqshlu_n, VectorRet), 2111 NEONMAP1(vqshlh_s16, aarch64_neon_vqshls, VectorRet), 2112 NEONMAP1(vqshlh_u16, aarch64_neon_vqshlu, VectorRet), 2113 NEONMAP1(vqshls_n_s32, aarch64_neon_vqshls_n, VectorRet), 2114 NEONMAP1(vqshls_n_u32, aarch64_neon_vqshlu_n, VectorRet), 2115 NEONMAP1(vqshls_s32, aarch64_neon_vqshls, VectorRet), 2116 NEONMAP1(vqshls_u32, aarch64_neon_vqshlu, VectorRet), 2117 NEONMAP1(vqshlub_n_s8, aarch64_neon_vsqshlu, VectorRet), 2118 NEONMAP1(vqshlud_n_s64, aarch64_neon_vsqshlu, VectorRet), 2119 NEONMAP1(vqshluh_n_s16, aarch64_neon_vsqshlu, VectorRet), 2120 NEONMAP1(vqshlus_n_s32, aarch64_neon_vsqshlu, VectorRet), 2121 NEONMAP1(vqshrnd_n_s64, aarch64_neon_vsqshrn, VectorRet), 2122 NEONMAP1(vqshrnd_n_u64, aarch64_neon_vuqshrn, VectorRet), 2123 NEONMAP1(vqshrnh_n_s16, aarch64_neon_vsqshrn, VectorRet), 2124 NEONMAP1(vqshrnh_n_u16, aarch64_neon_vuqshrn, VectorRet), 2125 NEONMAP1(vqshrns_n_s32, aarch64_neon_vsqshrn, VectorRet), 2126 NEONMAP1(vqshrns_n_u32, aarch64_neon_vuqshrn, VectorRet), 2127 NEONMAP1(vqshrund_n_s64, aarch64_neon_vsqshrun, VectorRet), 2128 NEONMAP1(vqshrunh_n_s16, aarch64_neon_vsqshrun, VectorRet), 2129 NEONMAP1(vqshruns_n_s32, aarch64_neon_vsqshrun, VectorRet), 2130 NEONMAP1(vqsubb_s8, arm_neon_vqsubs, VectorRet), 2131 NEONMAP1(vqsubb_u8, arm_neon_vqsubu, VectorRet), 2132 NEONMAP1(vqsubd_s64, arm_neon_vqsubs, VectorRet), 2133 NEONMAP1(vqsubd_u64, arm_neon_vqsubu, VectorRet), 2134 NEONMAP1(vqsubh_s16, arm_neon_vqsubs, VectorRet), 2135 NEONMAP1(vqsubh_u16, arm_neon_vqsubu, VectorRet), 2136 NEONMAP1(vqsubs_s32, arm_neon_vqsubs, VectorRet), 2137 NEONMAP1(vqsubs_u32, arm_neon_vqsubu, VectorRet), 2138 NEONMAP1(vrecped_f64, aarch64_neon_vrecpe, AddRetType), 2139 NEONMAP1(vrecpes_f32, aarch64_neon_vrecpe, AddRetType), 2140 NEONMAP1(vrecpsd_f64, aarch64_neon_vrecps, AddRetType), 2141 NEONMAP1(vrecpss_f32, aarch64_neon_vrecps, AddRetType), 2142 NEONMAP1(vrecpxd_f64, aarch64_neon_vrecpx, AddRetType), 2143 NEONMAP1(vrecpxs_f32, aarch64_neon_vrecpx, AddRetType), 2144 NEONMAP1(vrshld_s64, aarch64_neon_vrshlds, 0), 2145 NEONMAP1(vrshld_u64, aarch64_neon_vrshldu, 0), 2146 NEONMAP1(vrshrd_n_s64, aarch64_neon_vsrshr, VectorRet), 2147 NEONMAP1(vrshrd_n_u64, aarch64_neon_vurshr, VectorRet), 2148 NEONMAP1(vrsqrted_f64, aarch64_neon_vrsqrte, AddRetType), 2149 NEONMAP1(vrsqrtes_f32, aarch64_neon_vrsqrte, AddRetType), 2150 NEONMAP1(vrsqrtsd_f64, aarch64_neon_vrsqrts, AddRetType), 2151 NEONMAP1(vrsqrtss_f32, aarch64_neon_vrsqrts, AddRetType), 2152 NEONMAP1(vrsrad_n_s64, aarch64_neon_vrsrads_n, 0), 2153 NEONMAP1(vrsrad_n_u64, aarch64_neon_vrsradu_n, 0), 2154 NEONMAP0(vset_lane_f32), 2155 NEONMAP0(vset_lane_f64), 2156 NEONMAP0(vset_lane_i16), 2157 NEONMAP0(vset_lane_i32), 2158 NEONMAP0(vset_lane_i64), 2159 NEONMAP0(vset_lane_i8), 2160 NEONMAP0(vsetq_lane_f32), 2161 NEONMAP0(vsetq_lane_f64), 2162 NEONMAP0(vsetq_lane_i16), 2163 NEONMAP0(vsetq_lane_i32), 2164 NEONMAP0(vsetq_lane_i64), 2165 NEONMAP0(vsetq_lane_i8), 2166 NEONMAP1(vsha1cq_u32, arm_neon_sha1c, 0), 2167 NEONMAP1(vsha1h_u32, arm_neon_sha1h, 0), 2168 NEONMAP1(vsha1mq_u32, arm_neon_sha1m, 0), 2169 NEONMAP1(vsha1pq_u32, arm_neon_sha1p, 0), 2170 NEONMAP1(vshld_n_s64, aarch64_neon_vshld_n, 0), 2171 NEONMAP1(vshld_n_u64, aarch64_neon_vshld_n, 0), 2172 NEONMAP1(vshld_s64, aarch64_neon_vshlds, 0), 2173 NEONMAP1(vshld_u64, aarch64_neon_vshldu, 0), 2174 NEONMAP1(vshrd_n_s64, aarch64_neon_vshrds_n, 0), 2175 NEONMAP1(vshrd_n_u64, aarch64_neon_vshrdu_n, 0), 2176 NEONMAP1(vslid_n_s64, aarch64_neon_vsli, VectorRet), 2177 NEONMAP1(vslid_n_u64, aarch64_neon_vsli, VectorRet), 2178 NEONMAP1(vsqaddb_u8, aarch64_neon_vsqadd, VectorRet), 2179 NEONMAP1(vsqaddd_u64, aarch64_neon_vsqadd, VectorRet), 2180 NEONMAP1(vsqaddh_u16, aarch64_neon_vsqadd, VectorRet), 2181 NEONMAP1(vsqadds_u32, aarch64_neon_vsqadd, VectorRet), 2182 NEONMAP1(vsrad_n_s64, aarch64_neon_vsrads_n, 0), 2183 NEONMAP1(vsrad_n_u64, aarch64_neon_vsradu_n, 0), 2184 NEONMAP1(vsrid_n_s64, aarch64_neon_vsri, VectorRet), 2185 NEONMAP1(vsrid_n_u64, aarch64_neon_vsri, VectorRet), 2186 NEONMAP1(vsubd_s64, aarch64_neon_vsubds, 0), 2187 NEONMAP1(vsubd_u64, aarch64_neon_vsubdu, 0), 2188 NEONMAP1(vtstd_s64, aarch64_neon_vtstd, VectorRetGetArgs01), 2189 NEONMAP1(vtstd_u64, aarch64_neon_vtstd, VectorRetGetArgs01), 2190 NEONMAP1(vuqaddb_s8, aarch64_neon_vuqadd, VectorRet), 2191 NEONMAP1(vuqaddd_s64, aarch64_neon_vuqadd, VectorRet), 2192 NEONMAP1(vuqaddh_s16, aarch64_neon_vuqadd, VectorRet), 2193 NEONMAP1(vuqadds_s32, aarch64_neon_vuqadd, VectorRet) 2194 }; 2195 2196 static NeonIntrinsicInfo ARMSIMDIntrinsicMap [] = { 2197 NEONMAP2(vabd_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts), 2198 NEONMAP2(vabdq_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts), 2199 NEONMAP1(vabs_v, arm_neon_vabs, 0), 2200 NEONMAP1(vabsq_v, arm_neon_vabs, 0), 2201 NEONMAP0(vaddhn_v), 2202 NEONMAP1(vaesdq_v, arm_neon_aesd, 0), 2203 NEONMAP1(vaeseq_v, arm_neon_aese, 0), 2204 NEONMAP1(vaesimcq_v, arm_neon_aesimc, 0), 2205 NEONMAP1(vaesmcq_v, arm_neon_aesmc, 0), 2206 NEONMAP1(vbsl_v, arm_neon_vbsl, AddRetType), 2207 NEONMAP1(vbslq_v, arm_neon_vbsl, AddRetType), 2208 NEONMAP1(vcage_v, arm_neon_vacge, 0), 2209 NEONMAP1(vcageq_v, arm_neon_vacge, 0), 2210 NEONMAP1(vcagt_v, arm_neon_vacgt, 0), 2211 NEONMAP1(vcagtq_v, arm_neon_vacgt, 0), 2212 NEONMAP1(vcale_v, arm_neon_vacge, 0), 2213 NEONMAP1(vcaleq_v, arm_neon_vacge, 0), 2214 NEONMAP1(vcalt_v, arm_neon_vacgt, 0), 2215 NEONMAP1(vcaltq_v, arm_neon_vacgt, 0), 2216 NEONMAP1(vcls_v, arm_neon_vcls, Add1ArgType), 2217 NEONMAP1(vclsq_v, arm_neon_vcls, Add1ArgType), 2218 NEONMAP1(vclz_v, ctlz, Add1ArgType), 2219 NEONMAP1(vclzq_v, ctlz, Add1ArgType), 2220 NEONMAP1(vcnt_v, ctpop, Add1ArgType), 2221 NEONMAP1(vcntq_v, ctpop, Add1ArgType), 2222 NEONMAP1(vcvt_f16_v, arm_neon_vcvtfp2hf, 0), 2223 NEONMAP1(vcvt_f32_f16, arm_neon_vcvthf2fp, 0), 2224 NEONMAP0(vcvt_f32_v), 2225 NEONMAP2(vcvt_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0), 2226 NEONMAP1(vcvt_n_s32_v, arm_neon_vcvtfp2fxs, 0), 2227 NEONMAP1(vcvt_n_s64_v, arm_neon_vcvtfp2fxs, 0), 2228 NEONMAP1(vcvt_n_u32_v, arm_neon_vcvtfp2fxu, 0), 2229 NEONMAP1(vcvt_n_u64_v, arm_neon_vcvtfp2fxu, 0), 2230 NEONMAP0(vcvt_s32_v), 2231 NEONMAP0(vcvt_s64_v), 2232 NEONMAP0(vcvt_u32_v), 2233 NEONMAP0(vcvt_u64_v), 2234 NEONMAP1(vcvta_s32_v, arm_neon_vcvtas, 0), 2235 NEONMAP1(vcvta_s64_v, arm_neon_vcvtas, 0), 2236 NEONMAP1(vcvta_u32_v, arm_neon_vcvtau, 0), 2237 NEONMAP1(vcvta_u64_v, arm_neon_vcvtau, 0), 2238 NEONMAP1(vcvtaq_s32_v, arm_neon_vcvtas, 0), 2239 NEONMAP1(vcvtaq_s64_v, arm_neon_vcvtas, 0), 2240 NEONMAP1(vcvtaq_u32_v, arm_neon_vcvtau, 0), 2241 NEONMAP1(vcvtaq_u64_v, arm_neon_vcvtau, 0), 2242 NEONMAP1(vcvtm_s32_v, arm_neon_vcvtms, 0), 2243 NEONMAP1(vcvtm_s64_v, arm_neon_vcvtms, 0), 2244 NEONMAP1(vcvtm_u32_v, arm_neon_vcvtmu, 0), 2245 NEONMAP1(vcvtm_u64_v, arm_neon_vcvtmu, 0), 2246 NEONMAP1(vcvtmq_s32_v, arm_neon_vcvtms, 0), 2247 NEONMAP1(vcvtmq_s64_v, arm_neon_vcvtms, 0), 2248 NEONMAP1(vcvtmq_u32_v, arm_neon_vcvtmu, 0), 2249 NEONMAP1(vcvtmq_u64_v, arm_neon_vcvtmu, 0), 2250 NEONMAP1(vcvtn_s32_v, arm_neon_vcvtns, 0), 2251 NEONMAP1(vcvtn_s64_v, arm_neon_vcvtns, 0), 2252 NEONMAP1(vcvtn_u32_v, arm_neon_vcvtnu, 0), 2253 NEONMAP1(vcvtn_u64_v, arm_neon_vcvtnu, 0), 2254 NEONMAP1(vcvtnq_s32_v, arm_neon_vcvtns, 0), 2255 NEONMAP1(vcvtnq_s64_v, arm_neon_vcvtns, 0), 2256 NEONMAP1(vcvtnq_u32_v, arm_neon_vcvtnu, 0), 2257 NEONMAP1(vcvtnq_u64_v, arm_neon_vcvtnu, 0), 2258 NEONMAP1(vcvtp_s32_v, arm_neon_vcvtps, 0), 2259 NEONMAP1(vcvtp_s64_v, arm_neon_vcvtps, 0), 2260 NEONMAP1(vcvtp_u32_v, arm_neon_vcvtpu, 0), 2261 NEONMAP1(vcvtp_u64_v, arm_neon_vcvtpu, 0), 2262 NEONMAP1(vcvtpq_s32_v, arm_neon_vcvtps, 0), 2263 NEONMAP1(vcvtpq_s64_v, arm_neon_vcvtps, 0), 2264 NEONMAP1(vcvtpq_u32_v, arm_neon_vcvtpu, 0), 2265 NEONMAP1(vcvtpq_u64_v, arm_neon_vcvtpu, 0), 2266 NEONMAP0(vcvtq_f32_v), 2267 NEONMAP2(vcvtq_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0), 2268 NEONMAP1(vcvtq_n_s32_v, arm_neon_vcvtfp2fxs, 0), 2269 NEONMAP1(vcvtq_n_s64_v, arm_neon_vcvtfp2fxs, 0), 2270 NEONMAP1(vcvtq_n_u32_v, arm_neon_vcvtfp2fxu, 0), 2271 NEONMAP1(vcvtq_n_u64_v, arm_neon_vcvtfp2fxu, 0), 2272 NEONMAP0(vcvtq_s32_v), 2273 NEONMAP0(vcvtq_s64_v), 2274 NEONMAP0(vcvtq_u32_v), 2275 NEONMAP0(vcvtq_u64_v), 2276 NEONMAP0(vext_v), 2277 NEONMAP0(vextq_v), 2278 NEONMAP0(vfma_v), 2279 NEONMAP0(vfmaq_v), 2280 NEONMAP2(vhadd_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts), 2281 NEONMAP2(vhaddq_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts), 2282 NEONMAP2(vhsub_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts), 2283 NEONMAP2(vhsubq_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts), 2284 NEONMAP0(vld1_dup_v), 2285 NEONMAP1(vld1_v, arm_neon_vld1, 0), 2286 NEONMAP0(vld1q_dup_v), 2287 NEONMAP1(vld1q_v, arm_neon_vld1, 0), 2288 NEONMAP1(vld2_lane_v, arm_neon_vld2lane, 0), 2289 NEONMAP1(vld2_v, arm_neon_vld2, 0), 2290 NEONMAP1(vld2q_lane_v, arm_neon_vld2lane, 0), 2291 NEONMAP1(vld2q_v, arm_neon_vld2, 0), 2292 NEONMAP1(vld3_lane_v, arm_neon_vld3lane, 0), 2293 NEONMAP1(vld3_v, arm_neon_vld3, 0), 2294 NEONMAP1(vld3q_lane_v, arm_neon_vld3lane, 0), 2295 NEONMAP1(vld3q_v, arm_neon_vld3, 0), 2296 NEONMAP1(vld4_lane_v, arm_neon_vld4lane, 0), 2297 NEONMAP1(vld4_v, arm_neon_vld4, 0), 2298 NEONMAP1(vld4q_lane_v, arm_neon_vld4lane, 0), 2299 NEONMAP1(vld4q_v, arm_neon_vld4, 0), 2300 NEONMAP2(vmax_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts), 2301 NEONMAP2(vmaxq_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts), 2302 NEONMAP2(vmin_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts), 2303 NEONMAP2(vminq_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts), 2304 NEONMAP0(vmovl_v), 2305 NEONMAP0(vmovn_v), 2306 NEONMAP1(vmul_v, arm_neon_vmulp, Add1ArgType), 2307 NEONMAP0(vmull_v), 2308 NEONMAP1(vmulq_v, arm_neon_vmulp, Add1ArgType), 2309 NEONMAP2(vpadal_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts), 2310 NEONMAP2(vpadalq_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts), 2311 NEONMAP1(vpadd_v, arm_neon_vpadd, Add1ArgType), 2312 NEONMAP2(vpaddl_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts), 2313 NEONMAP2(vpaddlq_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts), 2314 NEONMAP1(vpaddq_v, arm_neon_vpadd, Add1ArgType), 2315 NEONMAP2(vpmax_v, arm_neon_vpmaxu, arm_neon_vpmaxs, Add1ArgType | UnsignedAlts), 2316 NEONMAP2(vpmin_v, arm_neon_vpminu, arm_neon_vpmins, Add1ArgType | UnsignedAlts), 2317 NEONMAP1(vqabs_v, arm_neon_vqabs, Add1ArgType), 2318 NEONMAP1(vqabsq_v, arm_neon_vqabs, Add1ArgType), 2319 NEONMAP2(vqadd_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts), 2320 NEONMAP2(vqaddq_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts), 2321 NEONMAP2(vqdmlal_v, arm_neon_vqdmull, arm_neon_vqadds, 0), 2322 NEONMAP2(vqdmlsl_v, arm_neon_vqdmull, arm_neon_vqsubs, 0), 2323 NEONMAP1(vqdmulh_v, arm_neon_vqdmulh, Add1ArgType), 2324 NEONMAP1(vqdmulhq_v, arm_neon_vqdmulh, Add1ArgType), 2325 NEONMAP1(vqdmull_v, arm_neon_vqdmull, Add1ArgType), 2326 NEONMAP2(vqmovn_v, arm_neon_vqmovnu, arm_neon_vqmovns, Add1ArgType | UnsignedAlts), 2327 NEONMAP1(vqmovun_v, arm_neon_vqmovnsu, Add1ArgType), 2328 NEONMAP1(vqneg_v, arm_neon_vqneg, Add1ArgType), 2329 NEONMAP1(vqnegq_v, arm_neon_vqneg, Add1ArgType), 2330 NEONMAP1(vqrdmulh_v, arm_neon_vqrdmulh, Add1ArgType), 2331 NEONMAP1(vqrdmulhq_v, arm_neon_vqrdmulh, Add1ArgType), 2332 NEONMAP2(vqrshl_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts), 2333 NEONMAP2(vqrshlq_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts), 2334 NEONMAP2(vqshl_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts), 2335 NEONMAP2(vqshl_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts), 2336 NEONMAP2(vqshlq_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts), 2337 NEONMAP2(vqshlq_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts), 2338 NEONMAP2(vqsub_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts), 2339 NEONMAP2(vqsubq_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts), 2340 NEONMAP1(vraddhn_v, arm_neon_vraddhn, Add1ArgType), 2341 NEONMAP2(vrecpe_v, arm_neon_vrecpe, arm_neon_vrecpe, 0), 2342 NEONMAP2(vrecpeq_v, arm_neon_vrecpe, arm_neon_vrecpe, 0), 2343 NEONMAP1(vrecps_v, arm_neon_vrecps, Add1ArgType), 2344 NEONMAP1(vrecpsq_v, arm_neon_vrecps, Add1ArgType), 2345 NEONMAP2(vrhadd_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts), 2346 NEONMAP2(vrhaddq_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts), 2347 NEONMAP2(vrshl_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts), 2348 NEONMAP2(vrshlq_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts), 2349 NEONMAP2(vrsqrte_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0), 2350 NEONMAP2(vrsqrteq_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0), 2351 NEONMAP1(vrsqrts_v, arm_neon_vrsqrts, Add1ArgType), 2352 NEONMAP1(vrsqrtsq_v, arm_neon_vrsqrts, Add1ArgType), 2353 NEONMAP1(vrsubhn_v, arm_neon_vrsubhn, Add1ArgType), 2354 NEONMAP1(vsha1su0q_v, arm_neon_sha1su0, 0), 2355 NEONMAP1(vsha1su1q_v, arm_neon_sha1su1, 0), 2356 NEONMAP1(vsha256h2q_v, arm_neon_sha256h2, 0), 2357 NEONMAP1(vsha256hq_v, arm_neon_sha256h, 0), 2358 NEONMAP1(vsha256su0q_v, arm_neon_sha256su0, 0), 2359 NEONMAP1(vsha256su1q_v, arm_neon_sha256su1, 0), 2360 NEONMAP0(vshl_n_v), 2361 NEONMAP2(vshl_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts), 2362 NEONMAP0(vshll_n_v), 2363 NEONMAP0(vshlq_n_v), 2364 NEONMAP2(vshlq_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts), 2365 NEONMAP0(vshr_n_v), 2366 NEONMAP0(vshrn_n_v), 2367 NEONMAP0(vshrq_n_v), 2368 NEONMAP1(vst1_v, arm_neon_vst1, 0), 2369 NEONMAP1(vst1q_v, arm_neon_vst1, 0), 2370 NEONMAP1(vst2_lane_v, arm_neon_vst2lane, 0), 2371 NEONMAP1(vst2_v, arm_neon_vst2, 0), 2372 NEONMAP1(vst2q_lane_v, arm_neon_vst2lane, 0), 2373 NEONMAP1(vst2q_v, arm_neon_vst2, 0), 2374 NEONMAP1(vst3_lane_v, arm_neon_vst3lane, 0), 2375 NEONMAP1(vst3_v, arm_neon_vst3, 0), 2376 NEONMAP1(vst3q_lane_v, arm_neon_vst3lane, 0), 2377 NEONMAP1(vst3q_v, arm_neon_vst3, 0), 2378 NEONMAP1(vst4_lane_v, arm_neon_vst4lane, 0), 2379 NEONMAP1(vst4_v, arm_neon_vst4, 0), 2380 NEONMAP1(vst4q_lane_v, arm_neon_vst4lane, 0), 2381 NEONMAP1(vst4q_v, arm_neon_vst4, 0), 2382 NEONMAP0(vsubhn_v), 2383 NEONMAP0(vtrn_v), 2384 NEONMAP0(vtrnq_v), 2385 NEONMAP0(vtst_v), 2386 NEONMAP0(vtstq_v), 2387 NEONMAP0(vuzp_v), 2388 NEONMAP0(vuzpq_v), 2389 NEONMAP0(vzip_v), 2390 NEONMAP0(vzipq_v) 2391 }; 2392 2393 #undef NEONMAP0 2394 #undef NEONMAP1 2395 #undef NEONMAP2 2396 2397 static bool NEONSIMDIntrinsicsProvenSorted = false; 2398 2399 static bool AArch64SISDIntrinsicInfoProvenSorted = false; 2400 2401 static const NeonIntrinsicInfo * 2402 findNeonIntrinsicInMap(llvm::ArrayRef<NeonIntrinsicInfo> IntrinsicMap, 2403 unsigned BuiltinID, bool &MapProvenSorted) { 2404 2405 #ifndef NDEBUG 2406 if (!MapProvenSorted) { 2407 // FIXME: use std::is_sorted once C++11 is allowed 2408 for (unsigned i = 0; i < IntrinsicMap.size() - 1; ++i) 2409 assert(IntrinsicMap[i].BuiltinID <= IntrinsicMap[i + 1].BuiltinID); 2410 MapProvenSorted = true; 2411 } 2412 #endif 2413 2414 const NeonIntrinsicInfo *Builtin = 2415 std::lower_bound(IntrinsicMap.begin(), IntrinsicMap.end(), BuiltinID); 2416 2417 if (Builtin != IntrinsicMap.end() && Builtin->BuiltinID == BuiltinID) 2418 return Builtin; 2419 2420 return 0; 2421 } 2422 2423 Function *CodeGenFunction::LookupNeonLLVMIntrinsic(unsigned IntrinsicID, 2424 unsigned Modifier, 2425 llvm::Type *ArgType, 2426 const CallExpr *E) { 2427 // Return type. 2428 SmallVector<llvm::Type *, 3> Tys; 2429 if (Modifier & AddRetType) { 2430 llvm::Type *Ty = ConvertType(E->getCallReturnType()); 2431 if (Modifier & VectorizeRetType) 2432 Ty = llvm::VectorType::get(Ty, 1); 2433 2434 Tys.push_back(Ty); 2435 } 2436 2437 // Arguments. 2438 if (Modifier & VectorizeArgTypes) 2439 ArgType = llvm::VectorType::get(ArgType, 1); 2440 2441 if (Modifier & (Add1ArgType | Add2ArgTypes)) 2442 Tys.push_back(ArgType); 2443 2444 if (Modifier & Add2ArgTypes) 2445 Tys.push_back(ArgType); 2446 2447 if (Modifier & InventFloatType) 2448 Tys.push_back(FloatTy); 2449 2450 return CGM.getIntrinsic(IntrinsicID, Tys); 2451 } 2452 2453 2454 static Value *EmitAArch64ScalarBuiltinExpr(CodeGenFunction &CGF, 2455 const NeonIntrinsicInfo &SISDInfo, 2456 const CallExpr *E) { 2457 unsigned BuiltinID = SISDInfo.BuiltinID; 2458 unsigned int Int = SISDInfo.LLVMIntrinsic; 2459 unsigned IntTypes = SISDInfo.TypeModifier; 2460 const char *s = SISDInfo.NameHint; 2461 2462 SmallVector<Value *, 4> Ops; 2463 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) { 2464 Ops.push_back(CGF.EmitScalarExpr(E->getArg(i))); 2465 } 2466 2467 // AArch64 scalar builtins are not overloaded, they do not have an extra 2468 // argument that specifies the vector type, need to handle each case. 2469 switch (BuiltinID) { 2470 default: break; 2471 case NEON::BI__builtin_neon_vdups_lane_f32: 2472 case NEON::BI__builtin_neon_vdupd_lane_f64: 2473 case NEON::BI__builtin_neon_vdups_laneq_f32: 2474 case NEON::BI__builtin_neon_vdupd_laneq_f64: { 2475 return CGF.Builder.CreateExtractElement(Ops[0], Ops[1], "vdup_lane"); 2476 } 2477 case NEON::BI__builtin_neon_vdupb_lane_i8: 2478 case NEON::BI__builtin_neon_vduph_lane_i16: 2479 case NEON::BI__builtin_neon_vdups_lane_i32: 2480 case NEON::BI__builtin_neon_vdupd_lane_i64: 2481 case NEON::BI__builtin_neon_vdupb_laneq_i8: 2482 case NEON::BI__builtin_neon_vduph_laneq_i16: 2483 case NEON::BI__builtin_neon_vdups_laneq_i32: 2484 case NEON::BI__builtin_neon_vdupd_laneq_i64: { 2485 // The backend treats Neon scalar types as v1ix types 2486 // So we want to dup lane from any vector to v1ix vector 2487 // with shufflevector 2488 s = "vdup_lane"; 2489 Value* SV = llvm::ConstantVector::getSplat(1, cast<ConstantInt>(Ops[1])); 2490 Value *Result = CGF.Builder.CreateShuffleVector(Ops[0], Ops[0], SV, s); 2491 llvm::Type *Ty = CGF.ConvertType(E->getCallReturnType()); 2492 // AArch64 intrinsic one-element vector type cast to 2493 // scalar type expected by the builtin 2494 return CGF.Builder.CreateBitCast(Result, Ty, s); 2495 } 2496 case NEON::BI__builtin_neon_vqdmlalh_lane_s16 : 2497 case NEON::BI__builtin_neon_vqdmlalh_laneq_s16 : 2498 case NEON::BI__builtin_neon_vqdmlals_lane_s32 : 2499 case NEON::BI__builtin_neon_vqdmlals_laneq_s32 : 2500 case NEON::BI__builtin_neon_vqdmlslh_lane_s16 : 2501 case NEON::BI__builtin_neon_vqdmlslh_laneq_s16 : 2502 case NEON::BI__builtin_neon_vqdmlsls_lane_s32 : 2503 case NEON::BI__builtin_neon_vqdmlsls_laneq_s32 : { 2504 Int = Intrinsic::arm_neon_vqadds; 2505 if (BuiltinID == NEON::BI__builtin_neon_vqdmlslh_lane_s16 || 2506 BuiltinID == NEON::BI__builtin_neon_vqdmlslh_laneq_s16 || 2507 BuiltinID == NEON::BI__builtin_neon_vqdmlsls_lane_s32 || 2508 BuiltinID == NEON::BI__builtin_neon_vqdmlsls_laneq_s32) { 2509 Int = Intrinsic::arm_neon_vqsubs; 2510 } 2511 // create vqdmull call with b * c[i] 2512 llvm::Type *Ty = CGF.ConvertType(E->getArg(1)->getType()); 2513 llvm::VectorType *OpVTy = llvm::VectorType::get(Ty, 1); 2514 Ty = CGF.ConvertType(E->getArg(0)->getType()); 2515 llvm::VectorType *ResVTy = llvm::VectorType::get(Ty, 1); 2516 Value *F = CGF.CGM.getIntrinsic(Intrinsic::arm_neon_vqdmull, ResVTy); 2517 Value *V = UndefValue::get(OpVTy); 2518 llvm::Constant *CI = ConstantInt::get(CGF.Int32Ty, 0); 2519 SmallVector<Value *, 2> MulOps; 2520 MulOps.push_back(Ops[1]); 2521 MulOps.push_back(Ops[2]); 2522 MulOps[0] = CGF.Builder.CreateInsertElement(V, MulOps[0], CI); 2523 MulOps[1] = CGF.Builder.CreateExtractElement(MulOps[1], Ops[3], "extract"); 2524 MulOps[1] = CGF.Builder.CreateInsertElement(V, MulOps[1], CI); 2525 Value *MulRes = CGF.Builder.CreateCall2(F, MulOps[0], MulOps[1]); 2526 // create vqadds call with a +/- vqdmull result 2527 F = CGF.CGM.getIntrinsic(Int, ResVTy); 2528 SmallVector<Value *, 2> AddOps; 2529 AddOps.push_back(Ops[0]); 2530 AddOps.push_back(MulRes); 2531 V = UndefValue::get(ResVTy); 2532 AddOps[0] = CGF.Builder.CreateInsertElement(V, AddOps[0], CI); 2533 Value *AddRes = CGF.Builder.CreateCall2(F, AddOps[0], AddOps[1]); 2534 return CGF.Builder.CreateBitCast(AddRes, Ty); 2535 } 2536 case NEON::BI__builtin_neon_vfmas_lane_f32: 2537 case NEON::BI__builtin_neon_vfmas_laneq_f32: 2538 case NEON::BI__builtin_neon_vfmad_lane_f64: 2539 case NEON::BI__builtin_neon_vfmad_laneq_f64: { 2540 llvm::Type *Ty = CGF.ConvertType(E->getCallReturnType()); 2541 Value *F = CGF.CGM.getIntrinsic(Intrinsic::fma, Ty); 2542 Ops[2] = CGF.Builder.CreateExtractElement(Ops[2], Ops[3], "extract"); 2543 return CGF.Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]); 2544 } 2545 // Scalar Floating-point Multiply Extended 2546 case NEON::BI__builtin_neon_vmulxs_f32: 2547 case NEON::BI__builtin_neon_vmulxd_f64: { 2548 Int = Intrinsic::aarch64_neon_vmulx; 2549 llvm::Type *Ty = CGF.ConvertType(E->getCallReturnType()); 2550 return CGF.EmitNeonCall(CGF.CGM.getIntrinsic(Int, Ty), Ops, "vmulx"); 2551 } 2552 case NEON::BI__builtin_neon_vmul_n_f64: { 2553 // v1f64 vmul_n_f64 should be mapped to Neon scalar mul lane 2554 llvm::Type *VTy = GetNeonType(&CGF, 2555 NeonTypeFlags(NeonTypeFlags::Float64, false, false)); 2556 Ops[0] = CGF.Builder.CreateBitCast(Ops[0], VTy); 2557 llvm::Value *Idx = llvm::ConstantInt::get(CGF.Int32Ty, 0); 2558 Ops[0] = CGF.Builder.CreateExtractElement(Ops[0], Idx, "extract"); 2559 Value *Result = CGF.Builder.CreateFMul(Ops[0], Ops[1]); 2560 return CGF.Builder.CreateBitCast(Result, VTy); 2561 } 2562 case NEON::BI__builtin_neon_vget_lane_i8: 2563 case NEON::BI__builtin_neon_vget_lane_i16: 2564 case NEON::BI__builtin_neon_vget_lane_i32: 2565 case NEON::BI__builtin_neon_vget_lane_i64: 2566 case NEON::BI__builtin_neon_vget_lane_f32: 2567 case NEON::BI__builtin_neon_vget_lane_f64: 2568 case NEON::BI__builtin_neon_vgetq_lane_i8: 2569 case NEON::BI__builtin_neon_vgetq_lane_i16: 2570 case NEON::BI__builtin_neon_vgetq_lane_i32: 2571 case NEON::BI__builtin_neon_vgetq_lane_i64: 2572 case NEON::BI__builtin_neon_vgetq_lane_f32: 2573 case NEON::BI__builtin_neon_vgetq_lane_f64: 2574 return CGF.EmitARMBuiltinExpr(NEON::BI__builtin_neon_vget_lane_i8, E); 2575 case NEON::BI__builtin_neon_vset_lane_i8: 2576 case NEON::BI__builtin_neon_vset_lane_i16: 2577 case NEON::BI__builtin_neon_vset_lane_i32: 2578 case NEON::BI__builtin_neon_vset_lane_i64: 2579 case NEON::BI__builtin_neon_vset_lane_f32: 2580 case NEON::BI__builtin_neon_vset_lane_f64: 2581 case NEON::BI__builtin_neon_vsetq_lane_i8: 2582 case NEON::BI__builtin_neon_vsetq_lane_i16: 2583 case NEON::BI__builtin_neon_vsetq_lane_i32: 2584 case NEON::BI__builtin_neon_vsetq_lane_i64: 2585 case NEON::BI__builtin_neon_vsetq_lane_f32: 2586 case NEON::BI__builtin_neon_vsetq_lane_f64: 2587 return CGF.EmitARMBuiltinExpr(NEON::BI__builtin_neon_vset_lane_i8, E); 2588 2589 case NEON::BI__builtin_neon_vcled_s64: 2590 case NEON::BI__builtin_neon_vcled_u64: 2591 case NEON::BI__builtin_neon_vcles_f32: 2592 case NEON::BI__builtin_neon_vcled_f64: 2593 case NEON::BI__builtin_neon_vcltd_s64: 2594 case NEON::BI__builtin_neon_vcltd_u64: 2595 case NEON::BI__builtin_neon_vclts_f32: 2596 case NEON::BI__builtin_neon_vcltd_f64: 2597 case NEON::BI__builtin_neon_vcales_f32: 2598 case NEON::BI__builtin_neon_vcaled_f64: 2599 case NEON::BI__builtin_neon_vcalts_f32: 2600 case NEON::BI__builtin_neon_vcaltd_f64: 2601 // Only one direction of comparisons actually exist, cmle is actually a cmge 2602 // with swapped operands. The table gives us the right intrinsic but we 2603 // still need to do the swap. 2604 std::swap(Ops[0], Ops[1]); 2605 break; 2606 case NEON::BI__builtin_neon_vceqzd_s64: 2607 case NEON::BI__builtin_neon_vceqzd_u64: 2608 case NEON::BI__builtin_neon_vcgezd_s64: 2609 case NEON::BI__builtin_neon_vcgtzd_s64: 2610 case NEON::BI__builtin_neon_vclezd_s64: 2611 case NEON::BI__builtin_neon_vcltzd_s64: 2612 // Add implicit zero operand. 2613 Ops.push_back(llvm::Constant::getNullValue(Ops[0]->getType())); 2614 break; 2615 case NEON::BI__builtin_neon_vceqzs_f32: 2616 case NEON::BI__builtin_neon_vceqzd_f64: 2617 case NEON::BI__builtin_neon_vcgezs_f32: 2618 case NEON::BI__builtin_neon_vcgezd_f64: 2619 case NEON::BI__builtin_neon_vcgtzs_f32: 2620 case NEON::BI__builtin_neon_vcgtzd_f64: 2621 case NEON::BI__builtin_neon_vclezs_f32: 2622 case NEON::BI__builtin_neon_vclezd_f64: 2623 case NEON::BI__builtin_neon_vcltzs_f32: 2624 case NEON::BI__builtin_neon_vcltzd_f64: 2625 // Add implicit zero operand. 2626 Ops.push_back(llvm::Constant::getNullValue(CGF.FloatTy)); 2627 break; 2628 } 2629 2630 2631 assert(Int && "Generic code assumes a valid intrinsic"); 2632 2633 // Determine the type(s) of this overloaded AArch64 intrinsic. 2634 const Expr *Arg = E->getArg(0); 2635 llvm::Type *ArgTy = CGF.ConvertType(Arg->getType()); 2636 Function *F = CGF.LookupNeonLLVMIntrinsic(Int, IntTypes, ArgTy, E); 2637 2638 Value *Result = CGF.EmitNeonCall(F, Ops, s); 2639 llvm::Type *ResultType = CGF.ConvertType(E->getType()); 2640 // AArch64 intrinsic one-element vector type cast to 2641 // scalar type expected by the builtin 2642 return CGF.Builder.CreateBitCast(Result, ResultType, s); 2643 } 2644 2645 Value *CodeGenFunction::EmitCommonNeonBuiltinExpr( 2646 unsigned BuiltinID, unsigned LLVMIntrinsic, unsigned AltLLVMIntrinsic, 2647 const char *NameHint, unsigned Modifier, const CallExpr *E, 2648 SmallVectorImpl<llvm::Value *> &Ops, llvm::Value *Align) { 2649 // Get the last argument, which specifies the vector type. 2650 llvm::APSInt NeonTypeConst; 2651 const Expr *Arg = E->getArg(E->getNumArgs() - 1); 2652 if (!Arg->isIntegerConstantExpr(NeonTypeConst, getContext())) 2653 return 0; 2654 2655 // Determine the type of this overloaded NEON intrinsic. 2656 NeonTypeFlags Type(NeonTypeConst.getZExtValue()); 2657 bool Usgn = Type.isUnsigned(); 2658 bool Quad = Type.isQuad(); 2659 2660 llvm::VectorType *VTy = GetNeonType(this, Type); 2661 llvm::Type *Ty = VTy; 2662 if (!Ty) 2663 return 0; 2664 2665 unsigned Int = LLVMIntrinsic; 2666 if ((Modifier & UnsignedAlts) && !Usgn) 2667 Int = AltLLVMIntrinsic; 2668 2669 switch (BuiltinID) { 2670 default: break; 2671 case NEON::BI__builtin_neon_vabs_v: 2672 case NEON::BI__builtin_neon_vabsq_v: 2673 if (VTy->getElementType()->isFloatingPointTy()) 2674 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::fabs, Ty), Ops, "vabs"); 2675 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), Ops, "vabs"); 2676 case NEON::BI__builtin_neon_vaddhn_v: { 2677 llvm::VectorType *SrcTy = 2678 llvm::VectorType::getExtendedElementVectorType(VTy); 2679 2680 // %sum = add <4 x i32> %lhs, %rhs 2681 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 2682 Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy); 2683 Ops[0] = Builder.CreateAdd(Ops[0], Ops[1], "vaddhn"); 2684 2685 // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16> 2686 Constant *ShiftAmt = ConstantInt::get(SrcTy->getElementType(), 2687 SrcTy->getScalarSizeInBits() / 2); 2688 ShiftAmt = ConstantVector::getSplat(VTy->getNumElements(), ShiftAmt); 2689 Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vaddhn"); 2690 2691 // %res = trunc <4 x i32> %high to <4 x i16> 2692 return Builder.CreateTrunc(Ops[0], VTy, "vaddhn"); 2693 } 2694 case NEON::BI__builtin_neon_vcale_v: 2695 case NEON::BI__builtin_neon_vcaleq_v: 2696 case NEON::BI__builtin_neon_vcalt_v: 2697 case NEON::BI__builtin_neon_vcaltq_v: 2698 std::swap(Ops[0], Ops[1]); 2699 case NEON::BI__builtin_neon_vcage_v: 2700 case NEON::BI__builtin_neon_vcageq_v: 2701 case NEON::BI__builtin_neon_vcagt_v: 2702 case NEON::BI__builtin_neon_vcagtq_v: { 2703 llvm::Type *VecFlt = llvm::VectorType::get( 2704 VTy->getScalarSizeInBits() == 32 ? FloatTy : DoubleTy, 2705 VTy->getNumElements()); 2706 llvm::Type *Tys[] = { VTy, VecFlt }; 2707 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 2708 return EmitNeonCall(F, Ops, NameHint); 2709 } 2710 case NEON::BI__builtin_neon_vclz_v: 2711 case NEON::BI__builtin_neon_vclzq_v: 2712 // We generate target-independent intrinsic, which needs a second argument 2713 // for whether or not clz of zero is undefined; on ARM it isn't. 2714 Ops.push_back(Builder.getInt1(getTarget().isCLZForZeroUndef())); 2715 break; 2716 case NEON::BI__builtin_neon_vcvt_f32_v: 2717 case NEON::BI__builtin_neon_vcvtq_f32_v: 2718 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2719 Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, Quad)); 2720 return Usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") 2721 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); 2722 case NEON::BI__builtin_neon_vcvt_n_f32_v: 2723 case NEON::BI__builtin_neon_vcvtq_n_f32_v: { 2724 bool Double = 2725 (cast<llvm::IntegerType>(VTy->getElementType())->getBitWidth() == 64); 2726 llvm::Type *FloatTy = 2727 GetNeonType(this, NeonTypeFlags(Double ? NeonTypeFlags::Float64 2728 : NeonTypeFlags::Float32, 2729 false, Quad)); 2730 llvm::Type *Tys[2] = { FloatTy, Ty }; 2731 Int = Usgn ? LLVMIntrinsic : AltLLVMIntrinsic; 2732 Function *F = CGM.getIntrinsic(Int, Tys); 2733 return EmitNeonCall(F, Ops, "vcvt_n"); 2734 } 2735 case NEON::BI__builtin_neon_vcvt_n_s32_v: 2736 case NEON::BI__builtin_neon_vcvt_n_u32_v: 2737 case NEON::BI__builtin_neon_vcvt_n_s64_v: 2738 case NEON::BI__builtin_neon_vcvt_n_u64_v: 2739 case NEON::BI__builtin_neon_vcvtq_n_s32_v: 2740 case NEON::BI__builtin_neon_vcvtq_n_u32_v: 2741 case NEON::BI__builtin_neon_vcvtq_n_s64_v: 2742 case NEON::BI__builtin_neon_vcvtq_n_u64_v: { 2743 bool Double = 2744 (cast<llvm::IntegerType>(VTy->getElementType())->getBitWidth() == 64); 2745 llvm::Type *FloatTy = 2746 GetNeonType(this, NeonTypeFlags(Double ? NeonTypeFlags::Float64 2747 : NeonTypeFlags::Float32, 2748 false, Quad)); 2749 llvm::Type *Tys[2] = { Ty, FloatTy }; 2750 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 2751 return EmitNeonCall(F, Ops, "vcvt_n"); 2752 } 2753 case NEON::BI__builtin_neon_vcvt_s32_v: 2754 case NEON::BI__builtin_neon_vcvt_u32_v: 2755 case NEON::BI__builtin_neon_vcvt_s64_v: 2756 case NEON::BI__builtin_neon_vcvt_u64_v: 2757 case NEON::BI__builtin_neon_vcvtq_s32_v: 2758 case NEON::BI__builtin_neon_vcvtq_u32_v: 2759 case NEON::BI__builtin_neon_vcvtq_s64_v: 2760 case NEON::BI__builtin_neon_vcvtq_u64_v: { 2761 bool Double = 2762 (cast<llvm::IntegerType>(VTy->getElementType())->getBitWidth() == 64); 2763 llvm::Type *FloatTy = 2764 GetNeonType(this, NeonTypeFlags(Double ? NeonTypeFlags::Float64 2765 : NeonTypeFlags::Float32, 2766 false, Quad)); 2767 Ops[0] = Builder.CreateBitCast(Ops[0], FloatTy); 2768 return Usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt") 2769 : Builder.CreateFPToSI(Ops[0], Ty, "vcvt"); 2770 } 2771 case NEON::BI__builtin_neon_vcvta_s32_v: 2772 case NEON::BI__builtin_neon_vcvta_s64_v: 2773 case NEON::BI__builtin_neon_vcvta_u32_v: 2774 case NEON::BI__builtin_neon_vcvta_u64_v: 2775 case NEON::BI__builtin_neon_vcvtaq_s32_v: 2776 case NEON::BI__builtin_neon_vcvtaq_s64_v: 2777 case NEON::BI__builtin_neon_vcvtaq_u32_v: 2778 case NEON::BI__builtin_neon_vcvtaq_u64_v: 2779 case NEON::BI__builtin_neon_vcvtn_s32_v: 2780 case NEON::BI__builtin_neon_vcvtn_s64_v: 2781 case NEON::BI__builtin_neon_vcvtn_u32_v: 2782 case NEON::BI__builtin_neon_vcvtn_u64_v: 2783 case NEON::BI__builtin_neon_vcvtnq_s32_v: 2784 case NEON::BI__builtin_neon_vcvtnq_s64_v: 2785 case NEON::BI__builtin_neon_vcvtnq_u32_v: 2786 case NEON::BI__builtin_neon_vcvtnq_u64_v: 2787 case NEON::BI__builtin_neon_vcvtp_s32_v: 2788 case NEON::BI__builtin_neon_vcvtp_s64_v: 2789 case NEON::BI__builtin_neon_vcvtp_u32_v: 2790 case NEON::BI__builtin_neon_vcvtp_u64_v: 2791 case NEON::BI__builtin_neon_vcvtpq_s32_v: 2792 case NEON::BI__builtin_neon_vcvtpq_s64_v: 2793 case NEON::BI__builtin_neon_vcvtpq_u32_v: 2794 case NEON::BI__builtin_neon_vcvtpq_u64_v: 2795 case NEON::BI__builtin_neon_vcvtm_s32_v: 2796 case NEON::BI__builtin_neon_vcvtm_s64_v: 2797 case NEON::BI__builtin_neon_vcvtm_u32_v: 2798 case NEON::BI__builtin_neon_vcvtm_u64_v: 2799 case NEON::BI__builtin_neon_vcvtmq_s32_v: 2800 case NEON::BI__builtin_neon_vcvtmq_s64_v: 2801 case NEON::BI__builtin_neon_vcvtmq_u32_v: 2802 case NEON::BI__builtin_neon_vcvtmq_u64_v: { 2803 bool Double = 2804 (cast<llvm::IntegerType>(VTy->getElementType())->getBitWidth() == 64); 2805 llvm::Type *InTy = 2806 GetNeonType(this, 2807 NeonTypeFlags(Double ? NeonTypeFlags::Float64 2808 : NeonTypeFlags::Float32, false, Quad)); 2809 llvm::Type *Tys[2] = { Ty, InTy }; 2810 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, NameHint); 2811 } 2812 case NEON::BI__builtin_neon_vext_v: 2813 case NEON::BI__builtin_neon_vextq_v: { 2814 int CV = cast<ConstantInt>(Ops[2])->getSExtValue(); 2815 SmallVector<Constant*, 16> Indices; 2816 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 2817 Indices.push_back(ConstantInt::get(Int32Ty, i+CV)); 2818 2819 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2820 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 2821 Value *SV = llvm::ConstantVector::get(Indices); 2822 return Builder.CreateShuffleVector(Ops[0], Ops[1], SV, "vext"); 2823 } 2824 case NEON::BI__builtin_neon_vfma_v: 2825 case NEON::BI__builtin_neon_vfmaq_v: { 2826 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 2827 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2828 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 2829 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 2830 2831 // NEON intrinsic puts accumulator first, unlike the LLVM fma. 2832 return Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]); 2833 } 2834 case NEON::BI__builtin_neon_vld1_v: 2835 case NEON::BI__builtin_neon_vld1q_v: 2836 Ops.push_back(Align); 2837 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), Ops, "vld1"); 2838 case NEON::BI__builtin_neon_vld2_v: 2839 case NEON::BI__builtin_neon_vld2q_v: 2840 case NEON::BI__builtin_neon_vld3_v: 2841 case NEON::BI__builtin_neon_vld3q_v: 2842 case NEON::BI__builtin_neon_vld4_v: 2843 case NEON::BI__builtin_neon_vld4q_v: { 2844 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Ty); 2845 Ops[1] = Builder.CreateCall2(F, Ops[1], Align, NameHint); 2846 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 2847 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2848 return Builder.CreateStore(Ops[1], Ops[0]); 2849 } 2850 case NEON::BI__builtin_neon_vld1_dup_v: 2851 case NEON::BI__builtin_neon_vld1q_dup_v: { 2852 Value *V = UndefValue::get(Ty); 2853 Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 2854 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2855 LoadInst *Ld = Builder.CreateLoad(Ops[0]); 2856 Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); 2857 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 2858 Ops[0] = Builder.CreateInsertElement(V, Ld, CI); 2859 return EmitNeonSplat(Ops[0], CI); 2860 } 2861 case NEON::BI__builtin_neon_vld2_lane_v: 2862 case NEON::BI__builtin_neon_vld2q_lane_v: 2863 case NEON::BI__builtin_neon_vld3_lane_v: 2864 case NEON::BI__builtin_neon_vld3q_lane_v: 2865 case NEON::BI__builtin_neon_vld4_lane_v: 2866 case NEON::BI__builtin_neon_vld4q_lane_v: { 2867 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Ty); 2868 for (unsigned I = 2; I < Ops.size() - 1; ++I) 2869 Ops[I] = Builder.CreateBitCast(Ops[I], Ty); 2870 Ops.push_back(Align); 2871 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), NameHint); 2872 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 2873 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 2874 return Builder.CreateStore(Ops[1], Ops[0]); 2875 } 2876 case NEON::BI__builtin_neon_vmovl_v: { 2877 llvm::Type *DTy =llvm::VectorType::getTruncatedElementVectorType(VTy); 2878 Ops[0] = Builder.CreateBitCast(Ops[0], DTy); 2879 if (Usgn) 2880 return Builder.CreateZExt(Ops[0], Ty, "vmovl"); 2881 return Builder.CreateSExt(Ops[0], Ty, "vmovl"); 2882 } 2883 case NEON::BI__builtin_neon_vmovn_v: { 2884 llvm::Type *QTy = llvm::VectorType::getExtendedElementVectorType(VTy); 2885 Ops[0] = Builder.CreateBitCast(Ops[0], QTy); 2886 return Builder.CreateTrunc(Ops[0], Ty, "vmovn"); 2887 } 2888 case NEON::BI__builtin_neon_vmull_v: 2889 // FIXME: the integer vmull operations could be emitted in terms of pure 2890 // LLVM IR (2 exts followed by a mul). Unfortunately LLVM has a habit of 2891 // hoisting the exts outside loops. Until global ISel comes along that can 2892 // see through such movement this leads to bad CodeGen. So we need an 2893 // intrinsic for now. 2894 Int = Usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls; 2895 Int = Type.isPoly() ? (unsigned)Intrinsic::arm_neon_vmullp : Int; 2896 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull"); 2897 case NEON::BI__builtin_neon_vpadal_v: 2898 case NEON::BI__builtin_neon_vpadalq_v: { 2899 // The source operand type has twice as many elements of half the size. 2900 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 2901 llvm::Type *EltTy = 2902 llvm::IntegerType::get(getLLVMContext(), EltBits / 2); 2903 llvm::Type *NarrowTy = 2904 llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); 2905 llvm::Type *Tys[2] = { Ty, NarrowTy }; 2906 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, NameHint); 2907 } 2908 case NEON::BI__builtin_neon_vpaddl_v: 2909 case NEON::BI__builtin_neon_vpaddlq_v: { 2910 // The source operand type has twice as many elements of half the size. 2911 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 2912 llvm::Type *EltTy = llvm::IntegerType::get(getLLVMContext(), EltBits / 2); 2913 llvm::Type *NarrowTy = 2914 llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); 2915 llvm::Type *Tys[2] = { Ty, NarrowTy }; 2916 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vpaddl"); 2917 } 2918 case NEON::BI__builtin_neon_vqdmlal_v: 2919 case NEON::BI__builtin_neon_vqdmlsl_v: { 2920 SmallVector<Value *, 2> MulOps(Ops.begin() + 1, Ops.end()); 2921 Value *Mul = EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), 2922 MulOps, "vqdmlal"); 2923 2924 SmallVector<Value *, 2> AccumOps; 2925 AccumOps.push_back(Ops[0]); 2926 AccumOps.push_back(Mul); 2927 return EmitNeonCall(CGM.getIntrinsic(AltLLVMIntrinsic, Ty), 2928 AccumOps, NameHint); 2929 } 2930 case NEON::BI__builtin_neon_vqshl_n_v: 2931 case NEON::BI__builtin_neon_vqshlq_n_v: 2932 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshl_n", 2933 1, false); 2934 case NEON::BI__builtin_neon_vrecpe_v: 2935 case NEON::BI__builtin_neon_vrecpeq_v: 2936 case NEON::BI__builtin_neon_vrsqrte_v: 2937 case NEON::BI__builtin_neon_vrsqrteq_v: 2938 Int = Ty->isFPOrFPVectorTy() ? LLVMIntrinsic : AltLLVMIntrinsic; 2939 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, NameHint); 2940 2941 case NEON::BI__builtin_neon_vshl_n_v: 2942 case NEON::BI__builtin_neon_vshlq_n_v: 2943 Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false); 2944 return Builder.CreateShl(Builder.CreateBitCast(Ops[0],Ty), Ops[1], 2945 "vshl_n"); 2946 case NEON::BI__builtin_neon_vshll_n_v: { 2947 llvm::Type *SrcTy = llvm::VectorType::getTruncatedElementVectorType(VTy); 2948 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 2949 if (Usgn) 2950 Ops[0] = Builder.CreateZExt(Ops[0], VTy); 2951 else 2952 Ops[0] = Builder.CreateSExt(Ops[0], VTy); 2953 Ops[1] = EmitNeonShiftVector(Ops[1], VTy, false); 2954 return Builder.CreateShl(Ops[0], Ops[1], "vshll_n"); 2955 } 2956 case NEON::BI__builtin_neon_vshrn_n_v: { 2957 llvm::Type *SrcTy = llvm::VectorType::getExtendedElementVectorType(VTy); 2958 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 2959 Ops[1] = EmitNeonShiftVector(Ops[1], SrcTy, false); 2960 if (Usgn) 2961 Ops[0] = Builder.CreateLShr(Ops[0], Ops[1]); 2962 else 2963 Ops[0] = Builder.CreateAShr(Ops[0], Ops[1]); 2964 return Builder.CreateTrunc(Ops[0], Ty, "vshrn_n"); 2965 } 2966 case NEON::BI__builtin_neon_vshr_n_v: 2967 case NEON::BI__builtin_neon_vshrq_n_v: 2968 return EmitNeonRShiftImm(Ops[0], Ops[1], Ty, Usgn, "vshr_n"); 2969 case NEON::BI__builtin_neon_vst1_v: 2970 case NEON::BI__builtin_neon_vst1q_v: 2971 case NEON::BI__builtin_neon_vst2_v: 2972 case NEON::BI__builtin_neon_vst2q_v: 2973 case NEON::BI__builtin_neon_vst3_v: 2974 case NEON::BI__builtin_neon_vst3q_v: 2975 case NEON::BI__builtin_neon_vst4_v: 2976 case NEON::BI__builtin_neon_vst4q_v: 2977 case NEON::BI__builtin_neon_vst2_lane_v: 2978 case NEON::BI__builtin_neon_vst2q_lane_v: 2979 case NEON::BI__builtin_neon_vst3_lane_v: 2980 case NEON::BI__builtin_neon_vst3q_lane_v: 2981 case NEON::BI__builtin_neon_vst4_lane_v: 2982 case NEON::BI__builtin_neon_vst4q_lane_v: 2983 Ops.push_back(Align); 2984 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, ""); 2985 case NEON::BI__builtin_neon_vsubhn_v: { 2986 llvm::VectorType *SrcTy = 2987 llvm::VectorType::getExtendedElementVectorType(VTy); 2988 2989 // %sum = add <4 x i32> %lhs, %rhs 2990 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 2991 Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy); 2992 Ops[0] = Builder.CreateSub(Ops[0], Ops[1], "vsubhn"); 2993 2994 // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16> 2995 Constant *ShiftAmt = ConstantInt::get(SrcTy->getElementType(), 2996 SrcTy->getScalarSizeInBits() / 2); 2997 ShiftAmt = ConstantVector::getSplat(VTy->getNumElements(), ShiftAmt); 2998 Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vsubhn"); 2999 3000 // %res = trunc <4 x i32> %high to <4 x i16> 3001 return Builder.CreateTrunc(Ops[0], VTy, "vsubhn"); 3002 } 3003 case NEON::BI__builtin_neon_vtrn_v: 3004 case NEON::BI__builtin_neon_vtrnq_v: { 3005 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 3006 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3007 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 3008 Value *SV = 0; 3009 3010 for (unsigned vi = 0; vi != 2; ++vi) { 3011 SmallVector<Constant*, 16> Indices; 3012 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 3013 Indices.push_back(Builder.getInt32(i+vi)); 3014 Indices.push_back(Builder.getInt32(i+e+vi)); 3015 } 3016 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi); 3017 SV = llvm::ConstantVector::get(Indices); 3018 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vtrn"); 3019 SV = Builder.CreateStore(SV, Addr); 3020 } 3021 return SV; 3022 } 3023 case NEON::BI__builtin_neon_vtst_v: 3024 case NEON::BI__builtin_neon_vtstq_v: { 3025 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3026 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3027 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]); 3028 Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0], 3029 ConstantAggregateZero::get(Ty)); 3030 return Builder.CreateSExt(Ops[0], Ty, "vtst"); 3031 } 3032 case NEON::BI__builtin_neon_vuzp_v: 3033 case NEON::BI__builtin_neon_vuzpq_v: { 3034 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 3035 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3036 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 3037 Value *SV = 0; 3038 3039 for (unsigned vi = 0; vi != 2; ++vi) { 3040 SmallVector<Constant*, 16> Indices; 3041 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 3042 Indices.push_back(ConstantInt::get(Int32Ty, 2*i+vi)); 3043 3044 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi); 3045 SV = llvm::ConstantVector::get(Indices); 3046 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vuzp"); 3047 SV = Builder.CreateStore(SV, Addr); 3048 } 3049 return SV; 3050 } 3051 case NEON::BI__builtin_neon_vzip_v: 3052 case NEON::BI__builtin_neon_vzipq_v: { 3053 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 3054 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3055 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 3056 Value *SV = 0; 3057 3058 for (unsigned vi = 0; vi != 2; ++vi) { 3059 SmallVector<Constant*, 16> Indices; 3060 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 3061 Indices.push_back(ConstantInt::get(Int32Ty, (i + vi*e) >> 1)); 3062 Indices.push_back(ConstantInt::get(Int32Ty, ((i + vi*e) >> 1)+e)); 3063 } 3064 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi); 3065 SV = llvm::ConstantVector::get(Indices); 3066 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vzip"); 3067 SV = Builder.CreateStore(SV, Addr); 3068 } 3069 return SV; 3070 } 3071 } 3072 3073 assert(Int && "Expected valid intrinsic number"); 3074 3075 // Determine the type(s) of this overloaded AArch64 intrinsic. 3076 Function *F = LookupNeonLLVMIntrinsic(Int, Modifier, Ty, E); 3077 3078 Value *Result = EmitNeonCall(F, Ops, NameHint); 3079 llvm::Type *ResultType = ConvertType(E->getType()); 3080 // AArch64 intrinsic one-element vector type cast to 3081 // scalar type expected by the builtin 3082 return Builder.CreateBitCast(Result, ResultType, NameHint); 3083 } 3084 3085 Value *CodeGenFunction::EmitAArch64CompareBuiltinExpr( 3086 Value *Op, llvm::Type *Ty, const CmpInst::Predicate Fp, 3087 const CmpInst::Predicate Ip, const Twine &Name) { 3088 llvm::Type *OTy = ((llvm::User *)Op)->getOperand(0)->getType(); 3089 if (OTy->isPointerTy()) 3090 OTy = Ty; 3091 Op = Builder.CreateBitCast(Op, OTy); 3092 if (((llvm::VectorType *)OTy)->getElementType()->isFloatingPointTy()) { 3093 Op = Builder.CreateFCmp(Fp, Op, ConstantAggregateZero::get(OTy)); 3094 } else { 3095 Op = Builder.CreateICmp(Ip, Op, ConstantAggregateZero::get(OTy)); 3096 } 3097 return Builder.CreateSExt(Op, Ty, Name); 3098 } 3099 3100 static Value *packTBLDVectorList(CodeGenFunction &CGF, ArrayRef<Value *> Ops, 3101 Value *ExtOp, Value *IndexOp, 3102 llvm::Type *ResTy, unsigned IntID, 3103 const char *Name) { 3104 SmallVector<Value *, 2> TblOps; 3105 if (ExtOp) 3106 TblOps.push_back(ExtOp); 3107 3108 // Build a vector containing sequential number like (0, 1, 2, ..., 15) 3109 SmallVector<Constant*, 16> Indices; 3110 llvm::VectorType *TblTy = cast<llvm::VectorType>(Ops[0]->getType()); 3111 for (unsigned i = 0, e = TblTy->getNumElements(); i != e; ++i) { 3112 Indices.push_back(ConstantInt::get(CGF.Int32Ty, 2*i)); 3113 Indices.push_back(ConstantInt::get(CGF.Int32Ty, 2*i+1)); 3114 } 3115 Value *SV = llvm::ConstantVector::get(Indices); 3116 3117 int PairPos = 0, End = Ops.size() - 1; 3118 while (PairPos < End) { 3119 TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos], 3120 Ops[PairPos+1], SV, Name)); 3121 PairPos += 2; 3122 } 3123 3124 // If there's an odd number of 64-bit lookup table, fill the high 64-bit 3125 // of the 128-bit lookup table with zero. 3126 if (PairPos == End) { 3127 Value *ZeroTbl = ConstantAggregateZero::get(TblTy); 3128 TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos], 3129 ZeroTbl, SV, Name)); 3130 } 3131 3132 Function *TblF; 3133 TblOps.push_back(IndexOp); 3134 TblF = CGF.CGM.getIntrinsic(IntID, ResTy); 3135 3136 return CGF.EmitNeonCall(TblF, TblOps, Name); 3137 } 3138 3139 static Value *EmitAArch64TblBuiltinExpr(CodeGenFunction &CGF, 3140 unsigned BuiltinID, 3141 const CallExpr *E) { 3142 unsigned int Int = 0; 3143 const char *s = NULL; 3144 3145 switch (BuiltinID) { 3146 default: 3147 return 0; 3148 case NEON::BI__builtin_neon_vtbl1_v: 3149 case NEON::BI__builtin_neon_vqtbl1_v: 3150 case NEON::BI__builtin_neon_vqtbl1q_v: 3151 case NEON::BI__builtin_neon_vtbl2_v: 3152 case NEON::BI__builtin_neon_vqtbl2_v: 3153 case NEON::BI__builtin_neon_vqtbl2q_v: 3154 case NEON::BI__builtin_neon_vtbl3_v: 3155 case NEON::BI__builtin_neon_vqtbl3_v: 3156 case NEON::BI__builtin_neon_vqtbl3q_v: 3157 case NEON::BI__builtin_neon_vtbl4_v: 3158 case NEON::BI__builtin_neon_vqtbl4_v: 3159 case NEON::BI__builtin_neon_vqtbl4q_v: 3160 case NEON::BI__builtin_neon_vtbx1_v: 3161 case NEON::BI__builtin_neon_vqtbx1_v: 3162 case NEON::BI__builtin_neon_vqtbx1q_v: 3163 case NEON::BI__builtin_neon_vtbx2_v: 3164 case NEON::BI__builtin_neon_vqtbx2_v: 3165 case NEON::BI__builtin_neon_vqtbx2q_v: 3166 case NEON::BI__builtin_neon_vtbx3_v: 3167 case NEON::BI__builtin_neon_vqtbx3_v: 3168 case NEON::BI__builtin_neon_vqtbx3q_v: 3169 case NEON::BI__builtin_neon_vtbx4_v: 3170 case NEON::BI__builtin_neon_vqtbx4_v: 3171 case NEON::BI__builtin_neon_vqtbx4q_v: 3172 break; 3173 } 3174 3175 assert(E->getNumArgs() >= 3); 3176 3177 // Get the last argument, which specifies the vector type. 3178 llvm::APSInt Result; 3179 const Expr *Arg = E->getArg(E->getNumArgs() - 1); 3180 if (!Arg->isIntegerConstantExpr(Result, CGF.getContext())) 3181 return 0; 3182 3183 // Determine the type of this overloaded NEON intrinsic. 3184 NeonTypeFlags Type(Result.getZExtValue()); 3185 llvm::VectorType *VTy = GetNeonType(&CGF, Type); 3186 llvm::Type *Ty = VTy; 3187 if (!Ty) 3188 return 0; 3189 3190 SmallVector<Value *, 4> Ops; 3191 for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) { 3192 Ops.push_back(CGF.EmitScalarExpr(E->getArg(i))); 3193 } 3194 3195 unsigned nElts = VTy->getNumElements(); 3196 3197 // AArch64 scalar builtins are not overloaded, they do not have an extra 3198 // argument that specifies the vector type, need to handle each case. 3199 SmallVector<Value *, 2> TblOps; 3200 switch (BuiltinID) { 3201 case NEON::BI__builtin_neon_vtbl1_v: { 3202 TblOps.push_back(Ops[0]); 3203 return packTBLDVectorList(CGF, TblOps, 0, Ops[1], Ty, 3204 Intrinsic::aarch64_neon_vtbl1, "vtbl1"); 3205 } 3206 case NEON::BI__builtin_neon_vtbl2_v: { 3207 TblOps.push_back(Ops[0]); 3208 TblOps.push_back(Ops[1]); 3209 return packTBLDVectorList(CGF, TblOps, 0, Ops[2], Ty, 3210 Intrinsic::aarch64_neon_vtbl1, "vtbl1"); 3211 } 3212 case NEON::BI__builtin_neon_vtbl3_v: { 3213 TblOps.push_back(Ops[0]); 3214 TblOps.push_back(Ops[1]); 3215 TblOps.push_back(Ops[2]); 3216 return packTBLDVectorList(CGF, TblOps, 0, Ops[3], Ty, 3217 Intrinsic::aarch64_neon_vtbl2, "vtbl2"); 3218 } 3219 case NEON::BI__builtin_neon_vtbl4_v: { 3220 TblOps.push_back(Ops[0]); 3221 TblOps.push_back(Ops[1]); 3222 TblOps.push_back(Ops[2]); 3223 TblOps.push_back(Ops[3]); 3224 return packTBLDVectorList(CGF, TblOps, 0, Ops[4], Ty, 3225 Intrinsic::aarch64_neon_vtbl2, "vtbl2"); 3226 } 3227 case NEON::BI__builtin_neon_vtbx1_v: { 3228 TblOps.push_back(Ops[1]); 3229 Value *TblRes = packTBLDVectorList(CGF, TblOps, 0, Ops[2], Ty, 3230 Intrinsic::aarch64_neon_vtbl1, "vtbl1"); 3231 3232 llvm::Constant *Eight = ConstantInt::get(VTy->getElementType(), 8); 3233 Value* EightV = llvm::ConstantVector::getSplat(nElts, Eight); 3234 Value *CmpRes = CGF.Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[2], EightV); 3235 CmpRes = CGF.Builder.CreateSExt(CmpRes, Ty); 3236 3237 SmallVector<Value *, 4> BslOps; 3238 BslOps.push_back(CmpRes); 3239 BslOps.push_back(Ops[0]); 3240 BslOps.push_back(TblRes); 3241 Function *BslF = CGF.CGM.getIntrinsic(Intrinsic::arm_neon_vbsl, Ty); 3242 return CGF.EmitNeonCall(BslF, BslOps, "vbsl"); 3243 } 3244 case NEON::BI__builtin_neon_vtbx2_v: { 3245 TblOps.push_back(Ops[1]); 3246 TblOps.push_back(Ops[2]); 3247 return packTBLDVectorList(CGF, TblOps, Ops[0], Ops[3], Ty, 3248 Intrinsic::aarch64_neon_vtbx1, "vtbx1"); 3249 } 3250 case NEON::BI__builtin_neon_vtbx3_v: { 3251 TblOps.push_back(Ops[1]); 3252 TblOps.push_back(Ops[2]); 3253 TblOps.push_back(Ops[3]); 3254 Value *TblRes = packTBLDVectorList(CGF, TblOps, 0, Ops[4], Ty, 3255 Intrinsic::aarch64_neon_vtbl2, "vtbl2"); 3256 3257 llvm::Constant *TwentyFour = ConstantInt::get(VTy->getElementType(), 24); 3258 Value* TwentyFourV = llvm::ConstantVector::getSplat(nElts, TwentyFour); 3259 Value *CmpRes = CGF.Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[4], 3260 TwentyFourV); 3261 CmpRes = CGF.Builder.CreateSExt(CmpRes, Ty); 3262 3263 SmallVector<Value *, 4> BslOps; 3264 BslOps.push_back(CmpRes); 3265 BslOps.push_back(Ops[0]); 3266 BslOps.push_back(TblRes); 3267 Function *BslF = CGF.CGM.getIntrinsic(Intrinsic::arm_neon_vbsl, Ty); 3268 return CGF.EmitNeonCall(BslF, BslOps, "vbsl"); 3269 } 3270 case NEON::BI__builtin_neon_vtbx4_v: { 3271 TblOps.push_back(Ops[1]); 3272 TblOps.push_back(Ops[2]); 3273 TblOps.push_back(Ops[3]); 3274 TblOps.push_back(Ops[4]); 3275 return packTBLDVectorList(CGF, TblOps, Ops[0], Ops[5], Ty, 3276 Intrinsic::aarch64_neon_vtbx2, "vtbx2"); 3277 } 3278 case NEON::BI__builtin_neon_vqtbl1_v: 3279 case NEON::BI__builtin_neon_vqtbl1q_v: 3280 Int = Intrinsic::aarch64_neon_vtbl1; s = "vtbl1"; break; 3281 case NEON::BI__builtin_neon_vqtbl2_v: 3282 case NEON::BI__builtin_neon_vqtbl2q_v: { 3283 Int = Intrinsic::aarch64_neon_vtbl2; s = "vtbl2"; break; 3284 case NEON::BI__builtin_neon_vqtbl3_v: 3285 case NEON::BI__builtin_neon_vqtbl3q_v: 3286 Int = Intrinsic::aarch64_neon_vtbl3; s = "vtbl3"; break; 3287 case NEON::BI__builtin_neon_vqtbl4_v: 3288 case NEON::BI__builtin_neon_vqtbl4q_v: 3289 Int = Intrinsic::aarch64_neon_vtbl4; s = "vtbl4"; break; 3290 case NEON::BI__builtin_neon_vqtbx1_v: 3291 case NEON::BI__builtin_neon_vqtbx1q_v: 3292 Int = Intrinsic::aarch64_neon_vtbx1; s = "vtbx1"; break; 3293 case NEON::BI__builtin_neon_vqtbx2_v: 3294 case NEON::BI__builtin_neon_vqtbx2q_v: 3295 Int = Intrinsic::aarch64_neon_vtbx2; s = "vtbx2"; break; 3296 case NEON::BI__builtin_neon_vqtbx3_v: 3297 case NEON::BI__builtin_neon_vqtbx3q_v: 3298 Int = Intrinsic::aarch64_neon_vtbx3; s = "vtbx3"; break; 3299 case NEON::BI__builtin_neon_vqtbx4_v: 3300 case NEON::BI__builtin_neon_vqtbx4q_v: 3301 Int = Intrinsic::aarch64_neon_vtbx4; s = "vtbx4"; break; 3302 } 3303 } 3304 3305 if (!Int) 3306 return 0; 3307 3308 Function *F = CGF.CGM.getIntrinsic(Int, Ty); 3309 return CGF.EmitNeonCall(F, Ops, s); 3310 } 3311 3312 Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, 3313 const CallExpr *E) { 3314 3315 // Process AArch64 scalar builtins 3316 llvm::ArrayRef<NeonIntrinsicInfo> SISDInfo(AArch64SISDIntrinsicInfo); 3317 const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap( 3318 SISDInfo, BuiltinID, AArch64SISDIntrinsicInfoProvenSorted); 3319 3320 if (Builtin) { 3321 Value *Result = EmitAArch64ScalarBuiltinExpr(*this, *Builtin, E); 3322 assert(Result && "SISD intrinsic should have been handled"); 3323 return Result; 3324 } 3325 3326 // Process AArch64 table lookup builtins 3327 if (Value *Result = EmitAArch64TblBuiltinExpr(*this, BuiltinID, E)) 3328 return Result; 3329 3330 if (BuiltinID == AArch64::BI__clear_cache) { 3331 assert(E->getNumArgs() == 2 && 3332 "Variadic __clear_cache slipped through on AArch64"); 3333 3334 const FunctionDecl *FD = E->getDirectCallee(); 3335 SmallVector<Value *, 2> Ops; 3336 for (unsigned i = 0; i < E->getNumArgs(); i++) 3337 Ops.push_back(EmitScalarExpr(E->getArg(i))); 3338 llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); 3339 llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); 3340 StringRef Name = FD->getName(); 3341 return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); 3342 } 3343 3344 SmallVector<Value *, 4> Ops; 3345 llvm::Value *Align = 0; // Alignment for load/store 3346 3347 if (BuiltinID == NEON::BI__builtin_neon_vldrq_p128) { 3348 Value *Op = EmitScalarExpr(E->getArg(0)); 3349 unsigned addressSpace = 3350 cast<llvm::PointerType>(Op->getType())->getAddressSpace(); 3351 llvm::Type *Ty = llvm::Type::getFP128PtrTy(getLLVMContext(), addressSpace); 3352 Op = Builder.CreateBitCast(Op, Ty); 3353 Op = Builder.CreateLoad(Op); 3354 Ty = llvm::Type::getIntNTy(getLLVMContext(), 128); 3355 return Builder.CreateBitCast(Op, Ty); 3356 } 3357 if (BuiltinID == NEON::BI__builtin_neon_vstrq_p128) { 3358 Value *Op0 = EmitScalarExpr(E->getArg(0)); 3359 unsigned addressSpace = 3360 cast<llvm::PointerType>(Op0->getType())->getAddressSpace(); 3361 llvm::Type *PTy = llvm::Type::getFP128PtrTy(getLLVMContext(), addressSpace); 3362 Op0 = Builder.CreateBitCast(Op0, PTy); 3363 Value *Op1 = EmitScalarExpr(E->getArg(1)); 3364 llvm::Type *Ty = llvm::Type::getFP128Ty(getLLVMContext()); 3365 Op1 = Builder.CreateBitCast(Op1, Ty); 3366 return Builder.CreateStore(Op1, Op0); 3367 } 3368 for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) { 3369 if (i == 0) { 3370 switch (BuiltinID) { 3371 case NEON::BI__builtin_neon_vld1_v: 3372 case NEON::BI__builtin_neon_vld1q_v: 3373 case NEON::BI__builtin_neon_vst1_v: 3374 case NEON::BI__builtin_neon_vst1q_v: 3375 case NEON::BI__builtin_neon_vst2_v: 3376 case NEON::BI__builtin_neon_vst2q_v: 3377 case NEON::BI__builtin_neon_vst3_v: 3378 case NEON::BI__builtin_neon_vst3q_v: 3379 case NEON::BI__builtin_neon_vst4_v: 3380 case NEON::BI__builtin_neon_vst4q_v: 3381 case NEON::BI__builtin_neon_vst1_x2_v: 3382 case NEON::BI__builtin_neon_vst1q_x2_v: 3383 case NEON::BI__builtin_neon_vst1_x3_v: 3384 case NEON::BI__builtin_neon_vst1q_x3_v: 3385 case NEON::BI__builtin_neon_vst1_x4_v: 3386 case NEON::BI__builtin_neon_vst1q_x4_v: 3387 // Handle ld1/st1 lane in this function a little different from ARM. 3388 case NEON::BI__builtin_neon_vld1_lane_v: 3389 case NEON::BI__builtin_neon_vld1q_lane_v: 3390 case NEON::BI__builtin_neon_vst1_lane_v: 3391 case NEON::BI__builtin_neon_vst1q_lane_v: 3392 case NEON::BI__builtin_neon_vst2_lane_v: 3393 case NEON::BI__builtin_neon_vst2q_lane_v: 3394 case NEON::BI__builtin_neon_vst3_lane_v: 3395 case NEON::BI__builtin_neon_vst3q_lane_v: 3396 case NEON::BI__builtin_neon_vst4_lane_v: 3397 case NEON::BI__builtin_neon_vst4q_lane_v: 3398 case NEON::BI__builtin_neon_vld1_dup_v: 3399 case NEON::BI__builtin_neon_vld1q_dup_v: 3400 // Get the alignment for the argument in addition to the value; 3401 // we'll use it later. 3402 std::pair<llvm::Value *, unsigned> Src = 3403 EmitPointerWithAlignment(E->getArg(0)); 3404 Ops.push_back(Src.first); 3405 Align = Builder.getInt32(Src.second); 3406 continue; 3407 } 3408 } 3409 if (i == 1) { 3410 switch (BuiltinID) { 3411 case NEON::BI__builtin_neon_vld2_v: 3412 case NEON::BI__builtin_neon_vld2q_v: 3413 case NEON::BI__builtin_neon_vld3_v: 3414 case NEON::BI__builtin_neon_vld3q_v: 3415 case NEON::BI__builtin_neon_vld4_v: 3416 case NEON::BI__builtin_neon_vld4q_v: 3417 case NEON::BI__builtin_neon_vld1_x2_v: 3418 case NEON::BI__builtin_neon_vld1q_x2_v: 3419 case NEON::BI__builtin_neon_vld1_x3_v: 3420 case NEON::BI__builtin_neon_vld1q_x3_v: 3421 case NEON::BI__builtin_neon_vld1_x4_v: 3422 case NEON::BI__builtin_neon_vld1q_x4_v: 3423 // Handle ld1/st1 dup lane in this function a little different from ARM. 3424 case NEON::BI__builtin_neon_vld2_dup_v: 3425 case NEON::BI__builtin_neon_vld2q_dup_v: 3426 case NEON::BI__builtin_neon_vld3_dup_v: 3427 case NEON::BI__builtin_neon_vld3q_dup_v: 3428 case NEON::BI__builtin_neon_vld4_dup_v: 3429 case NEON::BI__builtin_neon_vld4q_dup_v: 3430 case NEON::BI__builtin_neon_vld2_lane_v: 3431 case NEON::BI__builtin_neon_vld2q_lane_v: 3432 case NEON::BI__builtin_neon_vld3_lane_v: 3433 case NEON::BI__builtin_neon_vld3q_lane_v: 3434 case NEON::BI__builtin_neon_vld4_lane_v: 3435 case NEON::BI__builtin_neon_vld4q_lane_v: 3436 // Get the alignment for the argument in addition to the value; 3437 // we'll use it later. 3438 std::pair<llvm::Value *, unsigned> Src = 3439 EmitPointerWithAlignment(E->getArg(1)); 3440 Ops.push_back(Src.first); 3441 Align = Builder.getInt32(Src.second); 3442 continue; 3443 } 3444 } 3445 Ops.push_back(EmitScalarExpr(E->getArg(i))); 3446 } 3447 3448 // Get the last argument, which specifies the vector type. 3449 llvm::APSInt Result; 3450 const Expr *Arg = E->getArg(E->getNumArgs() - 1); 3451 if (!Arg->isIntegerConstantExpr(Result, getContext())) 3452 return 0; 3453 3454 // Determine the type of this overloaded NEON intrinsic. 3455 NeonTypeFlags Type(Result.getZExtValue()); 3456 bool usgn = Type.isUnsigned(); 3457 bool quad = Type.isQuad(); 3458 3459 llvm::VectorType *VTy = GetNeonType(this, Type); 3460 llvm::Type *Ty = VTy; 3461 if (!Ty) 3462 return 0; 3463 3464 3465 // Many NEON builtins have identical semantics and uses in ARM and 3466 // AArch64. Emit these in a single function. 3467 llvm::ArrayRef<NeonIntrinsicInfo> IntrinsicMap(ARMSIMDIntrinsicMap); 3468 Builtin = findNeonIntrinsicInMap(IntrinsicMap, BuiltinID, 3469 NEONSIMDIntrinsicsProvenSorted); 3470 if (Builtin) 3471 return EmitCommonNeonBuiltinExpr( 3472 Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic, 3473 Builtin->NameHint, Builtin->TypeModifier, E, Ops, Align); 3474 3475 unsigned Int; 3476 switch (BuiltinID) { 3477 default: 3478 return 0; 3479 3480 // AArch64 builtins mapping to legacy ARM v7 builtins. 3481 // FIXME: the mapped builtins listed correspond to what has been tested 3482 // in aarch64-neon-intrinsics.c so far. 3483 3484 // Shift by immediate 3485 case NEON::BI__builtin_neon_vrshr_n_v: 3486 case NEON::BI__builtin_neon_vrshrq_n_v: 3487 Int = usgn ? Intrinsic::aarch64_neon_vurshr 3488 : Intrinsic::aarch64_neon_vsrshr; 3489 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshr_n"); 3490 case NEON::BI__builtin_neon_vsra_n_v: 3491 if (VTy->getElementType()->isIntegerTy(64)) { 3492 Int = usgn ? Intrinsic::aarch64_neon_vsradu_n 3493 : Intrinsic::aarch64_neon_vsrads_n; 3494 return EmitNeonCall(CGM.getIntrinsic(Int), Ops, "vsra_n"); 3495 } 3496 return EmitARMBuiltinExpr(NEON::BI__builtin_neon_vsra_n_v, E); 3497 case NEON::BI__builtin_neon_vsraq_n_v: 3498 return EmitARMBuiltinExpr(NEON::BI__builtin_neon_vsraq_n_v, E); 3499 case NEON::BI__builtin_neon_vrsra_n_v: 3500 if (VTy->getElementType()->isIntegerTy(64)) { 3501 Int = usgn ? Intrinsic::aarch64_neon_vrsradu_n 3502 : Intrinsic::aarch64_neon_vrsrads_n; 3503 return EmitNeonCall(CGM.getIntrinsic(Int), Ops, "vrsra_n"); 3504 } 3505 // fall through 3506 case NEON::BI__builtin_neon_vrsraq_n_v: { 3507 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3508 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3509 Int = usgn ? Intrinsic::aarch64_neon_vurshr 3510 : Intrinsic::aarch64_neon_vsrshr; 3511 Ops[1] = Builder.CreateCall2(CGM.getIntrinsic(Int, Ty), Ops[1], Ops[2]); 3512 return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n"); 3513 } 3514 case NEON::BI__builtin_neon_vqshlu_n_v: 3515 case NEON::BI__builtin_neon_vqshluq_n_v: 3516 Int = Intrinsic::aarch64_neon_vsqshlu; 3517 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshlu_n"); 3518 case NEON::BI__builtin_neon_vsri_n_v: 3519 case NEON::BI__builtin_neon_vsriq_n_v: 3520 Int = Intrinsic::aarch64_neon_vsri; 3521 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsri_n"); 3522 case NEON::BI__builtin_neon_vsli_n_v: 3523 case NEON::BI__builtin_neon_vsliq_n_v: 3524 Int = Intrinsic::aarch64_neon_vsli; 3525 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsli_n"); 3526 case NEON::BI__builtin_neon_vqshrun_n_v: 3527 Int = Intrinsic::aarch64_neon_vsqshrun; 3528 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrun_n"); 3529 case NEON::BI__builtin_neon_vrshrn_n_v: 3530 Int = Intrinsic::aarch64_neon_vrshrn; 3531 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshrn_n"); 3532 case NEON::BI__builtin_neon_vqrshrun_n_v: 3533 Int = Intrinsic::aarch64_neon_vsqrshrun; 3534 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrun_n"); 3535 case NEON::BI__builtin_neon_vqshrn_n_v: 3536 Int = usgn ? Intrinsic::aarch64_neon_vuqshrn 3537 : Intrinsic::aarch64_neon_vsqshrn; 3538 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n"); 3539 case NEON::BI__builtin_neon_vqrshrn_n_v: 3540 Int = usgn ? Intrinsic::aarch64_neon_vuqrshrn 3541 : Intrinsic::aarch64_neon_vsqrshrn; 3542 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n"); 3543 3544 // Convert 3545 case NEON::BI__builtin_neon_vcvt_n_f64_v: 3546 case NEON::BI__builtin_neon_vcvtq_n_f64_v: { 3547 llvm::Type *FloatTy = 3548 GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, quad)); 3549 llvm::Type *Tys[2] = { FloatTy, Ty }; 3550 Int = usgn ? Intrinsic::arm_neon_vcvtfxu2fp 3551 : Intrinsic::arm_neon_vcvtfxs2fp; 3552 Function *F = CGM.getIntrinsic(Int, Tys); 3553 return EmitNeonCall(F, Ops, "vcvt_n"); 3554 } 3555 3556 // Load/Store 3557 case NEON::BI__builtin_neon_vld1_x2_v: 3558 case NEON::BI__builtin_neon_vld1q_x2_v: 3559 case NEON::BI__builtin_neon_vld1_x3_v: 3560 case NEON::BI__builtin_neon_vld1q_x3_v: 3561 case NEON::BI__builtin_neon_vld1_x4_v: 3562 case NEON::BI__builtin_neon_vld1q_x4_v: { 3563 unsigned Int; 3564 switch (BuiltinID) { 3565 case NEON::BI__builtin_neon_vld1_x2_v: 3566 case NEON::BI__builtin_neon_vld1q_x2_v: 3567 Int = Intrinsic::aarch64_neon_vld1x2; 3568 break; 3569 case NEON::BI__builtin_neon_vld1_x3_v: 3570 case NEON::BI__builtin_neon_vld1q_x3_v: 3571 Int = Intrinsic::aarch64_neon_vld1x3; 3572 break; 3573 case NEON::BI__builtin_neon_vld1_x4_v: 3574 case NEON::BI__builtin_neon_vld1q_x4_v: 3575 Int = Intrinsic::aarch64_neon_vld1x4; 3576 break; 3577 } 3578 Function *F = CGM.getIntrinsic(Int, Ty); 3579 Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld1xN"); 3580 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 3581 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3582 return Builder.CreateStore(Ops[1], Ops[0]); 3583 } 3584 case NEON::BI__builtin_neon_vst1_x2_v: 3585 case NEON::BI__builtin_neon_vst1q_x2_v: 3586 case NEON::BI__builtin_neon_vst1_x3_v: 3587 case NEON::BI__builtin_neon_vst1q_x3_v: 3588 case NEON::BI__builtin_neon_vst1_x4_v: 3589 case NEON::BI__builtin_neon_vst1q_x4_v: { 3590 Ops.push_back(Align); 3591 unsigned Int; 3592 switch (BuiltinID) { 3593 case NEON::BI__builtin_neon_vst1_x2_v: 3594 case NEON::BI__builtin_neon_vst1q_x2_v: 3595 Int = Intrinsic::aarch64_neon_vst1x2; 3596 break; 3597 case NEON::BI__builtin_neon_vst1_x3_v: 3598 case NEON::BI__builtin_neon_vst1q_x3_v: 3599 Int = Intrinsic::aarch64_neon_vst1x3; 3600 break; 3601 case NEON::BI__builtin_neon_vst1_x4_v: 3602 case NEON::BI__builtin_neon_vst1q_x4_v: 3603 Int = Intrinsic::aarch64_neon_vst1x4; 3604 break; 3605 } 3606 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, ""); 3607 } 3608 case NEON::BI__builtin_neon_vld1_lane_v: 3609 case NEON::BI__builtin_neon_vld1q_lane_v: { 3610 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3611 Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 3612 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3613 LoadInst *Ld = Builder.CreateLoad(Ops[0]); 3614 Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); 3615 return Builder.CreateInsertElement(Ops[1], Ld, Ops[2], "vld1_lane"); 3616 } 3617 case NEON::BI__builtin_neon_vst1_lane_v: 3618 case NEON::BI__builtin_neon_vst1q_lane_v: { 3619 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3620 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); 3621 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 3622 StoreInst *St = 3623 Builder.CreateStore(Ops[1], Builder.CreateBitCast(Ops[0], Ty)); 3624 St->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); 3625 return St; 3626 } 3627 case NEON::BI__builtin_neon_vld2_dup_v: 3628 case NEON::BI__builtin_neon_vld2q_dup_v: 3629 case NEON::BI__builtin_neon_vld3_dup_v: 3630 case NEON::BI__builtin_neon_vld3q_dup_v: 3631 case NEON::BI__builtin_neon_vld4_dup_v: 3632 case NEON::BI__builtin_neon_vld4q_dup_v: { 3633 // Handle 64-bit x 1 elements as a special-case. There is no "dup" needed. 3634 if (VTy->getElementType()->getPrimitiveSizeInBits() == 64 && 3635 VTy->getNumElements() == 1) { 3636 switch (BuiltinID) { 3637 case NEON::BI__builtin_neon_vld2_dup_v: 3638 Int = Intrinsic::arm_neon_vld2; 3639 break; 3640 case NEON::BI__builtin_neon_vld3_dup_v: 3641 Int = Intrinsic::arm_neon_vld3; 3642 break; 3643 case NEON::BI__builtin_neon_vld4_dup_v: 3644 Int = Intrinsic::arm_neon_vld4; 3645 break; 3646 default: 3647 llvm_unreachable("unknown vld_dup intrinsic?"); 3648 } 3649 Function *F = CGM.getIntrinsic(Int, Ty); 3650 Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld_dup"); 3651 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 3652 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3653 return Builder.CreateStore(Ops[1], Ops[0]); 3654 } 3655 switch (BuiltinID) { 3656 case NEON::BI__builtin_neon_vld2_dup_v: 3657 case NEON::BI__builtin_neon_vld2q_dup_v: 3658 Int = Intrinsic::arm_neon_vld2lane; 3659 break; 3660 case NEON::BI__builtin_neon_vld3_dup_v: 3661 case NEON::BI__builtin_neon_vld3q_dup_v: 3662 Int = Intrinsic::arm_neon_vld3lane; 3663 break; 3664 case NEON::BI__builtin_neon_vld4_dup_v: 3665 case NEON::BI__builtin_neon_vld4q_dup_v: 3666 Int = Intrinsic::arm_neon_vld4lane; 3667 break; 3668 } 3669 Function *F = CGM.getIntrinsic(Int, Ty); 3670 llvm::StructType *STy = cast<llvm::StructType>(F->getReturnType()); 3671 3672 SmallVector<Value *, 6> Args; 3673 Args.push_back(Ops[1]); 3674 Args.append(STy->getNumElements(), UndefValue::get(Ty)); 3675 3676 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 3677 Args.push_back(CI); 3678 Args.push_back(Align); 3679 3680 Ops[1] = Builder.CreateCall(F, Args, "vld_dup"); 3681 // splat lane 0 to all elts in each vector of the result. 3682 for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { 3683 Value *Val = Builder.CreateExtractValue(Ops[1], i); 3684 Value *Elt = Builder.CreateBitCast(Val, Ty); 3685 Elt = EmitNeonSplat(Elt, CI); 3686 Elt = Builder.CreateBitCast(Elt, Val->getType()); 3687 Ops[1] = Builder.CreateInsertValue(Ops[1], Elt, i); 3688 } 3689 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 3690 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3691 return Builder.CreateStore(Ops[1], Ops[0]); 3692 } 3693 3694 case NEON::BI__builtin_neon_vmul_lane_v: 3695 case NEON::BI__builtin_neon_vmul_laneq_v: { 3696 // v1f64 vmul_lane should be mapped to Neon scalar mul lane 3697 bool Quad = false; 3698 if (BuiltinID == NEON::BI__builtin_neon_vmul_laneq_v) 3699 Quad = true; 3700 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 3701 llvm::Type *VTy = GetNeonType(this, 3702 NeonTypeFlags(NeonTypeFlags::Float64, false, Quad)); 3703 Ops[1] = Builder.CreateBitCast(Ops[1], VTy); 3704 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2], "extract"); 3705 Value *Result = Builder.CreateFMul(Ops[0], Ops[1]); 3706 return Builder.CreateBitCast(Result, Ty); 3707 } 3708 3709 // AArch64-only builtins 3710 case NEON::BI__builtin_neon_vfmaq_laneq_v: { 3711 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 3712 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3713 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3714 3715 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 3716 Ops[2] = EmitNeonSplat(Ops[2], cast<ConstantInt>(Ops[3])); 3717 return Builder.CreateCall3(F, Ops[2], Ops[1], Ops[0]); 3718 } 3719 case NEON::BI__builtin_neon_vfmaq_lane_v: { 3720 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 3721 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3722 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3723 3724 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 3725 llvm::Type *STy = llvm::VectorType::get(VTy->getElementType(), 3726 VTy->getNumElements() / 2); 3727 Ops[2] = Builder.CreateBitCast(Ops[2], STy); 3728 Value* SV = llvm::ConstantVector::getSplat(VTy->getNumElements(), 3729 cast<ConstantInt>(Ops[3])); 3730 Ops[2] = Builder.CreateShuffleVector(Ops[2], Ops[2], SV, "lane"); 3731 3732 return Builder.CreateCall3(F, Ops[2], Ops[1], Ops[0]); 3733 } 3734 case NEON::BI__builtin_neon_vfma_lane_v: { 3735 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 3736 // v1f64 fma should be mapped to Neon scalar f64 fma 3737 if (VTy && VTy->getElementType() == DoubleTy) { 3738 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 3739 Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy); 3740 llvm::Type *VTy = GetNeonType(this, 3741 NeonTypeFlags(NeonTypeFlags::Float64, false, false)); 3742 Ops[2] = Builder.CreateBitCast(Ops[2], VTy); 3743 Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract"); 3744 Value *F = CGM.getIntrinsic(Intrinsic::fma, DoubleTy); 3745 Value *Result = Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]); 3746 return Builder.CreateBitCast(Result, Ty); 3747 } 3748 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 3749 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3750 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3751 3752 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 3753 Ops[2] = EmitNeonSplat(Ops[2], cast<ConstantInt>(Ops[3])); 3754 return Builder.CreateCall3(F, Ops[2], Ops[1], Ops[0]); 3755 } 3756 case NEON::BI__builtin_neon_vfma_laneq_v: { 3757 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 3758 // v1f64 fma should be mapped to Neon scalar f64 fma 3759 if (VTy && VTy->getElementType() == DoubleTy) { 3760 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 3761 Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy); 3762 llvm::Type *VTy = GetNeonType(this, 3763 NeonTypeFlags(NeonTypeFlags::Float64, false, true)); 3764 Ops[2] = Builder.CreateBitCast(Ops[2], VTy); 3765 Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract"); 3766 Value *F = CGM.getIntrinsic(Intrinsic::fma, DoubleTy); 3767 Value *Result = Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]); 3768 return Builder.CreateBitCast(Result, Ty); 3769 } 3770 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 3771 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3772 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3773 3774 llvm::Type *STy = llvm::VectorType::get(VTy->getElementType(), 3775 VTy->getNumElements() * 2); 3776 Ops[2] = Builder.CreateBitCast(Ops[2], STy); 3777 Value* SV = llvm::ConstantVector::getSplat(VTy->getNumElements(), 3778 cast<ConstantInt>(Ops[3])); 3779 Ops[2] = Builder.CreateShuffleVector(Ops[2], Ops[2], SV, "lane"); 3780 3781 return Builder.CreateCall3(F, Ops[2], Ops[1], Ops[0]); 3782 } 3783 case NEON::BI__builtin_neon_vfms_v: 3784 case NEON::BI__builtin_neon_vfmsq_v: { 3785 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 3786 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3787 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3788 Ops[1] = Builder.CreateFNeg(Ops[1]); 3789 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 3790 3791 // LLVM's fma intrinsic puts the accumulator in the last position, but the 3792 // AArch64 intrinsic has it first. 3793 return Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]); 3794 } 3795 case NEON::BI__builtin_neon_vmaxnm_v: 3796 case NEON::BI__builtin_neon_vmaxnmq_v: { 3797 Int = Intrinsic::aarch64_neon_vmaxnm; 3798 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmaxnm"); 3799 } 3800 case NEON::BI__builtin_neon_vminnm_v: 3801 case NEON::BI__builtin_neon_vminnmq_v: { 3802 Int = Intrinsic::aarch64_neon_vminnm; 3803 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vminnm"); 3804 } 3805 case NEON::BI__builtin_neon_vpmaxnm_v: 3806 case NEON::BI__builtin_neon_vpmaxnmq_v: { 3807 Int = Intrinsic::aarch64_neon_vpmaxnm; 3808 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmaxnm"); 3809 } 3810 case NEON::BI__builtin_neon_vpminnm_v: 3811 case NEON::BI__builtin_neon_vpminnmq_v: { 3812 Int = Intrinsic::aarch64_neon_vpminnm; 3813 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpminnm"); 3814 } 3815 case NEON::BI__builtin_neon_vpmaxq_v: { 3816 Int = usgn ? Intrinsic::arm_neon_vpmaxu : Intrinsic::arm_neon_vpmaxs; 3817 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmax"); 3818 } 3819 case NEON::BI__builtin_neon_vpminq_v: { 3820 Int = usgn ? Intrinsic::arm_neon_vpminu : Intrinsic::arm_neon_vpmins; 3821 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmin"); 3822 } 3823 case NEON::BI__builtin_neon_vmulx_v: 3824 case NEON::BI__builtin_neon_vmulxq_v: { 3825 Int = Intrinsic::aarch64_neon_vmulx; 3826 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmulx"); 3827 } 3828 case NEON::BI__builtin_neon_vsqadd_v: 3829 case NEON::BI__builtin_neon_vsqaddq_v: { 3830 Int = Intrinsic::aarch64_neon_usqadd; 3831 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqadd"); 3832 } 3833 case NEON::BI__builtin_neon_vuqadd_v: 3834 case NEON::BI__builtin_neon_vuqaddq_v: { 3835 Int = Intrinsic::aarch64_neon_suqadd; 3836 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vuqadd"); 3837 } 3838 case NEON::BI__builtin_neon_vrbit_v: 3839 case NEON::BI__builtin_neon_vrbitq_v: 3840 Int = Intrinsic::aarch64_neon_rbit; 3841 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrbit"); 3842 case NEON::BI__builtin_neon_vcvt_f32_f64: { 3843 NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float64, false, true); 3844 Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag)); 3845 return Builder.CreateFPTrunc(Ops[0], Ty, "vcvt"); 3846 } 3847 case NEON::BI__builtin_neon_vcvtx_f32_v: { 3848 llvm::Type *EltTy = FloatTy; 3849 llvm::Type *ResTy = llvm::VectorType::get(EltTy, 2); 3850 llvm::Type *Tys[2] = { ResTy, Ty }; 3851 Int = Intrinsic::aarch64_neon_vcvtxn; 3852 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtx_f32_f64"); 3853 } 3854 case NEON::BI__builtin_neon_vcvt_f64_f32: { 3855 llvm::Type *OpTy = 3856 GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, false)); 3857 Ops[0] = Builder.CreateBitCast(Ops[0], OpTy); 3858 return Builder.CreateFPExt(Ops[0], Ty, "vcvt"); 3859 } 3860 case NEON::BI__builtin_neon_vcvt_f64_v: 3861 case NEON::BI__builtin_neon_vcvtq_f64_v: { 3862 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3863 Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, quad)); 3864 return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") 3865 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); 3866 } 3867 case NEON::BI__builtin_neon_vrndn_v: 3868 case NEON::BI__builtin_neon_vrndnq_v: { 3869 Int = Intrinsic::aarch64_neon_frintn; 3870 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndn"); 3871 } 3872 case NEON::BI__builtin_neon_vrnda_v: 3873 case NEON::BI__builtin_neon_vrndaq_v: { 3874 Int = Intrinsic::round; 3875 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrnda"); 3876 } 3877 case NEON::BI__builtin_neon_vrndp_v: 3878 case NEON::BI__builtin_neon_vrndpq_v: { 3879 Int = Intrinsic::ceil; 3880 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndp"); 3881 } 3882 case NEON::BI__builtin_neon_vrndm_v: 3883 case NEON::BI__builtin_neon_vrndmq_v: { 3884 Int = Intrinsic::floor; 3885 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndm"); 3886 } 3887 case NEON::BI__builtin_neon_vrndx_v: 3888 case NEON::BI__builtin_neon_vrndxq_v: { 3889 Int = Intrinsic::rint; 3890 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndx"); 3891 } 3892 case NEON::BI__builtin_neon_vrnd_v: 3893 case NEON::BI__builtin_neon_vrndq_v: { 3894 Int = Intrinsic::trunc; 3895 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrnd"); 3896 } 3897 case NEON::BI__builtin_neon_vrndi_v: 3898 case NEON::BI__builtin_neon_vrndiq_v: { 3899 Int = Intrinsic::nearbyint; 3900 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndi"); 3901 } 3902 case NEON::BI__builtin_neon_vsqrt_v: 3903 case NEON::BI__builtin_neon_vsqrtq_v: { 3904 Int = Intrinsic::sqrt; 3905 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqrt"); 3906 } 3907 case NEON::BI__builtin_neon_vceqz_v: 3908 case NEON::BI__builtin_neon_vceqzq_v: 3909 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OEQ, 3910 ICmpInst::ICMP_EQ, "vceqz"); 3911 case NEON::BI__builtin_neon_vcgez_v: 3912 case NEON::BI__builtin_neon_vcgezq_v: 3913 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGE, 3914 ICmpInst::ICMP_SGE, "vcgez"); 3915 case NEON::BI__builtin_neon_vclez_v: 3916 case NEON::BI__builtin_neon_vclezq_v: 3917 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLE, 3918 ICmpInst::ICMP_SLE, "vclez"); 3919 case NEON::BI__builtin_neon_vcgtz_v: 3920 case NEON::BI__builtin_neon_vcgtzq_v: 3921 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGT, 3922 ICmpInst::ICMP_SGT, "vcgtz"); 3923 case NEON::BI__builtin_neon_vcltz_v: 3924 case NEON::BI__builtin_neon_vcltzq_v: 3925 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLT, 3926 ICmpInst::ICMP_SLT, "vcltz"); 3927 } 3928 } 3929 3930 Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, 3931 const CallExpr *E) { 3932 if (BuiltinID == ARM::BI__clear_cache) { 3933 assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments"); 3934 const FunctionDecl *FD = E->getDirectCallee(); 3935 SmallVector<Value*, 2> Ops; 3936 for (unsigned i = 0; i < 2; i++) 3937 Ops.push_back(EmitScalarExpr(E->getArg(i))); 3938 llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); 3939 llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); 3940 StringRef Name = FD->getName(); 3941 return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); 3942 } 3943 3944 if (BuiltinID == ARM::BI__builtin_arm_ldrexd || 3945 (BuiltinID == ARM::BI__builtin_arm_ldrex && 3946 getContext().getTypeSize(E->getType()) == 64)) { 3947 Function *F = CGM.getIntrinsic(Intrinsic::arm_ldrexd); 3948 3949 Value *LdPtr = EmitScalarExpr(E->getArg(0)); 3950 Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy), 3951 "ldrexd"); 3952 3953 Value *Val0 = Builder.CreateExtractValue(Val, 1); 3954 Value *Val1 = Builder.CreateExtractValue(Val, 0); 3955 Val0 = Builder.CreateZExt(Val0, Int64Ty); 3956 Val1 = Builder.CreateZExt(Val1, Int64Ty); 3957 3958 Value *ShiftCst = llvm::ConstantInt::get(Int64Ty, 32); 3959 Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */); 3960 Val = Builder.CreateOr(Val, Val1); 3961 return Builder.CreateBitCast(Val, ConvertType(E->getType())); 3962 } 3963 3964 if (BuiltinID == ARM::BI__builtin_arm_ldrex) { 3965 Value *LoadAddr = EmitScalarExpr(E->getArg(0)); 3966 3967 QualType Ty = E->getType(); 3968 llvm::Type *RealResTy = ConvertType(Ty); 3969 llvm::Type *IntResTy = llvm::IntegerType::get(getLLVMContext(), 3970 getContext().getTypeSize(Ty)); 3971 LoadAddr = Builder.CreateBitCast(LoadAddr, IntResTy->getPointerTo()); 3972 3973 Function *F = CGM.getIntrinsic(Intrinsic::arm_ldrex, LoadAddr->getType()); 3974 Value *Val = Builder.CreateCall(F, LoadAddr, "ldrex"); 3975 3976 if (RealResTy->isPointerTy()) 3977 return Builder.CreateIntToPtr(Val, RealResTy); 3978 else { 3979 Val = Builder.CreateTruncOrBitCast(Val, IntResTy); 3980 return Builder.CreateBitCast(Val, RealResTy); 3981 } 3982 } 3983 3984 if (BuiltinID == ARM::BI__builtin_arm_strexd || 3985 (BuiltinID == ARM::BI__builtin_arm_strex && 3986 getContext().getTypeSize(E->getArg(0)->getType()) == 64)) { 3987 Function *F = CGM.getIntrinsic(Intrinsic::arm_strexd); 3988 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, NULL); 3989 3990 Value *Tmp = CreateMemTemp(E->getArg(0)->getType()); 3991 Value *Val = EmitScalarExpr(E->getArg(0)); 3992 Builder.CreateStore(Val, Tmp); 3993 3994 Value *LdPtr = Builder.CreateBitCast(Tmp,llvm::PointerType::getUnqual(STy)); 3995 Val = Builder.CreateLoad(LdPtr); 3996 3997 Value *Arg0 = Builder.CreateExtractValue(Val, 0); 3998 Value *Arg1 = Builder.CreateExtractValue(Val, 1); 3999 Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), Int8PtrTy); 4000 return Builder.CreateCall3(F, Arg0, Arg1, StPtr, "strexd"); 4001 } 4002 4003 if (BuiltinID == ARM::BI__builtin_arm_strex) { 4004 Value *StoreVal = EmitScalarExpr(E->getArg(0)); 4005 Value *StoreAddr = EmitScalarExpr(E->getArg(1)); 4006 4007 QualType Ty = E->getArg(0)->getType(); 4008 llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(), 4009 getContext().getTypeSize(Ty)); 4010 StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo()); 4011 4012 if (StoreVal->getType()->isPointerTy()) 4013 StoreVal = Builder.CreatePtrToInt(StoreVal, Int32Ty); 4014 else { 4015 StoreVal = Builder.CreateBitCast(StoreVal, StoreTy); 4016 StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int32Ty); 4017 } 4018 4019 Function *F = CGM.getIntrinsic(Intrinsic::arm_strex, StoreAddr->getType()); 4020 return Builder.CreateCall2(F, StoreVal, StoreAddr, "strex"); 4021 } 4022 4023 if (BuiltinID == ARM::BI__builtin_arm_clrex) { 4024 Function *F = CGM.getIntrinsic(Intrinsic::arm_clrex); 4025 return Builder.CreateCall(F); 4026 } 4027 4028 if (BuiltinID == ARM::BI__builtin_arm_sevl) { 4029 Function *F = CGM.getIntrinsic(Intrinsic::arm_sevl); 4030 return Builder.CreateCall(F); 4031 } 4032 4033 // CRC32 4034 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic; 4035 switch (BuiltinID) { 4036 case ARM::BI__builtin_arm_crc32b: 4037 CRCIntrinsicID = Intrinsic::arm_crc32b; break; 4038 case ARM::BI__builtin_arm_crc32cb: 4039 CRCIntrinsicID = Intrinsic::arm_crc32cb; break; 4040 case ARM::BI__builtin_arm_crc32h: 4041 CRCIntrinsicID = Intrinsic::arm_crc32h; break; 4042 case ARM::BI__builtin_arm_crc32ch: 4043 CRCIntrinsicID = Intrinsic::arm_crc32ch; break; 4044 case ARM::BI__builtin_arm_crc32w: 4045 case ARM::BI__builtin_arm_crc32d: 4046 CRCIntrinsicID = Intrinsic::arm_crc32w; break; 4047 case ARM::BI__builtin_arm_crc32cw: 4048 case ARM::BI__builtin_arm_crc32cd: 4049 CRCIntrinsicID = Intrinsic::arm_crc32cw; break; 4050 } 4051 4052 if (CRCIntrinsicID != Intrinsic::not_intrinsic) { 4053 Value *Arg0 = EmitScalarExpr(E->getArg(0)); 4054 Value *Arg1 = EmitScalarExpr(E->getArg(1)); 4055 4056 // crc32{c,}d intrinsics are implemnted as two calls to crc32{c,}w 4057 // intrinsics, hence we need different codegen for these cases. 4058 if (BuiltinID == ARM::BI__builtin_arm_crc32d || 4059 BuiltinID == ARM::BI__builtin_arm_crc32cd) { 4060 Value *C1 = llvm::ConstantInt::get(Int64Ty, 32); 4061 Value *Arg1a = Builder.CreateTruncOrBitCast(Arg1, Int32Ty); 4062 Value *Arg1b = Builder.CreateLShr(Arg1, C1); 4063 Arg1b = Builder.CreateTruncOrBitCast(Arg1b, Int32Ty); 4064 4065 Function *F = CGM.getIntrinsic(CRCIntrinsicID); 4066 Value *Res = Builder.CreateCall2(F, Arg0, Arg1a); 4067 return Builder.CreateCall2(F, Res, Arg1b); 4068 } else { 4069 Arg1 = Builder.CreateZExtOrBitCast(Arg1, Int32Ty); 4070 4071 Function *F = CGM.getIntrinsic(CRCIntrinsicID); 4072 return Builder.CreateCall2(F, Arg0, Arg1); 4073 } 4074 } 4075 4076 SmallVector<Value*, 4> Ops; 4077 llvm::Value *Align = 0; 4078 for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) { 4079 if (i == 0) { 4080 switch (BuiltinID) { 4081 case NEON::BI__builtin_neon_vld1_v: 4082 case NEON::BI__builtin_neon_vld1q_v: 4083 case NEON::BI__builtin_neon_vld1q_lane_v: 4084 case NEON::BI__builtin_neon_vld1_lane_v: 4085 case NEON::BI__builtin_neon_vld1_dup_v: 4086 case NEON::BI__builtin_neon_vld1q_dup_v: 4087 case NEON::BI__builtin_neon_vst1_v: 4088 case NEON::BI__builtin_neon_vst1q_v: 4089 case NEON::BI__builtin_neon_vst1q_lane_v: 4090 case NEON::BI__builtin_neon_vst1_lane_v: 4091 case NEON::BI__builtin_neon_vst2_v: 4092 case NEON::BI__builtin_neon_vst2q_v: 4093 case NEON::BI__builtin_neon_vst2_lane_v: 4094 case NEON::BI__builtin_neon_vst2q_lane_v: 4095 case NEON::BI__builtin_neon_vst3_v: 4096 case NEON::BI__builtin_neon_vst3q_v: 4097 case NEON::BI__builtin_neon_vst3_lane_v: 4098 case NEON::BI__builtin_neon_vst3q_lane_v: 4099 case NEON::BI__builtin_neon_vst4_v: 4100 case NEON::BI__builtin_neon_vst4q_v: 4101 case NEON::BI__builtin_neon_vst4_lane_v: 4102 case NEON::BI__builtin_neon_vst4q_lane_v: 4103 // Get the alignment for the argument in addition to the value; 4104 // we'll use it later. 4105 std::pair<llvm::Value*, unsigned> Src = 4106 EmitPointerWithAlignment(E->getArg(0)); 4107 Ops.push_back(Src.first); 4108 Align = Builder.getInt32(Src.second); 4109 continue; 4110 } 4111 } 4112 if (i == 1) { 4113 switch (BuiltinID) { 4114 case NEON::BI__builtin_neon_vld2_v: 4115 case NEON::BI__builtin_neon_vld2q_v: 4116 case NEON::BI__builtin_neon_vld3_v: 4117 case NEON::BI__builtin_neon_vld3q_v: 4118 case NEON::BI__builtin_neon_vld4_v: 4119 case NEON::BI__builtin_neon_vld4q_v: 4120 case NEON::BI__builtin_neon_vld2_lane_v: 4121 case NEON::BI__builtin_neon_vld2q_lane_v: 4122 case NEON::BI__builtin_neon_vld3_lane_v: 4123 case NEON::BI__builtin_neon_vld3q_lane_v: 4124 case NEON::BI__builtin_neon_vld4_lane_v: 4125 case NEON::BI__builtin_neon_vld4q_lane_v: 4126 case NEON::BI__builtin_neon_vld2_dup_v: 4127 case NEON::BI__builtin_neon_vld3_dup_v: 4128 case NEON::BI__builtin_neon_vld4_dup_v: 4129 // Get the alignment for the argument in addition to the value; 4130 // we'll use it later. 4131 std::pair<llvm::Value*, unsigned> Src = 4132 EmitPointerWithAlignment(E->getArg(1)); 4133 Ops.push_back(Src.first); 4134 Align = Builder.getInt32(Src.second); 4135 continue; 4136 } 4137 } 4138 Ops.push_back(EmitScalarExpr(E->getArg(i))); 4139 } 4140 4141 switch (BuiltinID) { 4142 default: break; 4143 // vget_lane and vset_lane are not overloaded and do not have an extra 4144 // argument that specifies the vector type. 4145 case NEON::BI__builtin_neon_vget_lane_i8: 4146 case NEON::BI__builtin_neon_vget_lane_i16: 4147 case NEON::BI__builtin_neon_vget_lane_i32: 4148 case NEON::BI__builtin_neon_vget_lane_i64: 4149 case NEON::BI__builtin_neon_vget_lane_f32: 4150 case NEON::BI__builtin_neon_vgetq_lane_i8: 4151 case NEON::BI__builtin_neon_vgetq_lane_i16: 4152 case NEON::BI__builtin_neon_vgetq_lane_i32: 4153 case NEON::BI__builtin_neon_vgetq_lane_i64: 4154 case NEON::BI__builtin_neon_vgetq_lane_f32: 4155 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 4156 "vget_lane"); 4157 case NEON::BI__builtin_neon_vset_lane_i8: 4158 case NEON::BI__builtin_neon_vset_lane_i16: 4159 case NEON::BI__builtin_neon_vset_lane_i32: 4160 case NEON::BI__builtin_neon_vset_lane_i64: 4161 case NEON::BI__builtin_neon_vset_lane_f32: 4162 case NEON::BI__builtin_neon_vsetq_lane_i8: 4163 case NEON::BI__builtin_neon_vsetq_lane_i16: 4164 case NEON::BI__builtin_neon_vsetq_lane_i32: 4165 case NEON::BI__builtin_neon_vsetq_lane_i64: 4166 case NEON::BI__builtin_neon_vsetq_lane_f32: 4167 Ops.push_back(EmitScalarExpr(E->getArg(2))); 4168 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 4169 4170 // Non-polymorphic crypto instructions also not overloaded 4171 case NEON::BI__builtin_neon_vsha1h_u32: 4172 Ops.push_back(EmitScalarExpr(E->getArg(0))); 4173 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1h), Ops, 4174 "vsha1h"); 4175 case NEON::BI__builtin_neon_vsha1cq_u32: 4176 Ops.push_back(EmitScalarExpr(E->getArg(2))); 4177 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1c), Ops, 4178 "vsha1h"); 4179 case NEON::BI__builtin_neon_vsha1pq_u32: 4180 Ops.push_back(EmitScalarExpr(E->getArg(2))); 4181 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1p), Ops, 4182 "vsha1h"); 4183 case NEON::BI__builtin_neon_vsha1mq_u32: 4184 Ops.push_back(EmitScalarExpr(E->getArg(2))); 4185 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1m), Ops, 4186 "vsha1h"); 4187 } 4188 4189 // Get the last argument, which specifies the vector type. 4190 llvm::APSInt Result; 4191 const Expr *Arg = E->getArg(E->getNumArgs()-1); 4192 if (!Arg->isIntegerConstantExpr(Result, getContext())) 4193 return 0; 4194 4195 if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f || 4196 BuiltinID == ARM::BI__builtin_arm_vcvtr_d) { 4197 // Determine the overloaded type of this builtin. 4198 llvm::Type *Ty; 4199 if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f) 4200 Ty = FloatTy; 4201 else 4202 Ty = DoubleTy; 4203 4204 // Determine whether this is an unsigned conversion or not. 4205 bool usgn = Result.getZExtValue() == 1; 4206 unsigned Int = usgn ? Intrinsic::arm_vcvtru : Intrinsic::arm_vcvtr; 4207 4208 // Call the appropriate intrinsic. 4209 Function *F = CGM.getIntrinsic(Int, Ty); 4210 return Builder.CreateCall(F, Ops, "vcvtr"); 4211 } 4212 4213 // Determine the type of this overloaded NEON intrinsic. 4214 NeonTypeFlags Type(Result.getZExtValue()); 4215 bool usgn = Type.isUnsigned(); 4216 bool rightShift = false; 4217 4218 llvm::VectorType *VTy = GetNeonType(this, Type); 4219 llvm::Type *Ty = VTy; 4220 if (!Ty) 4221 return 0; 4222 4223 // Many NEON builtins have identical semantics and uses in ARM and 4224 // AArch64. Emit these in a single function. 4225 llvm::ArrayRef<NeonIntrinsicInfo> IntrinsicMap(ARMSIMDIntrinsicMap); 4226 const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap( 4227 IntrinsicMap, BuiltinID, NEONSIMDIntrinsicsProvenSorted); 4228 if (Builtin) 4229 return EmitCommonNeonBuiltinExpr( 4230 Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic, 4231 Builtin->NameHint, Builtin->TypeModifier, E, Ops, Align); 4232 4233 unsigned Int; 4234 switch (BuiltinID) { 4235 default: return 0; 4236 case NEON::BI__builtin_neon_vld1q_lane_v: 4237 // Handle 64-bit integer elements as a special case. Use shuffles of 4238 // one-element vectors to avoid poor code for i64 in the backend. 4239 if (VTy->getElementType()->isIntegerTy(64)) { 4240 // Extract the other lane. 4241 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4242 int Lane = cast<ConstantInt>(Ops[2])->getZExtValue(); 4243 Value *SV = llvm::ConstantVector::get(ConstantInt::get(Int32Ty, 1-Lane)); 4244 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); 4245 // Load the value as a one-element vector. 4246 Ty = llvm::VectorType::get(VTy->getElementType(), 1); 4247 Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Ty); 4248 Value *Ld = Builder.CreateCall2(F, Ops[0], Align); 4249 // Combine them. 4250 SmallVector<Constant*, 2> Indices; 4251 Indices.push_back(ConstantInt::get(Int32Ty, 1-Lane)); 4252 Indices.push_back(ConstantInt::get(Int32Ty, Lane)); 4253 SV = llvm::ConstantVector::get(Indices); 4254 return Builder.CreateShuffleVector(Ops[1], Ld, SV, "vld1q_lane"); 4255 } 4256 // fall through 4257 case NEON::BI__builtin_neon_vld1_lane_v: { 4258 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4259 Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 4260 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4261 LoadInst *Ld = Builder.CreateLoad(Ops[0]); 4262 Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); 4263 return Builder.CreateInsertElement(Ops[1], Ld, Ops[2], "vld1_lane"); 4264 } 4265 case NEON::BI__builtin_neon_vld2_dup_v: 4266 case NEON::BI__builtin_neon_vld3_dup_v: 4267 case NEON::BI__builtin_neon_vld4_dup_v: { 4268 // Handle 64-bit elements as a special-case. There is no "dup" needed. 4269 if (VTy->getElementType()->getPrimitiveSizeInBits() == 64) { 4270 switch (BuiltinID) { 4271 case NEON::BI__builtin_neon_vld2_dup_v: 4272 Int = Intrinsic::arm_neon_vld2; 4273 break; 4274 case NEON::BI__builtin_neon_vld3_dup_v: 4275 Int = Intrinsic::arm_neon_vld3; 4276 break; 4277 case NEON::BI__builtin_neon_vld4_dup_v: 4278 Int = Intrinsic::arm_neon_vld4; 4279 break; 4280 default: llvm_unreachable("unknown vld_dup intrinsic?"); 4281 } 4282 Function *F = CGM.getIntrinsic(Int, Ty); 4283 Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld_dup"); 4284 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 4285 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4286 return Builder.CreateStore(Ops[1], Ops[0]); 4287 } 4288 switch (BuiltinID) { 4289 case NEON::BI__builtin_neon_vld2_dup_v: 4290 Int = Intrinsic::arm_neon_vld2lane; 4291 break; 4292 case NEON::BI__builtin_neon_vld3_dup_v: 4293 Int = Intrinsic::arm_neon_vld3lane; 4294 break; 4295 case NEON::BI__builtin_neon_vld4_dup_v: 4296 Int = Intrinsic::arm_neon_vld4lane; 4297 break; 4298 default: llvm_unreachable("unknown vld_dup intrinsic?"); 4299 } 4300 Function *F = CGM.getIntrinsic(Int, Ty); 4301 llvm::StructType *STy = cast<llvm::StructType>(F->getReturnType()); 4302 4303 SmallVector<Value*, 6> Args; 4304 Args.push_back(Ops[1]); 4305 Args.append(STy->getNumElements(), UndefValue::get(Ty)); 4306 4307 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 4308 Args.push_back(CI); 4309 Args.push_back(Align); 4310 4311 Ops[1] = Builder.CreateCall(F, Args, "vld_dup"); 4312 // splat lane 0 to all elts in each vector of the result. 4313 for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { 4314 Value *Val = Builder.CreateExtractValue(Ops[1], i); 4315 Value *Elt = Builder.CreateBitCast(Val, Ty); 4316 Elt = EmitNeonSplat(Elt, CI); 4317 Elt = Builder.CreateBitCast(Elt, Val->getType()); 4318 Ops[1] = Builder.CreateInsertValue(Ops[1], Elt, i); 4319 } 4320 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 4321 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4322 return Builder.CreateStore(Ops[1], Ops[0]); 4323 } 4324 case NEON::BI__builtin_neon_vqrshrn_n_v: 4325 Int = 4326 usgn ? Intrinsic::arm_neon_vqrshiftnu : Intrinsic::arm_neon_vqrshiftns; 4327 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n", 4328 1, true); 4329 case NEON::BI__builtin_neon_vqrshrun_n_v: 4330 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrshiftnsu, Ty), 4331 Ops, "vqrshrun_n", 1, true); 4332 case NEON::BI__builtin_neon_vqshlu_n_v: 4333 case NEON::BI__builtin_neon_vqshluq_n_v: 4334 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftsu, Ty), 4335 Ops, "vqshlu", 1, false); 4336 case NEON::BI__builtin_neon_vqshrn_n_v: 4337 Int = usgn ? Intrinsic::arm_neon_vqshiftnu : Intrinsic::arm_neon_vqshiftns; 4338 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n", 4339 1, true); 4340 case NEON::BI__builtin_neon_vqshrun_n_v: 4341 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftnsu, Ty), 4342 Ops, "vqshrun_n", 1, true); 4343 case NEON::BI__builtin_neon_vrecpe_v: 4344 case NEON::BI__builtin_neon_vrecpeq_v: 4345 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecpe, Ty), 4346 Ops, "vrecpe"); 4347 case NEON::BI__builtin_neon_vrshrn_n_v: 4348 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrshiftn, Ty), 4349 Ops, "vrshrn_n", 1, true); 4350 case NEON::BI__builtin_neon_vrshr_n_v: 4351 case NEON::BI__builtin_neon_vrshrq_n_v: 4352 Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 4353 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshr_n", 1, true); 4354 case NEON::BI__builtin_neon_vrsra_n_v: 4355 case NEON::BI__builtin_neon_vrsraq_n_v: 4356 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4357 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4358 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, true); 4359 Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 4360 Ops[1] = Builder.CreateCall2(CGM.getIntrinsic(Int, Ty), Ops[1], Ops[2]); 4361 return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n"); 4362 case NEON::BI__builtin_neon_vsri_n_v: 4363 case NEON::BI__builtin_neon_vsriq_n_v: 4364 rightShift = true; 4365 case NEON::BI__builtin_neon_vsli_n_v: 4366 case NEON::BI__builtin_neon_vsliq_n_v: 4367 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, rightShift); 4368 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftins, Ty), 4369 Ops, "vsli_n"); 4370 case NEON::BI__builtin_neon_vsra_n_v: 4371 case NEON::BI__builtin_neon_vsraq_n_v: 4372 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4373 Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n"); 4374 return Builder.CreateAdd(Ops[0], Ops[1]); 4375 case NEON::BI__builtin_neon_vst1q_lane_v: 4376 // Handle 64-bit integer elements as a special case. Use a shuffle to get 4377 // a one-element vector and avoid poor code for i64 in the backend. 4378 if (VTy->getElementType()->isIntegerTy(64)) { 4379 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4380 Value *SV = llvm::ConstantVector::get(cast<llvm::Constant>(Ops[2])); 4381 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); 4382 Ops[2] = Align; 4383 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, 4384 Ops[1]->getType()), Ops); 4385 } 4386 // fall through 4387 case NEON::BI__builtin_neon_vst1_lane_v: { 4388 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4389 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); 4390 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 4391 StoreInst *St = Builder.CreateStore(Ops[1], 4392 Builder.CreateBitCast(Ops[0], Ty)); 4393 St->setAlignment(cast<ConstantInt>(Align)->getZExtValue()); 4394 return St; 4395 } 4396 case NEON::BI__builtin_neon_vtbl1_v: 4397 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl1), 4398 Ops, "vtbl1"); 4399 case NEON::BI__builtin_neon_vtbl2_v: 4400 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl2), 4401 Ops, "vtbl2"); 4402 case NEON::BI__builtin_neon_vtbl3_v: 4403 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl3), 4404 Ops, "vtbl3"); 4405 case NEON::BI__builtin_neon_vtbl4_v: 4406 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl4), 4407 Ops, "vtbl4"); 4408 case NEON::BI__builtin_neon_vtbx1_v: 4409 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx1), 4410 Ops, "vtbx1"); 4411 case NEON::BI__builtin_neon_vtbx2_v: 4412 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx2), 4413 Ops, "vtbx2"); 4414 case NEON::BI__builtin_neon_vtbx3_v: 4415 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx3), 4416 Ops, "vtbx3"); 4417 case NEON::BI__builtin_neon_vtbx4_v: 4418 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx4), 4419 Ops, "vtbx4"); 4420 } 4421 } 4422 4423 llvm::Value *CodeGenFunction:: 4424 BuildVector(ArrayRef<llvm::Value*> Ops) { 4425 assert((Ops.size() & (Ops.size() - 1)) == 0 && 4426 "Not a power-of-two sized vector!"); 4427 bool AllConstants = true; 4428 for (unsigned i = 0, e = Ops.size(); i != e && AllConstants; ++i) 4429 AllConstants &= isa<Constant>(Ops[i]); 4430 4431 // If this is a constant vector, create a ConstantVector. 4432 if (AllConstants) { 4433 SmallVector<llvm::Constant*, 16> CstOps; 4434 for (unsigned i = 0, e = Ops.size(); i != e; ++i) 4435 CstOps.push_back(cast<Constant>(Ops[i])); 4436 return llvm::ConstantVector::get(CstOps); 4437 } 4438 4439 // Otherwise, insertelement the values to build the vector. 4440 Value *Result = 4441 llvm::UndefValue::get(llvm::VectorType::get(Ops[0]->getType(), Ops.size())); 4442 4443 for (unsigned i = 0, e = Ops.size(); i != e; ++i) 4444 Result = Builder.CreateInsertElement(Result, Ops[i], Builder.getInt32(i)); 4445 4446 return Result; 4447 } 4448 4449 Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, 4450 const CallExpr *E) { 4451 SmallVector<Value*, 4> Ops; 4452 4453 // Find out if any arguments are required to be integer constant expressions. 4454 unsigned ICEArguments = 0; 4455 ASTContext::GetBuiltinTypeError Error; 4456 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 4457 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 4458 4459 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) { 4460 // If this is a normal argument, just emit it as a scalar. 4461 if ((ICEArguments & (1 << i)) == 0) { 4462 Ops.push_back(EmitScalarExpr(E->getArg(i))); 4463 continue; 4464 } 4465 4466 // If this is required to be a constant, constant fold it so that we know 4467 // that the generated intrinsic gets a ConstantInt. 4468 llvm::APSInt Result; 4469 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext()); 4470 assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst; 4471 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result)); 4472 } 4473 4474 switch (BuiltinID) { 4475 default: return 0; 4476 case X86::BI_mm_prefetch: { 4477 Value *Address = EmitScalarExpr(E->getArg(0)); 4478 Value *RW = ConstantInt::get(Int32Ty, 0); 4479 Value *Locality = EmitScalarExpr(E->getArg(1)); 4480 Value *Data = ConstantInt::get(Int32Ty, 1); 4481 Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 4482 return Builder.CreateCall4(F, Address, RW, Locality, Data); 4483 } 4484 case X86::BI__builtin_ia32_vec_init_v8qi: 4485 case X86::BI__builtin_ia32_vec_init_v4hi: 4486 case X86::BI__builtin_ia32_vec_init_v2si: 4487 return Builder.CreateBitCast(BuildVector(Ops), 4488 llvm::Type::getX86_MMXTy(getLLVMContext())); 4489 case X86::BI__builtin_ia32_vec_ext_v2si: 4490 return Builder.CreateExtractElement(Ops[0], 4491 llvm::ConstantInt::get(Ops[1]->getType(), 0)); 4492 case X86::BI__builtin_ia32_ldmxcsr: { 4493 Value *Tmp = CreateMemTemp(E->getArg(0)->getType()); 4494 Builder.CreateStore(Ops[0], Tmp); 4495 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr), 4496 Builder.CreateBitCast(Tmp, Int8PtrTy)); 4497 } 4498 case X86::BI__builtin_ia32_stmxcsr: { 4499 Value *Tmp = CreateMemTemp(E->getType()); 4500 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr), 4501 Builder.CreateBitCast(Tmp, Int8PtrTy)); 4502 return Builder.CreateLoad(Tmp, "stmxcsr"); 4503 } 4504 case X86::BI__builtin_ia32_storehps: 4505 case X86::BI__builtin_ia32_storelps: { 4506 llvm::Type *PtrTy = llvm::PointerType::getUnqual(Int64Ty); 4507 llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2); 4508 4509 // cast val v2i64 4510 Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast"); 4511 4512 // extract (0, 1) 4513 unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1; 4514 llvm::Value *Idx = llvm::ConstantInt::get(Int32Ty, Index); 4515 Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract"); 4516 4517 // cast pointer to i64 & store 4518 Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy); 4519 return Builder.CreateStore(Ops[1], Ops[0]); 4520 } 4521 case X86::BI__builtin_ia32_palignr: { 4522 unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 4523 4524 // If palignr is shifting the pair of input vectors less than 9 bytes, 4525 // emit a shuffle instruction. 4526 if (shiftVal <= 8) { 4527 SmallVector<llvm::Constant*, 8> Indices; 4528 for (unsigned i = 0; i != 8; ++i) 4529 Indices.push_back(llvm::ConstantInt::get(Int32Ty, shiftVal + i)); 4530 4531 Value* SV = llvm::ConstantVector::get(Indices); 4532 return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 4533 } 4534 4535 // If palignr is shifting the pair of input vectors more than 8 but less 4536 // than 16 bytes, emit a logical right shift of the destination. 4537 if (shiftVal < 16) { 4538 // MMX has these as 1 x i64 vectors for some odd optimization reasons. 4539 llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 1); 4540 4541 Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 4542 Ops[1] = llvm::ConstantInt::get(VecTy, (shiftVal-8) * 8); 4543 4544 // create i32 constant 4545 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_mmx_psrl_q); 4546 return Builder.CreateCall(F, makeArrayRef(&Ops[0], 2), "palignr"); 4547 } 4548 4549 // If palignr is shifting the pair of vectors more than 16 bytes, emit zero. 4550 return llvm::Constant::getNullValue(ConvertType(E->getType())); 4551 } 4552 case X86::BI__builtin_ia32_palignr128: { 4553 unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 4554 4555 // If palignr is shifting the pair of input vectors less than 17 bytes, 4556 // emit a shuffle instruction. 4557 if (shiftVal <= 16) { 4558 SmallVector<llvm::Constant*, 16> Indices; 4559 for (unsigned i = 0; i != 16; ++i) 4560 Indices.push_back(llvm::ConstantInt::get(Int32Ty, shiftVal + i)); 4561 4562 Value* SV = llvm::ConstantVector::get(Indices); 4563 return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 4564 } 4565 4566 // If palignr is shifting the pair of input vectors more than 16 but less 4567 // than 32 bytes, emit a logical right shift of the destination. 4568 if (shiftVal < 32) { 4569 llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2); 4570 4571 Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 4572 Ops[1] = llvm::ConstantInt::get(Int32Ty, (shiftVal-16) * 8); 4573 4574 // create i32 constant 4575 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse2_psrl_dq); 4576 return Builder.CreateCall(F, makeArrayRef(&Ops[0], 2), "palignr"); 4577 } 4578 4579 // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 4580 return llvm::Constant::getNullValue(ConvertType(E->getType())); 4581 } 4582 case X86::BI__builtin_ia32_palignr256: { 4583 unsigned shiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 4584 4585 // If palignr is shifting the pair of input vectors less than 17 bytes, 4586 // emit a shuffle instruction. 4587 if (shiftVal <= 16) { 4588 SmallVector<llvm::Constant*, 32> Indices; 4589 // 256-bit palignr operates on 128-bit lanes so we need to handle that 4590 for (unsigned l = 0; l != 2; ++l) { 4591 unsigned LaneStart = l * 16; 4592 unsigned LaneEnd = (l+1) * 16; 4593 for (unsigned i = 0; i != 16; ++i) { 4594 unsigned Idx = shiftVal + i + LaneStart; 4595 if (Idx >= LaneEnd) Idx += 16; // end of lane, switch operand 4596 Indices.push_back(llvm::ConstantInt::get(Int32Ty, Idx)); 4597 } 4598 } 4599 4600 Value* SV = llvm::ConstantVector::get(Indices); 4601 return Builder.CreateShuffleVector(Ops[1], Ops[0], SV, "palignr"); 4602 } 4603 4604 // If palignr is shifting the pair of input vectors more than 16 but less 4605 // than 32 bytes, emit a logical right shift of the destination. 4606 if (shiftVal < 32) { 4607 llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 4); 4608 4609 Ops[0] = Builder.CreateBitCast(Ops[0], VecTy, "cast"); 4610 Ops[1] = llvm::ConstantInt::get(Int32Ty, (shiftVal-16) * 8); 4611 4612 // create i32 constant 4613 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_avx2_psrl_dq); 4614 return Builder.CreateCall(F, makeArrayRef(&Ops[0], 2), "palignr"); 4615 } 4616 4617 // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 4618 return llvm::Constant::getNullValue(ConvertType(E->getType())); 4619 } 4620 case X86::BI__builtin_ia32_movntps: 4621 case X86::BI__builtin_ia32_movntps256: 4622 case X86::BI__builtin_ia32_movntpd: 4623 case X86::BI__builtin_ia32_movntpd256: 4624 case X86::BI__builtin_ia32_movntdq: 4625 case X86::BI__builtin_ia32_movntdq256: 4626 case X86::BI__builtin_ia32_movnti: 4627 case X86::BI__builtin_ia32_movnti64: { 4628 llvm::MDNode *Node = llvm::MDNode::get(getLLVMContext(), 4629 Builder.getInt32(1)); 4630 4631 // Convert the type of the pointer to a pointer to the stored type. 4632 Value *BC = Builder.CreateBitCast(Ops[0], 4633 llvm::PointerType::getUnqual(Ops[1]->getType()), 4634 "cast"); 4635 StoreInst *SI = Builder.CreateStore(Ops[1], BC); 4636 SI->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); 4637 4638 // If the operand is an integer, we can't assume alignment. Otherwise, 4639 // assume natural alignment. 4640 QualType ArgTy = E->getArg(1)->getType(); 4641 unsigned Align; 4642 if (ArgTy->isIntegerType()) 4643 Align = 1; 4644 else 4645 Align = getContext().getTypeSizeInChars(ArgTy).getQuantity(); 4646 SI->setAlignment(Align); 4647 return SI; 4648 } 4649 // 3DNow! 4650 case X86::BI__builtin_ia32_pswapdsf: 4651 case X86::BI__builtin_ia32_pswapdsi: { 4652 const char *name = 0; 4653 Intrinsic::ID ID = Intrinsic::not_intrinsic; 4654 switch(BuiltinID) { 4655 default: llvm_unreachable("Unsupported intrinsic!"); 4656 case X86::BI__builtin_ia32_pswapdsf: 4657 case X86::BI__builtin_ia32_pswapdsi: 4658 name = "pswapd"; 4659 ID = Intrinsic::x86_3dnowa_pswapd; 4660 break; 4661 } 4662 llvm::Type *MMXTy = llvm::Type::getX86_MMXTy(getLLVMContext()); 4663 Ops[0] = Builder.CreateBitCast(Ops[0], MMXTy, "cast"); 4664 llvm::Function *F = CGM.getIntrinsic(ID); 4665 return Builder.CreateCall(F, Ops, name); 4666 } 4667 case X86::BI__builtin_ia32_rdrand16_step: 4668 case X86::BI__builtin_ia32_rdrand32_step: 4669 case X86::BI__builtin_ia32_rdrand64_step: 4670 case X86::BI__builtin_ia32_rdseed16_step: 4671 case X86::BI__builtin_ia32_rdseed32_step: 4672 case X86::BI__builtin_ia32_rdseed64_step: { 4673 Intrinsic::ID ID; 4674 switch (BuiltinID) { 4675 default: llvm_unreachable("Unsupported intrinsic!"); 4676 case X86::BI__builtin_ia32_rdrand16_step: 4677 ID = Intrinsic::x86_rdrand_16; 4678 break; 4679 case X86::BI__builtin_ia32_rdrand32_step: 4680 ID = Intrinsic::x86_rdrand_32; 4681 break; 4682 case X86::BI__builtin_ia32_rdrand64_step: 4683 ID = Intrinsic::x86_rdrand_64; 4684 break; 4685 case X86::BI__builtin_ia32_rdseed16_step: 4686 ID = Intrinsic::x86_rdseed_16; 4687 break; 4688 case X86::BI__builtin_ia32_rdseed32_step: 4689 ID = Intrinsic::x86_rdseed_32; 4690 break; 4691 case X86::BI__builtin_ia32_rdseed64_step: 4692 ID = Intrinsic::x86_rdseed_64; 4693 break; 4694 } 4695 4696 Value *Call = Builder.CreateCall(CGM.getIntrinsic(ID)); 4697 Builder.CreateStore(Builder.CreateExtractValue(Call, 0), Ops[0]); 4698 return Builder.CreateExtractValue(Call, 1); 4699 } 4700 // AVX2 broadcast 4701 case X86::BI__builtin_ia32_vbroadcastsi256: { 4702 Value *VecTmp = CreateMemTemp(E->getArg(0)->getType()); 4703 Builder.CreateStore(Ops[0], VecTmp); 4704 Value *F = CGM.getIntrinsic(Intrinsic::x86_avx2_vbroadcasti128); 4705 return Builder.CreateCall(F, Builder.CreateBitCast(VecTmp, Int8PtrTy)); 4706 } 4707 } 4708 } 4709 4710 4711 Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, 4712 const CallExpr *E) { 4713 SmallVector<Value*, 4> Ops; 4714 4715 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) 4716 Ops.push_back(EmitScalarExpr(E->getArg(i))); 4717 4718 Intrinsic::ID ID = Intrinsic::not_intrinsic; 4719 4720 switch (BuiltinID) { 4721 default: return 0; 4722 4723 // vec_ld, vec_lvsl, vec_lvsr 4724 case PPC::BI__builtin_altivec_lvx: 4725 case PPC::BI__builtin_altivec_lvxl: 4726 case PPC::BI__builtin_altivec_lvebx: 4727 case PPC::BI__builtin_altivec_lvehx: 4728 case PPC::BI__builtin_altivec_lvewx: 4729 case PPC::BI__builtin_altivec_lvsl: 4730 case PPC::BI__builtin_altivec_lvsr: 4731 { 4732 Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy); 4733 4734 Ops[0] = Builder.CreateGEP(Ops[1], Ops[0]); 4735 Ops.pop_back(); 4736 4737 switch (BuiltinID) { 4738 default: llvm_unreachable("Unsupported ld/lvsl/lvsr intrinsic!"); 4739 case PPC::BI__builtin_altivec_lvx: 4740 ID = Intrinsic::ppc_altivec_lvx; 4741 break; 4742 case PPC::BI__builtin_altivec_lvxl: 4743 ID = Intrinsic::ppc_altivec_lvxl; 4744 break; 4745 case PPC::BI__builtin_altivec_lvebx: 4746 ID = Intrinsic::ppc_altivec_lvebx; 4747 break; 4748 case PPC::BI__builtin_altivec_lvehx: 4749 ID = Intrinsic::ppc_altivec_lvehx; 4750 break; 4751 case PPC::BI__builtin_altivec_lvewx: 4752 ID = Intrinsic::ppc_altivec_lvewx; 4753 break; 4754 case PPC::BI__builtin_altivec_lvsl: 4755 ID = Intrinsic::ppc_altivec_lvsl; 4756 break; 4757 case PPC::BI__builtin_altivec_lvsr: 4758 ID = Intrinsic::ppc_altivec_lvsr; 4759 break; 4760 } 4761 llvm::Function *F = CGM.getIntrinsic(ID); 4762 return Builder.CreateCall(F, Ops, ""); 4763 } 4764 4765 // vec_st 4766 case PPC::BI__builtin_altivec_stvx: 4767 case PPC::BI__builtin_altivec_stvxl: 4768 case PPC::BI__builtin_altivec_stvebx: 4769 case PPC::BI__builtin_altivec_stvehx: 4770 case PPC::BI__builtin_altivec_stvewx: 4771 { 4772 Ops[2] = Builder.CreateBitCast(Ops[2], Int8PtrTy); 4773 Ops[1] = Builder.CreateGEP(Ops[2], Ops[1]); 4774 Ops.pop_back(); 4775 4776 switch (BuiltinID) { 4777 default: llvm_unreachable("Unsupported st intrinsic!"); 4778 case PPC::BI__builtin_altivec_stvx: 4779 ID = Intrinsic::ppc_altivec_stvx; 4780 break; 4781 case PPC::BI__builtin_altivec_stvxl: 4782 ID = Intrinsic::ppc_altivec_stvxl; 4783 break; 4784 case PPC::BI__builtin_altivec_stvebx: 4785 ID = Intrinsic::ppc_altivec_stvebx; 4786 break; 4787 case PPC::BI__builtin_altivec_stvehx: 4788 ID = Intrinsic::ppc_altivec_stvehx; 4789 break; 4790 case PPC::BI__builtin_altivec_stvewx: 4791 ID = Intrinsic::ppc_altivec_stvewx; 4792 break; 4793 } 4794 llvm::Function *F = CGM.getIntrinsic(ID); 4795 return Builder.CreateCall(F, Ops, ""); 4796 } 4797 } 4798 } 4799