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に変換する。