LLVMにはすでにRISC-Vのバックエンドサポートが追加されている。しかし、勉強のために独自のRISC-V実装をLLVMに追加している。
Chapter-3のサイズの大きなスタックフレームの処理に関して、どうにも解決できずに悩んでいる。 とりあえず最初から全体的に見直すために、いろいろ見直す場所もあるので最初から作り直している。
ディレクトリ構成
lib/Target/MYRISCVX
├── CMakeLists.txt
├── LLVMBuild.txt
├── MCTargetDesc
│?? ├── CMakeLists.txt
│?? ├── LLVMBuild.txt
│?? ├── MYRISCVXABIInfo.cpp
│?? ├── MYRISCVXABIInfo.h
│?? ├── MYRISCVXMCTargetDesc.cpp
│?? └── MYRISCVXMCTargetDesc.h
├── MYRISCVX.h
├── MYRISCVX.td
├── MYRISCVXCallingConv.td
├── MYRISCVXFrameLowering.cpp
├── MYRISCVXFrameLowering.h
├── MYRISCVXISelLowering.cpp
├── MYRISCVXISelLowering.h
├── MYRISCVXInstrFormats.td
├── MYRISCVXInstrInfo.cpp
├── MYRISCVXInstrInfo.h
├── MYRISCVXInstrInfo.td
├── MYRISCVXMachineFunction.cpp
├── MYRISCVXMachineFunction.h
├── MYRISCVXOther.td
├── MYRISCVXRegisterInfo.cpp
├── MYRISCVXRegisterInfo.h
├── MYRISCVXRegisterInfo.td
├── MYRISCVXSEFrameLowering.cpp
├── MYRISCVXSEFrameLowering.h
├── MYRISCVXSEISelLowering.cpp
├── MYRISCVXSEISelLowering.h
├── MYRISCVXSEInstrInfo.cpp
├── MYRISCVXSEInstrInfo.h
├── MYRISCVXSERegisterInfo.cpp
├── MYRISCVXSERegisterInfo.h
├── MYRISCVXSchedule.td
├── MYRISCVXSubtarget.cpp
├── MYRISCVXSubtarget.h
├── MYRISCVXTargetMachine.cpp
├── MYRISCVXTargetMachine.h
├── MYRISCVXTargetObjectFile.cpp
├── MYRISCVXTargetObjectFile.h
└── TargetInfo
├── CMakeLists.txt
├── LLVMBuild.txt
└── MYRISCVXTargetInfo.cpp
TargetInfo/MYRISCVXTargetInfo.cpp
Targetを32bitと64bitの2つ登録する。どちらともリトルエンディアン。
- extern Target TheMYRISCVXTarget; - extern Target TheMYRISCVXelTarget; + extern Target TheMYRISCVX32Target; + extern Target TheMYRISCVX64Target; -Target llvm::TheMYRISCVX32Target, llvm::TheMYRISCVX64Target; +namespace llvm { +Target TheMYRISCVX32Target; +Target TheMYRISCVX64Target; +}
MYRISCVXTargetObjectFile.{h, cpp}
SmallDataSectionとBSSDataSectionを定義している。あとMYRISCVXTargetMachineオブジェクト。
SmallDataSectionのスレッショルド値は8と設定されている?
SSThreshold("MYRISCVX-ssection-threshold", cl::Hidden, cl::desc("Small data and bss section threshold size (default=8)"), cl::init(8));
Initializeにおいて、
- ELFの初期化 (
InitializeELF()) - SmallSection の初期化 (.sdata)
ELF::SHT_PROGBITS,ELF::SHF_WRITE | ELF::SHF_ALLOC - SmallBSSSectionの初期化 (.sbss)
ELF::SHT_NOBITS,ELF::SHF_WRITE | ELF::SHF_ALLOC
MYRISCVXTargetMachine.{h, cpp}
isLittleという変数により、BigEndianとLittleEndianを判定する。
LLVMInitializeMYRISCVXTargetが定義され、BigEndian版とLittleEndian版が定義されるようだが、LittleEndianしか必要ない?というか、isLittleも必要ないのでMYRISCVXTargetMachineのみ定義することにした。
MYRISCVXTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Optional<Reloc::Model> RM, CodeModel::Model CM, CodeGenOpt::Level OL);
MYRISCVX{SE}FrameLowering.{h,cpp}
MYRISCVXのフレームを定義する。SEは32bit用という通例となっている。
とりあえず形だけ。
MYRISCVXSelILowering.{h,cpp}
LLVM IRをSelection DAGに変換する。
