brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.4 KiB · 3a7af34 Raw
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