10#include "TargetInfo.h"
21class ARMABIInfo :
public ABIInfo {
23 bool IsFloatABISoftFP;
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:
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:
69 unsigned functionCallConv)
const;
71 unsigned functionCallConv)
const;
73 uint64_t Members)
const;
75 bool isIllegalVectorType(
QualType Ty)
const;
76 bool containsAnyFP16Vectors(
QualType Ty)
const;
80 uint64_t Members)
const override;
83 bool isEffectivelyAAPCS_VFP(
unsigned callConvention,
bool acceptHalf)
const;
90 llvm::CallingConv::ID getLLVMDefaultCC()
const;
91 llvm::CallingConv::ID getABIDefaultCC()
const;
101 unsigned NumElts)
const override;
108 SwiftInfo = std::make_unique<ARMSwiftABIInfo>(CGT);
116 return "mov\tr7, r7\t\t// marker for objc_retainAutoreleaseReturnValue";
120 llvm::Value *
Address)
const override {
121 llvm::Value *Four8 = llvm::ConstantInt::get(CGF.
Int8Ty, 4);
129 if (getABIInfo<ARMABIInfo>().isEABI())
136 if (GV->isDeclaration())
141 auto *
Fn = cast<llvm::Function>(GV);
143 if (
const auto *TA = FD->
getAttr<TargetAttr>()) {
146 if (!
Attr.BranchProtection.empty()) {
152 Arch, BPI, DiagMsg)) {
155 diag::warn_target_unsupported_branch_protection_attribute)
159 }
else if (CGM.
getLangOpts().BranchTargetEnforcement ||
167 diag::warn_target_unsupported_branch_protection_attribute)
176 const ARMInterruptAttr *
Attr = FD->
getAttr<ARMInterruptAttr>();
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;
190 Fn->addFnAttr(
"interrupt", Kind);
192 ARMABIKind ABI = getABIInfo<ARMABIInfo>().getABIKind();
193 if (ABI == ARMABIKind::APCS)
199 llvm::AttrBuilder B(
Fn->getContext());
200 B.addStackAlignmentAttr(8);
205class WindowsARMTargetCodeGenInfo :
public ARMTargetCodeGenInfo {
208 : ARMTargetCodeGenInfo(CGT, K) {}
210 void setTargetAttributes(
const Decl *
D, llvm::GlobalValue *GV,
213 void getDependentLibraryOption(llvm::StringRef Lib,
215 Opt =
"/DEFAULTLIB:" + qualifyWindowsLibrary(Lib);
218 void getDetectMismatchOption(llvm::StringRef Name, llvm::StringRef
Value,
220 Opt =
"/FAILIFMISMATCH:\"" + Name.str() +
"=" +
Value.str() +
"\"";
224void WindowsARMTargetCodeGenInfo::setTargetAttributes(
226 ARMTargetCodeGenInfo::setTargetAttributes(
D, GV, CGM);
227 if (GV->isDeclaration())
229 addStackProbeTargetAttributes(
D, GV, CGM);
247 llvm::CallingConv::ID cc = getRuntimeCC();
248 if (cc != llvm::CallingConv::C)
253llvm::CallingConv::ID ARMABIInfo::getLLVMDefaultCC()
const {
255 if (isEABIHF() || getTarget().getTriple().isWatchABI())
256 return llvm::CallingConv::ARM_AAPCS_VFP;
258 return llvm::CallingConv::ARM_AAPCS;
260 return llvm::CallingConv::ARM_APCS;
265llvm::CallingConv::ID ARMABIInfo::getABIDefaultCC()
const {
266 switch (getABIKind()) {
267 case ARMABIKind::APCS:
268 return llvm::CallingConv::ARM_APCS;
269 case ARMABIKind::AAPCS:
270 return llvm::CallingConv::ARM_AAPCS;
271 case ARMABIKind::AAPCS_VFP:
272 return llvm::CallingConv::ARM_AAPCS_VFP;
273 case ARMABIKind::AAPCS16_VFP:
274 return llvm::CallingConv::ARM_AAPCS_VFP;
276 llvm_unreachable(
"bad ABI kind");
279void ARMABIInfo::setCCs() {
280 assert(getRuntimeCC() == llvm::CallingConv::C);
284 llvm::CallingConv::ID abiCC = getABIDefaultCC();
285 if (abiCC != getLLVMDefaultCC())
292 llvm::Type *ResType =
293 llvm::Type::getInt32Ty(getVMContext());
296 if (Size == 64 || Size == 128) {
297 auto *ResType = llvm::FixedVectorType::get(
298 llvm::Type::getInt32Ty(getVMContext()), Size / 32);
301 return getNaturalAlignIndirect(Ty,
false);
306 uint64_t Members)
const {
307 assert(
Base &&
"Base class should be set for homogeneous aggregate");
311 if (!getTarget().hasLegalHalfType() && containsAnyFP16Vectors(Ty)) {
313 auto *NewVecTy = llvm::FixedVectorType::get(
314 llvm::Type::getInt32Ty(getVMContext()), Size / 32);
315 llvm::Type *Ty = llvm::ArrayType::get(NewVecTy, Members);
320 if (getABIKind() == ARMABIKind::AAPCS ||
321 getABIKind() == ARMABIKind::AAPCS_VFP) {
324 Align = getContext().getTypeUnadjustedAlignInChars(Ty).getQuantity();
325 unsigned BaseAlign = getContext().getTypeAlignInChars(
Base).getQuantity();
326 Align = (Align > BaseAlign && Align >= 8) ? 8 : 0;
332 unsigned functionCallConv)
const {
342 !isVariadic && isEffectivelyAAPCS_VFP(functionCallConv,
false);
347 if (isIllegalVectorType(Ty))
348 return coerceIllegalVector(Ty);
353 Ty = EnumTy->getDecl()->getIntegerType();
357 if (EIT->getNumBits() > 64)
358 return getNaturalAlignIndirect(Ty,
true);
360 return (isPromotableIntegerTypeForABI(Ty)
378 if (isHomogeneousAggregate(Ty,
Base, Members))
379 return classifyHomogeneousAggregate(Ty,
Base, Members);
380 }
else if (getABIKind() == ARMABIKind::AAPCS16_VFP) {
386 if (isHomogeneousAggregate(Ty,
Base, Members)) {
387 assert(
Base && Members <= 4 &&
"unexpected homogeneous aggregate");
394 if (getABIKind() == ARMABIKind::AAPCS16_VFP &&
409 if (getABIKind() == ARMABIKind::AAPCS_VFP ||
410 getABIKind() == ARMABIKind::AAPCS) {
411 TyAlign = getContext().getTypeUnadjustedAlignInChars(Ty).getQuantity();
412 ABIAlign = std::clamp(TyAlign, (uint64_t)4, (uint64_t)8);
414 TyAlign = getContext().getTypeAlignInChars(Ty).getQuantity();
417 assert(getABIKind() != ARMABIKind::AAPCS16_VFP &&
"unexpected byval");
429 ElemTy = llvm::Type::getInt32Ty(getVMContext());
430 SizeRegs = (getContext().getTypeSize(Ty) + 31) / 32;
432 ElemTy = llvm::Type::getInt64Ty(getVMContext());
433 SizeRegs = (getContext().getTypeSize(Ty) + 63) / 64;
440 llvm::LLVMContext &VMContext) {
472 if (!RT)
return false;
483 bool HadField =
false;
486 i != e; ++i, ++idx) {
525 unsigned functionCallConv)
const {
529 !isVariadic && isEffectivelyAAPCS_VFP(functionCallConv,
true);
536 if (getContext().getTypeSize(RetTy) > 128)
537 return getNaturalAlignIndirect(RetTy);
540 if ((!getTarget().hasLegalHalfType() &&
541 (VT->getElementType()->isFloat16Type() ||
542 VT->getElementType()->isHalfType())) ||
544 VT->getElementType()->isBFloat16Type()))
545 return coerceIllegalVector(RetTy);
551 RetTy = EnumTy->getDecl()->getIntegerType();
554 if (EIT->getNumBits() > 64)
555 return getNaturalAlignIndirect(RetTy,
false);
562 if (getABIKind() == ARMABIKind::APCS) {
572 getVMContext(), getContext().getTypeSize(RetTy)));
586 return getNaturalAlignIndirect(RetTy);
598 if (isHomogeneousAggregate(RetTy,
Base, Members))
599 return classifyHomogeneousAggregate(RetTy,
Base, Members);
606 if (getDataLayout().isBigEndian())
616 }
else if (Size <= 128 && getABIKind() == ARMABIKind::AAPCS16_VFP) {
617 llvm::Type *Int32Ty = llvm::Type::getInt32Ty(getVMContext());
618 llvm::Type *CoerceTy =
619 llvm::ArrayType::get(Int32Ty, llvm::alignTo(Size, 32) / 32);
623 return getNaturalAlignIndirect(RetTy);
627bool ARMABIInfo::isIllegalVectorType(
QualType Ty)
const {
635 if ((!getTarget().hasLegalHalfType() &&
636 (VT->getElementType()->isFloat16Type() ||
637 VT->getElementType()->isHalfType())) ||
639 VT->getElementType()->isBFloat16Type()))
647 unsigned NumElements = VT->getNumElements();
649 if (!llvm::isPowerOf2_32(NumElements) && NumElements != 3)
653 unsigned NumElements = VT->getNumElements();
656 if (!llvm::isPowerOf2_32(NumElements))
666bool ARMABIInfo::containsAnyFP16Vectors(
QualType Ty)
const {
668 uint64_t NElements = AT->getZExtSize();
671 return containsAnyFP16Vectors(AT->getElementType());