clang 23.0.0git
ARM.cpp
Go to the documentation of this file.
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
12using namespace clang;
13using namespace clang::CodeGen;
14
15//===----------------------------------------------------------------------===//
16// ARM ABI Implementation
17//===----------------------------------------------------------------------===//
18
19namespace {
20
21class ARMABIInfo : public ABIInfo {
22 ARMABIKind Kind;
23 bool IsFloatABISoftFP;
24
25public:
26 ARMABIInfo(CodeGenTypes &CGT, ARMABIKind Kind) : ABIInfo(CGT), Kind(Kind) {
27 setCCs();
28 IsFloatABISoftFP = CGT.getCodeGenOpts().FloatABI == "softfp" ||
29 CGT.getCodeGenOpts().FloatABI == ""; // 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
67private:
68 ABIArgInfo classifyReturnType(QualType RetTy, bool isVariadic,
69 unsigned functionCallConv) const;
70 ABIArgInfo classifyArgumentType(QualType RetTy, bool isVariadic,
71 unsigned functionCallConv) const;
72 ABIArgInfo classifyHomogeneousAggregate(QualType Ty, const Type *Base,
73 uint64_t Members) const;
74 bool shouldIgnoreEmptyArg(QualType Ty) const;
75 ABIArgInfo coerceIllegalVector(QualType Ty) const;
76 bool isIllegalVectorType(QualType Ty) const;
77 bool containsAnyFP16Vectors(QualType Ty) const;
78
79 bool isHomogeneousAggregateBaseType(QualType Ty) const override;
80 bool isHomogeneousAggregateSmallEnough(const Type *Ty,
81 uint64_t Members) const override;
82 bool isZeroLengthBitfieldPermittedInHomogeneousAggregate() const override;
83
84 bool isEffectivelyAAPCS_VFP(unsigned callConvention, bool acceptHalf) const;
85
86 void computeInfo(CGFunctionInfo &FI) const override;
87
88 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
89 AggValueSlot Slot) const override;
90
91 llvm::CallingConv::ID getLLVMDefaultCC() const;
92 llvm::CallingConv::ID getABIDefaultCC() const;
93 void setCCs();
94};
95
96class ARMSwiftABIInfo : public SwiftABIInfo {
97public:
98 explicit ARMSwiftABIInfo(CodeGenTypes &CGT)
99 : SwiftABIInfo(CGT, /*SwiftErrorInRegister=*/true) {}
100
101 bool isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,
102 unsigned NumElts) const override;
103};
104
105class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
106public:
107 ARMTargetCodeGenInfo(CodeGenTypes &CGT, ARMABIKind K)
108 : TargetCodeGenInfo(std::make_unique<ARMABIInfo>(CGT, K)) {
109 SwiftInfo = std::make_unique<ARMSwiftABIInfo>(CGT);
110 }
111
112 int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
113 return 13;
114 }
115
116 StringRef getARCRetainAutoreleasedReturnValueMarker() const override {
117 return "mov\tr7, r7\t\t// marker for objc_retainAutoreleaseReturnValue";
118 }
119
120 bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
121 llvm::Value *Address) const override {
122 llvm::Value *Four8 = llvm::ConstantInt::get(CGF.Int8Ty, 4);
123
124 // 0-15 are the 16 integer registers.
125 AssignToArrayRange(CGF.Builder, Address, Four8, 0, 15);
126 return false;
127 }
128
129 unsigned getSizeOfUnwindException() const override {
130 if (getABIInfo<ARMABIInfo>().isEABI())
131 return 88;
133 }
134
135 void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
136 CodeGen::CodeGenModule &CGM) const override {
137 auto *Fn = dyn_cast<llvm::Function>(GV);
138 if (!Fn)
139 return;
140 const auto *FD = dyn_cast_or_null<FunctionDecl>(D);
141
142 if (FD && FD->hasAttr<TargetAttr>()) {
143 const auto *TA = FD->getAttr<TargetAttr>();
144 ParsedTargetAttr Attr =
145 CGM.getTarget().parseTargetAttr(TA->getFeaturesStr());
146 if (!Attr.BranchProtection.empty()) {
147 TargetInfo::BranchProtectionInfo BPI{};
148 StringRef DiagMsg;
149 StringRef Arch =
150 Attr.CPU.empty() ? CGM.getTarget().getTargetOpts().CPU : Attr.CPU;
152 Attr.BranchProtection, Arch, BPI, CGM.getLangOpts(), DiagMsg)) {
153 CGM.getDiags().Report(
154 D->getLocation(),
155 diag::warn_target_unsupported_branch_protection_attribute)
156 << Arch;
157 } else
158 setBranchProtectionFnAttributes(BPI, (*Fn));
159 } else if (CGM.getLangOpts().BranchTargetEnforcement ||
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(Attr.CPU))
165 CGM.getDiags().Report(
166 D->getLocation(),
167 diag::warn_target_unsupported_branch_protection_attribute)
168 << Attr.CPU;
169 }
171 CGM.getTarget().getTargetOpts().CPU)) {
172 TargetInfo::BranchProtectionInfo BPI(CGM.getLangOpts());
173 setBranchProtectionFnAttributes(BPI, (*Fn));
174 }
175
176 if (!FD || !FD->hasAttr<ARMInterruptAttr>())
177 return;
178
179 const ARMInterruptAttr *Attr = FD->getAttr<ARMInterruptAttr>();
180 const char *Kind;
181 switch (Attr->getInterrupt()) {
182 case ARMInterruptAttr::Generic: Kind = ""; break;
183 case ARMInterruptAttr::IRQ: Kind = "IRQ"; break;
184 case ARMInterruptAttr::FIQ: Kind = "FIQ"; break;
185 case ARMInterruptAttr::SWI: Kind = "SWI"; break;
186 case ARMInterruptAttr::ABORT: Kind = "ABORT"; break;
187 case ARMInterruptAttr::UNDEF: Kind = "UNDEF"; break;
188 }
189
190 Fn->addFnAttr("interrupt", Kind);
191
192 // Note: the ARMSaveFPAttr can only exist if we also have an interrupt
193 // attribute
194 const ARMSaveFPAttr *SaveFPAttr = FD->getAttr<ARMSaveFPAttr>();
195 if (SaveFPAttr)
196 Fn->addFnAttr("save-fp");
197
198 ARMABIKind ABI = getABIInfo<ARMABIInfo>().getABIKind();
199 if (ABI == ARMABIKind::APCS)
200 return;
201
202 // AAPCS guarantees that sp will be 8-byte aligned on any public interface,
203 // however this is not necessarily true on taking any interrupt. Instruct
204 // the backend to perform a realignment as part of the function prologue.
205 llvm::AttrBuilder B(Fn->getContext());
206 B.addStackAlignmentAttr(8);
207 Fn->addFnAttrs(B);
208 }
209};
210
211class WindowsARMTargetCodeGenInfo : public ARMTargetCodeGenInfo {
212public:
213 WindowsARMTargetCodeGenInfo(CodeGenTypes &CGT, ARMABIKind K)
214 : ARMTargetCodeGenInfo(CGT, K) {}
215
216 void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
217 CodeGen::CodeGenModule &CGM) const override;
218
219 void getDependentLibraryOption(llvm::StringRef Lib,
220 llvm::SmallString<24> &Opt) const override {
221 Opt = "/DEFAULTLIB:" + qualifyWindowsLibrary(Lib);
222 }
223
224 void getDetectMismatchOption(llvm::StringRef Name, llvm::StringRef Value,
225 llvm::SmallString<32> &Opt) const override {
226 Opt = "/FAILIFMISMATCH:\"" + Name.str() + "=" + Value.str() + "\"";
227 }
228};
229
230void WindowsARMTargetCodeGenInfo::setTargetAttributes(
231 const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const {
232 ARMTargetCodeGenInfo::setTargetAttributes(D, GV, CGM);
233 if (GV->isDeclaration())
234 return;
235 addStackProbeTargetAttributes(D, GV, CGM);
236}
237}
238
239void ARMABIInfo::computeInfo(CGFunctionInfo &FI) const {
240 if (!::classifyReturnType(getCXXABI(), FI, *this))
243
244 for (auto &I : FI.arguments())
245 I.info = classifyArgumentType(I.type, FI.isVariadic(),
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)
256}
257
258/// Return the default calling convention that LLVM will use.
259llvm::CallingConv::ID ARMABIInfo::getLLVMDefaultCC() const {
260 // The default calling convention that LLVM will infer.
261 if (isEABIHF() || getTarget().getTriple().isWatchABI())
262 return llvm::CallingConv::ARM_AAPCS_VFP;
263 else if (isEABI())
264 return llvm::CallingConv::ARM_AAPCS;
265 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.
271llvm::CallingConv::ID ARMABIInfo::getABIDefaultCC() const {
272 switch (getABIKind()) {
273 case ARMABIKind::APCS:
274 return llvm::CallingConv::ARM_APCS;
275 case ARMABIKind::AAPCS:
276 return llvm::CallingConv::ARM_AAPCS;
277 case ARMABIKind::AAPCS_VFP:
278 return llvm::CallingConv::ARM_AAPCS_VFP;
279 case ARMABIKind::AAPCS16_VFP:
280 return llvm::CallingConv::ARM_AAPCS_VFP;
281 }
282 llvm_unreachable("bad ABI kind");
283}
284
285void ARMABIInfo::setCCs() {
286 assert(getRuntimeCC() == llvm::CallingConv::C);
287
288 // Don't muddy up the IR with a ton of explicit annotations 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
295ABIArgInfo ARMABIInfo::coerceIllegalVector(QualType Ty) const {
296 uint64_t Size = getContext().getTypeSize(Ty);
297 if (Size <= 32) {
298 llvm::Type *ResType =
299 llvm::Type::getInt32Ty(getVMContext());
300 return ABIArgInfo::getDirect(ResType);
301 }
302 if (Size == 64 || Size == 128) {
303 auto *ResType = llvm::FixedVectorType::get(
304 llvm::Type::getInt32Ty(getVMContext()), Size / 32);
305 return ABIArgInfo::getDirect(ResType);
306 }
307 return getNaturalAlignIndirect(
308 Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),
309 /*ByVal=*/false);
310}
311
312ABIArgInfo ARMABIInfo::classifyHomogeneousAggregate(QualType Ty,
313 const Type *Base,
314 uint64_t Members) const {
315 assert(Base && "Base class should be set for homogeneous aggregate");
316 // Base can be a floating-point or a vector.
317 if (const VectorType *VT = Base->getAs<VectorType>()) {
318 // FP16 vectors should be converted to integer vectors
319 if (!getTarget().hasFastHalfType() && containsAnyFP16Vectors(Ty)) {
320 uint64_t Size = getContext().getTypeSize(VT);
321 auto *NewVecTy = llvm::FixedVectorType::get(
322 llvm::Type::getInt32Ty(getVMContext()), Size / 32);
323 llvm::Type *Ty = llvm::ArrayType::get(NewVecTy, Members);
324 return ABIArgInfo::getDirect(Ty, 0, nullptr, false);
325 }
326 }
327 unsigned Align = 0;
328 if (getABIKind() == ARMABIKind::AAPCS ||
329 getABIKind() == ARMABIKind::AAPCS_VFP) {
330 // For alignment adjusted HFAs, cap the argument alignment to 8, leave it
331 // default otherwise.
332 Align = getContext().getTypeUnadjustedAlignInChars(Ty).getQuantity();
333 unsigned BaseAlign = getContext().getTypeAlignInChars(Base).getQuantity();
334 Align = (Align > BaseAlign && Align >= 8) ? 8 : 0;
335 }
336 return ABIArgInfo::getDirect(nullptr, 0, nullptr, false, Align);
337}
338
339bool ARMABIInfo::shouldIgnoreEmptyArg(QualType Ty) const {
340 uint64_t Size = getContext().getTypeSize(Ty);
341 assert((isEmptyRecord(getContext(), Ty, true) || Size == 0) &&
342 "Arg is not empty");
343
344 // Empty records are ignored in C mode, and in C++ on WatchOS.
345 if (!getContext().getLangOpts().CPlusPlus ||
346 getABIKind() == ARMABIKind::AAPCS16_VFP)
347 return true;
348
349 // In C++ mode, arguments which have sizeof() == 0 are ignored. This is not 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().isCompatibleWith(LangOptions::ClangABI::Ver19))
357 return true;
358
359 // Otherwise, they are passed as if they have a size of 1 byte.
360 return false;
361}
362
363ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, bool isVariadic,
364 unsigned functionCallConv) const {
365 // 6.1.2.1 The following argument types are VFP CPRCs:
366 // A single-precision floating-point type (including promoted
367 // half-precision types); A double-precision floating-point type;
368 // A 64-bit or 128-bit containerized vector type; Homogeneous Aggregate
369 // with a Base Type of a single- or double-precision floating-point type,
370 // 64-bit containerized vectors or 128-bit containerized vectors with one
371 // to four Elements.
372 // Variadic functions should always marshal to the base standard.
373 bool IsAAPCS_VFP =
374 !isVariadic && isEffectivelyAAPCS_VFP(functionCallConv, /* AAPCS16 */ false);
375
377
378 // Handle illegal vector types here.
379 if (isIllegalVectorType(Ty))
380 return coerceIllegalVector(Ty);
381
382 if (!isAggregateTypeForABI(Ty)) {
383 // Treat an enum type as its underlying type.
384 if (const auto *ED = Ty->getAsEnumDecl()) {
385 Ty = ED->getIntegerType();
386 }
387
388 if (const auto *EIT = Ty->getAs<BitIntType>())
389 if (EIT->getNumBits() > 64)
390 return getNaturalAlignIndirect(
391 Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),
392 /*ByVal=*/true);
393
394 return (isPromotableIntegerTypeForABI(Ty)
397 }
398
399 if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) {
400 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
402 }
403
404 // Empty records are either ignored completely or passed as if they were a
405 // 1-byte object, depending on the ABI and language standard.
406 if (isEmptyRecord(getContext(), Ty, true) ||
407 getContext().getTypeSize(Ty) == 0) {
408 if (shouldIgnoreEmptyArg(Ty))
409 return ABIArgInfo::getIgnore();
410 else
411 return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));
412 }
413
414 if (IsAAPCS_VFP) {
415 // Homogeneous Aggregates need to be expanded when we can fit the aggregate
416 // into VFP registers.
417 const Type *Base = nullptr;
418 uint64_t Members = 0;
419 if (isHomogeneousAggregate(Ty, Base, Members))
420 return classifyHomogeneousAggregate(Ty, Base, Members);
421 } else if (getABIKind() == ARMABIKind::AAPCS16_VFP) {
422 // WatchOS does have homogeneous aggregates. Note that we intentionally use
423 // this convention even for a variadic function: the backend will use GPRs
424 // if needed.
425 const Type *Base = nullptr;
426 uint64_t Members = 0;
427 if (isHomogeneousAggregate(Ty, Base, Members)) {
428 assert(Base && Members <= 4 && "unexpected homogeneous aggregate");
429 llvm::Type *Ty =
430 llvm::ArrayType::get(CGT.ConvertType(QualType(Base, 0)), Members);
431 return ABIArgInfo::getDirect(Ty, 0, nullptr, false);
432 }
433 }
434
435 if (getABIKind() == ARMABIKind::AAPCS16_VFP &&
436 getContext().getTypeSizeInChars(Ty) > CharUnits::fromQuantity(16)) {
437 // WatchOS is adopting the 64-bit AAPCS rule on composite types: if they're
438 // bigger than 128-bits, they get placed in space allocated by the caller,
439 // and a pointer is passed.
441 CharUnits::fromQuantity(getContext().getTypeAlign(Ty) / 8),
442 getDataLayout().getAllocaAddrSpace(), false);
443 }
444
445 // Support byval for ARM.
446 // The ABI alignment for APCS is 4-byte and for AAPCS at least 4-byte and at
447 // most 8-byte. We realign the indirect argument if type alignment is bigger
448 // than ABI alignment.
449 uint64_t ABIAlign = 4;
450 uint64_t TyAlign;
451 if (getABIKind() == ARMABIKind::AAPCS_VFP ||
452 getABIKind() == ARMABIKind::AAPCS) {
453 TyAlign = getContext().getTypeUnadjustedAlignInChars(Ty).getQuantity();
454 ABIAlign = std::clamp(TyAlign, (uint64_t)4, (uint64_t)8);
455 } else {
456 TyAlign = getContext().getTypeAlignInChars(Ty).getQuantity();
457 }
458 if (getContext().getTypeSizeInChars(Ty) > CharUnits::fromQuantity(64)) {
459 assert(getABIKind() != ARMABIKind::AAPCS16_VFP && "unexpected byval");
461 CharUnits::fromQuantity(ABIAlign),
462 /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),
463 /*ByVal=*/true, /*Realign=*/TyAlign > ABIAlign);
464 }
465
466 // Otherwise, pass by coercing to a structure of the appropriate size.
467 llvm::Type* ElemTy;
468 unsigned SizeRegs;
469 // FIXME: Try to match the types of the arguments more accurately where
470 // we can.
471 if (TyAlign <= 4) {
472 ElemTy = llvm::Type::getInt32Ty(getVMContext());
473 SizeRegs = (getContext().getTypeSize(Ty) + 31) / 32;
474 } else {
475 ElemTy = llvm::Type::getInt64Ty(getVMContext());
476 SizeRegs = (getContext().getTypeSize(Ty) + 63) / 64;
477 }
478
479 return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, SizeRegs));
480}
481
482static bool isIntegerLikeType(QualType Ty, ASTContext &Context,
483 llvm::LLVMContext &VMContext) {
484 // APCS, C Language Calling Conventions, Non-Simple Return Values: A structure
485 // is called integer-like if its size is less than or equal to one word, and
486 // the offset of each of its addressable sub-fields is zero.
487
488 uint64_t Size = Context.getTypeSize(Ty);
489
490 // Check that the type fits in a word.
491 if (Size > 32)
492 return false;
493
494 // FIXME: Handle vector types!
495 if (Ty->isVectorType())
496 return false;
497
498 // Float types are never treated as "integer like".
499 if (Ty->isRealFloatingType())
500 return false;
501
502 // If this is a builtin or pointer type then it is ok.
503 if (Ty->getAs<BuiltinType>() || Ty->isPointerType())
504 return true;
505
506 // Small complex integer types are "integer like".
507 if (const ComplexType *CT = Ty->getAs<ComplexType>())
508 return isIntegerLikeType(CT->getElementType(), Context, VMContext);
509
510 // Single element and zero sized arrays should be allowed, by the definition
511 // above, but they are not.
512
513 // Otherwise, it must be a record type.
514 const RecordType *RT = Ty->getAsCanonical<RecordType>();
515 if (!RT) return false;
516
517 // Ignore records with flexible arrays.
518 const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
519 if (RD->hasFlexibleArrayMember())
520 return false;
521
522 // Check that all sub-fields are at offset 0, and are themselves "integer
523 // like".
524 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
525
526 bool HadField = false;
527 unsigned idx = 0;
528 for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
529 i != e; ++i, ++idx) {
530 const FieldDecl *FD = *i;
531
532 // Bit-fields are not addressable, we only need to verify they are "integer
533 // like". We still have to disallow a subsequent non-bitfield, for example:
534 // struct { int : 0; int x }
535 // is non-integer like according to gcc.
536 if (FD->isBitField()) {
537 if (!RD->isUnion())
538 HadField = true;
539
540 if (!isIntegerLikeType(FD->getType(), Context, VMContext))
541 return false;
542
543 continue;
544 }
545
546 // Check if this field is at offset 0.
547 if (Layout.getFieldOffset(idx) != 0)
548 return false;
549
550 if (!isIntegerLikeType(FD->getType(), Context, VMContext))
551 return false;
552
553 // Only allow at most one field in a structure. This doesn't match the
554 // wording above, but follows gcc in situations with a field following an
555 // empty structure.
556 if (!RD->isUnion()) {
557 if (HadField)
558 return false;
559
560 HadField = true;
561 }
562 }
563
564 return true;
565}
566
567ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy, bool isVariadic,
568 unsigned functionCallConv) const {
569
570 // Variadic functions should always marshal to the base standard.
571 bool IsAAPCS_VFP =
572 !isVariadic && isEffectivelyAAPCS_VFP(functionCallConv, /* AAPCS16 */ true);
573
574 if (RetTy->isVoidType())
575 return ABIArgInfo::getIgnore();
576
577 if (const VectorType *VT = RetTy->getAs<VectorType>()) {
578 // Large vector types should be returned via memory.
579 if (getContext().getTypeSize(RetTy) > 128)
580 return getNaturalAlignIndirect(RetTy,
581 getDataLayout().getAllocaAddrSpace());
582 // TODO: FP16/BF16 vectors should be converted to integer vectors
583 // This check is similar to isIllegalVectorType - refactor?
584 if ((!getTarget().hasFastHalfType() &&
585 (VT->getElementType()->isFloat16Type() ||
586 VT->getElementType()->isHalfType())) ||
587 (IsFloatABISoftFP &&
588 VT->getElementType()->isBFloat16Type()))
589 return coerceIllegalVector(RetTy);
590 }
591
592 if (!isAggregateTypeForABI(RetTy)) {
593 // Treat an enum type as its underlying type.
594 if (const auto *ED = RetTy->getAsEnumDecl())
595 RetTy = ED->getIntegerType();
596
597 if (const auto *EIT = RetTy->getAs<BitIntType>())
598 if (EIT->getNumBits() > 64)
599 return getNaturalAlignIndirect(
600 RetTy, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),
601 /*ByVal=*/false);
602
603 return isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
604 : ABIArgInfo::getDirect();
605 }
606
607 // Are we following APCS?
608 if (getABIKind() == ARMABIKind::APCS) {
609 if (isEmptyRecord(getContext(), RetTy, false))
610 return ABIArgInfo::getIgnore();
611
612 // Complex types are all returned as packed integers.
613 //
614 // FIXME: Consider using 2 x vector types if the back end handles them
615 // correctly.
616 if (RetTy->isAnyComplexType())
617 return ABIArgInfo::getDirect(llvm::IntegerType::get(
618 getVMContext(), getContext().getTypeSize(RetTy)));
619
620 // Integer like structures are returned in r0.
621 if (isIntegerLikeType(RetTy, getContext(), getVMContext())) {
622 // Return in the smallest viable integer type.
623 uint64_t Size = getContext().getTypeSize(RetTy);
624 if (Size <= 8)
625 return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));
626 if (Size <= 16)
627 return ABIArgInfo::getDirect(llvm::Type::getInt16Ty(getVMContext()));
628 return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext()));
629 }
630
631 // Otherwise return in memory.
632 return getNaturalAlignIndirect(RetTy, getDataLayout().getAllocaAddrSpace());
633 }
634
635 // Otherwise this is an AAPCS variant.
636
637 if (isEmptyRecord(getContext(), RetTy, true) ||
638 getContext().getTypeSize(RetTy) == 0)
639 return ABIArgInfo::getIgnore();
640
641 // Check for homogeneous aggregates with AAPCS-VFP.
642 if (IsAAPCS_VFP) {
643 const Type *Base = nullptr;
644 uint64_t Members = 0;
645 if (isHomogeneousAggregate(RetTy, Base, Members))
646 return classifyHomogeneousAggregate(RetTy, Base, Members);
647 }
648
649 // Aggregates <= 4 bytes are returned in r0; other aggregates
650 // are returned indirectly.
651 uint64_t Size = getContext().getTypeSize(RetTy);
652 if (Size <= 32) {
653 if (getDataLayout().isBigEndian())
654 // Return in 32 bit integer integer type (as if loaded by LDR, AAPCS 5.4)
655 return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext()));
656
657 // Return in the smallest viable integer type.
658 if (Size <= 8)
659 return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));
660 if (Size <= 16)
661 return ABIArgInfo::getDirect(llvm::Type::getInt16Ty(getVMContext()));
662 return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext()));
663 } else if (Size <= 128 && getABIKind() == ARMABIKind::AAPCS16_VFP) {
664 llvm::Type *Int32Ty = llvm::Type::getInt32Ty(getVMContext());
665 llvm::Type *CoerceTy =
666 llvm::ArrayType::get(Int32Ty, llvm::alignTo(Size, 32) / 32);
667 return ABIArgInfo::getDirect(CoerceTy);
668 }
669
670 return getNaturalAlignIndirect(RetTy, getDataLayout().getAllocaAddrSpace());
671}
672
673/// isIllegalVector - check whether Ty is an illegal vector type.
674bool ARMABIInfo::isIllegalVectorType(QualType Ty) const {
675 if (const VectorType *VT = Ty->getAs<VectorType> ()) {
676 // On targets that don't support half, fp16 or bfloat, they are expanded
677 // into float, and we don't want the ABI to depend on whether or not they
678 // are supported in hardware. Thus return false to coerce vectors of these
679 // types into integer vectors.
680 // We do not depend on hasFastHalfType for bfloat as it is a
681 // separate IR type.
682 if ((!getTarget().hasFastHalfType() &&
683 (VT->getElementType()->isFloat16Type() ||
684 VT->getElementType()->isHalfType())) ||
685 (IsFloatABISoftFP &&
686 VT->getElementType()->isBFloat16Type()))
687 return true;
688 if (isAndroid()) {
689 // Android shipped using Clang 3.1, which supported a slightly different
690 // vector ABI. The primary differences were that 3-element vector types
691 // were legal, and so were sub 32-bit vectors (i.e. <2 x i8>). This path
692 // accepts that legacy behavior for Android only.
693 // Check whether VT is legal.
694 unsigned NumElements = VT->getNumElements();
695 // NumElements should be power of 2 or equal to 3.
696 if (!llvm::isPowerOf2_32(NumElements) && NumElements != 3)
697 return true;
698 } else {
699 // Check whether VT is legal.
700 unsigned NumElements = VT->getNumElements();
701 uint64_t Size = getContext().getTypeSize(VT);
702 // NumElements should be power of 2.
703 if (!llvm::isPowerOf2_32(NumElements))
704 return true;
705 // Size should be greater than 32 bits.
706 return Size <= 32;
707 }
708 }
709 return false;
710}
711
712/// Return true if a type contains any 16-bit floating point vectors
713bool ARMABIInfo::containsAnyFP16Vectors(QualType Ty) const {
714 if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) {
715 uint64_t NElements = AT->getZExtSize();
716 if (NElements == 0)
717 return false;
718 return containsAnyFP16Vectors(AT->getElementType());
719 }
720 if (const auto *RD = Ty->getAsRecordDecl()) {
721 // If this is a C++ record, check the bases first.
722 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
723 if (llvm::any_of(CXXRD->bases(), [this](const CXXBaseSpecifier &B) {
724 return containsAnyFP16Vectors(B.getType());
725 }))
726 return true;
727
728 if (llvm::any_of(RD->fields(), [this](FieldDecl *FD) {
729 return FD && containsAnyFP16Vectors(FD->getType());
730 }))
731 return true;
732
733 return false;
734 } else {
735 if (const VectorType *VT = Ty->getAs<VectorType>())
736 return (VT->getElementType()->isFloat16Type() ||
737 VT->getElementType()->isBFloat16Type() ||
738 VT->getElementType()->isHalfType());
739 return false;
740 }
741}
742
743bool ARMSwiftABIInfo::isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,
744 unsigned NumElts) const {
745 if (!llvm::isPowerOf2_32(NumElts))
746 return false;
747 unsigned size = CGT.getDataLayout().getTypeStoreSizeInBits(EltTy);
748 if (size > 64)
749 return false;
750 if (VectorSize.getQuantity() != 8 &&
751 (VectorSize.getQuantity() != 16 || NumElts == 1))
752 return false;
753 return true;
754}
755
756bool ARMABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const {
757 // Homogeneous aggregates for AAPCS-VFP must have base types of float,
758 // double, or 64-bit or 128-bit vectors.
759 if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) {
760 if (BT->getKind() == BuiltinType::Float ||
761 BT->getKind() == BuiltinType::Double ||
762 BT->getKind() == BuiltinType::LongDouble)
763 return true;
764 } else if (const VectorType *VT = Ty->getAs<VectorType>()) {
765 unsigned VecSize = getContext().getTypeSize(VT);
766 if (VecSize == 64 || VecSize == 128)
767 return true;
768 }
769 return false;
770}
771
772bool ARMABIInfo::isHomogeneousAggregateSmallEnough(const Type *Base,
773 uint64_t Members) const {
774 return Members <= 4;
775}
776
777bool ARMABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate() const {
778 // AAPCS32 says that the rule for whether something is a homogeneous
779 // aggregate is applied to the output of the data layout decision. So
780 // anything that doesn't affect the data layout also does not affect
781 // homogeneity. In particular, zero-length bitfields don't stop a struct
782 // being homogeneous.
783 return true;
784}
785
786bool ARMABIInfo::isEffectivelyAAPCS_VFP(unsigned callConvention,
787 bool acceptHalf) const {
788 // Give precedence to user-specified calling conventions.
789 if (callConvention != llvm::CallingConv::C)
790 return (callConvention == llvm::CallingConv::ARM_AAPCS_VFP);
791 else
792 return (getABIKind() == ARMABIKind::AAPCS_VFP) ||
793 (acceptHalf && (getABIKind() == ARMABIKind::AAPCS16_VFP));
794}
795
796RValue ARMABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
797 QualType Ty, AggValueSlot Slot) const {
798 CharUnits SlotSize = CharUnits::fromQuantity(4);
799
800 // Empty records are ignored for parameter passing purposes.
801 uint64_t Size = getContext().getTypeSize(Ty);
802 bool IsEmpty = isEmptyRecord(getContext(), Ty, true);
803 if ((IsEmpty || Size == 0) && shouldIgnoreEmptyArg(Ty))
804 return Slot.asRValue();
805
806 CharUnits TySize = getContext().getTypeSizeInChars(Ty);
807 CharUnits TyAlignForABI = getContext().getTypeUnadjustedAlignInChars(Ty);
808
809 // Use indirect if size of the illegal vector is bigger than 16 bytes.
810 bool IsIndirect = false;
811 const Type *Base = nullptr;
812 uint64_t Members = 0;
813 if (TySize > CharUnits::fromQuantity(16) && isIllegalVectorType(Ty)) {
814 IsIndirect = true;
815
816 // ARMv7k passes structs bigger than 16 bytes indirectly, in space
817 // allocated by the caller.
818 } else if (TySize > CharUnits::fromQuantity(16) &&
819 getABIKind() == ARMABIKind::AAPCS16_VFP &&
820 !isHomogeneousAggregate(Ty, Base, Members)) {
821 IsIndirect = true;
822
823 // Otherwise, bound the type's ABI alignment.
824 // The ABI alignment for 64-bit or 128-bit vectors is 8 for AAPCS and 4 for
825 // APCS. For AAPCS, the ABI alignment is at least 4-byte and at most 8-byte.
826 // Our callers should be prepared to handle an under-aligned address.
827 } else if (getABIKind() == ARMABIKind::AAPCS_VFP ||
828 getABIKind() == ARMABIKind::AAPCS) {
829 TyAlignForABI = std::max(TyAlignForABI, CharUnits::fromQuantity(4));
830 TyAlignForABI = std::min(TyAlignForABI, CharUnits::fromQuantity(8));
831 } else if (getABIKind() == ARMABIKind::AAPCS16_VFP) {
832 // ARMv7k allows type alignment up to 16 bytes.
833 TyAlignForABI = std::max(TyAlignForABI, CharUnits::fromQuantity(4));
834 TyAlignForABI = std::min(TyAlignForABI, CharUnits::fromQuantity(16));
835 } else {
836 TyAlignForABI = CharUnits::fromQuantity(4);
837 }
838
839 TypeInfoChars TyInfo(TySize, TyAlignForABI, AlignRequirementKind::None);
840 return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, TyInfo, SlotSize,
841 /*AllowHigherAlign*/ true, Slot);
842}
843
844std::unique_ptr<TargetCodeGenInfo>
846 return std::make_unique<ARMTargetCodeGenInfo>(CGM.getTypes(), Kind);
847}
848
849std::unique_ptr<TargetCodeGenInfo>
851 return std::make_unique<WindowsARMTargetCodeGenInfo>(CGM.getTypes(), K);
852}
static bool isIntegerLikeType(QualType Ty, ASTContext &Context, llvm::LLVMContext &VMContext)
Definition ARM.cpp:482
static StringRef getTriple(const Command &Job)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
This class is used for builtin types like 'int'.
Definition TypeBase.h:3228
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition CharUnits.h:185
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition CharUnits.h:63
std::string FloatABI
The ABI to use for passing floating point arguments.
static ABIArgInfo getIgnore()
static ABIArgInfo getDirect(llvm::Type *T=nullptr, unsigned Offset=0, llvm::Type *Padding=nullptr, bool CanBeFlattened=true, unsigned Align=0)
static ABIArgInfo getIndirect(CharUnits Alignment, unsigned AddrSpace, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
static ABIArgInfo getExtend(QualType Ty, llvm::Type *T=nullptr)
ABIInfo - Target specific hooks for defining how a type should be passed or returned from functions.
Definition ABIInfo.h:48
RValue asRValue() const
Definition CGValue.h:713
RecordArgABI
Specify how one should pass an argument of a record type.
Definition CGCXXABI.h:150
@ RAA_DirectInMemory
Pass it on the stack using its defined layout.
Definition CGCXXABI.h:158
unsigned getCallingConvention() const
getCallingConvention - Return the user specified calling convention, which has been translated into a...
CanQualType getReturnType() const
MutableArrayRef< ArgInfo > arguments()
void setEffectiveCallingConvention(unsigned Value)
This class organizes the cross-function state that is used while generating LLVM code.
DiagnosticsEngine & getDiags() const
const LangOptions & getLangOpts() const
const TargetInfo & getTarget() const
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
const CodeGenOptions & getCodeGenOpts() const
const llvm::DataLayout & getDataLayout() const
Target specific hooks for defining how a type should be passed or returned from functions with one of...
Definition ABIInfo.h:149
TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...
Definition TargetInfo.h:50
virtual unsigned getSizeOfUnwindException() const
Determines the size of struct _Unwind_Exception on this platform, in 8-bit units.
Complex values, per C99 6.2.5p11.
Definition TypeBase.h:3339
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
SourceLocation getLocation() const
Definition DeclBase.h:447
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Represents a member of a struct/union/class.
Definition Decl.h:3182
bool isBitField() const
Determines whether this field is a bitfield.
Definition Decl.h:3285
bool hasSignReturnAddress() const
Check if return address signing is enabled.
A (possibly-)qualified type.
Definition TypeBase.h:937
Represents a struct/union/class.
Definition Decl.h:4347
bool hasFlexibleArrayMember() const
Definition Decl.h:4380
field_iterator field_end() const
Definition Decl.h:4553
specific_decl_iterator< FieldDecl > field_iterator
Definition Decl.h:4547
RecordDecl * getDefinitionOrSelf() const
Definition Decl.h:4535
field_iterator field_begin() const
Definition Decl.cpp:5271
bool isUnion() const
Definition Decl.h:3950
TargetOptions & getTargetOpts() const
Retrieve the target options.
Definition TargetInfo.h:327
virtual bool isBranchProtectionSupportedArch(StringRef Arch) const
Determine if the Architecture in this TargetInfo supports branch protection.
virtual bool validateBranchProtection(StringRef Spec, StringRef Arch, BranchProtectionInfo &BPI, const LangOptions &LO, StringRef &Err) const
Determine if this TargetInfo supports the given branch protection specification.
virtual ParsedTargetAttr parseTargetAttr(StringRef Str) const
std::string CPU
If given, the name of the target CPU to generate code for.
bool isVoidType() const
Definition TypeBase.h:9050
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition Type.h:41
bool isPointerType() const
Definition TypeBase.h:8684
bool isAnyComplexType() const
Definition TypeBase.h:8819
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
Definition Type.h:53
bool isVectorType() const
Definition TypeBase.h:8823
bool isRealFloatingType() const
Floating point categories.
Definition Type.cpp:2405
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition TypeBase.h:2985
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9277
QualType getType() const
Definition Decl.h:723
ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to pass a particular type.
bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize, llvm::VectorType *vectorTy)
Is the given vector type "legal" for Swift's perspective on the current platform?
std::unique_ptr< TargetCodeGenInfo > createARMTargetCodeGenInfo(CodeGenModule &CGM, ARMABIKind Kind)
Definition ARM.cpp:845
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
Definition CGValue.h:146
CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
RValue emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType ValueTy, bool IsIndirect, TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign, bool AllowHigherAlign, AggValueSlot Slot, bool ForceRightAdjust=false)
Emit va_arg for a platform using the common void* representation, where arguments are simply emitted ...
bool isAggregateTypeForABI(QualType T)
std::unique_ptr< TargetCodeGenInfo > createWindowsARMTargetCodeGenInfo(CodeGenModule &CGM, ARMABIKind K)
Definition ARM.cpp:850
void AssignToArrayRange(CodeGen::CGBuilderTy &Builder, llvm::Value *Array, llvm::Value *Value, unsigned FirstIndex, unsigned LastIndex)
QualType useFirstFieldIfTransparentUnion(QualType Ty)
Pass transparent unions as if they were the type of the first element.
bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, bool AsIfNoUniqueAddr=false)
isEmptyRecord - Return true iff a structure contains only empty fields.
The JSON file list parser is used to communicate input to InstallAPI.
@ CPlusPlus
@ Type
The name was classified as a type.
Definition Sema.h:564
unsigned long uint64_t
#define true
Definition stdbool.h:25
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64