xref: /llvm-project/clang/lib/CodeGen/Targets/ARM.cpp (revision af7c58b7ea853ef34462ce97739203e2da3c5894)
1992cb984SSergei Barannikov //===- ARM.cpp ------------------------------------------------------------===//
2992cb984SSergei Barannikov //
3992cb984SSergei Barannikov // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4992cb984SSergei Barannikov // See https://llvm.org/LICENSE.txt for license information.
5992cb984SSergei Barannikov // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6992cb984SSergei Barannikov //
7992cb984SSergei Barannikov //===----------------------------------------------------------------------===//
8992cb984SSergei Barannikov 
9992cb984SSergei Barannikov #include "ABIInfoImpl.h"
10992cb984SSergei Barannikov #include "TargetInfo.h"
11992cb984SSergei Barannikov 
12992cb984SSergei Barannikov using namespace clang;
13992cb984SSergei Barannikov using namespace clang::CodeGen;
14992cb984SSergei Barannikov 
15992cb984SSergei Barannikov //===----------------------------------------------------------------------===//
16992cb984SSergei Barannikov // ARM ABI Implementation
17992cb984SSergei Barannikov //===----------------------------------------------------------------------===//
18992cb984SSergei Barannikov 
19992cb984SSergei Barannikov namespace {
20992cb984SSergei Barannikov 
21992cb984SSergei Barannikov class ARMABIInfo : public ABIInfo {
22992cb984SSergei Barannikov   ARMABIKind Kind;
23992cb984SSergei Barannikov   bool IsFloatABISoftFP;
24992cb984SSergei Barannikov 
25992cb984SSergei Barannikov public:
26992cb984SSergei Barannikov   ARMABIInfo(CodeGenTypes &CGT, ARMABIKind Kind) : ABIInfo(CGT), Kind(Kind) {
27992cb984SSergei Barannikov     setCCs();
28992cb984SSergei Barannikov     IsFloatABISoftFP = CGT.getCodeGenOpts().FloatABI == "softfp" ||
29992cb984SSergei Barannikov         CGT.getCodeGenOpts().FloatABI == ""; // default
30992cb984SSergei Barannikov   }
31992cb984SSergei Barannikov 
32992cb984SSergei Barannikov   bool isEABI() const {
33992cb984SSergei Barannikov     switch (getTarget().getTriple().getEnvironment()) {
34992cb984SSergei Barannikov     case llvm::Triple::Android:
35992cb984SSergei Barannikov     case llvm::Triple::EABI:
36992cb984SSergei Barannikov     case llvm::Triple::EABIHF:
37992cb984SSergei Barannikov     case llvm::Triple::GNUEABI:
38*387b37afSMichał Górny     case llvm::Triple::GNUEABIT64:
39992cb984SSergei Barannikov     case llvm::Triple::GNUEABIHF:
40*387b37afSMichał Górny     case llvm::Triple::GNUEABIHFT64:
41992cb984SSergei Barannikov     case llvm::Triple::MuslEABI:
42992cb984SSergei Barannikov     case llvm::Triple::MuslEABIHF:
43992cb984SSergei Barannikov       return true;
44992cb984SSergei Barannikov     default:
45992cb984SSergei Barannikov       return getTarget().getTriple().isOHOSFamily();
46992cb984SSergei Barannikov     }
47992cb984SSergei Barannikov   }
48992cb984SSergei Barannikov 
49992cb984SSergei Barannikov   bool isEABIHF() const {
50992cb984SSergei Barannikov     switch (getTarget().getTriple().getEnvironment()) {
51992cb984SSergei Barannikov     case llvm::Triple::EABIHF:
52992cb984SSergei Barannikov     case llvm::Triple::GNUEABIHF:
53*387b37afSMichał Górny     case llvm::Triple::GNUEABIHFT64:
54992cb984SSergei Barannikov     case llvm::Triple::MuslEABIHF:
55992cb984SSergei Barannikov       return true;
56992cb984SSergei Barannikov     default:
57992cb984SSergei Barannikov       return false;
58992cb984SSergei Barannikov     }
59992cb984SSergei Barannikov   }
60992cb984SSergei Barannikov 
61992cb984SSergei Barannikov   ARMABIKind getABIKind() const { return Kind; }
62992cb984SSergei Barannikov 
63992cb984SSergei Barannikov   bool allowBFloatArgsAndRet() const override {
64992cb984SSergei Barannikov     return !IsFloatABISoftFP && getTarget().hasBFloat16Type();
65992cb984SSergei Barannikov   }
66992cb984SSergei Barannikov 
67992cb984SSergei Barannikov private:
68992cb984SSergei Barannikov   ABIArgInfo classifyReturnType(QualType RetTy, bool isVariadic,
69992cb984SSergei Barannikov                                 unsigned functionCallConv) const;
70992cb984SSergei Barannikov   ABIArgInfo classifyArgumentType(QualType RetTy, bool isVariadic,
71992cb984SSergei Barannikov                                   unsigned functionCallConv) const;
72992cb984SSergei Barannikov   ABIArgInfo classifyHomogeneousAggregate(QualType Ty, const Type *Base,
73992cb984SSergei Barannikov                                           uint64_t Members) const;
74992cb984SSergei Barannikov   ABIArgInfo coerceIllegalVector(QualType Ty) const;
75992cb984SSergei Barannikov   bool isIllegalVectorType(QualType Ty) const;
76992cb984SSergei Barannikov   bool containsAnyFP16Vectors(QualType Ty) const;
77992cb984SSergei Barannikov 
78992cb984SSergei Barannikov   bool isHomogeneousAggregateBaseType(QualType Ty) const override;
79992cb984SSergei Barannikov   bool isHomogeneousAggregateSmallEnough(const Type *Ty,
80992cb984SSergei Barannikov                                          uint64_t Members) const override;
81992cb984SSergei Barannikov   bool isZeroLengthBitfieldPermittedInHomogeneousAggregate() const override;
82992cb984SSergei Barannikov 
83992cb984SSergei Barannikov   bool isEffectivelyAAPCS_VFP(unsigned callConvention, bool acceptHalf) const;
84992cb984SSergei Barannikov 
85992cb984SSergei Barannikov   void computeInfo(CGFunctionInfo &FI) const override;
86992cb984SSergei Barannikov 
876d973b45SMariya Podchishchaeva   RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
886d973b45SMariya Podchishchaeva                    AggValueSlot Slot) const override;
89992cb984SSergei Barannikov 
90992cb984SSergei Barannikov   llvm::CallingConv::ID getLLVMDefaultCC() const;
91992cb984SSergei Barannikov   llvm::CallingConv::ID getABIDefaultCC() const;
92992cb984SSergei Barannikov   void setCCs();
93992cb984SSergei Barannikov };
94992cb984SSergei Barannikov 
95992cb984SSergei Barannikov class ARMSwiftABIInfo : public SwiftABIInfo {
96992cb984SSergei Barannikov public:
97992cb984SSergei Barannikov   explicit ARMSwiftABIInfo(CodeGenTypes &CGT)
98992cb984SSergei Barannikov       : SwiftABIInfo(CGT, /*SwiftErrorInRegister=*/true) {}
99992cb984SSergei Barannikov 
100992cb984SSergei Barannikov   bool isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,
101992cb984SSergei Barannikov                          unsigned NumElts) const override;
102992cb984SSergei Barannikov };
103992cb984SSergei Barannikov 
104992cb984SSergei Barannikov class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
105992cb984SSergei Barannikov public:
106992cb984SSergei Barannikov   ARMTargetCodeGenInfo(CodeGenTypes &CGT, ARMABIKind K)
107992cb984SSergei Barannikov       : TargetCodeGenInfo(std::make_unique<ARMABIInfo>(CGT, K)) {
108992cb984SSergei Barannikov     SwiftInfo = std::make_unique<ARMSwiftABIInfo>(CGT);
109992cb984SSergei Barannikov   }
110992cb984SSergei Barannikov 
111992cb984SSergei Barannikov   int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
112992cb984SSergei Barannikov     return 13;
113992cb984SSergei Barannikov   }
114992cb984SSergei Barannikov 
115992cb984SSergei Barannikov   StringRef getARCRetainAutoreleasedReturnValueMarker() const override {
116992cb984SSergei Barannikov     return "mov\tr7, r7\t\t// marker for objc_retainAutoreleaseReturnValue";
117992cb984SSergei Barannikov   }
118992cb984SSergei Barannikov 
119992cb984SSergei Barannikov   bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
120992cb984SSergei Barannikov                                llvm::Value *Address) const override {
121992cb984SSergei Barannikov     llvm::Value *Four8 = llvm::ConstantInt::get(CGF.Int8Ty, 4);
122992cb984SSergei Barannikov 
123992cb984SSergei Barannikov     // 0-15 are the 16 integer registers.
124992cb984SSergei Barannikov     AssignToArrayRange(CGF.Builder, Address, Four8, 0, 15);
125992cb984SSergei Barannikov     return false;
126992cb984SSergei Barannikov   }
127992cb984SSergei Barannikov 
128992cb984SSergei Barannikov   unsigned getSizeOfUnwindException() const override {
129992cb984SSergei Barannikov     if (getABIInfo<ARMABIInfo>().isEABI())
130992cb984SSergei Barannikov       return 88;
131992cb984SSergei Barannikov     return TargetCodeGenInfo::getSizeOfUnwindException();
132992cb984SSergei Barannikov   }
133992cb984SSergei Barannikov 
134992cb984SSergei Barannikov   void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
135992cb984SSergei Barannikov                            CodeGen::CodeGenModule &CGM) const override {
136992cb984SSergei Barannikov     if (GV->isDeclaration())
137992cb984SSergei Barannikov       return;
138992cb984SSergei Barannikov     const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
139992cb984SSergei Barannikov     if (!FD)
140992cb984SSergei Barannikov       return;
141992cb984SSergei Barannikov     auto *Fn = cast<llvm::Function>(GV);
142992cb984SSergei Barannikov 
143992cb984SSergei Barannikov     if (const auto *TA = FD->getAttr<TargetAttr>()) {
144992cb984SSergei Barannikov       ParsedTargetAttr Attr =
145992cb984SSergei Barannikov           CGM.getTarget().parseTargetAttr(TA->getFeaturesStr());
146992cb984SSergei Barannikov       if (!Attr.BranchProtection.empty()) {
147e03f6651SDaniel Kiss         TargetInfo::BranchProtectionInfo BPI{};
148992cb984SSergei Barannikov         StringRef DiagMsg;
149992cb984SSergei Barannikov         StringRef Arch =
150992cb984SSergei Barannikov             Attr.CPU.empty() ? CGM.getTarget().getTargetOpts().CPU : Attr.CPU;
151992cb984SSergei Barannikov         if (!CGM.getTarget().validateBranchProtection(Attr.BranchProtection,
152992cb984SSergei Barannikov                                                       Arch, BPI, DiagMsg)) {
153992cb984SSergei Barannikov           CGM.getDiags().Report(
154992cb984SSergei Barannikov               D->getLocation(),
155992cb984SSergei Barannikov               diag::warn_target_unsupported_branch_protection_attribute)
156992cb984SSergei Barannikov               << Arch;
157f34a1654SDaniel Kiss         } else
158f34a1654SDaniel Kiss           setBranchProtectionFnAttributes(BPI, (*Fn));
159992cb984SSergei Barannikov       } else if (CGM.getLangOpts().BranchTargetEnforcement ||
160992cb984SSergei Barannikov                  CGM.getLangOpts().hasSignReturnAddress()) {
161992cb984SSergei Barannikov         // If the Branch Protection attribute is missing, validate the target
162992cb984SSergei Barannikov         // Architecture attribute against Branch Protection command line
163992cb984SSergei Barannikov         // settings.
164992cb984SSergei Barannikov         if (!CGM.getTarget().isBranchProtectionSupportedArch(Attr.CPU))
165992cb984SSergei Barannikov           CGM.getDiags().Report(
166992cb984SSergei Barannikov               D->getLocation(),
167992cb984SSergei Barannikov               diag::warn_target_unsupported_branch_protection_attribute)
168992cb984SSergei Barannikov               << Attr.CPU;
169992cb984SSergei Barannikov       }
1701782810bSDaniel Kiss     } else if (CGM.getTarget().isBranchProtectionSupportedArch(
1711782810bSDaniel Kiss                    CGM.getTarget().getTargetOpts().CPU)) {
1721782810bSDaniel Kiss       TargetInfo::BranchProtectionInfo BPI(CGM.getLangOpts());
173f34a1654SDaniel Kiss       setBranchProtectionFnAttributes(BPI, (*Fn));
174992cb984SSergei Barannikov     }
175992cb984SSergei Barannikov 
176992cb984SSergei Barannikov     const ARMInterruptAttr *Attr = FD->getAttr<ARMInterruptAttr>();
177992cb984SSergei Barannikov     if (!Attr)
178992cb984SSergei Barannikov       return;
179992cb984SSergei Barannikov 
180992cb984SSergei Barannikov     const char *Kind;
181992cb984SSergei Barannikov     switch (Attr->getInterrupt()) {
182992cb984SSergei Barannikov     case ARMInterruptAttr::Generic: Kind = ""; break;
183992cb984SSergei Barannikov     case ARMInterruptAttr::IRQ:     Kind = "IRQ"; break;
184992cb984SSergei Barannikov     case ARMInterruptAttr::FIQ:     Kind = "FIQ"; break;
185992cb984SSergei Barannikov     case ARMInterruptAttr::SWI:     Kind = "SWI"; break;
186992cb984SSergei Barannikov     case ARMInterruptAttr::ABORT:   Kind = "ABORT"; break;
187992cb984SSergei Barannikov     case ARMInterruptAttr::UNDEF:   Kind = "UNDEF"; break;
188992cb984SSergei Barannikov     }
189992cb984SSergei Barannikov 
190992cb984SSergei Barannikov     Fn->addFnAttr("interrupt", Kind);
191992cb984SSergei Barannikov 
192992cb984SSergei Barannikov     ARMABIKind ABI = getABIInfo<ARMABIInfo>().getABIKind();
193992cb984SSergei Barannikov     if (ABI == ARMABIKind::APCS)
194992cb984SSergei Barannikov       return;
195992cb984SSergei Barannikov 
196992cb984SSergei Barannikov     // AAPCS guarantees that sp will be 8-byte aligned on any public interface,
197992cb984SSergei Barannikov     // however this is not necessarily true on taking any interrupt. Instruct
198992cb984SSergei Barannikov     // the backend to perform a realignment as part of the function prologue.
199992cb984SSergei Barannikov     llvm::AttrBuilder B(Fn->getContext());
200992cb984SSergei Barannikov     B.addStackAlignmentAttr(8);
201992cb984SSergei Barannikov     Fn->addFnAttrs(B);
202992cb984SSergei Barannikov   }
203992cb984SSergei Barannikov };
204992cb984SSergei Barannikov 
205992cb984SSergei Barannikov class WindowsARMTargetCodeGenInfo : public ARMTargetCodeGenInfo {
206992cb984SSergei Barannikov public:
207992cb984SSergei Barannikov   WindowsARMTargetCodeGenInfo(CodeGenTypes &CGT, ARMABIKind K)
208992cb984SSergei Barannikov       : ARMTargetCodeGenInfo(CGT, K) {}
209992cb984SSergei Barannikov 
210992cb984SSergei Barannikov   void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
211992cb984SSergei Barannikov                            CodeGen::CodeGenModule &CGM) const override;
212992cb984SSergei Barannikov 
213992cb984SSergei Barannikov   void getDependentLibraryOption(llvm::StringRef Lib,
214992cb984SSergei Barannikov                                  llvm::SmallString<24> &Opt) const override {
215992cb984SSergei Barannikov     Opt = "/DEFAULTLIB:" + qualifyWindowsLibrary(Lib);
216992cb984SSergei Barannikov   }
217992cb984SSergei Barannikov 
218992cb984SSergei Barannikov   void getDetectMismatchOption(llvm::StringRef Name, llvm::StringRef Value,
219992cb984SSergei Barannikov                                llvm::SmallString<32> &Opt) const override {
220992cb984SSergei Barannikov     Opt = "/FAILIFMISMATCH:\"" + Name.str() + "=" + Value.str() + "\"";
221992cb984SSergei Barannikov   }
222992cb984SSergei Barannikov };
223992cb984SSergei Barannikov 
224992cb984SSergei Barannikov void WindowsARMTargetCodeGenInfo::setTargetAttributes(
225992cb984SSergei Barannikov     const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const {
226992cb984SSergei Barannikov   ARMTargetCodeGenInfo::setTargetAttributes(D, GV, CGM);
227992cb984SSergei Barannikov   if (GV->isDeclaration())
228992cb984SSergei Barannikov     return;
229992cb984SSergei Barannikov   addStackProbeTargetAttributes(D, GV, CGM);
230992cb984SSergei Barannikov }
231992cb984SSergei Barannikov }
232992cb984SSergei Barannikov 
233992cb984SSergei Barannikov void ARMABIInfo::computeInfo(CGFunctionInfo &FI) const {
234992cb984SSergei Barannikov   if (!::classifyReturnType(getCXXABI(), FI, *this))
235992cb984SSergei Barannikov     FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), FI.isVariadic(),
236992cb984SSergei Barannikov                                             FI.getCallingConvention());
237992cb984SSergei Barannikov 
238992cb984SSergei Barannikov   for (auto &I : FI.arguments())
239992cb984SSergei Barannikov     I.info = classifyArgumentType(I.type, FI.isVariadic(),
240992cb984SSergei Barannikov                                   FI.getCallingConvention());
241992cb984SSergei Barannikov 
242992cb984SSergei Barannikov 
243992cb984SSergei Barannikov   // Always honor user-specified calling convention.
244992cb984SSergei Barannikov   if (FI.getCallingConvention() != llvm::CallingConv::C)
245992cb984SSergei Barannikov     return;
246992cb984SSergei Barannikov 
247992cb984SSergei Barannikov   llvm::CallingConv::ID cc = getRuntimeCC();
248992cb984SSergei Barannikov   if (cc != llvm::CallingConv::C)
249992cb984SSergei Barannikov     FI.setEffectiveCallingConvention(cc);
250992cb984SSergei Barannikov }
251992cb984SSergei Barannikov 
252992cb984SSergei Barannikov /// Return the default calling convention that LLVM will use.
253992cb984SSergei Barannikov llvm::CallingConv::ID ARMABIInfo::getLLVMDefaultCC() const {
254992cb984SSergei Barannikov   // The default calling convention that LLVM will infer.
255992cb984SSergei Barannikov   if (isEABIHF() || getTarget().getTriple().isWatchABI())
256992cb984SSergei Barannikov     return llvm::CallingConv::ARM_AAPCS_VFP;
257992cb984SSergei Barannikov   else if (isEABI())
258992cb984SSergei Barannikov     return llvm::CallingConv::ARM_AAPCS;
259992cb984SSergei Barannikov   else
260992cb984SSergei Barannikov     return llvm::CallingConv::ARM_APCS;
261992cb984SSergei Barannikov }
262992cb984SSergei Barannikov 
263992cb984SSergei Barannikov /// Return the calling convention that our ABI would like us to use
264992cb984SSergei Barannikov /// as the C calling convention.
265992cb984SSergei Barannikov llvm::CallingConv::ID ARMABIInfo::getABIDefaultCC() const {
266992cb984SSergei Barannikov   switch (getABIKind()) {
267992cb984SSergei Barannikov   case ARMABIKind::APCS:
268992cb984SSergei Barannikov     return llvm::CallingConv::ARM_APCS;
269992cb984SSergei Barannikov   case ARMABIKind::AAPCS:
270992cb984SSergei Barannikov     return llvm::CallingConv::ARM_AAPCS;
271992cb984SSergei Barannikov   case ARMABIKind::AAPCS_VFP:
272992cb984SSergei Barannikov     return llvm::CallingConv::ARM_AAPCS_VFP;
273992cb984SSergei Barannikov   case ARMABIKind::AAPCS16_VFP:
274992cb984SSergei Barannikov     return llvm::CallingConv::ARM_AAPCS_VFP;
275992cb984SSergei Barannikov   }
276992cb984SSergei Barannikov   llvm_unreachable("bad ABI kind");
277992cb984SSergei Barannikov }
278992cb984SSergei Barannikov 
279992cb984SSergei Barannikov void ARMABIInfo::setCCs() {
280992cb984SSergei Barannikov   assert(getRuntimeCC() == llvm::CallingConv::C);
281992cb984SSergei Barannikov 
282992cb984SSergei Barannikov   // Don't muddy up the IR with a ton of explicit annotations if
283992cb984SSergei Barannikov   // they'd just match what LLVM will infer from the triple.
284992cb984SSergei Barannikov   llvm::CallingConv::ID abiCC = getABIDefaultCC();
285992cb984SSergei Barannikov   if (abiCC != getLLVMDefaultCC())
286992cb984SSergei Barannikov     RuntimeCC = abiCC;
287992cb984SSergei Barannikov }
288992cb984SSergei Barannikov 
289992cb984SSergei Barannikov ABIArgInfo ARMABIInfo::coerceIllegalVector(QualType Ty) const {
290992cb984SSergei Barannikov   uint64_t Size = getContext().getTypeSize(Ty);
291992cb984SSergei Barannikov   if (Size <= 32) {
292992cb984SSergei Barannikov     llvm::Type *ResType =
293992cb984SSergei Barannikov         llvm::Type::getInt32Ty(getVMContext());
294992cb984SSergei Barannikov     return ABIArgInfo::getDirect(ResType);
295992cb984SSergei Barannikov   }
296992cb984SSergei Barannikov   if (Size == 64 || Size == 128) {
297992cb984SSergei Barannikov     auto *ResType = llvm::FixedVectorType::get(
298992cb984SSergei Barannikov         llvm::Type::getInt32Ty(getVMContext()), Size / 32);
299992cb984SSergei Barannikov     return ABIArgInfo::getDirect(ResType);
300992cb984SSergei Barannikov   }
301992cb984SSergei Barannikov   return getNaturalAlignIndirect(Ty, /*ByVal=*/false);
302992cb984SSergei Barannikov }
303992cb984SSergei Barannikov 
304992cb984SSergei Barannikov ABIArgInfo ARMABIInfo::classifyHomogeneousAggregate(QualType Ty,
305992cb984SSergei Barannikov                                                     const Type *Base,
306992cb984SSergei Barannikov                                                     uint64_t Members) const {
307992cb984SSergei Barannikov   assert(Base && "Base class should be set for homogeneous aggregate");
308992cb984SSergei Barannikov   // Base can be a floating-point or a vector.
309992cb984SSergei Barannikov   if (const VectorType *VT = Base->getAs<VectorType>()) {
310992cb984SSergei Barannikov     // FP16 vectors should be converted to integer vectors
311992cb984SSergei Barannikov     if (!getTarget().hasLegalHalfType() && containsAnyFP16Vectors(Ty)) {
312992cb984SSergei Barannikov       uint64_t Size = getContext().getTypeSize(VT);
313992cb984SSergei Barannikov       auto *NewVecTy = llvm::FixedVectorType::get(
314992cb984SSergei Barannikov           llvm::Type::getInt32Ty(getVMContext()), Size / 32);
315992cb984SSergei Barannikov       llvm::Type *Ty = llvm::ArrayType::get(NewVecTy, Members);
316992cb984SSergei Barannikov       return ABIArgInfo::getDirect(Ty, 0, nullptr, false);
317992cb984SSergei Barannikov     }
318992cb984SSergei Barannikov   }
319992cb984SSergei Barannikov   unsigned Align = 0;
320992cb984SSergei Barannikov   if (getABIKind() == ARMABIKind::AAPCS ||
321992cb984SSergei Barannikov       getABIKind() == ARMABIKind::AAPCS_VFP) {
322992cb984SSergei Barannikov     // For alignment adjusted HFAs, cap the argument alignment to 8, leave it
323992cb984SSergei Barannikov     // default otherwise.
324992cb984SSergei Barannikov     Align = getContext().getTypeUnadjustedAlignInChars(Ty).getQuantity();
325992cb984SSergei Barannikov     unsigned BaseAlign = getContext().getTypeAlignInChars(Base).getQuantity();
326992cb984SSergei Barannikov     Align = (Align > BaseAlign && Align >= 8) ? 8 : 0;
327992cb984SSergei Barannikov   }
328992cb984SSergei Barannikov   return ABIArgInfo::getDirect(nullptr, 0, nullptr, false, Align);
329992cb984SSergei Barannikov }
330992cb984SSergei Barannikov 
331992cb984SSergei Barannikov ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, bool isVariadic,
332992cb984SSergei Barannikov                                             unsigned functionCallConv) const {
333992cb984SSergei Barannikov   // 6.1.2.1 The following argument types are VFP CPRCs:
334992cb984SSergei Barannikov   //   A single-precision floating-point type (including promoted
335992cb984SSergei Barannikov   //   half-precision types); A double-precision floating-point type;
336992cb984SSergei Barannikov   //   A 64-bit or 128-bit containerized vector type; Homogeneous Aggregate
337992cb984SSergei Barannikov   //   with a Base Type of a single- or double-precision floating-point type,
338992cb984SSergei Barannikov   //   64-bit containerized vectors or 128-bit containerized vectors with one
339992cb984SSergei Barannikov   //   to four Elements.
340992cb984SSergei Barannikov   // Variadic functions should always marshal to the base standard.
341992cb984SSergei Barannikov   bool IsAAPCS_VFP =
342992cb984SSergei Barannikov       !isVariadic && isEffectivelyAAPCS_VFP(functionCallConv, /* AAPCS16 */ false);
343992cb984SSergei Barannikov 
344992cb984SSergei Barannikov   Ty = useFirstFieldIfTransparentUnion(Ty);
345992cb984SSergei Barannikov 
346992cb984SSergei Barannikov   // Handle illegal vector types here.
347992cb984SSergei Barannikov   if (isIllegalVectorType(Ty))
348992cb984SSergei Barannikov     return coerceIllegalVector(Ty);
349992cb984SSergei Barannikov 
350992cb984SSergei Barannikov   if (!isAggregateTypeForABI(Ty)) {
351992cb984SSergei Barannikov     // Treat an enum type as its underlying type.
352992cb984SSergei Barannikov     if (const EnumType *EnumTy = Ty->getAs<EnumType>()) {
353992cb984SSergei Barannikov       Ty = EnumTy->getDecl()->getIntegerType();
354992cb984SSergei Barannikov     }
355992cb984SSergei Barannikov 
356992cb984SSergei Barannikov     if (const auto *EIT = Ty->getAs<BitIntType>())
357992cb984SSergei Barannikov       if (EIT->getNumBits() > 64)
358992cb984SSergei Barannikov         return getNaturalAlignIndirect(Ty, /*ByVal=*/true);
359992cb984SSergei Barannikov 
360ea920450SLei Huang     return (isPromotableIntegerTypeForABI(Ty)
361ea920450SLei Huang                 ? ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty))
362992cb984SSergei Barannikov                 : ABIArgInfo::getDirect());
363992cb984SSergei Barannikov   }
364992cb984SSergei Barannikov 
365992cb984SSergei Barannikov   if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) {
366992cb984SSergei Barannikov     return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory);
367992cb984SSergei Barannikov   }
368992cb984SSergei Barannikov 
369992cb984SSergei Barannikov   // Ignore empty records.
370992cb984SSergei Barannikov   if (isEmptyRecord(getContext(), Ty, true))
371992cb984SSergei Barannikov     return ABIArgInfo::getIgnore();
372992cb984SSergei Barannikov 
373992cb984SSergei Barannikov   if (IsAAPCS_VFP) {
374992cb984SSergei Barannikov     // Homogeneous Aggregates need to be expanded when we can fit the aggregate
375992cb984SSergei Barannikov     // into VFP registers.
376992cb984SSergei Barannikov     const Type *Base = nullptr;
377992cb984SSergei Barannikov     uint64_t Members = 0;
378992cb984SSergei Barannikov     if (isHomogeneousAggregate(Ty, Base, Members))
379992cb984SSergei Barannikov       return classifyHomogeneousAggregate(Ty, Base, Members);
380992cb984SSergei Barannikov   } else if (getABIKind() == ARMABIKind::AAPCS16_VFP) {
381992cb984SSergei Barannikov     // WatchOS does have homogeneous aggregates. Note that we intentionally use
382992cb984SSergei Barannikov     // this convention even for a variadic function: the backend will use GPRs
383992cb984SSergei Barannikov     // if needed.
384992cb984SSergei Barannikov     const Type *Base = nullptr;
385992cb984SSergei Barannikov     uint64_t Members = 0;
386992cb984SSergei Barannikov     if (isHomogeneousAggregate(Ty, Base, Members)) {
387992cb984SSergei Barannikov       assert(Base && Members <= 4 && "unexpected homogeneous aggregate");
388992cb984SSergei Barannikov       llvm::Type *Ty =
389992cb984SSergei Barannikov         llvm::ArrayType::get(CGT.ConvertType(QualType(Base, 0)), Members);
390992cb984SSergei Barannikov       return ABIArgInfo::getDirect(Ty, 0, nullptr, false);
391992cb984SSergei Barannikov     }
392992cb984SSergei Barannikov   }
393992cb984SSergei Barannikov 
394992cb984SSergei Barannikov   if (getABIKind() == ARMABIKind::AAPCS16_VFP &&
395992cb984SSergei Barannikov       getContext().getTypeSizeInChars(Ty) > CharUnits::fromQuantity(16)) {
396992cb984SSergei Barannikov     // WatchOS is adopting the 64-bit AAPCS rule on composite types: if they're
397992cb984SSergei Barannikov     // bigger than 128-bits, they get placed in space allocated by the caller,
398992cb984SSergei Barannikov     // and a pointer is passed.
399992cb984SSergei Barannikov     return ABIArgInfo::getIndirect(
400992cb984SSergei Barannikov         CharUnits::fromQuantity(getContext().getTypeAlign(Ty) / 8), false);
401992cb984SSergei Barannikov   }
402992cb984SSergei Barannikov 
403992cb984SSergei Barannikov   // Support byval for ARM.
404992cb984SSergei Barannikov   // The ABI alignment for APCS is 4-byte and for AAPCS at least 4-byte and at
405992cb984SSergei Barannikov   // most 8-byte. We realign the indirect argument if type alignment is bigger
406992cb984SSergei Barannikov   // than ABI alignment.
407992cb984SSergei Barannikov   uint64_t ABIAlign = 4;
408992cb984SSergei Barannikov   uint64_t TyAlign;
409992cb984SSergei Barannikov   if (getABIKind() == ARMABIKind::AAPCS_VFP ||
410992cb984SSergei Barannikov       getABIKind() == ARMABIKind::AAPCS) {
411992cb984SSergei Barannikov     TyAlign = getContext().getTypeUnadjustedAlignInChars(Ty).getQuantity();
412992cb984SSergei Barannikov     ABIAlign = std::clamp(TyAlign, (uint64_t)4, (uint64_t)8);
413992cb984SSergei Barannikov   } else {
414992cb984SSergei Barannikov     TyAlign = getContext().getTypeAlignInChars(Ty).getQuantity();
415992cb984SSergei Barannikov   }
416992cb984SSergei Barannikov   if (getContext().getTypeSizeInChars(Ty) > CharUnits::fromQuantity(64)) {
417992cb984SSergei Barannikov     assert(getABIKind() != ARMABIKind::AAPCS16_VFP && "unexpected byval");
418992cb984SSergei Barannikov     return ABIArgInfo::getIndirect(CharUnits::fromQuantity(ABIAlign),
419992cb984SSergei Barannikov                                    /*ByVal=*/true,
420992cb984SSergei Barannikov                                    /*Realign=*/TyAlign > ABIAlign);
421992cb984SSergei Barannikov   }
422992cb984SSergei Barannikov 
423992cb984SSergei Barannikov   // Otherwise, pass by coercing to a structure of the appropriate size.
424992cb984SSergei Barannikov   llvm::Type* ElemTy;
425992cb984SSergei Barannikov   unsigned SizeRegs;
426992cb984SSergei Barannikov   // FIXME: Try to match the types of the arguments more accurately where
427992cb984SSergei Barannikov   // we can.
428992cb984SSergei Barannikov   if (TyAlign <= 4) {
429992cb984SSergei Barannikov     ElemTy = llvm::Type::getInt32Ty(getVMContext());
430992cb984SSergei Barannikov     SizeRegs = (getContext().getTypeSize(Ty) + 31) / 32;
431992cb984SSergei Barannikov   } else {
432992cb984SSergei Barannikov     ElemTy = llvm::Type::getInt64Ty(getVMContext());
433992cb984SSergei Barannikov     SizeRegs = (getContext().getTypeSize(Ty) + 63) / 64;
434992cb984SSergei Barannikov   }
435992cb984SSergei Barannikov 
436992cb984SSergei Barannikov   return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, SizeRegs));
437992cb984SSergei Barannikov }
438992cb984SSergei Barannikov 
439992cb984SSergei Barannikov static bool isIntegerLikeType(QualType Ty, ASTContext &Context,
440992cb984SSergei Barannikov                               llvm::LLVMContext &VMContext) {
441992cb984SSergei Barannikov   // APCS, C Language Calling Conventions, Non-Simple Return Values: A structure
442992cb984SSergei Barannikov   // is called integer-like if its size is less than or equal to one word, and
443992cb984SSergei Barannikov   // the offset of each of its addressable sub-fields is zero.
444992cb984SSergei Barannikov 
445992cb984SSergei Barannikov   uint64_t Size = Context.getTypeSize(Ty);
446992cb984SSergei Barannikov 
447992cb984SSergei Barannikov   // Check that the type fits in a word.
448992cb984SSergei Barannikov   if (Size > 32)
449992cb984SSergei Barannikov     return false;
450992cb984SSergei Barannikov 
451992cb984SSergei Barannikov   // FIXME: Handle vector types!
452992cb984SSergei Barannikov   if (Ty->isVectorType())
453992cb984SSergei Barannikov     return false;
454992cb984SSergei Barannikov 
455992cb984SSergei Barannikov   // Float types are never treated as "integer like".
456992cb984SSergei Barannikov   if (Ty->isRealFloatingType())
457992cb984SSergei Barannikov     return false;
458992cb984SSergei Barannikov 
459992cb984SSergei Barannikov   // If this is a builtin or pointer type then it is ok.
460992cb984SSergei Barannikov   if (Ty->getAs<BuiltinType>() || Ty->isPointerType())
461992cb984SSergei Barannikov     return true;
462992cb984SSergei Barannikov 
463992cb984SSergei Barannikov   // Small complex integer types are "integer like".
464992cb984SSergei Barannikov   if (const ComplexType *CT = Ty->getAs<ComplexType>())
465992cb984SSergei Barannikov     return isIntegerLikeType(CT->getElementType(), Context, VMContext);
466992cb984SSergei Barannikov 
467992cb984SSergei Barannikov   // Single element and zero sized arrays should be allowed, by the definition
468992cb984SSergei Barannikov   // above, but they are not.
469992cb984SSergei Barannikov 
470992cb984SSergei Barannikov   // Otherwise, it must be a record type.
471992cb984SSergei Barannikov   const RecordType *RT = Ty->getAs<RecordType>();
472992cb984SSergei Barannikov   if (!RT) return false;
473992cb984SSergei Barannikov 
474992cb984SSergei Barannikov   // Ignore records with flexible arrays.
475992cb984SSergei Barannikov   const RecordDecl *RD = RT->getDecl();
476992cb984SSergei Barannikov   if (RD->hasFlexibleArrayMember())
477992cb984SSergei Barannikov     return false;
478992cb984SSergei Barannikov 
479992cb984SSergei Barannikov   // Check that all sub-fields are at offset 0, and are themselves "integer
480992cb984SSergei Barannikov   // like".
481992cb984SSergei Barannikov   const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
482992cb984SSergei Barannikov 
483992cb984SSergei Barannikov   bool HadField = false;
484992cb984SSergei Barannikov   unsigned idx = 0;
485992cb984SSergei Barannikov   for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
486992cb984SSergei Barannikov        i != e; ++i, ++idx) {
487992cb984SSergei Barannikov     const FieldDecl *FD = *i;
488992cb984SSergei Barannikov 
489992cb984SSergei Barannikov     // Bit-fields are not addressable, we only need to verify they are "integer
490992cb984SSergei Barannikov     // like". We still have to disallow a subsequent non-bitfield, for example:
491992cb984SSergei Barannikov     //   struct { int : 0; int x }
492992cb984SSergei Barannikov     // is non-integer like according to gcc.
493992cb984SSergei Barannikov     if (FD->isBitField()) {
494992cb984SSergei Barannikov       if (!RD->isUnion())
495992cb984SSergei Barannikov         HadField = true;
496992cb984SSergei Barannikov 
497992cb984SSergei Barannikov       if (!isIntegerLikeType(FD->getType(), Context, VMContext))
498992cb984SSergei Barannikov         return false;
499992cb984SSergei Barannikov 
500992cb984SSergei Barannikov       continue;
501992cb984SSergei Barannikov     }
502992cb984SSergei Barannikov 
503992cb984SSergei Barannikov     // Check if this field is at offset 0.
504992cb984SSergei Barannikov     if (Layout.getFieldOffset(idx) != 0)
505992cb984SSergei Barannikov       return false;
506992cb984SSergei Barannikov 
507992cb984SSergei Barannikov     if (!isIntegerLikeType(FD->getType(), Context, VMContext))
508992cb984SSergei Barannikov       return false;
509992cb984SSergei Barannikov 
510992cb984SSergei Barannikov     // Only allow at most one field in a structure. This doesn't match the
511992cb984SSergei Barannikov     // wording above, but follows gcc in situations with a field following an
512992cb984SSergei Barannikov     // empty structure.
513992cb984SSergei Barannikov     if (!RD->isUnion()) {
514992cb984SSergei Barannikov       if (HadField)
515992cb984SSergei Barannikov         return false;
516992cb984SSergei Barannikov 
517992cb984SSergei Barannikov       HadField = true;
518992cb984SSergei Barannikov     }
519992cb984SSergei Barannikov   }
520992cb984SSergei Barannikov 
521992cb984SSergei Barannikov   return true;
522992cb984SSergei Barannikov }
523992cb984SSergei Barannikov 
524992cb984SSergei Barannikov ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy, bool isVariadic,
525992cb984SSergei Barannikov                                           unsigned functionCallConv) const {
526992cb984SSergei Barannikov 
527992cb984SSergei Barannikov   // Variadic functions should always marshal to the base standard.
528992cb984SSergei Barannikov   bool IsAAPCS_VFP =
529992cb984SSergei Barannikov       !isVariadic && isEffectivelyAAPCS_VFP(functionCallConv, /* AAPCS16 */ true);
530992cb984SSergei Barannikov 
531992cb984SSergei Barannikov   if (RetTy->isVoidType())
532992cb984SSergei Barannikov     return ABIArgInfo::getIgnore();
533992cb984SSergei Barannikov 
534992cb984SSergei Barannikov   if (const VectorType *VT = RetTy->getAs<VectorType>()) {
535992cb984SSergei Barannikov     // Large vector types should be returned via memory.
536992cb984SSergei Barannikov     if (getContext().getTypeSize(RetTy) > 128)
537992cb984SSergei Barannikov       return getNaturalAlignIndirect(RetTy);
538992cb984SSergei Barannikov     // TODO: FP16/BF16 vectors should be converted to integer vectors
539992cb984SSergei Barannikov     // This check is similar  to isIllegalVectorType - refactor?
540992cb984SSergei Barannikov     if ((!getTarget().hasLegalHalfType() &&
541992cb984SSergei Barannikov         (VT->getElementType()->isFloat16Type() ||
542992cb984SSergei Barannikov          VT->getElementType()->isHalfType())) ||
543992cb984SSergei Barannikov         (IsFloatABISoftFP &&
544992cb984SSergei Barannikov          VT->getElementType()->isBFloat16Type()))
545992cb984SSergei Barannikov       return coerceIllegalVector(RetTy);
546992cb984SSergei Barannikov   }
547992cb984SSergei Barannikov 
548992cb984SSergei Barannikov   if (!isAggregateTypeForABI(RetTy)) {
549992cb984SSergei Barannikov     // Treat an enum type as its underlying type.
550992cb984SSergei Barannikov     if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
551992cb984SSergei Barannikov       RetTy = EnumTy->getDecl()->getIntegerType();
552992cb984SSergei Barannikov 
553992cb984SSergei Barannikov     if (const auto *EIT = RetTy->getAs<BitIntType>())
554992cb984SSergei Barannikov       if (EIT->getNumBits() > 64)
555992cb984SSergei Barannikov         return getNaturalAlignIndirect(RetTy, /*ByVal=*/false);
556992cb984SSergei Barannikov 
557992cb984SSergei Barannikov     return isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
558992cb984SSergei Barannikov                                                 : ABIArgInfo::getDirect();
559992cb984SSergei Barannikov   }
560992cb984SSergei Barannikov 
561992cb984SSergei Barannikov   // Are we following APCS?
562992cb984SSergei Barannikov   if (getABIKind() == ARMABIKind::APCS) {
563992cb984SSergei Barannikov     if (isEmptyRecord(getContext(), RetTy, false))
564992cb984SSergei Barannikov       return ABIArgInfo::getIgnore();
565992cb984SSergei Barannikov 
566992cb984SSergei Barannikov     // Complex types are all returned as packed integers.
567992cb984SSergei Barannikov     //
568992cb984SSergei Barannikov     // FIXME: Consider using 2 x vector types if the back end handles them
569992cb984SSergei Barannikov     // correctly.
570992cb984SSergei Barannikov     if (RetTy->isAnyComplexType())
571992cb984SSergei Barannikov       return ABIArgInfo::getDirect(llvm::IntegerType::get(
572992cb984SSergei Barannikov           getVMContext(), getContext().getTypeSize(RetTy)));
573992cb984SSergei Barannikov 
574992cb984SSergei Barannikov     // Integer like structures are returned in r0.
575992cb984SSergei Barannikov     if (isIntegerLikeType(RetTy, getContext(), getVMContext())) {
576992cb984SSergei Barannikov       // Return in the smallest viable integer type.
577992cb984SSergei Barannikov       uint64_t Size = getContext().getTypeSize(RetTy);
578992cb984SSergei Barannikov       if (Size <= 8)
579992cb984SSergei Barannikov         return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));
580992cb984SSergei Barannikov       if (Size <= 16)
581992cb984SSergei Barannikov         return ABIArgInfo::getDirect(llvm::Type::getInt16Ty(getVMContext()));
582992cb984SSergei Barannikov       return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext()));
583992cb984SSergei Barannikov     }
584992cb984SSergei Barannikov 
585992cb984SSergei Barannikov     // Otherwise return in memory.
586992cb984SSergei Barannikov     return getNaturalAlignIndirect(RetTy);
587992cb984SSergei Barannikov   }
588992cb984SSergei Barannikov 
589992cb984SSergei Barannikov   // Otherwise this is an AAPCS variant.
590992cb984SSergei Barannikov 
591992cb984SSergei Barannikov   if (isEmptyRecord(getContext(), RetTy, true))
592992cb984SSergei Barannikov     return ABIArgInfo::getIgnore();
593992cb984SSergei Barannikov 
594992cb984SSergei Barannikov   // Check for homogeneous aggregates with AAPCS-VFP.
595992cb984SSergei Barannikov   if (IsAAPCS_VFP) {
596992cb984SSergei Barannikov     const Type *Base = nullptr;
597992cb984SSergei Barannikov     uint64_t Members = 0;
598992cb984SSergei Barannikov     if (isHomogeneousAggregate(RetTy, Base, Members))
599992cb984SSergei Barannikov       return classifyHomogeneousAggregate(RetTy, Base, Members);
600992cb984SSergei Barannikov   }
601992cb984SSergei Barannikov 
602992cb984SSergei Barannikov   // Aggregates <= 4 bytes are returned in r0; other aggregates
603992cb984SSergei Barannikov   // are returned indirectly.
604992cb984SSergei Barannikov   uint64_t Size = getContext().getTypeSize(RetTy);
605992cb984SSergei Barannikov   if (Size <= 32) {
606992cb984SSergei Barannikov     if (getDataLayout().isBigEndian())
607992cb984SSergei Barannikov       // Return in 32 bit integer integer type (as if loaded by LDR, AAPCS 5.4)
608992cb984SSergei Barannikov       return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext()));
609992cb984SSergei Barannikov 
610992cb984SSergei Barannikov     // Return in the smallest viable integer type.
611992cb984SSergei Barannikov     if (Size <= 8)
612992cb984SSergei Barannikov       return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));
613992cb984SSergei Barannikov     if (Size <= 16)
614992cb984SSergei Barannikov       return ABIArgInfo::getDirect(llvm::Type::getInt16Ty(getVMContext()));
615992cb984SSergei Barannikov     return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext()));
616992cb984SSergei Barannikov   } else if (Size <= 128 && getABIKind() == ARMABIKind::AAPCS16_VFP) {
617992cb984SSergei Barannikov     llvm::Type *Int32Ty = llvm::Type::getInt32Ty(getVMContext());
618992cb984SSergei Barannikov     llvm::Type *CoerceTy =
619992cb984SSergei Barannikov         llvm::ArrayType::get(Int32Ty, llvm::alignTo(Size, 32) / 32);
620992cb984SSergei Barannikov     return ABIArgInfo::getDirect(CoerceTy);
621992cb984SSergei Barannikov   }
622992cb984SSergei Barannikov 
623992cb984SSergei Barannikov   return getNaturalAlignIndirect(RetTy);
624992cb984SSergei Barannikov }
625992cb984SSergei Barannikov 
626992cb984SSergei Barannikov /// isIllegalVector - check whether Ty is an illegal vector type.
627992cb984SSergei Barannikov bool ARMABIInfo::isIllegalVectorType(QualType Ty) const {
628992cb984SSergei Barannikov   if (const VectorType *VT = Ty->getAs<VectorType> ()) {
629992cb984SSergei Barannikov     // On targets that don't support half, fp16 or bfloat, they are expanded
630992cb984SSergei Barannikov     // into float, and we don't want the ABI to depend on whether or not they
631992cb984SSergei Barannikov     // are supported in hardware. Thus return false to coerce vectors of these
632992cb984SSergei Barannikov     // types into integer vectors.
633992cb984SSergei Barannikov     // We do not depend on hasLegalHalfType for bfloat as it is a
634992cb984SSergei Barannikov     // separate IR type.
635992cb984SSergei Barannikov     if ((!getTarget().hasLegalHalfType() &&
636992cb984SSergei Barannikov         (VT->getElementType()->isFloat16Type() ||
637992cb984SSergei Barannikov          VT->getElementType()->isHalfType())) ||
638992cb984SSergei Barannikov         (IsFloatABISoftFP &&
639992cb984SSergei Barannikov          VT->getElementType()->isBFloat16Type()))
640992cb984SSergei Barannikov       return true;
641992cb984SSergei Barannikov     if (isAndroid()) {
642992cb984SSergei Barannikov       // Android shipped using Clang 3.1, which supported a slightly different
643992cb984SSergei Barannikov       // vector ABI. The primary differences were that 3-element vector types
644992cb984SSergei Barannikov       // were legal, and so were sub 32-bit vectors (i.e. <2 x i8>). This path
645992cb984SSergei Barannikov       // accepts that legacy behavior for Android only.
646992cb984SSergei Barannikov       // Check whether VT is legal.
647992cb984SSergei Barannikov       unsigned NumElements = VT->getNumElements();
648992cb984SSergei Barannikov       // NumElements should be power of 2 or equal to 3.
649992cb984SSergei Barannikov       if (!llvm::isPowerOf2_32(NumElements) && NumElements != 3)
650992cb984SSergei Barannikov         return true;
651992cb984SSergei Barannikov     } else {
652992cb984SSergei Barannikov       // Check whether VT is legal.
653992cb984SSergei Barannikov       unsigned NumElements = VT->getNumElements();
654992cb984SSergei Barannikov       uint64_t Size = getContext().getTypeSize(VT);
655992cb984SSergei Barannikov       // NumElements should be power of 2.
656992cb984SSergei Barannikov       if (!llvm::isPowerOf2_32(NumElements))
657992cb984SSergei Barannikov         return true;
658992cb984SSergei Barannikov       // Size should be greater than 32 bits.
659992cb984SSergei Barannikov       return Size <= 32;
660992cb984SSergei Barannikov     }
661992cb984SSergei Barannikov   }
662992cb984SSergei Barannikov   return false;
663992cb984SSergei Barannikov }
664992cb984SSergei Barannikov 
665992cb984SSergei Barannikov /// Return true if a type contains any 16-bit floating point vectors
666992cb984SSergei Barannikov bool ARMABIInfo::containsAnyFP16Vectors(QualType Ty) const {
667992cb984SSergei Barannikov   if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) {
66828ddbd4aSChris B     uint64_t NElements = AT->getZExtSize();
669992cb984SSergei Barannikov     if (NElements == 0)
670992cb984SSergei Barannikov       return false;
671992cb984SSergei Barannikov     return containsAnyFP16Vectors(AT->getElementType());
672992cb984SSergei Barannikov   } else if (const RecordType *RT = Ty->getAs<RecordType>()) {
673992cb984SSergei Barannikov     const RecordDecl *RD = RT->getDecl();
674992cb984SSergei Barannikov 
675992cb984SSergei Barannikov     // If this is a C++ record, check the bases first.
676992cb984SSergei Barannikov     if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
677992cb984SSergei Barannikov       if (llvm::any_of(CXXRD->bases(), [this](const CXXBaseSpecifier &B) {
678992cb984SSergei Barannikov             return containsAnyFP16Vectors(B.getType());
679992cb984SSergei Barannikov           }))
680992cb984SSergei Barannikov         return true;
681992cb984SSergei Barannikov 
682992cb984SSergei Barannikov     if (llvm::any_of(RD->fields(), [this](FieldDecl *FD) {
683992cb984SSergei Barannikov           return FD && containsAnyFP16Vectors(FD->getType());
684992cb984SSergei Barannikov         }))
685992cb984SSergei Barannikov       return true;
686992cb984SSergei Barannikov 
687992cb984SSergei Barannikov     return false;
688992cb984SSergei Barannikov   } else {
689992cb984SSergei Barannikov     if (const VectorType *VT = Ty->getAs<VectorType>())
690992cb984SSergei Barannikov       return (VT->getElementType()->isFloat16Type() ||
691992cb984SSergei Barannikov               VT->getElementType()->isBFloat16Type() ||
692992cb984SSergei Barannikov               VT->getElementType()->isHalfType());
693992cb984SSergei Barannikov     return false;
694992cb984SSergei Barannikov   }
695992cb984SSergei Barannikov }
696992cb984SSergei Barannikov 
697992cb984SSergei Barannikov bool ARMSwiftABIInfo::isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,
698992cb984SSergei Barannikov                                         unsigned NumElts) const {
699992cb984SSergei Barannikov   if (!llvm::isPowerOf2_32(NumElts))
700992cb984SSergei Barannikov     return false;
701992cb984SSergei Barannikov   unsigned size = CGT.getDataLayout().getTypeStoreSizeInBits(EltTy);
702992cb984SSergei Barannikov   if (size > 64)
703992cb984SSergei Barannikov     return false;
704992cb984SSergei Barannikov   if (VectorSize.getQuantity() != 8 &&
705992cb984SSergei Barannikov       (VectorSize.getQuantity() != 16 || NumElts == 1))
706992cb984SSergei Barannikov     return false;
707992cb984SSergei Barannikov   return true;
708992cb984SSergei Barannikov }
709992cb984SSergei Barannikov 
710992cb984SSergei Barannikov bool ARMABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const {
711992cb984SSergei Barannikov   // Homogeneous aggregates for AAPCS-VFP must have base types of float,
712992cb984SSergei Barannikov   // double, or 64-bit or 128-bit vectors.
713992cb984SSergei Barannikov   if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) {
714992cb984SSergei Barannikov     if (BT->getKind() == BuiltinType::Float ||
715992cb984SSergei Barannikov         BT->getKind() == BuiltinType::Double ||
716992cb984SSergei Barannikov         BT->getKind() == BuiltinType::LongDouble)
717992cb984SSergei Barannikov       return true;
718992cb984SSergei Barannikov   } else if (const VectorType *VT = Ty->getAs<VectorType>()) {
719992cb984SSergei Barannikov     unsigned VecSize = getContext().getTypeSize(VT);
720992cb984SSergei Barannikov     if (VecSize == 64 || VecSize == 128)
721992cb984SSergei Barannikov       return true;
722992cb984SSergei Barannikov   }
723992cb984SSergei Barannikov   return false;
724992cb984SSergei Barannikov }
725992cb984SSergei Barannikov 
726992cb984SSergei Barannikov bool ARMABIInfo::isHomogeneousAggregateSmallEnough(const Type *Base,
727992cb984SSergei Barannikov                                                    uint64_t Members) const {
728992cb984SSergei Barannikov   return Members <= 4;
729992cb984SSergei Barannikov }
730992cb984SSergei Barannikov 
731992cb984SSergei Barannikov bool ARMABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate() const {
732992cb984SSergei Barannikov   // AAPCS32 says that the rule for whether something is a homogeneous
733992cb984SSergei Barannikov   // aggregate is applied to the output of the data layout decision. So
734992cb984SSergei Barannikov   // anything that doesn't affect the data layout also does not affect
735992cb984SSergei Barannikov   // homogeneity. In particular, zero-length bitfields don't stop a struct
736992cb984SSergei Barannikov   // being homogeneous.
737992cb984SSergei Barannikov   return true;
738992cb984SSergei Barannikov }
739992cb984SSergei Barannikov 
740992cb984SSergei Barannikov bool ARMABIInfo::isEffectivelyAAPCS_VFP(unsigned callConvention,
741992cb984SSergei Barannikov                                         bool acceptHalf) const {
742992cb984SSergei Barannikov   // Give precedence to user-specified calling conventions.
743992cb984SSergei Barannikov   if (callConvention != llvm::CallingConv::C)
744992cb984SSergei Barannikov     return (callConvention == llvm::CallingConv::ARM_AAPCS_VFP);
745992cb984SSergei Barannikov   else
746992cb984SSergei Barannikov     return (getABIKind() == ARMABIKind::AAPCS_VFP) ||
747992cb984SSergei Barannikov            (acceptHalf && (getABIKind() == ARMABIKind::AAPCS16_VFP));
748992cb984SSergei Barannikov }
749992cb984SSergei Barannikov 
7506d973b45SMariya Podchishchaeva RValue ARMABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
7516d973b45SMariya Podchishchaeva                              QualType Ty, AggValueSlot Slot) const {
752992cb984SSergei Barannikov   CharUnits SlotSize = CharUnits::fromQuantity(4);
753992cb984SSergei Barannikov 
754992cb984SSergei Barannikov   // Empty records are ignored for parameter passing purposes.
7556d973b45SMariya Podchishchaeva   if (isEmptyRecord(getContext(), Ty, true))
7566d973b45SMariya Podchishchaeva     return Slot.asRValue();
757992cb984SSergei Barannikov 
758992cb984SSergei Barannikov   CharUnits TySize = getContext().getTypeSizeInChars(Ty);
759992cb984SSergei Barannikov   CharUnits TyAlignForABI = getContext().getTypeUnadjustedAlignInChars(Ty);
760992cb984SSergei Barannikov 
761992cb984SSergei Barannikov   // Use indirect if size of the illegal vector is bigger than 16 bytes.
762992cb984SSergei Barannikov   bool IsIndirect = false;
763992cb984SSergei Barannikov   const Type *Base = nullptr;
764992cb984SSergei Barannikov   uint64_t Members = 0;
765992cb984SSergei Barannikov   if (TySize > CharUnits::fromQuantity(16) && isIllegalVectorType(Ty)) {
766992cb984SSergei Barannikov     IsIndirect = true;
767992cb984SSergei Barannikov 
768992cb984SSergei Barannikov   // ARMv7k passes structs bigger than 16 bytes indirectly, in space
769992cb984SSergei Barannikov   // allocated by the caller.
770992cb984SSergei Barannikov   } else if (TySize > CharUnits::fromQuantity(16) &&
771992cb984SSergei Barannikov              getABIKind() == ARMABIKind::AAPCS16_VFP &&
772992cb984SSergei Barannikov              !isHomogeneousAggregate(Ty, Base, Members)) {
773992cb984SSergei Barannikov     IsIndirect = true;
774992cb984SSergei Barannikov 
775992cb984SSergei Barannikov   // Otherwise, bound the type's ABI alignment.
776992cb984SSergei Barannikov   // The ABI alignment for 64-bit or 128-bit vectors is 8 for AAPCS and 4 for
777992cb984SSergei Barannikov   // APCS. For AAPCS, the ABI alignment is at least 4-byte and at most 8-byte.
778992cb984SSergei Barannikov   // Our callers should be prepared to handle an under-aligned address.
779992cb984SSergei Barannikov   } else if (getABIKind() == ARMABIKind::AAPCS_VFP ||
780992cb984SSergei Barannikov              getABIKind() == ARMABIKind::AAPCS) {
781992cb984SSergei Barannikov     TyAlignForABI = std::max(TyAlignForABI, CharUnits::fromQuantity(4));
782992cb984SSergei Barannikov     TyAlignForABI = std::min(TyAlignForABI, CharUnits::fromQuantity(8));
783992cb984SSergei Barannikov   } else if (getABIKind() == ARMABIKind::AAPCS16_VFP) {
784992cb984SSergei Barannikov     // ARMv7k allows type alignment up to 16 bytes.
785992cb984SSergei Barannikov     TyAlignForABI = std::max(TyAlignForABI, CharUnits::fromQuantity(4));
786992cb984SSergei Barannikov     TyAlignForABI = std::min(TyAlignForABI, CharUnits::fromQuantity(16));
787992cb984SSergei Barannikov   } else {
788992cb984SSergei Barannikov     TyAlignForABI = CharUnits::fromQuantity(4);
789992cb984SSergei Barannikov   }
790992cb984SSergei Barannikov 
791992cb984SSergei Barannikov   TypeInfoChars TyInfo(TySize, TyAlignForABI, AlignRequirementKind::None);
7926d973b45SMariya Podchishchaeva   return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, TyInfo, SlotSize,
7936d973b45SMariya Podchishchaeva                           /*AllowHigherAlign*/ true, Slot);
794992cb984SSergei Barannikov }
795992cb984SSergei Barannikov 
796992cb984SSergei Barannikov std::unique_ptr<TargetCodeGenInfo>
797992cb984SSergei Barannikov CodeGen::createARMTargetCodeGenInfo(CodeGenModule &CGM, ARMABIKind Kind) {
798992cb984SSergei Barannikov   return std::make_unique<ARMTargetCodeGenInfo>(CGM.getTypes(), Kind);
799992cb984SSergei Barannikov }
800992cb984SSergei Barannikov 
801992cb984SSergei Barannikov std::unique_ptr<TargetCodeGenInfo>
802992cb984SSergei Barannikov CodeGen::createWindowsARMTargetCodeGenInfo(CodeGenModule &CGM, ARMABIKind K) {
803992cb984SSergei Barannikov   return std::make_unique<WindowsARMTargetCodeGenInfo>(CGM.getTypes(), K);
804992cb984SSergei Barannikov }
805