Module generation stubs

This commit is contained in:
Dani Messerman 2015-04-27 19:18:35 +03:00
parent 5c27161b23
commit 6c7551d5f3
5 changed files with 114 additions and 14 deletions

View File

@ -1,9 +1,11 @@
set(SRCS
main.cpp
CodeGen.cpp
ModuleGen.cpp
)
set(HEADERS
CodeGen.h
ModuleGen.h
)
create_directory_groups(${SRCS} ${HEADERS})

View File

@ -1,5 +1,8 @@
#include "CodeGen.h"
#include "ModuleGen.h"
#include "core/loader/loader.h"
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/Host.h>
#include <llvm/Target/TargetSubtargetInfo.h>
@ -61,12 +64,12 @@ void CodeGen::IntializeLLVM()
module = make_unique<Module>("Module", getGlobalContext());
module->setTargetTriple(triple_string);
ir_builder = make_unique<IRBuilder<>>(getGlobalContext());
}
void CodeGen::GenerateModule()
{
// TODO:
moduleGenerator = std::make_unique<ModuleGen>(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");
}

View File

@ -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<ModuleGen> moduleGenerator;
std::unique_ptr<llvm::Triple> triple;
std::unique_ptr<llvm::TargetMachine> target_machine;
std::unique_ptr<llvm::Module> module;
std::unique_ptr<llvm::IRBuilder<>> ir_builder;
};

View File

@ -0,0 +1,52 @@
#include "ModuleGen.h"
#include <llvm/IR/Function.h>
#include <llvm/IR/GlobalVariable.h>
using namespace llvm;
ModuleGen::ModuleGen(llvm::Module* module)
: module(module)
{
ir_builder = make_unique<IRBuilder<>>(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();
}

View File

@ -0,0 +1,43 @@
#include <llvm/IR/IRBuilder.h>
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<llvm::IRBuilder<>> 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;
};