mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-24 14:51:04 +00:00
Module generation stubs
This commit is contained in:
parent
5c27161b23
commit
6c7551d5f3
@ -1,9 +1,11 @@
|
|||||||
set(SRCS
|
set(SRCS
|
||||||
main.cpp
|
main.cpp
|
||||||
CodeGen.cpp
|
CodeGen.cpp
|
||||||
|
ModuleGen.cpp
|
||||||
)
|
)
|
||||||
set(HEADERS
|
set(HEADERS
|
||||||
CodeGen.h
|
CodeGen.h
|
||||||
|
ModuleGen.h
|
||||||
)
|
)
|
||||||
|
|
||||||
create_directory_groups(${SRCS} ${HEADERS})
|
create_directory_groups(${SRCS} ${HEADERS})
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
#include "CodeGen.h"
|
#include "CodeGen.h"
|
||||||
|
#include "ModuleGen.h"
|
||||||
|
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
|
|
||||||
#include <llvm/Support/TargetSelect.h>
|
#include <llvm/Support/TargetSelect.h>
|
||||||
#include <llvm/Support/Host.h>
|
#include <llvm/Support/Host.h>
|
||||||
#include <llvm/Target/TargetSubtargetInfo.h>
|
#include <llvm/Target/TargetSubtargetInfo.h>
|
||||||
@ -61,12 +64,12 @@ void CodeGen::IntializeLLVM()
|
|||||||
|
|
||||||
module = make_unique<Module>("Module", getGlobalContext());
|
module = make_unique<Module>("Module", getGlobalContext());
|
||||||
module->setTargetTriple(triple_string);
|
module->setTargetTriple(triple_string);
|
||||||
ir_builder = make_unique<IRBuilder<>>(getGlobalContext());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGen::GenerateModule()
|
void CodeGen::GenerateModule()
|
||||||
{
|
{
|
||||||
// TODO:
|
moduleGenerator = std::make_unique<ModuleGen>(module.get());
|
||||||
|
moduleGenerator->Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGen::GenerateDebugFiles()
|
void CodeGen::GenerateDebugFiles()
|
||||||
@ -83,6 +86,7 @@ void CodeGen::GenerateDebugFiles()
|
|||||||
raw_os_ostream stream(file);
|
raw_os_ostream stream(file);
|
||||||
|
|
||||||
module->print(stream, nullptr);
|
module->print(stream, nullptr);
|
||||||
|
stream.flush();
|
||||||
file.close();
|
file.close();
|
||||||
LOG_INFO(BinaryTranslator, "Done");
|
LOG_INFO(BinaryTranslator, "Done");
|
||||||
}
|
}
|
||||||
@ -108,9 +112,14 @@ void CodeGen::OptimizeAndGenerate()
|
|||||||
PassManagerBuilder pass_manager_builder;
|
PassManagerBuilder pass_manager_builder;
|
||||||
|
|
||||||
FunctionPassManager function_pass_manager(module.get());
|
FunctionPassManager function_pass_manager(module.get());
|
||||||
|
PassManager pass_manager;
|
||||||
|
|
||||||
module->setDataLayout(target_machine->getSubtargetImpl()->getDataLayout());
|
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());
|
function_pass_manager.add(new DataLayoutPass());
|
||||||
target_machine->addAnalysisPasses(function_pass_manager);
|
target_machine->addAnalysisPasses(function_pass_manager);
|
||||||
|
|
||||||
@ -121,6 +130,7 @@ void CodeGen::OptimizeAndGenerate()
|
|||||||
pass_manager_builder.SLPVectorize = true;
|
pass_manager_builder.SLPVectorize = true;
|
||||||
|
|
||||||
pass_manager_builder.populateFunctionPassManager(function_pass_manager);
|
pass_manager_builder.populateFunctionPassManager(function_pass_manager);
|
||||||
|
pass_manager_builder.populateModulePassManager(pass_manager);
|
||||||
|
|
||||||
LOG_INFO(BinaryTranslator, "Optimizing functions");
|
LOG_INFO(BinaryTranslator, "Optimizing functions");
|
||||||
function_pass_manager.doInitialization();
|
function_pass_manager.doInitialization();
|
||||||
@ -129,18 +139,7 @@ void CodeGen::OptimizeAndGenerate()
|
|||||||
function_pass_manager.doFinalization();
|
function_pass_manager.doFinalization();
|
||||||
LOG_INFO(BinaryTranslator, "Done");
|
LOG_INFO(BinaryTranslator, "Done");
|
||||||
|
|
||||||
PassManager pass_manager;
|
|
||||||
|
|
||||||
pass_manager.add(createVerifierPass());
|
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;
|
MCContext *context;
|
||||||
std::ofstream file(output_object_filename, std::ios::binary);
|
std::ofstream file(output_object_filename, std::ios::binary);
|
||||||
@ -157,6 +156,7 @@ void CodeGen::OptimizeAndGenerate()
|
|||||||
}
|
}
|
||||||
LOG_INFO(BinaryTranslator, "Generating code");
|
LOG_INFO(BinaryTranslator, "Generating code");
|
||||||
pass_manager.run(*module);
|
pass_manager.run(*module);
|
||||||
|
stream.flush();
|
||||||
file.close();
|
file.close();
|
||||||
LOG_INFO(BinaryTranslator, "Done");
|
LOG_INFO(BinaryTranslator, "Done");
|
||||||
}
|
}
|
@ -7,6 +7,8 @@ namespace llvm
|
|||||||
class Module;
|
class Module;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ModuleGen;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Holds alls the basic llvm structures
|
* Holds alls the basic llvm structures
|
||||||
*/
|
*/
|
||||||
@ -26,8 +28,9 @@ private:
|
|||||||
const char *output_object_filename;
|
const char *output_object_filename;
|
||||||
const char *output_debug_filename;
|
const char *output_debug_filename;
|
||||||
|
|
||||||
|
std::unique_ptr<ModuleGen> moduleGenerator;
|
||||||
|
|
||||||
std::unique_ptr<llvm::Triple> triple;
|
std::unique_ptr<llvm::Triple> triple;
|
||||||
std::unique_ptr<llvm::TargetMachine> target_machine;
|
std::unique_ptr<llvm::TargetMachine> target_machine;
|
||||||
std::unique_ptr<llvm::Module> module;
|
std::unique_ptr<llvm::Module> module;
|
||||||
std::unique_ptr<llvm::IRBuilder<>> ir_builder;
|
|
||||||
};
|
};
|
52
src/binary_translation/ModuleGen.cpp
Normal file
52
src/binary_translation/ModuleGen.cpp
Normal 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();
|
||||||
|
}
|
43
src/binary_translation/ModuleGen.h
Normal file
43
src/binary_translation/ModuleGen.h
Normal 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;
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user