1 //===- BPF.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 // BPF ABI Implementation
17 //===----------------------------------------------------------------------===//
21 class BPFABIInfo
: public DefaultABIInfo
{
23 BPFABIInfo(CodeGenTypes
&CGT
) : DefaultABIInfo(CGT
) {}
25 ABIArgInfo
classifyArgumentType(QualType Ty
) const {
26 Ty
= useFirstFieldIfTransparentUnion(Ty
);
28 if (isAggregateTypeForABI(Ty
)) {
29 uint64_t Bits
= getContext().getTypeSize(Ty
);
31 return ABIArgInfo::getIgnore();
33 // If the aggregate needs 1 or 2 registers, do not use reference.
38 llvm::IntegerType::get(getVMContext(), llvm::alignTo(Bits
, 8));
40 llvm::Type
*RegTy
= llvm::IntegerType::get(getVMContext(), 64);
41 CoerceTy
= llvm::ArrayType::get(RegTy
, 2);
43 return ABIArgInfo::getDirect(CoerceTy
);
45 return getNaturalAlignIndirect(Ty
);
49 if (const EnumType
*EnumTy
= Ty
->getAs
<EnumType
>())
50 Ty
= EnumTy
->getDecl()->getIntegerType();
52 ASTContext
&Context
= getContext();
53 if (const auto *EIT
= Ty
->getAs
<BitIntType
>())
54 if (EIT
->getNumBits() > Context
.getTypeSize(Context
.Int128Ty
))
55 return getNaturalAlignIndirect(Ty
);
57 return (isPromotableIntegerTypeForABI(Ty
) ? ABIArgInfo::getExtend(Ty
)
58 : ABIArgInfo::getDirect());
61 ABIArgInfo
classifyReturnType(QualType RetTy
) const {
62 if (RetTy
->isVoidType())
63 return ABIArgInfo::getIgnore();
65 if (isAggregateTypeForABI(RetTy
))
66 return getNaturalAlignIndirect(RetTy
);
68 // Treat an enum type as its underlying type.
69 if (const EnumType
*EnumTy
= RetTy
->getAs
<EnumType
>())
70 RetTy
= EnumTy
->getDecl()->getIntegerType();
72 ASTContext
&Context
= getContext();
73 if (const auto *EIT
= RetTy
->getAs
<BitIntType
>())
74 if (EIT
->getNumBits() > Context
.getTypeSize(Context
.Int128Ty
))
75 return getNaturalAlignIndirect(RetTy
);
77 // Caller will do necessary sign/zero extension.
78 return ABIArgInfo::getDirect();
81 void computeInfo(CGFunctionInfo
&FI
) const override
{
82 FI
.getReturnInfo() = classifyReturnType(FI
.getReturnType());
83 for (auto &I
: FI
.arguments())
84 I
.info
= classifyArgumentType(I
.type
);
89 class BPFTargetCodeGenInfo
: public TargetCodeGenInfo
{
91 BPFTargetCodeGenInfo(CodeGenTypes
&CGT
)
92 : TargetCodeGenInfo(std::make_unique
<BPFABIInfo
>(CGT
)) {}
97 std::unique_ptr
<TargetCodeGenInfo
>
98 CodeGen::createBPFTargetCodeGenInfo(CodeGenModule
&CGM
) {
99 return std::make_unique
<BPFTargetCodeGenInfo
>(CGM
.getTypes());