From 6c7551d5f3ca42bcbd26f09b4d5b90bf774ecba4 Mon Sep 17 00:00:00 2001 From: Dani Messerman Date: Mon, 27 Apr 2015 19:18:35 +0300 Subject: [PATCH] Module generation stubs --- src/binary_translation/CMakeLists.txt | 2 ++ src/binary_translation/CodeGen.cpp | 26 +++++++------- src/binary_translation/CodeGen.h | 5 ++- src/binary_translation/ModuleGen.cpp | 52 +++++++++++++++++++++++++++ src/binary_translation/ModuleGen.h | 43 ++++++++++++++++++++++ 5 files changed, 114 insertions(+), 14 deletions(-) create mode 100644 src/binary_translation/ModuleGen.cpp create mode 100644 src/binary_translation/ModuleGen.h diff --git a/src/binary_translation/CMakeLists.txt b/src/binary_translation/CMakeLists.txt index 198736c17..089e952b5 100644 --- a/src/binary_translation/CMakeLists.txt +++ b/src/binary_translation/CMakeLists.txt @@ -1,9 +1,11 @@ set(SRCS main.cpp CodeGen.cpp + ModuleGen.cpp ) set(HEADERS CodeGen.h + ModuleGen.h ) create_directory_groups(${SRCS} ${HEADERS}) diff --git a/src/binary_translation/CodeGen.cpp b/src/binary_translation/CodeGen.cpp index 5132846d0..6bad65d0c 100644 --- a/src/binary_translation/CodeGen.cpp +++ b/src/binary_translation/CodeGen.cpp @@ -1,5 +1,8 @@ #include "CodeGen.h" +#include "ModuleGen.h" + #include "core/loader/loader.h" + #include #include #include @@ -61,12 +64,12 @@ void CodeGen::IntializeLLVM() module = make_unique("Module", getGlobalContext()); module->setTargetTriple(triple_string); - ir_builder = make_unique>(getGlobalContext()); } void CodeGen::GenerateModule() { - // TODO: + moduleGenerator = std::make_unique(module.get()); + moduleGenerator->Run(); } void CodeGen::GenerateDebugFiles() @@ -83,6 +86,7 @@ void CodeGen::GenerateDebugFiles() raw_os_ostream stream(file); module->print(stream, nullptr); + stream.flush(); file.close(); LOG_INFO(BinaryTranslator, "Done"); } @@ -108,9 +112,14 @@ void CodeGen::OptimizeAndGenerate() PassManagerBuilder pass_manager_builder; FunctionPassManager function_pass_manager(module.get()); + PassManager pass_manager; module->setDataLayout(target_machine->getSubtargetImpl()->getDataLayout()); + pass_manager.add(createVerifierPass()); + pass_manager.add(new TargetLibraryInfo(*triple)); + pass_manager.add(new DataLayoutPass()); + target_machine->addAnalysisPasses(pass_manager); function_pass_manager.add(new DataLayoutPass()); target_machine->addAnalysisPasses(function_pass_manager); @@ -121,6 +130,7 @@ void CodeGen::OptimizeAndGenerate() pass_manager_builder.SLPVectorize = true; pass_manager_builder.populateFunctionPassManager(function_pass_manager); + pass_manager_builder.populateModulePassManager(pass_manager); LOG_INFO(BinaryTranslator, "Optimizing functions"); function_pass_manager.doInitialization(); @@ -129,18 +139,7 @@ void CodeGen::OptimizeAndGenerate() function_pass_manager.doFinalization(); LOG_INFO(BinaryTranslator, "Done"); - PassManager pass_manager; - pass_manager.add(createVerifierPass()); - pass_manager.add(new TargetLibraryInfo(*triple)); - pass_manager.add(new DataLayoutPass()); - target_machine->addAnalysisPasses(pass_manager); - pass_manager_builder.populateModulePassManager(pass_manager); - pass_manager.add(createVerifierPass()); - - LOG_INFO(BinaryTranslator, "Optimizing module"); - pass_manager.run(*module); - LOG_INFO(BinaryTranslator, "Done"); MCContext *context; std::ofstream file(output_object_filename, std::ios::binary); @@ -157,6 +156,7 @@ void CodeGen::OptimizeAndGenerate() } LOG_INFO(BinaryTranslator, "Generating code"); pass_manager.run(*module); + stream.flush(); file.close(); LOG_INFO(BinaryTranslator, "Done"); } \ No newline at end of file diff --git a/src/binary_translation/CodeGen.h b/src/binary_translation/CodeGen.h index 9f52eaca7..4a6b9e2dd 100644 --- a/src/binary_translation/CodeGen.h +++ b/src/binary_translation/CodeGen.h @@ -7,6 +7,8 @@ namespace llvm class Module; } +class ModuleGen; + /* * Holds alls the basic llvm structures */ @@ -26,8 +28,9 @@ private: const char *output_object_filename; const char *output_debug_filename; + std::unique_ptr moduleGenerator; + std::unique_ptr triple; std::unique_ptr target_machine; std::unique_ptr module; - std::unique_ptr> ir_builder; }; \ No newline at end of file diff --git a/src/binary_translation/ModuleGen.cpp b/src/binary_translation/ModuleGen.cpp new file mode 100644 index 000000000..044681602 --- /dev/null +++ b/src/binary_translation/ModuleGen.cpp @@ -0,0 +1,52 @@ +#include "ModuleGen.h" +#include +#include + +using namespace llvm; + +ModuleGen::ModuleGen(llvm::Module* module) + : module(module) +{ + ir_builder = make_unique>(getGlobalContext()); +} + +ModuleGen::~ModuleGen() +{ +} + +void ModuleGen::Run() +{ + GenerateGlobals(); + GenerateCanRunFunction(); + GenerateRunFunction(); +} + +void ModuleGen::GenerateGlobals() +{ + auto registers_global_initializer = ConstantPointerNull::get(IntegerType::getInt32PtrTy(getGlobalContext())); + registers_global = new GlobalVariable(*module, registers_global_initializer->getType(), false, GlobalValue::ExternalLinkage, registers_global_initializer, "Registers"); + + // Flags is stored internally as i1* indexed in multiples of 4 + auto flags_global_initializer = ConstantPointerNull::get(IntegerType::getInt1PtrTy(getGlobalContext())); + flags_global = new GlobalVariable(*module, flags_global_initializer->getType(), false, GlobalValue::ExternalLinkage, flags_global_initializer, "Flags"); +} + +void ModuleGen::GenerateCanRunFunction() +{ + auto can_run_function_type = FunctionType::get(ir_builder->getInt1Ty(), false); + can_run_function = Function::Create(can_run_function_type, GlobalValue::ExternalLinkage, "CanRun", module); + auto basic_block = BasicBlock::Create(getGlobalContext(), "Entry", can_run_function); + + ir_builder->SetInsertPoint(basic_block); + ir_builder->CreateRet(ir_builder->getInt1(false)); +} + +void ModuleGen::GenerateRunFunction() +{ + auto run_function_type = FunctionType::get(ir_builder->getVoidTy(), false); + run_function = Function::Create(run_function_type, GlobalValue::ExternalLinkage, "Run", module); + auto basic_block = BasicBlock::Create(getGlobalContext(), "Entry", run_function); + + ir_builder->SetInsertPoint(basic_block); + ir_builder->CreateRetVoid(); +} \ No newline at end of file diff --git a/src/binary_translation/ModuleGen.h b/src/binary_translation/ModuleGen.h new file mode 100644 index 000000000..1ed03fa47 --- /dev/null +++ b/src/binary_translation/ModuleGen.h @@ -0,0 +1,43 @@ +#include + +namespace llvm +{ + class Module; +} + +class ModuleGen +{ +public: + explicit ModuleGen(llvm::Module *module); + ~ModuleGen(); + + void Run(); + void GenerateGlobals(); + void GenerateCanRunFunction(); + void GenerateRunFunction(); +private: + std::unique_ptr> ir_builder; + llvm::Module *module; + + /* + * u32 *Registers; + * The registers of the cpu + */ + llvm::GlobalVariable *registers_global; + /* + * u32 *Flags; + * The flags of the cpu + * Orderered N, Z, C, V + */ + llvm::GlobalVariable *flags_global; + /* + * bool CanRun() + * Returns whether there is a binary translation available for a PC + */ + llvm::Function *can_run_function; + /* + * void Run() + * Runs binary translated opcodes + */ + llvm::Function *run_function; +}; \ No newline at end of file