1 //===- Lanai.cpp ----------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "ABIInfoImpl.h"
10 #include "TargetInfo.h"
12 using namespace clang
;
13 using namespace clang::CodeGen
;
15 //===----------------------------------------------------------------------===//
16 // Lanai ABI Implementation
17 //===----------------------------------------------------------------------===//
20 class LanaiABIInfo
: public DefaultABIInfo
{
26 LanaiABIInfo(CodeGen::CodeGenTypes
&CGT
) : DefaultABIInfo(CGT
) {}
28 bool shouldUseInReg(QualType Ty
, CCState
&State
) const;
30 void computeInfo(CGFunctionInfo
&FI
) const override
{
32 // Lanai uses 4 registers to pass arguments unless the function has the
33 // regparm attribute set.
34 if (FI
.getHasRegParm()) {
35 State
.FreeRegs
= FI
.getRegParm();
40 if (!getCXXABI().classifyReturnType(FI
))
41 FI
.getReturnInfo() = classifyReturnType(FI
.getReturnType());
42 for (auto &I
: FI
.arguments())
43 I
.info
= classifyArgumentType(I
.type
, State
);
46 ABIArgInfo
getIndirectResult(QualType Ty
, bool ByVal
, CCState
&State
) const;
47 ABIArgInfo
classifyArgumentType(QualType RetTy
, CCState
&State
) const;
49 } // end anonymous namespace
51 bool LanaiABIInfo::shouldUseInReg(QualType Ty
, CCState
&State
) const {
52 unsigned Size
= getContext().getTypeSize(Ty
);
53 unsigned SizeInRegs
= llvm::alignTo(Size
, 32U) / 32U;
58 if (SizeInRegs
> State
.FreeRegs
) {
63 State
.FreeRegs
-= SizeInRegs
;
68 ABIArgInfo
LanaiABIInfo::getIndirectResult(QualType Ty
, bool ByVal
,
69 CCState
&State
) const {
72 --State
.FreeRegs
; // Non-byval indirects just use one pointer.
73 return getNaturalAlignIndirectInReg(Ty
);
75 return getNaturalAlignIndirect(Ty
, false);
78 // Compute the byval alignment.
79 const unsigned MinABIStackAlignInBytes
= 4;
80 unsigned TypeAlign
= getContext().getTypeAlign(Ty
) / 8;
81 return ABIArgInfo::getIndirect(CharUnits::fromQuantity(4), /*ByVal=*/true,
82 /*Realign=*/TypeAlign
>
83 MinABIStackAlignInBytes
);
86 ABIArgInfo
LanaiABIInfo::classifyArgumentType(QualType Ty
,
87 CCState
&State
) const {
88 // Check with the C++ ABI first.
89 const RecordType
*RT
= Ty
->getAs
<RecordType
>();
91 CGCXXABI::RecordArgABI RAA
= getRecordArgABI(RT
, getCXXABI());
92 if (RAA
== CGCXXABI::RAA_Indirect
) {
93 return getIndirectResult(Ty
, /*ByVal=*/false, State
);
94 } else if (RAA
== CGCXXABI::RAA_DirectInMemory
) {
95 return getNaturalAlignIndirect(Ty
, /*ByVal=*/true);
99 if (isAggregateTypeForABI(Ty
)) {
100 // Structures with flexible arrays are always indirect.
101 if (RT
&& RT
->getDecl()->hasFlexibleArrayMember())
102 return getIndirectResult(Ty
, /*ByVal=*/true, State
);
104 // Ignore empty structs/unions.
105 if (isEmptyRecord(getContext(), Ty
, true))
106 return ABIArgInfo::getIgnore();
108 llvm::LLVMContext
&LLVMContext
= getVMContext();
109 unsigned SizeInRegs
= (getContext().getTypeSize(Ty
) + 31) / 32;
110 if (SizeInRegs
<= State
.FreeRegs
) {
111 llvm::IntegerType
*Int32
= llvm::Type::getInt32Ty(LLVMContext
);
112 SmallVector
<llvm::Type
*, 3> Elements(SizeInRegs
, Int32
);
113 llvm::Type
*Result
= llvm::StructType::get(LLVMContext
, Elements
);
114 State
.FreeRegs
-= SizeInRegs
;
115 return ABIArgInfo::getDirectInReg(Result
);
119 return getIndirectResult(Ty
, true, State
);
122 // Treat an enum type as its underlying type.
123 if (const auto *EnumTy
= Ty
->getAs
<EnumType
>())
124 Ty
= EnumTy
->getDecl()->getIntegerType();
126 bool InReg
= shouldUseInReg(Ty
, State
);
128 // Don't pass >64 bit integers in registers.
129 if (const auto *EIT
= Ty
->getAs
<BitIntType
>())
130 if (EIT
->getNumBits() > 64)
131 return getIndirectResult(Ty
, /*ByVal=*/true, State
);
133 if (isPromotableIntegerTypeForABI(Ty
)) {
135 return ABIArgInfo::getDirectInReg();
136 return ABIArgInfo::getExtend(Ty
);
139 return ABIArgInfo::getDirectInReg();
140 return ABIArgInfo::getDirect();
144 class LanaiTargetCodeGenInfo
: public TargetCodeGenInfo
{
146 LanaiTargetCodeGenInfo(CodeGen::CodeGenTypes
&CGT
)
147 : TargetCodeGenInfo(std::make_unique
<LanaiABIInfo
>(CGT
)) {}
151 std::unique_ptr
<TargetCodeGenInfo
>
152 CodeGen::createLanaiTargetCodeGenInfo(CodeGenModule
&CGM
) {
153 return std::make_unique
<LanaiTargetCodeGenInfo
>(CGM
.getTypes());