854 lines · cpp
1//===- ARM.cpp ------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "ABIInfoImpl.h"10#include "TargetInfo.h"11 12using namespace clang;13using namespace clang::CodeGen;14 15//===----------------------------------------------------------------------===//16// ARM ABI Implementation17//===----------------------------------------------------------------------===//18 19namespace {20 21class ARMABIInfo : public ABIInfo {22 ARMABIKind Kind;23 bool IsFloatABISoftFP;24 25public:26 ARMABIInfo(CodeGenTypes &CGT, ARMABIKind Kind) : ABIInfo(CGT), Kind(Kind) {27 setCCs();28 IsFloatABISoftFP = CGT.getCodeGenOpts().FloatABI == "softfp" ||29 CGT.getCodeGenOpts().FloatABI == ""; // default30 }31 32 bool isEABI() const {33 switch (getTarget().getTriple().getEnvironment()) {34 case llvm::Triple::Android:35 case llvm::Triple::EABI:36 case llvm::Triple::EABIHF:37 case llvm::Triple::GNUEABI:38 case llvm::Triple::GNUEABIT64:39 case llvm::Triple::GNUEABIHF:40 case llvm::Triple::GNUEABIHFT64:41 case llvm::Triple::MuslEABI:42 case llvm::Triple::MuslEABIHF:43 return true;44 default:45 return getTarget().getTriple().isOHOSFamily();46 }47 }48 49 bool isEABIHF() const {50 switch (getTarget().getTriple().getEnvironment()) {51 case llvm::Triple::EABIHF:52 case llvm::Triple::GNUEABIHF:53 case llvm::Triple::GNUEABIHFT64:54 case llvm::Triple::MuslEABIHF:55 return true;56 default:57 return false;58 }59 }60 61 ARMABIKind getABIKind() const { return Kind; }62 63 bool allowBFloatArgsAndRet() const override {64 return !IsFloatABISoftFP && getTarget().hasBFloat16Type();65 }66 67private:68 ABIArgInfo classifyReturnType(QualType RetTy, bool isVariadic,69 unsigned functionCallConv) const;70 ABIArgInfo classifyArgumentType(QualType RetTy, bool isVariadic,71 unsigned functionCallConv) const;72 ABIArgInfo classifyHomogeneousAggregate(QualType Ty, const Type *Base,73 uint64_t Members) const;74 bool shouldIgnoreEmptyArg(QualType Ty) const;75 ABIArgInfo coerceIllegalVector(QualType Ty) const;76 bool isIllegalVectorType(QualType Ty) const;77 bool containsAnyFP16Vectors(QualType Ty) const;78 79 bool isHomogeneousAggregateBaseType(QualType Ty) const override;80 bool isHomogeneousAggregateSmallEnough(const Type *Ty,81 uint64_t Members) const override;82 bool isZeroLengthBitfieldPermittedInHomogeneousAggregate() const override;83 84 bool isEffectivelyAAPCS_VFP(unsigned callConvention, bool acceptHalf) const;85 86 void computeInfo(CGFunctionInfo &FI) const override;87 88 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,89 AggValueSlot Slot) const override;90 91 llvm::CallingConv::ID getLLVMDefaultCC() const;92 llvm::CallingConv::ID getABIDefaultCC() const;93 void setCCs();94};95 96class ARMSwiftABIInfo : public SwiftABIInfo {97public:98 explicit ARMSwiftABIInfo(CodeGenTypes &CGT)99 : SwiftABIInfo(CGT, /*SwiftErrorInRegister=*/true) {}100 101 bool isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,102 unsigned NumElts) const override;103};104 105class ARMTargetCodeGenInfo : public TargetCodeGenInfo {106public:107 ARMTargetCodeGenInfo(CodeGenTypes &CGT, ARMABIKind K)108 : TargetCodeGenInfo(std::make_unique<ARMABIInfo>(CGT, K)) {109 SwiftInfo = std::make_unique<ARMSwiftABIInfo>(CGT);110 }111 112 int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {113 return 13;114 }115 116 StringRef getARCRetainAutoreleasedReturnValueMarker() const override {117 return "mov\tr7, r7\t\t// marker for objc_retainAutoreleaseReturnValue";118 }119 120 bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,121 llvm::Value *Address) const override {122 llvm::Value *Four8 = llvm::ConstantInt::get(CGF.Int8Ty, 4);123 124 // 0-15 are the 16 integer registers.125 AssignToArrayRange(CGF.Builder, Address, Four8, 0, 15);126 return false;127 }128 129 unsigned getSizeOfUnwindException() const override {130 if (getABIInfo<ARMABIInfo>().isEABI())131 return 88;132 return TargetCodeGenInfo::getSizeOfUnwindException();133 }134 135 void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,136 CodeGen::CodeGenModule &CGM) const override {137 auto *Fn = dyn_cast<llvm::Function>(GV);138 if (!Fn)139 return;140 const auto *FD = dyn_cast_or_null<FunctionDecl>(D);141 142 if (FD && FD->hasAttr<TargetAttr>()) {143 const auto *TA = FD->getAttr<TargetAttr>();144 ParsedTargetAttr Attr =145 CGM.getTarget().parseTargetAttr(TA->getFeaturesStr());146 if (!Attr.BranchProtection.empty()) {147 TargetInfo::BranchProtectionInfo BPI{};148 StringRef DiagMsg;149 StringRef Arch =150 Attr.CPU.empty() ? CGM.getTarget().getTargetOpts().CPU : Attr.CPU;151 if (!CGM.getTarget().validateBranchProtection(152 Attr.BranchProtection, Arch, BPI, CGM.getLangOpts(), DiagMsg)) {153 CGM.getDiags().Report(154 D->getLocation(),155 diag::warn_target_unsupported_branch_protection_attribute)156 << Arch;157 } else158 setBranchProtectionFnAttributes(BPI, (*Fn));159 } else if (CGM.getLangOpts().BranchTargetEnforcement ||160 CGM.getLangOpts().hasSignReturnAddress()) {161 // If the Branch Protection attribute is missing, validate the target162 // Architecture attribute against Branch Protection command line163 // settings.164 if (!CGM.getTarget().isBranchProtectionSupportedArch(Attr.CPU))165 CGM.getDiags().Report(166 D->getLocation(),167 diag::warn_target_unsupported_branch_protection_attribute)168 << Attr.CPU;169 }170 } else if (CGM.getTarget().isBranchProtectionSupportedArch(171 CGM.getTarget().getTargetOpts().CPU)) {172 TargetInfo::BranchProtectionInfo BPI(CGM.getLangOpts());173 setBranchProtectionFnAttributes(BPI, (*Fn));174 }175 176 if (!FD || !FD->hasAttr<ARMInterruptAttr>())177 return;178 179 const ARMInterruptAttr *Attr = FD->getAttr<ARMInterruptAttr>();180 const char *Kind;181 switch (Attr->getInterrupt()) {182 case ARMInterruptAttr::Generic: Kind = ""; break;183 case ARMInterruptAttr::IRQ: Kind = "IRQ"; break;184 case ARMInterruptAttr::FIQ: Kind = "FIQ"; break;185 case ARMInterruptAttr::SWI: Kind = "SWI"; break;186 case ARMInterruptAttr::ABORT: Kind = "ABORT"; break;187 case ARMInterruptAttr::UNDEF: Kind = "UNDEF"; break;188 }189 190 Fn->addFnAttr("interrupt", Kind);191 192 // Note: the ARMSaveFPAttr can only exist if we also have an interrupt193 // attribute194 const ARMSaveFPAttr *SaveFPAttr = FD->getAttr<ARMSaveFPAttr>();195 if (SaveFPAttr)196 Fn->addFnAttr("save-fp");197 198 ARMABIKind ABI = getABIInfo<ARMABIInfo>().getABIKind();199 if (ABI == ARMABIKind::APCS)200 return;201 202 // AAPCS guarantees that sp will be 8-byte aligned on any public interface,203 // however this is not necessarily true on taking any interrupt. Instruct204 // the backend to perform a realignment as part of the function prologue.205 llvm::AttrBuilder B(Fn->getContext());206 B.addStackAlignmentAttr(8);207 Fn->addFnAttrs(B);208 }209};210 211class WindowsARMTargetCodeGenInfo : public ARMTargetCodeGenInfo {212public:213 WindowsARMTargetCodeGenInfo(CodeGenTypes &CGT, ARMABIKind K)214 : ARMTargetCodeGenInfo(CGT, K) {}215 216 void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,217 CodeGen::CodeGenModule &CGM) const override;218 219 void getDependentLibraryOption(llvm::StringRef Lib,220 llvm::SmallString<24> &Opt) const override {221 Opt = "/DEFAULTLIB:" + qualifyWindowsLibrary(Lib);222 }223 224 void getDetectMismatchOption(llvm::StringRef Name, llvm::StringRef Value,225 llvm::SmallString<32> &Opt) const override {226 Opt = "/FAILIFMISMATCH:\"" + Name.str() + "=" + Value.str() + "\"";227 }228};229 230void WindowsARMTargetCodeGenInfo::setTargetAttributes(231 const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const {232 ARMTargetCodeGenInfo::setTargetAttributes(D, GV, CGM);233 if (GV->isDeclaration())234 return;235 addStackProbeTargetAttributes(D, GV, CGM);236}237}238 239void ARMABIInfo::computeInfo(CGFunctionInfo &FI) const {240 if (!::classifyReturnType(getCXXABI(), FI, *this))241 FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), FI.isVariadic(),242 FI.getCallingConvention());243 244 for (auto &I : FI.arguments())245 I.info = classifyArgumentType(I.type, FI.isVariadic(),246 FI.getCallingConvention());247 248 249 // Always honor user-specified calling convention.250 if (FI.getCallingConvention() != llvm::CallingConv::C)251 return;252 253 llvm::CallingConv::ID cc = getRuntimeCC();254 if (cc != llvm::CallingConv::C)255 FI.setEffectiveCallingConvention(cc);256}257 258/// Return the default calling convention that LLVM will use.259llvm::CallingConv::ID ARMABIInfo::getLLVMDefaultCC() const {260 // The default calling convention that LLVM will infer.261 if (isEABIHF() || getTarget().getTriple().isWatchABI())262 return llvm::CallingConv::ARM_AAPCS_VFP;263 else if (isEABI())264 return llvm::CallingConv::ARM_AAPCS;265 else266 return llvm::CallingConv::ARM_APCS;267}268 269/// Return the calling convention that our ABI would like us to use270/// as the C calling convention.271llvm::CallingConv::ID ARMABIInfo::getABIDefaultCC() const {272 switch (getABIKind()) {273 case ARMABIKind::APCS:274 return llvm::CallingConv::ARM_APCS;275 case ARMABIKind::AAPCS:276 return llvm::CallingConv::ARM_AAPCS;277 case ARMABIKind::AAPCS_VFP:278 return llvm::CallingConv::ARM_AAPCS_VFP;279 case ARMABIKind::AAPCS16_VFP:280 return llvm::CallingConv::ARM_AAPCS_VFP;281 }282 llvm_unreachable("bad ABI kind");283}284 285void ARMABIInfo::setCCs() {286 assert(getRuntimeCC() == llvm::CallingConv::C);287 288 // Don't muddy up the IR with a ton of explicit annotations if289 // they'd just match what LLVM will infer from the triple.290 llvm::CallingConv::ID abiCC = getABIDefaultCC();291 if (abiCC != getLLVMDefaultCC())292 RuntimeCC = abiCC;293}294 295ABIArgInfo ARMABIInfo::coerceIllegalVector(QualType Ty) const {296 uint64_t Size = getContext().getTypeSize(Ty);297 if (Size <= 32) {298 llvm::Type *ResType =299 llvm::Type::getInt32Ty(getVMContext());300 return ABIArgInfo::getDirect(ResType);301 }302 if (Size == 64 || Size == 128) {303 auto *ResType = llvm::FixedVectorType::get(304 llvm::Type::getInt32Ty(getVMContext()), Size / 32);305 return ABIArgInfo::getDirect(ResType);306 }307 return getNaturalAlignIndirect(308 Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),309 /*ByVal=*/false);310}311 312ABIArgInfo ARMABIInfo::classifyHomogeneousAggregate(QualType Ty,313 const Type *Base,314 uint64_t Members) const {315 assert(Base && "Base class should be set for homogeneous aggregate");316 // Base can be a floating-point or a vector.317 if (const VectorType *VT = Base->getAs<VectorType>()) {318 // FP16 vectors should be converted to integer vectors319 if (!getTarget().hasFastHalfType() && containsAnyFP16Vectors(Ty)) {320 uint64_t Size = getContext().getTypeSize(VT);321 auto *NewVecTy = llvm::FixedVectorType::get(322 llvm::Type::getInt32Ty(getVMContext()), Size / 32);323 llvm::Type *Ty = llvm::ArrayType::get(NewVecTy, Members);324 return ABIArgInfo::getDirect(Ty, 0, nullptr, false);325 }326 }327 unsigned Align = 0;328 if (getABIKind() == ARMABIKind::AAPCS ||329 getABIKind() == ARMABIKind::AAPCS_VFP) {330 // For alignment adjusted HFAs, cap the argument alignment to 8, leave it331 // default otherwise.332 Align = getContext().getTypeUnadjustedAlignInChars(Ty).getQuantity();333 unsigned BaseAlign = getContext().getTypeAlignInChars(Base).getQuantity();334 Align = (Align > BaseAlign && Align >= 8) ? 8 : 0;335 }336 return ABIArgInfo::getDirect(nullptr, 0, nullptr, false, Align);337}338 339bool ARMABIInfo::shouldIgnoreEmptyArg(QualType Ty) const {340 uint64_t Size = getContext().getTypeSize(Ty);341 assert((isEmptyRecord(getContext(), Ty, true) || Size == 0) &&342 "Arg is not empty");343 344 // Empty records are ignored in C mode, and in C++ on WatchOS.345 if (!getContext().getLangOpts().CPlusPlus ||346 getABIKind() == ARMABIKind::AAPCS16_VFP)347 return true;348 349 // In C++ mode, arguments which have sizeof() == 0 are ignored. This is not a350 // situation which is defined by any C++ standard or ABI, but this matches351 // GCC's de facto ABI.352 if (Size == 0)353 return true;354 355 // Clang 19.0 and earlier always ignored empty struct arguments in C++ mode.356 if (getContext().getLangOpts().getClangABICompat() <=357 LangOptions::ClangABI::Ver19)358 return true;359 360 // Otherwise, they are passed as if they have a size of 1 byte.361 return false;362}363 364ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, bool isVariadic,365 unsigned functionCallConv) const {366 // 6.1.2.1 The following argument types are VFP CPRCs:367 // A single-precision floating-point type (including promoted368 // half-precision types); A double-precision floating-point type;369 // A 64-bit or 128-bit containerized vector type; Homogeneous Aggregate370 // with a Base Type of a single- or double-precision floating-point type,371 // 64-bit containerized vectors or 128-bit containerized vectors with one372 // to four Elements.373 // Variadic functions should always marshal to the base standard.374 bool IsAAPCS_VFP =375 !isVariadic && isEffectivelyAAPCS_VFP(functionCallConv, /* AAPCS16 */ false);376 377 Ty = useFirstFieldIfTransparentUnion(Ty);378 379 // Handle illegal vector types here.380 if (isIllegalVectorType(Ty))381 return coerceIllegalVector(Ty);382 383 if (!isAggregateTypeForABI(Ty)) {384 // Treat an enum type as its underlying type.385 if (const auto *ED = Ty->getAsEnumDecl()) {386 Ty = ED->getIntegerType();387 }388 389 if (const auto *EIT = Ty->getAs<BitIntType>())390 if (EIT->getNumBits() > 64)391 return getNaturalAlignIndirect(392 Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),393 /*ByVal=*/true);394 395 return (isPromotableIntegerTypeForABI(Ty)396 ? ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty))397 : ABIArgInfo::getDirect());398 }399 400 if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) {401 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),402 RAA == CGCXXABI::RAA_DirectInMemory);403 }404 405 // Empty records are either ignored completely or passed as if they were a406 // 1-byte object, depending on the ABI and language standard.407 if (isEmptyRecord(getContext(), Ty, true) ||408 getContext().getTypeSize(Ty) == 0) {409 if (shouldIgnoreEmptyArg(Ty))410 return ABIArgInfo::getIgnore();411 else412 return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));413 }414 415 if (IsAAPCS_VFP) {416 // Homogeneous Aggregates need to be expanded when we can fit the aggregate417 // into VFP registers.418 const Type *Base = nullptr;419 uint64_t Members = 0;420 if (isHomogeneousAggregate(Ty, Base, Members))421 return classifyHomogeneousAggregate(Ty, Base, Members);422 } else if (getABIKind() == ARMABIKind::AAPCS16_VFP) {423 // WatchOS does have homogeneous aggregates. Note that we intentionally use424 // this convention even for a variadic function: the backend will use GPRs425 // if needed.426 const Type *Base = nullptr;427 uint64_t Members = 0;428 if (isHomogeneousAggregate(Ty, Base, Members)) {429 assert(Base && Members <= 4 && "unexpected homogeneous aggregate");430 llvm::Type *Ty =431 llvm::ArrayType::get(CGT.ConvertType(QualType(Base, 0)), Members);432 return ABIArgInfo::getDirect(Ty, 0, nullptr, false);433 }434 }435 436 if (getABIKind() == ARMABIKind::AAPCS16_VFP &&437 getContext().getTypeSizeInChars(Ty) > CharUnits::fromQuantity(16)) {438 // WatchOS is adopting the 64-bit AAPCS rule on composite types: if they're439 // bigger than 128-bits, they get placed in space allocated by the caller,440 // and a pointer is passed.441 return ABIArgInfo::getIndirect(442 CharUnits::fromQuantity(getContext().getTypeAlign(Ty) / 8),443 getDataLayout().getAllocaAddrSpace(), false);444 }445 446 // Support byval for ARM.447 // The ABI alignment for APCS is 4-byte and for AAPCS at least 4-byte and at448 // most 8-byte. We realign the indirect argument if type alignment is bigger449 // than ABI alignment.450 uint64_t ABIAlign = 4;451 uint64_t TyAlign;452 if (getABIKind() == ARMABIKind::AAPCS_VFP ||453 getABIKind() == ARMABIKind::AAPCS) {454 TyAlign = getContext().getTypeUnadjustedAlignInChars(Ty).getQuantity();455 ABIAlign = std::clamp(TyAlign, (uint64_t)4, (uint64_t)8);456 } else {457 TyAlign = getContext().getTypeAlignInChars(Ty).getQuantity();458 }459 if (getContext().getTypeSizeInChars(Ty) > CharUnits::fromQuantity(64)) {460 assert(getABIKind() != ARMABIKind::AAPCS16_VFP && "unexpected byval");461 return ABIArgInfo::getIndirect(462 CharUnits::fromQuantity(ABIAlign),463 /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),464 /*ByVal=*/true, /*Realign=*/TyAlign > ABIAlign);465 }466 467 // Otherwise, pass by coercing to a structure of the appropriate size.468 llvm::Type* ElemTy;469 unsigned SizeRegs;470 // FIXME: Try to match the types of the arguments more accurately where471 // we can.472 if (TyAlign <= 4) {473 ElemTy = llvm::Type::getInt32Ty(getVMContext());474 SizeRegs = (getContext().getTypeSize(Ty) + 31) / 32;475 } else {476 ElemTy = llvm::Type::getInt64Ty(getVMContext());477 SizeRegs = (getContext().getTypeSize(Ty) + 63) / 64;478 }479 480 return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, SizeRegs));481}482 483static bool isIntegerLikeType(QualType Ty, ASTContext &Context,484 llvm::LLVMContext &VMContext) {485 // APCS, C Language Calling Conventions, Non-Simple Return Values: A structure486 // is called integer-like if its size is less than or equal to one word, and487 // the offset of each of its addressable sub-fields is zero.488 489 uint64_t Size = Context.getTypeSize(Ty);490 491 // Check that the type fits in a word.492 if (Size > 32)493 return false;494 495 // FIXME: Handle vector types!496 if (Ty->isVectorType())497 return false;498 499 // Float types are never treated as "integer like".500 if (Ty->isRealFloatingType())501 return false;502 503 // If this is a builtin or pointer type then it is ok.504 if (Ty->getAs<BuiltinType>() || Ty->isPointerType())505 return true;506 507 // Small complex integer types are "integer like".508 if (const ComplexType *CT = Ty->getAs<ComplexType>())509 return isIntegerLikeType(CT->getElementType(), Context, VMContext);510 511 // Single element and zero sized arrays should be allowed, by the definition512 // above, but they are not.513 514 // Otherwise, it must be a record type.515 const RecordType *RT = Ty->getAsCanonical<RecordType>();516 if (!RT) return false;517 518 // Ignore records with flexible arrays.519 const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();520 if (RD->hasFlexibleArrayMember())521 return false;522 523 // Check that all sub-fields are at offset 0, and are themselves "integer524 // like".525 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);526 527 bool HadField = false;528 unsigned idx = 0;529 for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();530 i != e; ++i, ++idx) {531 const FieldDecl *FD = *i;532 533 // Bit-fields are not addressable, we only need to verify they are "integer534 // like". We still have to disallow a subsequent non-bitfield, for example:535 // struct { int : 0; int x }536 // is non-integer like according to gcc.537 if (FD->isBitField()) {538 if (!RD->isUnion())539 HadField = true;540 541 if (!isIntegerLikeType(FD->getType(), Context, VMContext))542 return false;543 544 continue;545 }546 547 // Check if this field is at offset 0.548 if (Layout.getFieldOffset(idx) != 0)549 return false;550 551 if (!isIntegerLikeType(FD->getType(), Context, VMContext))552 return false;553 554 // Only allow at most one field in a structure. This doesn't match the555 // wording above, but follows gcc in situations with a field following an556 // empty structure.557 if (!RD->isUnion()) {558 if (HadField)559 return false;560 561 HadField = true;562 }563 }564 565 return true;566}567 568ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy, bool isVariadic,569 unsigned functionCallConv) const {570 571 // Variadic functions should always marshal to the base standard.572 bool IsAAPCS_VFP =573 !isVariadic && isEffectivelyAAPCS_VFP(functionCallConv, /* AAPCS16 */ true);574 575 if (RetTy->isVoidType())576 return ABIArgInfo::getIgnore();577 578 if (const VectorType *VT = RetTy->getAs<VectorType>()) {579 // Large vector types should be returned via memory.580 if (getContext().getTypeSize(RetTy) > 128)581 return getNaturalAlignIndirect(RetTy,582 getDataLayout().getAllocaAddrSpace());583 // TODO: FP16/BF16 vectors should be converted to integer vectors584 // This check is similar to isIllegalVectorType - refactor?585 if ((!getTarget().hasFastHalfType() &&586 (VT->getElementType()->isFloat16Type() ||587 VT->getElementType()->isHalfType())) ||588 (IsFloatABISoftFP &&589 VT->getElementType()->isBFloat16Type()))590 return coerceIllegalVector(RetTy);591 }592 593 if (!isAggregateTypeForABI(RetTy)) {594 // Treat an enum type as its underlying type.595 if (const auto *ED = RetTy->getAsEnumDecl())596 RetTy = ED->getIntegerType();597 598 if (const auto *EIT = RetTy->getAs<BitIntType>())599 if (EIT->getNumBits() > 64)600 return getNaturalAlignIndirect(601 RetTy, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),602 /*ByVal=*/false);603 604 return isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)605 : ABIArgInfo::getDirect();606 }607 608 // Are we following APCS?609 if (getABIKind() == ARMABIKind::APCS) {610 if (isEmptyRecord(getContext(), RetTy, false))611 return ABIArgInfo::getIgnore();612 613 // Complex types are all returned as packed integers.614 //615 // FIXME: Consider using 2 x vector types if the back end handles them616 // correctly.617 if (RetTy->isAnyComplexType())618 return ABIArgInfo::getDirect(llvm::IntegerType::get(619 getVMContext(), getContext().getTypeSize(RetTy)));620 621 // Integer like structures are returned in r0.622 if (isIntegerLikeType(RetTy, getContext(), getVMContext())) {623 // Return in the smallest viable integer type.624 uint64_t Size = getContext().getTypeSize(RetTy);625 if (Size <= 8)626 return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));627 if (Size <= 16)628 return ABIArgInfo::getDirect(llvm::Type::getInt16Ty(getVMContext()));629 return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext()));630 }631 632 // Otherwise return in memory.633 return getNaturalAlignIndirect(RetTy, getDataLayout().getAllocaAddrSpace());634 }635 636 // Otherwise this is an AAPCS variant.637 638 if (isEmptyRecord(getContext(), RetTy, true) ||639 getContext().getTypeSize(RetTy) == 0)640 return ABIArgInfo::getIgnore();641 642 // Check for homogeneous aggregates with AAPCS-VFP.643 if (IsAAPCS_VFP) {644 const Type *Base = nullptr;645 uint64_t Members = 0;646 if (isHomogeneousAggregate(RetTy, Base, Members))647 return classifyHomogeneousAggregate(RetTy, Base, Members);648 }649 650 // Aggregates <= 4 bytes are returned in r0; other aggregates651 // are returned indirectly.652 uint64_t Size = getContext().getTypeSize(RetTy);653 if (Size <= 32) {654 if (getDataLayout().isBigEndian())655 // Return in 32 bit integer integer type (as if loaded by LDR, AAPCS 5.4)656 return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext()));657 658 // Return in the smallest viable integer type.659 if (Size <= 8)660 return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));661 if (Size <= 16)662 return ABIArgInfo::getDirect(llvm::Type::getInt16Ty(getVMContext()));663 return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext()));664 } else if (Size <= 128 && getABIKind() == ARMABIKind::AAPCS16_VFP) {665 llvm::Type *Int32Ty = llvm::Type::getInt32Ty(getVMContext());666 llvm::Type *CoerceTy =667 llvm::ArrayType::get(Int32Ty, llvm::alignTo(Size, 32) / 32);668 return ABIArgInfo::getDirect(CoerceTy);669 }670 671 return getNaturalAlignIndirect(RetTy, getDataLayout().getAllocaAddrSpace());672}673 674/// isIllegalVector - check whether Ty is an illegal vector type.675bool ARMABIInfo::isIllegalVectorType(QualType Ty) const {676 if (const VectorType *VT = Ty->getAs<VectorType> ()) {677 // On targets that don't support half, fp16 or bfloat, they are expanded678 // into float, and we don't want the ABI to depend on whether or not they679 // are supported in hardware. Thus return false to coerce vectors of these680 // types into integer vectors.681 // We do not depend on hasFastHalfType for bfloat as it is a682 // separate IR type.683 if ((!getTarget().hasFastHalfType() &&684 (VT->getElementType()->isFloat16Type() ||685 VT->getElementType()->isHalfType())) ||686 (IsFloatABISoftFP &&687 VT->getElementType()->isBFloat16Type()))688 return true;689 if (isAndroid()) {690 // Android shipped using Clang 3.1, which supported a slightly different691 // vector ABI. The primary differences were that 3-element vector types692 // were legal, and so were sub 32-bit vectors (i.e. <2 x i8>). This path693 // accepts that legacy behavior for Android only.694 // Check whether VT is legal.695 unsigned NumElements = VT->getNumElements();696 // NumElements should be power of 2 or equal to 3.697 if (!llvm::isPowerOf2_32(NumElements) && NumElements != 3)698 return true;699 } else {700 // Check whether VT is legal.701 unsigned NumElements = VT->getNumElements();702 uint64_t Size = getContext().getTypeSize(VT);703 // NumElements should be power of 2.704 if (!llvm::isPowerOf2_32(NumElements))705 return true;706 // Size should be greater than 32 bits.707 return Size <= 32;708 }709 }710 return false;711}712 713/// Return true if a type contains any 16-bit floating point vectors714bool ARMABIInfo::containsAnyFP16Vectors(QualType Ty) const {715 if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) {716 uint64_t NElements = AT->getZExtSize();717 if (NElements == 0)718 return false;719 return containsAnyFP16Vectors(AT->getElementType());720 }721 if (const auto *RD = Ty->getAsRecordDecl()) {722 // If this is a C++ record, check the bases first.723 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))724 if (llvm::any_of(CXXRD->bases(), [this](const CXXBaseSpecifier &B) {725 return containsAnyFP16Vectors(B.getType());726 }))727 return true;728 729 if (llvm::any_of(RD->fields(), [this](FieldDecl *FD) {730 return FD && containsAnyFP16Vectors(FD->getType());731 }))732 return true;733 734 return false;735 } else {736 if (const VectorType *VT = Ty->getAs<VectorType>())737 return (VT->getElementType()->isFloat16Type() ||738 VT->getElementType()->isBFloat16Type() ||739 VT->getElementType()->isHalfType());740 return false;741 }742}743 744bool ARMSwiftABIInfo::isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,745 unsigned NumElts) const {746 if (!llvm::isPowerOf2_32(NumElts))747 return false;748 unsigned size = CGT.getDataLayout().getTypeStoreSizeInBits(EltTy);749 if (size > 64)750 return false;751 if (VectorSize.getQuantity() != 8 &&752 (VectorSize.getQuantity() != 16 || NumElts == 1))753 return false;754 return true;755}756 757bool ARMABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const {758 // Homogeneous aggregates for AAPCS-VFP must have base types of float,759 // double, or 64-bit or 128-bit vectors.760 if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) {761 if (BT->getKind() == BuiltinType::Float ||762 BT->getKind() == BuiltinType::Double ||763 BT->getKind() == BuiltinType::LongDouble)764 return true;765 } else if (const VectorType *VT = Ty->getAs<VectorType>()) {766 unsigned VecSize = getContext().getTypeSize(VT);767 if (VecSize == 64 || VecSize == 128)768 return true;769 }770 return false;771}772 773bool ARMABIInfo::isHomogeneousAggregateSmallEnough(const Type *Base,774 uint64_t Members) const {775 return Members <= 4;776}777 778bool ARMABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate() const {779 // AAPCS32 says that the rule for whether something is a homogeneous780 // aggregate is applied to the output of the data layout decision. So781 // anything that doesn't affect the data layout also does not affect782 // homogeneity. In particular, zero-length bitfields don't stop a struct783 // being homogeneous.784 return true;785}786 787bool ARMABIInfo::isEffectivelyAAPCS_VFP(unsigned callConvention,788 bool acceptHalf) const {789 // Give precedence to user-specified calling conventions.790 if (callConvention != llvm::CallingConv::C)791 return (callConvention == llvm::CallingConv::ARM_AAPCS_VFP);792 else793 return (getABIKind() == ARMABIKind::AAPCS_VFP) ||794 (acceptHalf && (getABIKind() == ARMABIKind::AAPCS16_VFP));795}796 797RValue ARMABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,798 QualType Ty, AggValueSlot Slot) const {799 CharUnits SlotSize = CharUnits::fromQuantity(4);800 801 // Empty records are ignored for parameter passing purposes.802 uint64_t Size = getContext().getTypeSize(Ty);803 bool IsEmpty = isEmptyRecord(getContext(), Ty, true);804 if ((IsEmpty || Size == 0) && shouldIgnoreEmptyArg(Ty))805 return Slot.asRValue();806 807 CharUnits TySize = getContext().getTypeSizeInChars(Ty);808 CharUnits TyAlignForABI = getContext().getTypeUnadjustedAlignInChars(Ty);809 810 // Use indirect if size of the illegal vector is bigger than 16 bytes.811 bool IsIndirect = false;812 const Type *Base = nullptr;813 uint64_t Members = 0;814 if (TySize > CharUnits::fromQuantity(16) && isIllegalVectorType(Ty)) {815 IsIndirect = true;816 817 // ARMv7k passes structs bigger than 16 bytes indirectly, in space818 // allocated by the caller.819 } else if (TySize > CharUnits::fromQuantity(16) &&820 getABIKind() == ARMABIKind::AAPCS16_VFP &&821 !isHomogeneousAggregate(Ty, Base, Members)) {822 IsIndirect = true;823 824 // Otherwise, bound the type's ABI alignment.825 // The ABI alignment for 64-bit or 128-bit vectors is 8 for AAPCS and 4 for826 // APCS. For AAPCS, the ABI alignment is at least 4-byte and at most 8-byte.827 // Our callers should be prepared to handle an under-aligned address.828 } else if (getABIKind() == ARMABIKind::AAPCS_VFP ||829 getABIKind() == ARMABIKind::AAPCS) {830 TyAlignForABI = std::max(TyAlignForABI, CharUnits::fromQuantity(4));831 TyAlignForABI = std::min(TyAlignForABI, CharUnits::fromQuantity(8));832 } else if (getABIKind() == ARMABIKind::AAPCS16_VFP) {833 // ARMv7k allows type alignment up to 16 bytes.834 TyAlignForABI = std::max(TyAlignForABI, CharUnits::fromQuantity(4));835 TyAlignForABI = std::min(TyAlignForABI, CharUnits::fromQuantity(16));836 } else {837 TyAlignForABI = CharUnits::fromQuantity(4);838 }839 840 TypeInfoChars TyInfo(TySize, TyAlignForABI, AlignRequirementKind::None);841 return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, TyInfo, SlotSize,842 /*AllowHigherAlign*/ true, Slot);843}844 845std::unique_ptr<TargetCodeGenInfo>846CodeGen::createARMTargetCodeGenInfo(CodeGenModule &CGM, ARMABIKind Kind) {847 return std::make_unique<ARMTargetCodeGenInfo>(CGM.getTypes(), Kind);848}849 850std::unique_ptr<TargetCodeGenInfo>851CodeGen::createWindowsARMTargetCodeGenInfo(CodeGenModule &CGM, ARMABIKind K) {852 return std::make_unique<WindowsARMTargetCodeGenInfo>(CGM.getTypes(), K);853}854