FPGA開発日記

FPGAというより、コンピュータアーキテクチャかもね! カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages

LLVMのバックエンドを作るための第一歩 (9. MCTargetDescとABIInfo)

f:id:msyksphinz:20190425001356p:plain
LLVM Compiler Infrastructure

前回に引き続きLLVMのバックエンドを作るために必要なファイルを読み解いていく。

MCTargetDesc/MYRISCVXMCTargetDesc.{h,cpp}

MYRISCVXMCTargeTDescでは明確なクラスを定義するわけではない。 その代わりに、これまでTarget Descriptionから生成したソースコードをincludeしていく。 MYRISCVXMCTargetDesc.hではenumなどのレジスタ番号を定義する。一方で、MYRISCVXMCTargetDesc.hは実装をincludeする。

f:id:msyksphinz:20190520003950p:plain
  • lib/Target/MYRISCVX/MCTargetDesc/MYRISCVXMCTargetDesc.h
// Defines symbolic names for MYRISCVX registers.  This defines a mapping from
// register name to register number.
#define GET_REGINFO_ENUM
#include "MYRISCVXGenRegisterInfo.inc"

// Defines symbolic names for the MYRISCVX instructions.
#define GET_INSTRINFO_ENUM
#include "MYRISCVXGenInstrInfo.inc"

#define GET_SUBTARGETINFO_ENUM
#include "MYRISCVXGenSubtargetInfo.inc"
  • lib/Target/MYRISCVX/MCTargetDesc/MYRISCVXMCTargetDesc.cpp
#define GET_INSTRINFO_MC_DESC
#include "MYRISCVXGenInstrInfo.inc"

#define GET_SUBTARGETINFO_MC_DESC
#include "MYRISCVXGenSubtargetInfo.inc"

#define GET_REGINFO_MC_DESC
#include "MYRISCVXGenRegisterInfo.inc"

MCTargetDesc/MYRISCVXABIInfo.{h,cpp}`

MYRISCVXABIInfoはABIに関するクラスだ。 MYRISCVXについては、1つのABIとしてLP32を定義した。 このABIを使用するための各種メソッドを定義していく。

  • lib/Target/MYRISCVX/MCTargetDesc/MYRISCVXABIInfo.h
  class MYRISCVXABIInfo {
   public:
    enum class ABI { Unknown, LP32 };

   protected:
    ABI ThisABI;

   public:
    MYRISCVXABIInfo(ABI ThisABI) : ThisABI(ThisABI) {}

    static MYRISCVXABIInfo Unknown() { return MYRISCVXABIInfo(ABI::Unknown); }
    static MYRISCVXABIInfo LP32() { return MYRISCVXABIInfo(ABI::LP32); }
    static MYRISCVXABIInfo computeTargetABI();

    bool IsKnown() const { return ThisABI != ABI::Unknown; }
    bool IsLP32 () const { return ThisABI == ABI::LP32; }
    ABI GetEnumValue() const { return ThisABI; }

    /// The registers to use for byval arguments.
    ArrayRef<MCPhysReg> GetByValArgRegs() const;

    /// The registers to use for the variable argument list.
    ArrayRef<MCPhysReg> GetVarArgRegs() const;

    /// Obtain the size of the area allocated by the callee for arguments.
    /// CallingConv::FastCall affects the value for O32.
    unsigned GetCalleeAllocdArgSizeInBytes(CallingConv::ID CC) const;

    /// Ordering of ABI's
    /// MYRISCVXGenSubtargetInfo.inc will use this to resolve conflicts when given
    /// multiple ABI options.
    bool operator<(const MYRISCVXABIInfo Other) const {
      return ThisABI < Other.GetEnumValue();
    }

    unsigned GetStackPtr() const;
    unsigned GetFramePtr() const;
    unsigned GetNullPtr() const;

    unsigned GetEhDataReg(unsigned I) const;
    int EhDataRegSize() const;
  };