Removing old llvm cruft.
This commit is contained in:
parent
63cee87420
commit
86002b2f44
|
@ -1,151 +0,0 @@
|
||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
|
||||||
******************************************************************************
|
|
||||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xenia/cpu/codegen/module_generator.h>
|
|
||||||
|
|
||||||
#include <llvm/DIBuilder.h>
|
|
||||||
#include <llvm/Linker.h>
|
|
||||||
#include <llvm/PassManager.h>
|
|
||||||
#include <llvm/DebugInfo.h>
|
|
||||||
#include <llvm/Analysis/Verifier.h>
|
|
||||||
#include <llvm/ExecutionEngine/ExecutionEngine.h>
|
|
||||||
#include <llvm/IR/Attributes.h>
|
|
||||||
#include <llvm/IR/DataLayout.h>
|
|
||||||
#include <llvm/IR/DerivedTypes.h>
|
|
||||||
#include <llvm/IR/IRBuilder.h>
|
|
||||||
#include <llvm/IR/LLVMContext.h>
|
|
||||||
#include <llvm/IR/Module.h>
|
|
||||||
#include <llvm/Transforms/IPO.h>
|
|
||||||
#include <llvm/Transforms/IPO/PassManagerBuilder.h>
|
|
||||||
|
|
||||||
#include <xenia/cpu/cpu-private.h>
|
|
||||||
#include <xenia/cpu/ppc.h>
|
|
||||||
#include <xenia/cpu/codegen/function_generator.h>
|
|
||||||
|
|
||||||
// Build out all the user functions.
|
|
||||||
size_t n = 0;
|
|
||||||
XELOGI("Beginning generation of %ld functions...", functions.size());
|
|
||||||
for (std::map<uint32_t, CodegenFunction*>::iterator it =
|
|
||||||
functions_.begin(); it != functions_.end(); ++it, ++n) {
|
|
||||||
FunctionSymbol* symbol = it->second->symbol;
|
|
||||||
XELOGI("Generating %ld/%ld %.8X %s",
|
|
||||||
n, functions_.size(), symbol->start_address, symbol->name());
|
|
||||||
BuildFunction(it->second);
|
|
||||||
}
|
|
||||||
XELOGI("Function generation complete");
|
|
||||||
|
|
||||||
di_builder_->finalize();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModuleGenerator::AddFunctionsToMap(
|
|
||||||
std::tr1::unordered_map<uint32_t, llvm::Function*>& map) {
|
|
||||||
for (std::map<uint32_t, CodegenFunction*>::iterator it = functions_.begin();
|
|
||||||
it != functions_.end(); ++it) {
|
|
||||||
map.insert(std::pair<uint32_t, Function*>(it->first, it->second->function));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ModuleGenerator::AddMissingImport(FunctionSymbol* fn) {
|
|
||||||
Module *m = gen_module_;
|
|
||||||
LLVMContext& context = m->getContext();
|
|
||||||
|
|
||||||
// Create the function (and setup args/attributes/etc).
|
|
||||||
Function* f = CreateFunctionDefinition(fn->name());
|
|
||||||
|
|
||||||
BasicBlock* block = BasicBlock::Create(context, "entry", f);
|
|
||||||
IRBuilder<> b(block);
|
|
||||||
|
|
||||||
if (FLAGS_trace_kernel_calls) {
|
|
||||||
Value* traceKernelCall = m->getFunction("XeTraceKernelCall");
|
|
||||||
b.CreateCall4(
|
|
||||||
traceKernelCall,
|
|
||||||
f->arg_begin(),
|
|
||||||
b.getInt64(fn->start_address),
|
|
||||||
++f->arg_begin(),
|
|
||||||
b.getInt64((uint64_t)fn->kernel_export));
|
|
||||||
}
|
|
||||||
|
|
||||||
b.CreateRetVoid();
|
|
||||||
|
|
||||||
OptimizeFunction(m, f);
|
|
||||||
|
|
||||||
//GlobalAlias *alias = new GlobalAlias(f->getType(), GlobalValue::InternalLinkage, name, f, m);
|
|
||||||
// printf(" F %.8X %.8X %.3X (%3d) %s %s\n",
|
|
||||||
// info->value_address, info->thunk_address, info->ordinal,
|
|
||||||
// info->ordinal, implemented ? " " : "!!", name);
|
|
||||||
// For values:
|
|
||||||
// printf(" V %.8X %.3X (%3d) %s %s\n",
|
|
||||||
// info->value_address, info->ordinal, info->ordinal,
|
|
||||||
// implemented ? " " : "!!", name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModuleGenerator::AddPresentImport(FunctionSymbol* fn) {
|
|
||||||
Module *m = gen_module_;
|
|
||||||
LLVMContext& context = m->getContext();
|
|
||||||
|
|
||||||
const DataLayout* dl = engine_->getDataLayout();
|
|
||||||
Type* intPtrTy = dl->getIntPtrType(context);
|
|
||||||
Type* int8PtrTy = PointerType::getUnqual(Type::getInt8Ty(context));
|
|
||||||
|
|
||||||
// Add the externs.
|
|
||||||
// We have both the shim function pointer and the shim data pointer.
|
|
||||||
char shim_name[256];
|
|
||||||
xesnprintfa(shim_name, XECOUNT(shim_name),
|
|
||||||
"__shim_%s", fn->kernel_export->name);
|
|
||||||
char shim_data_name[256];
|
|
||||||
xesnprintfa(shim_data_name, XECOUNT(shim_data_name),
|
|
||||||
"__shim_data_%s", fn->kernel_export->name);
|
|
||||||
std::vector<Type*> shimArgs;
|
|
||||||
shimArgs.push_back(int8PtrTy);
|
|
||||||
shimArgs.push_back(int8PtrTy);
|
|
||||||
FunctionType* shimTy = FunctionType::get(
|
|
||||||
Type::getVoidTy(context), shimArgs, false);
|
|
||||||
Function* shim = Function::Create(
|
|
||||||
shimTy, Function::ExternalLinkage, shim_name, m);
|
|
||||||
|
|
||||||
GlobalVariable* gv = new GlobalVariable(
|
|
||||||
*m, int8PtrTy, true, GlobalValue::ExternalLinkage, 0,
|
|
||||||
shim_data_name);
|
|
||||||
|
|
||||||
// TODO(benvanik): don't initialize on startup - move to exec_module
|
|
||||||
gv->setInitializer(ConstantExpr::getIntToPtr(
|
|
||||||
ConstantInt::get(intPtrTy,
|
|
||||||
(uintptr_t)fn->kernel_export->function_data.shim_data),
|
|
||||||
int8PtrTy));
|
|
||||||
engine_->addGlobalMapping(shim,
|
|
||||||
(void*)fn->kernel_export->function_data.shim);
|
|
||||||
|
|
||||||
// Create the function (and setup args/attributes/etc).
|
|
||||||
Function* f = CreateFunctionDefinition(fn->name());
|
|
||||||
|
|
||||||
BasicBlock* block = BasicBlock::Create(context, "entry", f);
|
|
||||||
IRBuilder<> b(block);
|
|
||||||
|
|
||||||
if (FLAGS_trace_kernel_calls) {
|
|
||||||
Value* traceKernelCall = m->getFunction("XeTraceKernelCall");
|
|
||||||
b.CreateCall4(
|
|
||||||
traceKernelCall,
|
|
||||||
f->arg_begin(),
|
|
||||||
b.getInt64(fn->start_address),
|
|
||||||
++f->arg_begin(),
|
|
||||||
b.getInt64((uint64_t)fn->kernel_export));
|
|
||||||
}
|
|
||||||
|
|
||||||
b.CreateCall2(
|
|
||||||
shim,
|
|
||||||
f->arg_begin(),
|
|
||||||
b.CreateLoad(gv));
|
|
||||||
|
|
||||||
b.CreateRetVoid();
|
|
||||||
|
|
||||||
OptimizeFunction(m, f);
|
|
||||||
}
|
|
|
@ -1,91 +0,0 @@
|
||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
|
||||||
******************************************************************************
|
|
||||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef XENIA_CPU_CODEGEN_MODULE_GENERATOR_H_
|
|
||||||
#define XENIA_CPU_CODEGEN_MODULE_GENERATOR_H_
|
|
||||||
|
|
||||||
#include <xenia/common.h>
|
|
||||||
#include <xenia/core.h>
|
|
||||||
|
|
||||||
#include <xenia/cpu/sdb.h>
|
|
||||||
#include <xenia/core/memory.h>
|
|
||||||
#include <xenia/kernel/export.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace llvm {
|
|
||||||
class DIBuilder;
|
|
||||||
class ExecutionEngine;
|
|
||||||
class Function;
|
|
||||||
class FunctionType;
|
|
||||||
class LLVMContext;
|
|
||||||
class Module;
|
|
||||||
class MDNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
namespace xe {
|
|
||||||
namespace cpu {
|
|
||||||
namespace codegen {
|
|
||||||
|
|
||||||
|
|
||||||
class ModuleGenerator {
|
|
||||||
public:
|
|
||||||
ModuleGenerator(
|
|
||||||
xe_memory_ref memory, kernel::ExportResolver* export_resolver,
|
|
||||||
const char* module_name, const char* module_path,
|
|
||||||
sdb::SymbolDatabase* sdb,
|
|
||||||
llvm::LLVMContext* context, llvm::Module* gen_module,
|
|
||||||
llvm::ExecutionEngine* engine);
|
|
||||||
~ModuleGenerator();
|
|
||||||
|
|
||||||
int Generate();
|
|
||||||
|
|
||||||
void AddFunctionsToMap(
|
|
||||||
std::tr1::unordered_map<uint32_t, llvm::Function*>& map);
|
|
||||||
|
|
||||||
private:
|
|
||||||
class CodegenFunction {
|
|
||||||
public:
|
|
||||||
sdb::FunctionSymbol* symbol;
|
|
||||||
llvm::FunctionType* function_type;
|
|
||||||
llvm::Function* function;
|
|
||||||
};
|
|
||||||
|
|
||||||
CodegenFunction* GetCodegenFunction(uint32_t address);
|
|
||||||
|
|
||||||
void AddImports();
|
|
||||||
llvm::Function* CreateFunctionDefinition(const char* name);
|
|
||||||
void AddMissingImport(sdb::FunctionSymbol* fn);
|
|
||||||
void AddPresentImport(sdb::FunctionSymbol* fn);
|
|
||||||
void PrepareFunction(sdb::FunctionSymbol* fn);
|
|
||||||
void BuildFunction(CodegenFunction* cgf);
|
|
||||||
void OptimizeFunction(llvm::Module* m, llvm::Function* fn);
|
|
||||||
|
|
||||||
xe_memory_ref memory_;
|
|
||||||
kernel::ExportResolver* export_resolver_;
|
|
||||||
char* module_name_;
|
|
||||||
char* module_path_;
|
|
||||||
sdb::SymbolDatabase* sdb_;
|
|
||||||
|
|
||||||
llvm::LLVMContext* context_;
|
|
||||||
llvm::Module* gen_module_;
|
|
||||||
llvm::ExecutionEngine* engine_;
|
|
||||||
llvm::DIBuilder* di_builder_;
|
|
||||||
llvm::MDNode* cu_;
|
|
||||||
|
|
||||||
std::map<uint32_t, CodegenFunction*> functions_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace codegen
|
|
||||||
} // namespace cpu
|
|
||||||
} // namespace xe
|
|
||||||
|
|
||||||
|
|
||||||
#endif // XENIA_CPU_CODEGEN_MODULE_GENERATOR_H_
|
|
|
@ -1,121 +0,0 @@
|
||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
|
||||||
******************************************************************************
|
|
||||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xenia/cpu/codegen/recompiler.h>
|
|
||||||
|
|
||||||
#include <llvm/Linker.h>
|
|
||||||
#include <llvm/PassManager.h>
|
|
||||||
#include <llvm/Analysis/Verifier.h>
|
|
||||||
#include <llvm/Bitcode/ReaderWriter.h>
|
|
||||||
#include <llvm/ExecutionEngine/GenericValue.h>
|
|
||||||
#include <llvm/ExecutionEngine/ExecutionEngine.h>
|
|
||||||
#include <llvm/IR/Constants.h>
|
|
||||||
#include <llvm/IR/DataLayout.h>
|
|
||||||
#include <llvm/IR/DerivedTypes.h>
|
|
||||||
#include <llvm/IR/LLVMContext.h>
|
|
||||||
#include <llvm/IR/Module.h>
|
|
||||||
#include <llvm/Support/Host.h>
|
|
||||||
#include <llvm/Support/MemoryBuffer.h>
|
|
||||||
#include <llvm/Support/raw_ostream.h>
|
|
||||||
#include <llvm/Support/system_error.h>
|
|
||||||
#include <llvm/Support/Threading.h>
|
|
||||||
#include <llvm/Transforms/IPO.h>
|
|
||||||
#include <llvm/Transforms/IPO/PassManagerBuilder.h>
|
|
||||||
|
|
||||||
#include <xenia/cpu/cpu-private.h>
|
|
||||||
#include <xenia/cpu/llvm_exports.h>
|
|
||||||
#include <xenia/cpu/sdb.h>
|
|
||||||
#include <xenia/cpu/codegen/module_generator.h>
|
|
||||||
#include <xenia/cpu/ppc/instr.h>
|
|
||||||
#include <xenia/cpu/ppc/state.h>
|
|
||||||
|
|
||||||
|
|
||||||
using namespace llvm;
|
|
||||||
using namespace xe;
|
|
||||||
using namespace xe::cpu;
|
|
||||||
using namespace xe::cpu::codegen;
|
|
||||||
using namespace xe::cpu::sdb;
|
|
||||||
using namespace xe::kernel;
|
|
||||||
|
|
||||||
|
|
||||||
Recompiler::Recompiler(
|
|
||||||
xe_memory_ref memory, shared_ptr<ExportResolver> export_resolver,
|
|
||||||
shared_ptr<SymbolDatabase> sdb, const char* module_name) {
|
|
||||||
memory_ = xe_memory_retain(memory);
|
|
||||||
export_resolver_ = export_resolver;
|
|
||||||
sdb_ = sdb;
|
|
||||||
}
|
|
||||||
|
|
||||||
Recompiler::~Recompiler() {
|
|
||||||
xe_memory_release(memory_);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Recompiler::Process() {
|
|
||||||
// Check to see if a cached result exists on disk - if so, use it.
|
|
||||||
if (!LoadLibrary(library_path)) {
|
|
||||||
// Succeeded - done!
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate all the code and dump it to code units.
|
|
||||||
// This happens in multiple threads.
|
|
||||||
if (GenerateCodeUnits()) {
|
|
||||||
XELOGCPU("Failed to generate code units for module");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Link all of the generated code units. This runs any link-time optimizations
|
|
||||||
// and other per-library operations.
|
|
||||||
if (LinkCodeUnits()) {
|
|
||||||
XELOGCPU("Failed to link code units");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load the built library now.
|
|
||||||
if (LoadLibrary(library_path)) {
|
|
||||||
XELOGCPU("Failed to load the generated library");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Recompiler::GenerateCodeUnits() {
|
|
||||||
xe_system_info sys_info;
|
|
||||||
XEEXPECTZERO(xe_pal_get_system_info(&sys_info));
|
|
||||||
// sys_info.processors.physical_count;
|
|
||||||
// sys_info.processors.logical_count;
|
|
||||||
|
|
||||||
// Queue up all functions to process.
|
|
||||||
|
|
||||||
// Spawn worker threads to process the queue.
|
|
||||||
|
|
||||||
// Wait until all threads complete.
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
XECLEANUP:
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Recompiler::LinkCodeUnits() {
|
|
||||||
// Invoke linker.
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Recompiler::LoadLibrary(const char* path) {
|
|
||||||
// Check file exists.
|
|
||||||
|
|
||||||
// TODO(benvanik): version check somehow?
|
|
||||||
|
|
||||||
// Load library.
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
|
||||||
******************************************************************************
|
|
||||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef XENIA_CPU_CODEGEN_RECOMPILER_H_
|
|
||||||
#define XENIA_CPU_CODEGEN_RECOMPILER_H_
|
|
||||||
|
|
||||||
#include <xenia/core.h>
|
|
||||||
|
|
||||||
#include <xenia/cpu/ppc.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace xe {
|
|
||||||
namespace cpu {
|
|
||||||
namespace codegen {
|
|
||||||
|
|
||||||
|
|
||||||
class Recompiler {
|
|
||||||
public:
|
|
||||||
Recompiler(
|
|
||||||
xe_memory_ref memory, shared_ptr<kernel::ExportResolver> export_resolver,
|
|
||||||
shared_ptr<sdb::SymbolDatabase> sdb, const char* module_name);
|
|
||||||
~Recompiler();
|
|
||||||
|
|
||||||
int Process();
|
|
||||||
|
|
||||||
private:
|
|
||||||
int GenerateCodeUnits();
|
|
||||||
int LinkCodeUnits();
|
|
||||||
int LoadLibrary(const char* path);
|
|
||||||
|
|
||||||
xechar_t* library_path_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace codegen
|
|
||||||
} // namespace cpu
|
|
||||||
} // namespace xe
|
|
||||||
|
|
||||||
|
|
||||||
#endif // XENIA_CPU_CODEGEN_RECOMPILER_H_
|
|
Loading…
Reference in New Issue