105 lines · cpp
1//===- BPF.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-exception6//7//===----------------------------------------------------------------------===//8 9#include "ABIInfoImpl.h"10#include "TargetInfo.h"11 12using namespace clang;13using namespace clang::CodeGen;14 15//===----------------------------------------------------------------------===//16// BPF ABI Implementation17//===----------------------------------------------------------------------===//18 19namespace {20 21class BPFABIInfo : public DefaultABIInfo {22public:23 BPFABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}24 25 ABIArgInfo classifyArgumentType(QualType Ty) const {26 Ty = useFirstFieldIfTransparentUnion(Ty);27 28 if (isAggregateTypeForABI(Ty)) {29 uint64_t Bits = getContext().getTypeSize(Ty);30 if (Bits == 0)31 return ABIArgInfo::getIgnore();32 33 // If the aggregate needs 1 or 2 registers, do not use reference.34 if (Bits <= 128) {35 llvm::Type *CoerceTy;36 if (Bits <= 64) {37 CoerceTy =38 llvm::IntegerType::get(getVMContext(), llvm::alignTo(Bits, 8));39 } else {40 llvm::Type *RegTy = llvm::IntegerType::get(getVMContext(), 64);41 CoerceTy = llvm::ArrayType::get(RegTy, 2);42 }43 return ABIArgInfo::getDirect(CoerceTy);44 } else {45 return getNaturalAlignIndirect(Ty,46 getDataLayout().getAllocaAddrSpace());47 }48 }49 50 if (const auto *ED = Ty->getAsEnumDecl())51 Ty = ED->getIntegerType();52 53 ASTContext &Context = getContext();54 if (const auto *EIT = Ty->getAs<BitIntType>())55 if (EIT->getNumBits() > Context.getTypeSize(Context.Int128Ty))56 return getNaturalAlignIndirect(Ty,57 getDataLayout().getAllocaAddrSpace());58 59 return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)60 : ABIArgInfo::getDirect());61 }62 63 ABIArgInfo classifyReturnType(QualType RetTy) const {64 if (RetTy->isVoidType())65 return ABIArgInfo::getIgnore();66 67 if (isAggregateTypeForABI(RetTy))68 return getNaturalAlignIndirect(RetTy,69 getDataLayout().getAllocaAddrSpace());70 71 // Treat an enum type as its underlying type.72 if (const auto *ED = RetTy->getAsEnumDecl())73 RetTy = ED->getIntegerType();74 75 ASTContext &Context = getContext();76 if (const auto *EIT = RetTy->getAs<BitIntType>())77 if (EIT->getNumBits() > Context.getTypeSize(Context.Int128Ty))78 return getNaturalAlignIndirect(RetTy,79 getDataLayout().getAllocaAddrSpace());80 81 // Caller will do necessary sign/zero extension.82 return ABIArgInfo::getDirect();83 }84 85 void computeInfo(CGFunctionInfo &FI) const override {86 FI.getReturnInfo() = classifyReturnType(FI.getReturnType());87 for (auto &I : FI.arguments())88 I.info = classifyArgumentType(I.type);89 }90 91};92 93class BPFTargetCodeGenInfo : public TargetCodeGenInfo {94public:95 BPFTargetCodeGenInfo(CodeGenTypes &CGT)96 : TargetCodeGenInfo(std::make_unique<BPFABIInfo>(CGT)) {}97};98 99}100 101std::unique_ptr<TargetCodeGenInfo>102CodeGen::createBPFTargetCodeGenInfo(CodeGenModule &CGM) {103 return std::make_unique<BPFTargetCodeGenInfo>(CGM.getTypes());104}105