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-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "ABIInfoImpl.h" |
10 | #include "TargetInfo.h" |
11 | |
12 | using namespace clang; |
13 | using namespace clang::CodeGen; |
14 | |
15 | //===----------------------------------------------------------------------===// |
16 | // ARM ABI Implementation |
17 | //===----------------------------------------------------------------------===// |
18 | |
19 | namespace { |
20 | |
21 | class ARMABIInfo : public ABIInfo { |
22 | ARMABIKind Kind; |
23 | bool IsFloatABISoftFP; |
24 | |
25 | public: |
26 | ARMABIInfo(CodeGenTypes &CGT, ARMABIKind Kind) : ABIInfo(CGT), Kind(Kind) { |
27 | setCCs(); |
28 | IsFloatABISoftFP = CGT.getCodeGenOpts().FloatABI == "softfp" || |
29 | CGT.getCodeGenOpts().FloatABI == "" ; // default |
30 | } |
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 | |
67 | private: |
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 | |
96 | class ARMSwiftABIInfo : public SwiftABIInfo { |
97 | public: |
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 | |
105 | class ARMTargetCodeGenInfo : public TargetCodeGenInfo { |
106 | public: |
107 | ARMTargetCodeGenInfo(CodeGenTypes &CGT, ARMABIKind K) |
108 | : TargetCodeGenInfo(std::make_unique<ARMABIInfo>(args&: CGT, args&: K)) { |
109 | SwiftInfo = std::make_unique<ARMSwiftABIInfo>(args&: 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(Ty: CGF.Int8Ty, V: 4); |
123 | |
124 | // 0-15 are the 16 integer registers. |
125 | AssignToArrayRange(Builder&: CGF.Builder, Array: Address, Value: Four8, FirstIndex: 0, LastIndex: 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>(Val: GV); |
138 | if (!Fn) |
139 | return; |
140 | const auto *FD = dyn_cast_or_null<FunctionDecl>(Val: D); |
141 | |
142 | if (FD && FD->hasAttr<TargetAttr>()) { |
143 | const auto *TA = FD->getAttr<TargetAttr>(); |
144 | ParsedTargetAttr Attr = |
145 | CGM.getTarget().parseTargetAttr(Str: 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 | Spec: Attr.BranchProtection, Arch, BPI, LO: CGM.getLangOpts(), Err&: DiagMsg)) { |
153 | CGM.getDiags().Report( |
154 | Loc: D->getLocation(), |
155 | DiagID: diag::warn_target_unsupported_branch_protection_attribute) |
156 | << Arch; |
157 | } else |
158 | setBranchProtectionFnAttributes(BPI, F&: (*Fn)); |
159 | } else if (CGM.getLangOpts().BranchTargetEnforcement || |
160 | CGM.getLangOpts().hasSignReturnAddress()) { |
161 | // If the Branch Protection attribute is missing, validate the target |
162 | // Architecture attribute against Branch Protection command line |
163 | // settings. |
164 | if (!CGM.getTarget().isBranchProtectionSupportedArch(Arch: Attr.CPU)) |
165 | CGM.getDiags().Report( |
166 | Loc: D->getLocation(), |
167 | DiagID: diag::warn_target_unsupported_branch_protection_attribute) |
168 | << Attr.CPU; |
169 | } |
170 | } else if (CGM.getTarget().isBranchProtectionSupportedArch( |
171 | Arch: CGM.getTarget().getTargetOpts().CPU)) { |
172 | TargetInfo::BranchProtectionInfo BPI(CGM.getLangOpts()); |
173 | setBranchProtectionFnAttributes(BPI, F&: (*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(Kind: "interrupt" , Val: Kind); |
191 | |
192 | // Note: the ARMSaveFPAttr can only exist if we also have an interrupt |
193 | // attribute |
194 | const ARMSaveFPAttr *SaveFPAttr = FD->getAttr<ARMSaveFPAttr>(); |
195 | if (SaveFPAttr) |
196 | Fn->addFnAttr(Kind: "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. Instruct |
204 | // the backend to perform a realignment as part of the function prologue. |
205 | llvm::AttrBuilder B(Fn->getContext()); |
206 | B.addStackAlignmentAttr(Align: 8); |
207 | Fn->addFnAttrs(Attrs: B); |
208 | } |
209 | }; |
210 | |
211 | class WindowsARMTargetCodeGenInfo : public ARMTargetCodeGenInfo { |
212 | public: |
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 | |
230 | void 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 | |
239 | void ARMABIInfo::computeInfo(CGFunctionInfo &FI) const { |
240 | if (!::classifyReturnType(CXXABI: getCXXABI(), FI, Info: *this)) |
241 | FI.getReturnInfo() = classifyReturnType(RetTy: FI.getReturnType(), isVariadic: FI.isVariadic(), |
242 | functionCallConv: FI.getCallingConvention()); |
243 | |
244 | for (auto &I : FI.arguments()) |
245 | I.info = classifyArgumentType(RetTy: I.type, isVariadic: FI.isVariadic(), |
246 | functionCallConv: 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. |
259 | llvm::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 | else |
266 | return llvm::CallingConv::ARM_APCS; |
267 | } |
268 | |
269 | /// Return the calling convention that our ABI would like us to use |
270 | /// as the C calling convention. |
271 | llvm::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 | |
285 | void ARMABIInfo::setCCs() { |
286 | assert(getRuntimeCC() == llvm::CallingConv::C); |
287 | |
288 | // Don't muddy up the IR with a ton of explicit annotations if |
289 | // 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 | |
295 | ABIArgInfo ARMABIInfo::coerceIllegalVector(QualType Ty) const { |
296 | uint64_t Size = getContext().getTypeSize(T: Ty); |
297 | if (Size <= 32) { |
298 | llvm::Type *ResType = |
299 | llvm::Type::getInt32Ty(C&: getVMContext()); |
300 | return ABIArgInfo::getDirect(T: ResType); |
301 | } |
302 | if (Size == 64 || Size == 128) { |
303 | auto *ResType = llvm::FixedVectorType::get( |
304 | ElementType: llvm::Type::getInt32Ty(C&: getVMContext()), NumElts: Size / 32); |
305 | return ABIArgInfo::getDirect(T: ResType); |
306 | } |
307 | return getNaturalAlignIndirect( |
308 | Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(), |
309 | /*ByVal=*/false); |
310 | } |
311 | |
312 | ABIArgInfo 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 vectors |
319 | if (!getTarget().hasLegalHalfType() && containsAnyFP16Vectors(Ty)) { |
320 | uint64_t Size = getContext().getTypeSize(T: VT); |
321 | auto *NewVecTy = llvm::FixedVectorType::get( |
322 | ElementType: llvm::Type::getInt32Ty(C&: getVMContext()), NumElts: Size / 32); |
323 | llvm::Type *Ty = llvm::ArrayType::get(ElementType: NewVecTy, NumElements: Members); |
324 | return ABIArgInfo::getDirect(T: Ty, Offset: 0, Padding: nullptr, CanBeFlattened: 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 it |
331 | // default otherwise. |
332 | Align = getContext().getTypeUnadjustedAlignInChars(T: Ty).getQuantity(); |
333 | unsigned BaseAlign = getContext().getTypeAlignInChars(T: Base).getQuantity(); |
334 | Align = (Align > BaseAlign && Align >= 8) ? 8 : 0; |
335 | } |
336 | return ABIArgInfo::getDirect(T: nullptr, Offset: 0, Padding: nullptr, CanBeFlattened: false, Align); |
337 | } |
338 | |
339 | bool ARMABIInfo::shouldIgnoreEmptyArg(QualType Ty) const { |
340 | uint64_t Size = getContext().getTypeSize(T: 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 a |
350 | // situation which is defined by any C++ standard or ABI, but this matches |
351 | // 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 | |
364 | ABIArgInfo 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 promoted |
368 | // half-precision types); A double-precision floating-point type; |
369 | // A 64-bit or 128-bit containerized vector type; Homogeneous Aggregate |
370 | // with a Base Type of a single- or double-precision floating-point type, |
371 | // 64-bit containerized vectors or 128-bit containerized vectors with one |
372 | // to four Elements. |
373 | // Variadic functions should always marshal to the base standard. |
374 | bool IsAAPCS_VFP = |
375 | !isVariadic && isEffectivelyAAPCS_VFP(callConvention: functionCallConv, /* AAPCS16 */ acceptHalf: 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(T: Ty)) { |
384 | // Treat an enum type as its underlying type. |
385 | if (const EnumType *EnumTy = Ty->getAs<EnumType>()) { |
386 | Ty = EnumTy->getDecl()->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, T: CGT.ConvertType(T: Ty)) |
397 | : ABIArgInfo::getDirect()); |
398 | } |
399 | |
400 | if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(T: Ty, CXXABI&: getCXXABI())) { |
401 | return getNaturalAlignIndirect(Ty, AddrSpace: getDataLayout().getAllocaAddrSpace(), |
402 | ByVal: RAA == CGCXXABI::RAA_DirectInMemory); |
403 | } |
404 | |
405 | // Empty records are either ignored completely or passed as if they were a |
406 | // 1-byte object, depending on the ABI and language standard. |
407 | if (isEmptyRecord(Context&: getContext(), T: Ty, AllowArrays: true) || |
408 | getContext().getTypeSize(T: Ty) == 0) { |
409 | if (shouldIgnoreEmptyArg(Ty)) |
410 | return ABIArgInfo::getIgnore(); |
411 | else |
412 | return ABIArgInfo::getDirect(T: llvm::Type::getInt8Ty(C&: getVMContext())); |
413 | } |
414 | |
415 | if (IsAAPCS_VFP) { |
416 | // Homogeneous Aggregates need to be expanded when we can fit the aggregate |
417 | // 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 use |
424 | // this convention even for a variadic function: the backend will use GPRs |
425 | // 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(ElementType: CGT.ConvertType(T: QualType(Base, 0)), NumElements: Members); |
432 | return ABIArgInfo::getDirect(T: Ty, Offset: 0, Padding: nullptr, CanBeFlattened: false); |
433 | } |
434 | } |
435 | |
436 | if (getABIKind() == ARMABIKind::AAPCS16_VFP && |
437 | getContext().getTypeSizeInChars(T: Ty) > CharUnits::fromQuantity(Quantity: 16)) { |
438 | // WatchOS is adopting the 64-bit AAPCS rule on composite types: if they're |
439 | // bigger than 128-bits, they get placed in space allocated by the caller, |
440 | // and a pointer is passed. |
441 | return ABIArgInfo::getIndirect( |
442 | Alignment: CharUnits::fromQuantity(Quantity: getContext().getTypeAlign(T: Ty) / 8), |
443 | AddrSpace: getDataLayout().getAllocaAddrSpace(), ByVal: 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 at |
448 | // most 8-byte. We realign the indirect argument if type alignment is bigger |
449 | // 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(T: Ty).getQuantity(); |
455 | ABIAlign = std::clamp(val: TyAlign, lo: (uint64_t)4, hi: (uint64_t)8); |
456 | } else { |
457 | TyAlign = getContext().getTypeAlignInChars(T: Ty).getQuantity(); |
458 | } |
459 | if (getContext().getTypeSizeInChars(T: Ty) > CharUnits::fromQuantity(Quantity: 64)) { |
460 | assert(getABIKind() != ARMABIKind::AAPCS16_VFP && "unexpected byval" ); |
461 | return ABIArgInfo::getIndirect( |
462 | Alignment: CharUnits::fromQuantity(Quantity: 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 where |
471 | // we can. |
472 | if (TyAlign <= 4) { |
473 | ElemTy = llvm::Type::getInt32Ty(C&: getVMContext()); |
474 | SizeRegs = (getContext().getTypeSize(T: Ty) + 31) / 32; |
475 | } else { |
476 | ElemTy = llvm::Type::getInt64Ty(C&: getVMContext()); |
477 | SizeRegs = (getContext().getTypeSize(T: Ty) + 63) / 64; |
478 | } |
479 | |
480 | return ABIArgInfo::getDirect(T: llvm::ArrayType::get(ElementType: ElemTy, NumElements: SizeRegs)); |
481 | } |
482 | |
483 | static bool isIntegerLikeType(QualType Ty, ASTContext &Context, |
484 | llvm::LLVMContext &VMContext) { |
485 | // APCS, C Language Calling Conventions, Non-Simple Return Values: A structure |
486 | // is called integer-like if its size is less than or equal to one word, and |
487 | // the offset of each of its addressable sub-fields is zero. |
488 | |
489 | uint64_t Size = Context.getTypeSize(T: 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(Ty: CT->getElementType(), Context, VMContext); |
510 | |
511 | // Single element and zero sized arrays should be allowed, by the definition |
512 | // above, but they are not. |
513 | |
514 | // Otherwise, it must be a record type. |
515 | const RecordType *RT = Ty->getAs<RecordType>(); |
516 | if (!RT) return false; |
517 | |
518 | // Ignore records with flexible arrays. |
519 | const RecordDecl *RD = RT->getDecl(); |
520 | if (RD->hasFlexibleArrayMember()) |
521 | return false; |
522 | |
523 | // Check that all sub-fields are at offset 0, and are themselves "integer |
524 | // like". |
525 | const ASTRecordLayout &Layout = Context.getASTRecordLayout(D: 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 "integer |
534 | // 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(Ty: 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(FieldNo: idx) != 0) |
549 | return false; |
550 | |
551 | if (!isIntegerLikeType(Ty: FD->getType(), Context, VMContext)) |
552 | return false; |
553 | |
554 | // Only allow at most one field in a structure. This doesn't match the |
555 | // wording above, but follows gcc in situations with a field following an |
556 | // empty structure. |
557 | if (!RD->isUnion()) { |
558 | if (HadField) |
559 | return false; |
560 | |
561 | HadField = true; |
562 | } |
563 | } |
564 | |
565 | return true; |
566 | } |
567 | |
568 | ABIArgInfo 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(callConvention: functionCallConv, /* AAPCS16 */ acceptHalf: 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(T: RetTy) > 128) |
581 | return getNaturalAlignIndirect(Ty: RetTy, |
582 | AddrSpace: getDataLayout().getAllocaAddrSpace()); |
583 | // TODO: FP16/BF16 vectors should be converted to integer vectors |
584 | // This check is similar to isIllegalVectorType - refactor? |
585 | if ((!getTarget().hasLegalHalfType() && |
586 | (VT->getElementType()->isFloat16Type() || |
587 | VT->getElementType()->isHalfType())) || |
588 | (IsFloatABISoftFP && |
589 | VT->getElementType()->isBFloat16Type())) |
590 | return coerceIllegalVector(Ty: RetTy); |
591 | } |
592 | |
593 | if (!isAggregateTypeForABI(T: RetTy)) { |
594 | // Treat an enum type as its underlying type. |
595 | if (const EnumType *EnumTy = RetTy->getAs<EnumType>()) |
596 | RetTy = EnumTy->getDecl()->getIntegerType(); |
597 | |
598 | if (const auto *EIT = RetTy->getAs<BitIntType>()) |
599 | if (EIT->getNumBits() > 64) |
600 | return getNaturalAlignIndirect( |
601 | Ty: RetTy, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(), |
602 | /*ByVal=*/false); |
603 | |
604 | return isPromotableIntegerTypeForABI(Ty: RetTy) ? ABIArgInfo::getExtend(Ty: RetTy) |
605 | : ABIArgInfo::getDirect(); |
606 | } |
607 | |
608 | // Are we following APCS? |
609 | if (getABIKind() == ARMABIKind::APCS) { |
610 | if (isEmptyRecord(Context&: getContext(), T: RetTy, AllowArrays: 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 them |
616 | // correctly. |
617 | if (RetTy->isAnyComplexType()) |
618 | return ABIArgInfo::getDirect(T: llvm::IntegerType::get( |
619 | C&: getVMContext(), NumBits: getContext().getTypeSize(T: RetTy))); |
620 | |
621 | // Integer like structures are returned in r0. |
622 | if (isIntegerLikeType(Ty: RetTy, Context&: getContext(), VMContext&: getVMContext())) { |
623 | // Return in the smallest viable integer type. |
624 | uint64_t Size = getContext().getTypeSize(T: RetTy); |
625 | if (Size <= 8) |
626 | return ABIArgInfo::getDirect(T: llvm::Type::getInt8Ty(C&: getVMContext())); |
627 | if (Size <= 16) |
628 | return ABIArgInfo::getDirect(T: llvm::Type::getInt16Ty(C&: getVMContext())); |
629 | return ABIArgInfo::getDirect(T: llvm::Type::getInt32Ty(C&: getVMContext())); |
630 | } |
631 | |
632 | // Otherwise return in memory. |
633 | return getNaturalAlignIndirect(Ty: RetTy, AddrSpace: getDataLayout().getAllocaAddrSpace()); |
634 | } |
635 | |
636 | // Otherwise this is an AAPCS variant. |
637 | |
638 | if (isEmptyRecord(Context&: getContext(), T: RetTy, AllowArrays: true) || |
639 | getContext().getTypeSize(T: 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(Ty: RetTy, Base, Members)) |
647 | return classifyHomogeneousAggregate(Ty: RetTy, Base, Members); |
648 | } |
649 | |
650 | // Aggregates <= 4 bytes are returned in r0; other aggregates |
651 | // are returned indirectly. |
652 | uint64_t Size = getContext().getTypeSize(T: 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(T: llvm::Type::getInt32Ty(C&: getVMContext())); |
657 | |
658 | // Return in the smallest viable integer type. |
659 | if (Size <= 8) |
660 | return ABIArgInfo::getDirect(T: llvm::Type::getInt8Ty(C&: getVMContext())); |
661 | if (Size <= 16) |
662 | return ABIArgInfo::getDirect(T: llvm::Type::getInt16Ty(C&: getVMContext())); |
663 | return ABIArgInfo::getDirect(T: llvm::Type::getInt32Ty(C&: getVMContext())); |
664 | } else if (Size <= 128 && getABIKind() == ARMABIKind::AAPCS16_VFP) { |
665 | llvm::Type *Int32Ty = llvm::Type::getInt32Ty(C&: getVMContext()); |
666 | llvm::Type *CoerceTy = |
667 | llvm::ArrayType::get(ElementType: Int32Ty, NumElements: llvm::alignTo(Value: Size, Align: 32) / 32); |
668 | return ABIArgInfo::getDirect(T: CoerceTy); |
669 | } |
670 | |
671 | return getNaturalAlignIndirect(Ty: RetTy, AddrSpace: getDataLayout().getAllocaAddrSpace()); |
672 | } |
673 | |
674 | /// isIllegalVector - check whether Ty is an illegal vector type. |
675 | bool 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 expanded |
678 | // into float, and we don't want the ABI to depend on whether or not they |
679 | // are supported in hardware. Thus return false to coerce vectors of these |
680 | // types into integer vectors. |
681 | // We do not depend on hasLegalHalfType for bfloat as it is a |
682 | // separate IR type. |
683 | if ((!getTarget().hasLegalHalfType() && |
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 different |
691 | // vector ABI. The primary differences were that 3-element vector types |
692 | // were legal, and so were sub 32-bit vectors (i.e. <2 x i8>). This path |
693 | // 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(Value: 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(T: VT); |
703 | // NumElements should be power of 2. |
704 | if (!llvm::isPowerOf2_32(Value: 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 vectors |
714 | bool ARMABIInfo::containsAnyFP16Vectors(QualType Ty) const { |
715 | if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(T: Ty)) { |
716 | uint64_t NElements = AT->getZExtSize(); |
717 | if (NElements == 0) |
718 | return false; |
719 | return containsAnyFP16Vectors(Ty: AT->getElementType()); |
720 | } else if (const RecordType *RT = Ty->getAs<RecordType>()) { |
721 | const RecordDecl *RD = RT->getDecl(); |
722 | |
723 | // If this is a C++ record, check the bases first. |
724 | if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(Val: RD)) |
725 | if (llvm::any_of(Range: CXXRD->bases(), P: [this](const CXXBaseSpecifier &B) { |
726 | return containsAnyFP16Vectors(Ty: B.getType()); |
727 | })) |
728 | return true; |
729 | |
730 | if (llvm::any_of(Range: RD->fields(), P: [this](FieldDecl *FD) { |
731 | return FD && containsAnyFP16Vectors(Ty: FD->getType()); |
732 | })) |
733 | return true; |
734 | |
735 | return false; |
736 | } else { |
737 | if (const VectorType *VT = Ty->getAs<VectorType>()) |
738 | return (VT->getElementType()->isFloat16Type() || |
739 | VT->getElementType()->isBFloat16Type() || |
740 | VT->getElementType()->isHalfType()); |
741 | return false; |
742 | } |
743 | } |
744 | |
745 | bool ARMSwiftABIInfo::isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy, |
746 | unsigned NumElts) const { |
747 | if (!llvm::isPowerOf2_32(Value: NumElts)) |
748 | return false; |
749 | unsigned size = CGT.getDataLayout().getTypeStoreSizeInBits(Ty: EltTy); |
750 | if (size > 64) |
751 | return false; |
752 | if (VectorSize.getQuantity() != 8 && |
753 | (VectorSize.getQuantity() != 16 || NumElts == 1)) |
754 | return false; |
755 | return true; |
756 | } |
757 | |
758 | bool ARMABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const { |
759 | // Homogeneous aggregates for AAPCS-VFP must have base types of float, |
760 | // double, or 64-bit or 128-bit vectors. |
761 | if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) { |
762 | if (BT->getKind() == BuiltinType::Float || |
763 | BT->getKind() == BuiltinType::Double || |
764 | BT->getKind() == BuiltinType::LongDouble) |
765 | return true; |
766 | } else if (const VectorType *VT = Ty->getAs<VectorType>()) { |
767 | unsigned VecSize = getContext().getTypeSize(T: VT); |
768 | if (VecSize == 64 || VecSize == 128) |
769 | return true; |
770 | } |
771 | return false; |
772 | } |
773 | |
774 | bool ARMABIInfo::isHomogeneousAggregateSmallEnough(const Type *Base, |
775 | uint64_t Members) const { |
776 | return Members <= 4; |
777 | } |
778 | |
779 | bool ARMABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate() const { |
780 | // AAPCS32 says that the rule for whether something is a homogeneous |
781 | // aggregate is applied to the output of the data layout decision. So |
782 | // anything that doesn't affect the data layout also does not affect |
783 | // homogeneity. In particular, zero-length bitfields don't stop a struct |
784 | // being homogeneous. |
785 | return true; |
786 | } |
787 | |
788 | bool ARMABIInfo::isEffectivelyAAPCS_VFP(unsigned callConvention, |
789 | bool acceptHalf) const { |
790 | // Give precedence to user-specified calling conventions. |
791 | if (callConvention != llvm::CallingConv::C) |
792 | return (callConvention == llvm::CallingConv::ARM_AAPCS_VFP); |
793 | else |
794 | return (getABIKind() == ARMABIKind::AAPCS_VFP) || |
795 | (acceptHalf && (getABIKind() == ARMABIKind::AAPCS16_VFP)); |
796 | } |
797 | |
798 | RValue ARMABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, |
799 | QualType Ty, AggValueSlot Slot) const { |
800 | CharUnits SlotSize = CharUnits::fromQuantity(Quantity: 4); |
801 | |
802 | // Empty records are ignored for parameter passing purposes. |
803 | uint64_t Size = getContext().getTypeSize(T: Ty); |
804 | bool IsEmpty = isEmptyRecord(Context&: getContext(), T: Ty, AllowArrays: true); |
805 | if ((IsEmpty || Size == 0) && shouldIgnoreEmptyArg(Ty)) |
806 | return Slot.asRValue(); |
807 | |
808 | CharUnits TySize = getContext().getTypeSizeInChars(T: Ty); |
809 | CharUnits TyAlignForABI = getContext().getTypeUnadjustedAlignInChars(T: Ty); |
810 | |
811 | // Use indirect if size of the illegal vector is bigger than 16 bytes. |
812 | bool IsIndirect = false; |
813 | const Type *Base = nullptr; |
814 | uint64_t Members = 0; |
815 | if (TySize > CharUnits::fromQuantity(Quantity: 16) && isIllegalVectorType(Ty)) { |
816 | IsIndirect = true; |
817 | |
818 | // ARMv7k passes structs bigger than 16 bytes indirectly, in space |
819 | // allocated by the caller. |
820 | } else if (TySize > CharUnits::fromQuantity(Quantity: 16) && |
821 | getABIKind() == ARMABIKind::AAPCS16_VFP && |
822 | !isHomogeneousAggregate(Ty, Base, Members)) { |
823 | IsIndirect = true; |
824 | |
825 | // Otherwise, bound the type's ABI alignment. |
826 | // The ABI alignment for 64-bit or 128-bit vectors is 8 for AAPCS and 4 for |
827 | // APCS. For AAPCS, the ABI alignment is at least 4-byte and at most 8-byte. |
828 | // Our callers should be prepared to handle an under-aligned address. |
829 | } else if (getABIKind() == ARMABIKind::AAPCS_VFP || |
830 | getABIKind() == ARMABIKind::AAPCS) { |
831 | TyAlignForABI = std::max(a: TyAlignForABI, b: CharUnits::fromQuantity(Quantity: 4)); |
832 | TyAlignForABI = std::min(a: TyAlignForABI, b: CharUnits::fromQuantity(Quantity: 8)); |
833 | } else if (getABIKind() == ARMABIKind::AAPCS16_VFP) { |
834 | // ARMv7k allows type alignment up to 16 bytes. |
835 | TyAlignForABI = std::max(a: TyAlignForABI, b: CharUnits::fromQuantity(Quantity: 4)); |
836 | TyAlignForABI = std::min(a: TyAlignForABI, b: CharUnits::fromQuantity(Quantity: 16)); |
837 | } else { |
838 | TyAlignForABI = CharUnits::fromQuantity(Quantity: 4); |
839 | } |
840 | |
841 | TypeInfoChars TyInfo(TySize, TyAlignForABI, AlignRequirementKind::None); |
842 | return emitVoidPtrVAArg(CGF, VAListAddr, ValueTy: Ty, IsIndirect, ValueInfo: TyInfo, SlotSizeAndAlign: SlotSize, |
843 | /*AllowHigherAlign*/ true, Slot); |
844 | } |
845 | |
846 | std::unique_ptr<TargetCodeGenInfo> |
847 | CodeGen::createARMTargetCodeGenInfo(CodeGenModule &CGM, ARMABIKind Kind) { |
848 | return std::make_unique<ARMTargetCodeGenInfo>(args&: CGM.getTypes(), args&: Kind); |
849 | } |
850 | |
851 | std::unique_ptr<TargetCodeGenInfo> |
852 | CodeGen::createWindowsARMTargetCodeGenInfo(CodeGenModule &CGM, ARMABIKind K) { |
853 | return std::make_unique<WindowsARMTargetCodeGenInfo>(args&: CGM.getTypes(), args&: K); |
854 | } |
855 | |