brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.0 KiB · 871a135 Raw
159 lines · cpp
1//===- Lanai.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// Lanai ABI Implementation17//===----------------------------------------------------------------------===//18 19namespace {20class LanaiABIInfo : public DefaultABIInfo {21  struct CCState {22    unsigned FreeRegs;23  };24 25public:26  LanaiABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}27 28  bool shouldUseInReg(QualType Ty, CCState &State) const;29 30  void computeInfo(CGFunctionInfo &FI) const override {31    CCState State;32    // Lanai uses 4 registers to pass arguments unless the function has the33    // regparm attribute set.34    if (FI.getHasRegParm()) {35      State.FreeRegs = FI.getRegParm();36    } else {37      State.FreeRegs = 4;38    }39 40    if (!getCXXABI().classifyReturnType(FI))41      FI.getReturnInfo() = classifyReturnType(FI.getReturnType());42    for (auto &I : FI.arguments())43      I.info = classifyArgumentType(I.type, State);44  }45 46  ABIArgInfo getIndirectResult(QualType Ty, bool ByVal, CCState &State) const;47  ABIArgInfo classifyArgumentType(QualType RetTy, CCState &State) const;48};49} // end anonymous namespace50 51bool LanaiABIInfo::shouldUseInReg(QualType Ty, CCState &State) const {52  unsigned Size = getContext().getTypeSize(Ty);53  unsigned SizeInRegs = llvm::alignTo(Size, 32U) / 32U;54 55  if (SizeInRegs == 0)56    return false;57 58  if (SizeInRegs > State.FreeRegs) {59    State.FreeRegs = 0;60    return false;61  }62 63  State.FreeRegs -= SizeInRegs;64 65  return true;66}67 68ABIArgInfo LanaiABIInfo::getIndirectResult(QualType Ty, bool ByVal,69                                           CCState &State) const {70  if (!ByVal) {71    if (State.FreeRegs) {72      --State.FreeRegs; // Non-byval indirects just use one pointer.73      return getNaturalAlignIndirectInReg(Ty);74    }75    return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),76                                   false);77  }78 79  // Compute the byval alignment.80  const unsigned MinABIStackAlignInBytes = 4;81  unsigned TypeAlign = getContext().getTypeAlign(Ty) / 8;82  return ABIArgInfo::getIndirect(83      CharUnits::fromQuantity(4),84      /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(), /*ByVal=*/true,85      /*Realign=*/TypeAlign > MinABIStackAlignInBytes);86}87 88ABIArgInfo LanaiABIInfo::classifyArgumentType(QualType Ty,89                                              CCState &State) const {90  // Check with the C++ ABI first.91  const RecordType *RT = Ty->getAsCanonical<RecordType>();92  if (RT) {93    CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, getCXXABI());94    if (RAA == CGCXXABI::RAA_Indirect) {95      return getIndirectResult(Ty, /*ByVal=*/false, State);96    } else if (RAA == CGCXXABI::RAA_DirectInMemory) {97      return getNaturalAlignIndirect(98          Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),99          /*ByVal=*/true);100    }101  }102 103  if (isAggregateTypeForABI(Ty)) {104    // Structures with flexible arrays are always indirect.105    if (RT && RT->getDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember())106      return getIndirectResult(Ty, /*ByVal=*/true, State);107 108    // Ignore empty structs/unions.109    if (isEmptyRecord(getContext(), Ty, true))110      return ABIArgInfo::getIgnore();111 112    llvm::LLVMContext &LLVMContext = getVMContext();113    unsigned SizeInRegs = (getContext().getTypeSize(Ty) + 31) / 32;114    if (SizeInRegs <= State.FreeRegs) {115      llvm::IntegerType *Int32 = llvm::Type::getInt32Ty(LLVMContext);116      SmallVector<llvm::Type *, 3> Elements(SizeInRegs, Int32);117      llvm::Type *Result = llvm::StructType::get(LLVMContext, Elements);118      State.FreeRegs -= SizeInRegs;119      return ABIArgInfo::getDirectInReg(Result);120    } else {121      State.FreeRegs = 0;122    }123    return getIndirectResult(Ty, true, State);124  }125 126  // Treat an enum type as its underlying type.127  if (const auto *ED = Ty->getAsEnumDecl())128    Ty = ED->getIntegerType();129 130  bool InReg = shouldUseInReg(Ty, State);131 132  // Don't pass >64 bit integers in registers.133  if (const auto *EIT = Ty->getAs<BitIntType>())134    if (EIT->getNumBits() > 64)135      return getIndirectResult(Ty, /*ByVal=*/true, State);136 137  if (isPromotableIntegerTypeForABI(Ty)) {138    if (InReg)139      return ABIArgInfo::getDirectInReg();140    return ABIArgInfo::getExtend(Ty);141  }142  if (InReg)143    return ABIArgInfo::getDirectInReg();144  return ABIArgInfo::getDirect();145}146 147namespace {148class LanaiTargetCodeGenInfo : public TargetCodeGenInfo {149public:150  LanaiTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT)151      : TargetCodeGenInfo(std::make_unique<LanaiABIInfo>(CGT)) {}152};153}154 155std::unique_ptr<TargetCodeGenInfo>156CodeGen::createLanaiTargetCodeGenInfo(CodeGenModule &CGM) {157  return std::make_unique<LanaiTargetCodeGenInfo>(CGM.getTypes());158}159