printInstruction()
などの命令プリントメソッドとMYRISCVXTargetMachine
との関連付けは、MCTargetDesc/MYRISCVXMCTargetDesc.cpp
で行われている。
llvm-myriscvx/lib/Target/MYRISCVX/MCTargetDesc/MYRISCVXMCTargetDesc.cpp
// MYRISCVXInstPrinterメソッドを返す。 static MCInstPrinter *createMYRISCVXMCInstPrinter(const Triple &T, unsigned SyntaxVariant, const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI) { return new MYRISCVXInstPrinter(MAI, MII, MRI); } extern "C" void LLVMInitializeMYRISCVXTargetMC() { for (Target *T : {&getTheMYRISCVX32Target(), &getTheMYRISCVX64Target()}) { // Register the MC asm info. RegisterMCAsmInfoFn X(*T, createMYRISCVXMCAsmInfo); // Register the MC instruction info. TargetRegistry::RegisterMCInstrInfo(*T, createMYRISCVXMCInstrInfo); // Register the MC register info. TargetRegistry::RegisterMCRegInfo(*T, createMYRISCVXMCRegisterInfo); // Register the MC subtarget info. TargetRegistry::RegisterMCSubtargetInfo(*T, createMYRISCVXMCSubtargetInfo); // Register the MC instruction analyzer. TargetRegistry::RegisterMCInstrAnalysis(*T, createMYRISCVXMCInstrAnalysis); // createMYRISCVXMCInstPrinterクラスを通じて、MYRISCVXInstPrintクラスを登録する。 TargetRegistry::RegisterMCInstPrinter(*T, createMYRISCVXMCInstPrinter); } }
このLLVMInitializeMYRISCVXTargetMC
では、各TargetMachineに必要な処理を登録している。
MYRISCVXは2つのTargetMachineMYRISCVX32TargetMachine
とMYRISCVX64TargetMachine
の2つがあるので、それぞれに命令を生成するためのメソッドを登録している。
RegisterMCAsmInfo
: アセンブリ言語生成のためのルーチンを登録する。ここで登録するルーチンはMYRISCVXMCAsmInfo
クラスをベースにして生成される。MYRISCVXAsmInfo()
では、アセンブリ出力時のファイルの先頭に出す基本的な情報を記載している。llvm-myriscvx/lib/Target/MYRISCVX/MCTargetDesc/MYRISCVXMCAsmInfo.cpp
MYRISCVXMCAsmInfo::MYRISCVXMCAsmInfo(const Triple &TheTriple) { AlignmentIsInBytes = false; Data16bitsDirective = "\t.2byte\t"; Data32bitsDirective = "\t.4byte\t"; Data64bitsDirective = "\t.8byte\t"; PrivateGlobalPrefix = "$"; // PrivateLabelPrefix: display $BB for the labels of basic block PrivateLabelPrefix = "$"; CommentString = "#"; ZeroDirective = "\t.space\t"; GPRel32Directive = "\t.gpword\t"; GPRel64Directive = "\t.gpdword\t"; WeakRefDirective = "\t.weak\t"; UseAssignmentForEHBegin = true; SupportsDebugInformation = true; ExceptionsType = ExceptionHandling::DwarfCFI; DwarfRegNumForCFI = true; }
RegisterMCInstrInfo
: MYRISCVXに属する命令に関する情報を持つクラスを登録する。ここで登録するクラスはMCInstrInfo
クラスだ。MCInstrInfo
クラスを生成し、MYRISCVXGenInstrInfo.inc
で生成したMYRISCVX命令群の基本情報を登録してTargetMachineに登録する。llvm-myriscvx/lib/Target/MYRISCVX/MCTargetDesc/MYRISCVXMCTargetDesc.cpp
static MCInstrInfo *createMYRISCVXMCInstrInfo() { MCInstrInfo *X = new MCInstrInfo(); InitMYRISCVXMCInstrInfo(X); // defined in MYRISCVXGenInstrInfo.inc return X; }
RegisterMCRegInfo
: MYRISCVXに属するレジスタの情報を持つクラスを登録する。ここで登録するクラスはMCRegisterInfo
クラスだ。MCRegisterInfo
クラスを生成し、MYRISCVXGenRegisterInfo.inc
d絵生成したMYRISCVXのレジスタ群の基本情報を追加してTargetMachineに登録する。llvm-myriscvx/lib/Target/MYRISCVX/MCTargetDesc/MYRISCVXMCTargetDesc.cpp
static MCRegisterInfo *createMYRISCVXMCRegisterInfo(const Triple &TT) { MCRegisterInfo *X = new MCRegisterInfo(); InitMYRISCVXMCRegisterInfo(X, MYRISCVX::RA); // defined in MYRISCVXGenRegisterInfo.inc return X; }
RegisterMCSubtargetInfo
: MYRISCVXに属するサブターゲットの情報を登録する。サブターゲットはMYRISCVXSubtarget.h
で登録したように、MYRISCVXの様々なアーキテクチャとCPUオプションを凝縮している。これらのサブターゲットの情報をTargetMachineに登録する。llvm-myriscvx/lib/Target/MYRISCVX/MCTargetDesc/MYRISCVXMCTargetDesc.cpp
static MCSubtargetInfo *createMYRISCVXMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) { std::string ArchFS = selectMYRISCVXArchFeature(TT, CPU); if (!FS.empty()) { if (!ArchFS.empty()) ArchFS = ArchFS + "," + FS.str(); else ArchFS = FS; } return createMYRISCVXMCSubtargetInfoImpl(TT, CPU, ArchFS); // createMYRISCVXMCSubtargetInfoImpl defined in MYRISCVXGenSubtargetInfo.inc }
RegisterMCInstrAnalysis
: MYRISCVXに関する命令解析の情報を登録する。この時点では特に命令解析に関して特別なことをする必要はないので、MCInstrAnalysis
クラスをそのまま継承してMYRISCVXInstrAnalysis
クラスを作成して登録している。llvm-myriscvx/lib/Target/MYRISCVX/MCTargetDesc/MYRISCVXMCTargetDesc.cpp
class MYRISCVXMCInstrAnalysis : public MCInstrAnalysis { public: MYRISCVXMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {} }; } static MCInstrAnalysis *createMYRISCVXMCInstrAnalysis(const MCInstrInfo *Info) { return new MYRISCVXMCInstrAnalysis(Info); }
RegisterMCInstPrinter
: 命令を出力するためのルーチンだ。MYRISCVXInstPrinter
クラスを生成してそのまま返する。TargetMachineにコンパイル後の命令をファイルに出力するためのルーチンを登録する。llvm-myriscvx/lib/Target/MYRISCVX/MCTargetDesc/MYRISCVXMCTargetDesc.cpp
static MCInstPrinter *createMYRISCVXMCInstPrinter(const Triple &T, unsigned SyntaxVariant, const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI) { return new MYRISCVXInstPrinter(MAI, MII, MRI); }