x64 emitter now generating redirection blocks and patching them up.
This commit is contained in:
parent
12444f6305
commit
d7d0b94aab
|
@ -125,8 +125,9 @@ public:
|
||||||
ExceptionEntrySymbol* ee;
|
ExceptionEntrySymbol* ee;
|
||||||
|
|
||||||
// Implementation-specific value. This could be a JIT'ed function ref
|
// Implementation-specific value. This could be a JIT'ed function ref
|
||||||
// or some other structure. Never freed.
|
// or some other structure. Never freed by the SDB.
|
||||||
void* impl_value;
|
void* impl_value;
|
||||||
|
size_t impl_size;
|
||||||
|
|
||||||
std::vector<FunctionCall> incoming_calls;
|
std::vector<FunctionCall> incoming_calls;
|
||||||
std::vector<FunctionCall> outgoing_calls;
|
std::vector<FunctionCall> outgoing_calls;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -22,19 +22,24 @@ namespace cpu {
|
||||||
namespace x64 {
|
namespace x64 {
|
||||||
|
|
||||||
|
|
||||||
|
// Typedef for all generated functions.
|
||||||
|
typedef void (*x64_function_t)(xe_ppc_state_t* ppc_state, uint64_t lr);
|
||||||
|
|
||||||
|
|
||||||
class X64Emitter {
|
class X64Emitter {
|
||||||
public:
|
public:
|
||||||
X64Emitter(xe_memory_ref memory);
|
X64Emitter(xe_memory_ref memory);
|
||||||
~X64Emitter();
|
~X64Emitter();
|
||||||
|
|
||||||
// jit_context_t context();
|
void Lock();
|
||||||
|
void Unlock();
|
||||||
|
|
||||||
// int PrepareFunction(sdb::FunctionSymbol* symbol);
|
int PrepareFunction(sdb::FunctionSymbol* symbol);
|
||||||
// int MakeFunction(sdb::FunctionSymbol* symbol, jit_function_t fn);
|
int MakeFunction(sdb::FunctionSymbol* symbol);
|
||||||
|
|
||||||
// sdb::FunctionSymbol* symbol();
|
AsmJit::X86Compiler& compiler();
|
||||||
// jit_function_t fn();
|
sdb::FunctionSymbol* symbol();
|
||||||
// sdb::FunctionBlock* fn_block();
|
sdb::FunctionBlock* fn_block();
|
||||||
|
|
||||||
// jit_value_t get_int32(int32_t value);
|
// jit_value_t get_int32(int32_t value);
|
||||||
// jit_value_t get_uint32(uint32_t value);
|
// jit_value_t get_uint32(uint32_t value);
|
||||||
|
@ -58,7 +63,8 @@ public:
|
||||||
// int call_function(sdb::FunctionSymbol* target_symbol, jit_value_t lr,
|
// int call_function(sdb::FunctionSymbol* target_symbol, jit_value_t lr,
|
||||||
// bool tail);
|
// bool tail);
|
||||||
|
|
||||||
// void TraceBranch(uint32_t cia);
|
void TraceBranch(uint32_t cia);
|
||||||
|
|
||||||
// int GenerateIndirectionBranch(uint32_t cia, jit_value_t target,
|
// int GenerateIndirectionBranch(uint32_t cia, jit_value_t target,
|
||||||
// bool lk, bool likely_local);
|
// bool lk, bool likely_local);
|
||||||
|
|
||||||
|
@ -67,8 +73,8 @@ public:
|
||||||
// void StoreStateValue(size_t offset, jit_type_t type, jit_value_t value);
|
// void StoreStateValue(size_t offset, jit_type_t type, jit_value_t value);
|
||||||
|
|
||||||
// jit_value_t SetupLocal(jit_type_t type, const char* name);
|
// jit_value_t SetupLocal(jit_type_t type, const char* name);
|
||||||
// void FillRegisters();
|
void FillRegisters();
|
||||||
// void SpillRegisters();
|
void SpillRegisters();
|
||||||
|
|
||||||
// jit_value_t xer_value();
|
// jit_value_t xer_value();
|
||||||
// void update_xer_value(jit_value_t value);
|
// void update_xer_value(jit_value_t value);
|
||||||
|
@ -100,38 +106,36 @@ public:
|
||||||
// bool release = false);
|
// bool release = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// int MakeUserFunction();
|
static void* OnDemandCompileTrampoline(
|
||||||
// int MakePresentImportFunction();
|
X64Emitter* emitter, sdb::FunctionSymbol* symbol);
|
||||||
// int MakeMissingImportFunction();
|
void* OnDemandCompile(sdb::FunctionSymbol* symbol);
|
||||||
|
int MakeUserFunction();
|
||||||
|
int MakePresentImportFunction();
|
||||||
|
int MakeMissingImportFunction();
|
||||||
|
|
||||||
// void GenerateBasicBlocks();
|
void GenerateBasicBlocks();
|
||||||
// void GenerateSharedBlocks();
|
void GenerateSharedBlocks();
|
||||||
// int PrepareBasicBlock(sdb::FunctionBlock* block);
|
int PrepareBasicBlock(sdb::FunctionBlock* block);
|
||||||
// void GenerateBasicBlock(sdb::FunctionBlock* block);
|
void GenerateBasicBlock(sdb::FunctionBlock* block);
|
||||||
// void SetupLocals();
|
void SetupLocals();
|
||||||
|
|
||||||
xe_memory_ref memory_;
|
xe_memory_ref memory_;
|
||||||
GlobalExports global_exports_;
|
GlobalExports global_exports_;
|
||||||
|
xe_mutex_t* lock_;
|
||||||
|
|
||||||
// jit_type_t fn_signature_;
|
AsmJit::Logger* logger_;
|
||||||
// jit_type_t shim_signature_;
|
AsmJit::X86Assembler assembler_;
|
||||||
// jit_type_t global_export_signature_2_;
|
AsmJit::X86Compiler compiler_;
|
||||||
// jit_type_t global_export_signature_3_;
|
|
||||||
// jit_type_t global_export_signature_4_;
|
|
||||||
|
|
||||||
// sdb::FunctionSymbol* symbol_;
|
sdb::FunctionSymbol* symbol_;
|
||||||
// jit_function_t fn_;
|
sdb::FunctionBlock* fn_block_;
|
||||||
// sdb::FunctionBlock* fn_block_;
|
|
||||||
// jit_label_t return_block_;
|
// jit_label_t return_block_;
|
||||||
// jit_label_t internal_indirection_block_;
|
// jit_label_t internal_indirection_block_;
|
||||||
// jit_label_t external_indirection_block_;
|
// jit_label_t external_indirection_block_;
|
||||||
|
|
||||||
// std::map<uint32_t, jit_label_t> bbs_;
|
// std::map<uint32_t, jit_label_t> bbs_;
|
||||||
|
|
||||||
// // Address of the instruction being generated.
|
ppc::InstrAccessBits access_bits_;
|
||||||
// uint32_t cia_;
|
|
||||||
|
|
||||||
// ppc::InstrAccessBits access_bits_;
|
|
||||||
// struct {
|
// struct {
|
||||||
// jit_value_t indirection_target;
|
// jit_value_t indirection_target;
|
||||||
// jit_value_t indirection_cia;
|
// jit_value_t indirection_cia;
|
||||||
|
|
|
@ -125,6 +125,11 @@ int X64JIT::CheckProcessor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int X64JIT::InitModule(ExecModule* module) {
|
int X64JIT::InitModule(ExecModule* module) {
|
||||||
|
// TODO(benvanik): precompile interesting functions (kernel calls, etc).
|
||||||
|
// TODO(benvanik): warn on unimplemented instructions.
|
||||||
|
// TODO(benvanik): dump instruction use report.
|
||||||
|
// TODO(benvanik): dump kernel use report.
|
||||||
|
// TODO(benvanik): check for cached code/patches/etc.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,29 +140,22 @@ int X64JIT::UninitModule(ExecModule* module) {
|
||||||
int X64JIT::Execute(xe_ppc_state_t* ppc_state, FunctionSymbol* fn_symbol) {
|
int X64JIT::Execute(xe_ppc_state_t* ppc_state, FunctionSymbol* fn_symbol) {
|
||||||
XELOGCPU("Execute(%.8X): %s...", fn_symbol->start_address, fn_symbol->name());
|
XELOGCPU("Execute(%.8X): %s...", fn_symbol->start_address, fn_symbol->name());
|
||||||
|
|
||||||
// // Check function.
|
// Check function.
|
||||||
// jit_function_t jit_fn = (jit_function_t)fn_symbol->impl_value;
|
x64_function_t fn_ptr = (x64_function_t)fn_symbol->impl_value;
|
||||||
// if (!jit_fn) {
|
if (!fn_ptr) {
|
||||||
// // Function hasn't been prepped yet - prep it.
|
// Function hasn't been prepped yet - make it now inline.
|
||||||
// if (emitter_->PrepareFunction(fn_symbol)) {
|
// The emitter will lock and do other fancy things, if required.
|
||||||
// XELOGCPU("Execute(%.8X): unable to make function %s",
|
if (emitter_->PrepareFunction(fn_symbol)) {
|
||||||
// fn_symbol->start_address, fn_symbol->name());
|
XELOGCPU("Execute(%.8X): unable to make function %s",
|
||||||
// return 1;
|
fn_symbol->start_address, fn_symbol->name());
|
||||||
// }
|
return 1;
|
||||||
// jit_fn = (jit_function_t)fn_symbol->impl_value;
|
}
|
||||||
// XEASSERTNOTNULL(jit_fn);
|
fn_ptr = (x64_function_t)fn_symbol->impl_value;
|
||||||
// }
|
XEASSERTNOTNULL(fn_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
// // Call into the function. This will compile it if needed.
|
// Call into the function. This will compile it if needed.
|
||||||
// jit_nuint lr = ppc_state->lr;
|
fn_ptr(ppc_state, ppc_state->lr);
|
||||||
// void* args[] = {&ppc_state, &lr};
|
|
||||||
// uint64_t return_value;
|
|
||||||
// int apply_result = jit_function_apply(jit_fn, (void**)&args, &return_value);
|
|
||||||
// if (!apply_result) {
|
|
||||||
// XELOGCPU("Execute(%.8X): apply failed with %d",
|
|
||||||
// fn_symbol->start_address, apply_result);
|
|
||||||
// return 1;
|
|
||||||
// }
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,6 +104,7 @@ typedef XECACHEALIGN volatile void xe_aligned_void_t;
|
||||||
#define XEBITMASK(a, b) (((unsigned) -1 >> (31 - (b))) & ~((1U << (a)) - 1))
|
#define XEBITMASK(a, b) (((unsigned) -1 >> (31 - (b))) & ~((1U << (a)) - 1))
|
||||||
#define XESELECTBITS(value, a, b) ((value & XEBITMASK(a, b)) >> a)
|
#define XESELECTBITS(value, a, b) ((value & XEBITMASK(a, b)) >> a)
|
||||||
|
|
||||||
|
#define XESUCCEED() goto XECLEANUP
|
||||||
#define XEFAIL() goto XECLEANUP
|
#define XEFAIL() goto XECLEANUP
|
||||||
#define XEEXPECT(expr) if (!(expr) ) { goto XECLEANUP; }
|
#define XEEXPECT(expr) if (!(expr) ) { goto XECLEANUP; }
|
||||||
#define XEEXPECTTRUE(expr) if (!(expr) ) { goto XECLEANUP; }
|
#define XEEXPECTTRUE(expr) if (!(expr) ) { goto XECLEANUP; }
|
||||||
|
|
Loading…
Reference in New Issue