FPGA開発日記

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

"Creating an LLVM Backend for the Cpu0 Architecture"をやってみる(8. BackEnd追加のまとめ1.)

f:id:msyksphinz:20181123225150p:plain

Cpu0のバックエンドをLLVMに追加するチュートリアル、第3章(?)のBackendの追加の章をやり終えた。 やり終えたといっても、ひたすら写経して、ビルドして、テストパタンを動かして終わりである。 これではさすがにもったいないので、もう少しまとめておきたい。

この章では、ターゲットマシン(Cpu0)の構想を決める。 変更を加えるファイルは以下。

  • lbdex/chapters/Chapter3_1/Cpu0TargetObjectFile.h : オブジェクトファイルの構造を決める。MCSectionなどのセクションを追加しているようだ。
  • lbdex/chapters/Chapter3_1/Cpu0TargetObjectFile.cpp : Cpu0のオブジェクトファイルについて定義をする。SmallDataSection = getContext().getELFSectionなど、各データセクションの定義を行う。
  • lbdex/chapters/Chapter3_1/Cpu0TargetMachine.h : Cpu0のターゲット情報を定義する。マシン情報の定義を行う。
  • lbdex/chapters/Chapter3_1/Cpu0TargetMachine.cpp : Cpu0のターゲット情報を定義する。ELとEBでそれぞれターゲットマシンを定義する。

    cpp Cpu0ebTargetMachine::Cpu0ebTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Optional<Reloc::Model> RM, CodeModel::Model CM, CodeGenOpt::Level OL) : Cpu0TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}

    cpp Cpu0elTargetMachine::Cpu0elTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Optional<Reloc::Model> RM, CodeModel::Model CM, CodeGenOpt::Level OL) : Cpu0TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}

  • include/llvm/Target/TargetInstInfo.h : Cpu0の命令情報を定義する。ここでCallFrameSetupOpcode, CallFrameDestroyOpcode が使われているが、これは今後定義するものと思われる。

  • lbdex/chapters/Chapter3_1/Cpu0.td : Cpu0のサブターゲットを定義している。サブターゲットというのは、Cpu0のマシンバリエーションのことだと思われる?

    cpp include "Cpu0CallingConv.td"

    cpp def FeatureChapter3_1 : SubtargetFeature<"ch3_1", "HasChapterDummy", "true", "Enable Chapter instructions.">; def FeatureChapter3_2 : SubtargetFeature<"ch3_2", "HasChapterDummy", "true", "Enable Chapter instructions.">; ...

  • lbdex/chapters/Chapter3_1/Cpu0CallingConv.td : Calling Conventionsを定義する。CalleSaveRegsの定義などを行っているようだ。

    ``` class CCIfSubtarget: CCIf<!strconcat("State.getTarget().getSubtarget().", F), A>;

    def CSR_O32 : CalleeSavedRegs<(add LR, FP, (sequence "S%u", 1, 0))>; ```

  • lbdex/chapters/Chapter3_1/Cpu0FrameLowering.h : Cpu0のフレーム定義を行う?

  • lbdex/chapters/Chapter3_1/Cpu0FrameLowering.cpp : Cpu0のフレーム定義本体。
  • lbdex/chapters/Chapter3_1/Cpu0SEFrameLowering.h : Cpu0SEとあるが、これはなんだか良く分からない?
  • lbdex/chapters/Chapter3_1/Cpu0SEFrameLowering.cpp

ちなみに、Cpu0のスタックフレームの構造は以下のようになっている:

//  0                 ----------
//  4                 Args to Pass
//  .                 saved $GP  (used in PIC)
//  .                 Alloca allocations
//  .                 Local Area
//  .                 CPU "Callee Saved" Registers
//  .                 saved FP
//  .                 saved RA
//  .                 FPU "Callee Saved" Registers
//  StackSize         -----------
  • lbdex/chapters/Chapter3_1/Cpu0InstrInfo.h, lbdex/chapters/Chapter3_1/Cpu0InstrInfo.cpp : Cpu0のTargetInstrInfoの実装が入っている。
    • getRegisterInfo は、必ず実装しなければならない?
  • lbdex/chapters/Chapter3_1/Cpu0InstrInfo.td : Cpuのサブターゲットを決めている。各章で実行できる内容を決めているようだ。これにより、mcpuなどで指定するターゲットによって挙動が変わる?
  • lbdex/chapters/Chapter3_1/Cpu0ISelLowering.h, lbdex/chapters/Chapter3_1/Cpu0ISelLowering.cpp : Cpu0が生成する命令で、DAGが命令を選択するのに必要なノードなどの情報を定義するらしい。
    • Cpu0ISD は、LLVMの中間コードの定義かな?
  • lbdex/chapters/Chapter3_1/Cpu0SEISelLowering.h, lbdex/chapters/Chapter3_1/Cpu0SEISelLowering.cpp : こちらは、Cpu0の特殊実装用の拡張用のファイルらしい?MipsSEを真似たためにこうなっているが、どういう意味なのかはよく分からない。
  • lbdex/chapters/Chapter3_1/Cpu0MachineFunction.h, lbdex/chapters/Chapter3_1/Cpu0MachineFunction.cpp : MachineFunctionというが、定義についてはVarArgsFrame...などの定義を行っているため、可変長引数などの処理を行っているのではないだろうか。
  • lbdex/chapters/Chapter3_1/MCTargetDesc/Cpu0ABIInfo.h, lbdex/chapters/Chapter3_1/MCTargetDesc/Cpu0ABIInfo.cpp : Cpu0のABIの定義を行う。
  • lbdex/chapters/Chapter3_1/Cpu0Subtarget.h, lbdex/chapters/Chapter3_1/Cpu0Subtarget.cpp` : Cpu0のサブターゲット(実装マシンごとの区分けなど)の定義を行っている。
  • lbdex/chapters/Chapter3_1/Cpu0RegisterInfo.h, lbdex/chapters/Chapter3_1/Cpu0RegisterInfo.cpp : Cpu0のレジスタの定義を行っている。

  • Chapter3_1で追加したクラス群のまとめ

    f:id:msyksphinz:20181218013550p:plain
    Cpu0 backend class access link

  • Add AsmPrinter

Cpu0GenAsmWrite.incを生成する。

  • lbdex/chapters/Chapter3_2/InstPrinter/Cpu0InstPrinter.h, lbdex/chapters/Chapter3_2/InstPrinter/Cpu0InstPrinter.cpp : 命令を表示するための関数群。レジスタ名とか、即値とか。
    • lbdex/chapters/Chapter2/Cpu0InstrInfo.td に示すように、PrintMethodを追加することによって、所望の逆アセンブルの表記を表示できるようになる。
  • lbdex/chapters/Chapter3_2/Cpu0MCInstLower.h, lbdex/chapters/Chapter3_2/Cpu0MCInstLower.cpp : InstLowerというのが良く分からないが命令の組を作っているように見える?
  • lbdex/chapters/Chapter3_2/MCTargetDesc/Cpu0BaseInfo.h : Cpu0のユーティリティ関数や、enumなどの定義を追加している。
  • lbdex/chapters/Chapter3_2/Cpu0MCAsmInfo.h, lbdex/chapters/Chapter3_2/Cpu0MCAsmInfo.cpp : セクションやアラインの表記方法などを示しているように見える?
  • lbdex/chapters/Chapter3_2/MCTargetDesc/Cpu0MCTargetDesc.h, lbdex/chapters/Chapter3_2/MCTargetDesc/Cpu0MCTargetDesc.cpp : 全体をまとめているクラス。
  • lbdex/chapters/Chapter3_2/Cpu0AsmPrinter.h, lbdex/chapters/Chapter3_2/Cpu0AsmPrinter.cpp : AsmPrinterの本体。