1 //===- PNaCl.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 // le32/PNaCl bitcode ABI Implementation
18 // This is a simplified version of the x86_32 ABI. Arguments and return values
19 // are always passed on the stack.
20 //===----------------------------------------------------------------------===//
22 class PNaClABIInfo
: public ABIInfo
{
24 PNaClABIInfo(CodeGen::CodeGenTypes
&CGT
) : ABIInfo(CGT
) {}
26 ABIArgInfo
classifyReturnType(QualType RetTy
) const;
27 ABIArgInfo
classifyArgumentType(QualType RetTy
) const;
29 void computeInfo(CGFunctionInfo
&FI
) const override
;
30 RValue
EmitVAArg(CodeGenFunction
&CGF
, Address VAListAddr
, QualType Ty
,
31 AggValueSlot Slot
) const override
;
34 class PNaClTargetCodeGenInfo
: public TargetCodeGenInfo
{
36 PNaClTargetCodeGenInfo(CodeGen::CodeGenTypes
&CGT
)
37 : TargetCodeGenInfo(std::make_unique
<PNaClABIInfo
>(CGT
)) {}
40 void PNaClABIInfo::computeInfo(CGFunctionInfo
&FI
) const {
41 if (!getCXXABI().classifyReturnType(FI
))
42 FI
.getReturnInfo() = classifyReturnType(FI
.getReturnType());
44 for (auto &I
: FI
.arguments())
45 I
.info
= classifyArgumentType(I
.type
);
48 RValue
PNaClABIInfo::EmitVAArg(CodeGenFunction
&CGF
, Address VAListAddr
,
49 QualType Ty
, AggValueSlot Slot
) const {
50 // The PNaCL ABI is a bit odd, in that varargs don't use normal
51 // function classification. Structs get passed directly for varargs
52 // functions, through a rewriting transform in
53 // pnacl-llvm/lib/Transforms/NaCl/ExpandVarArgs.cpp, which allows
54 // this target to actually support a va_arg instructions with an
55 // aggregate type, unlike other targets.
56 return CGF
.EmitLoadOfAnyValue(
58 EmitVAArgInstr(CGF
, VAListAddr
, Ty
, ABIArgInfo::getDirect()), Ty
),
62 /// Classify argument of given type \p Ty.
63 ABIArgInfo
PNaClABIInfo::classifyArgumentType(QualType Ty
) const {
64 if (isAggregateTypeForABI(Ty
)) {
65 if (CGCXXABI::RecordArgABI RAA
= getRecordArgABI(Ty
, getCXXABI()))
66 return getNaturalAlignIndirect(Ty
, RAA
== CGCXXABI::RAA_DirectInMemory
);
67 return getNaturalAlignIndirect(Ty
);
68 } else if (const EnumType
*EnumTy
= Ty
->getAs
<EnumType
>()) {
69 // Treat an enum type as its underlying type.
70 Ty
= EnumTy
->getDecl()->getIntegerType();
71 } else if (Ty
->isFloatingType()) {
72 // Floating-point types don't go inreg.
73 return ABIArgInfo::getDirect();
74 } else if (const auto *EIT
= Ty
->getAs
<BitIntType
>()) {
75 // Treat bit-precise integers as integers if <= 64, otherwise pass
77 if (EIT
->getNumBits() > 64)
78 return getNaturalAlignIndirect(Ty
);
79 return ABIArgInfo::getDirect();
82 return (isPromotableIntegerTypeForABI(Ty
) ? ABIArgInfo::getExtend(Ty
)
83 : ABIArgInfo::getDirect());
86 ABIArgInfo
PNaClABIInfo::classifyReturnType(QualType RetTy
) const {
87 if (RetTy
->isVoidType())
88 return ABIArgInfo::getIgnore();
90 // In the PNaCl ABI we always return records/structures on the stack.
91 if (isAggregateTypeForABI(RetTy
))
92 return getNaturalAlignIndirect(RetTy
);
94 // Treat bit-precise integers as integers if <= 64, otherwise pass indirectly.
95 if (const auto *EIT
= RetTy
->getAs
<BitIntType
>()) {
96 if (EIT
->getNumBits() > 64)
97 return getNaturalAlignIndirect(RetTy
);
98 return ABIArgInfo::getDirect();
101 // Treat an enum type as its underlying type.
102 if (const EnumType
*EnumTy
= RetTy
->getAs
<EnumType
>())
103 RetTy
= EnumTy
->getDecl()->getIntegerType();
105 return (isPromotableIntegerTypeForABI(RetTy
) ? ABIArgInfo::getExtend(RetTy
)
106 : ABIArgInfo::getDirect());
109 std::unique_ptr
<TargetCodeGenInfo
>
110 CodeGen::createPNaClTargetCodeGenInfo(CodeGenModule
&CGM
) {
111 return std::make_unique
<PNaClTargetCodeGenInfo
>(CGM
.getTypes());