Massive refactoring of all code + audio skeleton.
This should make it easier to find files and (in the future) split things up into separate libraries. It also changes around emulator initialization to make it a little more difficult to do things out of order and a little more sensible as to when real init work happens. Also adding a skeleton audio system/driver and reworking CPU register access to be more extensible.
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
|
||||
#include <xenia/common.h>
|
||||
|
||||
#include <xenia/core/memory.h>
|
||||
#include <xenia/memory.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
|
||||
@@ -16,11 +16,10 @@
|
||||
using namespace xe;
|
||||
using namespace xe::cpu;
|
||||
using namespace xe::cpu::sdb;
|
||||
using namespace xe::kernel;
|
||||
|
||||
|
||||
ExecModule::ExecModule(
|
||||
xe_memory_ref memory, shared_ptr<ExportResolver> export_resolver,
|
||||
xe_memory_ref memory, ExportResolver* export_resolver,
|
||||
SymbolTable* sym_table,
|
||||
const char* module_name, const char* module_path) {
|
||||
memory_ = xe_memory_retain(memory);
|
||||
@@ -42,7 +41,7 @@ SymbolDatabase* ExecModule::sdb() {
|
||||
|
||||
int ExecModule::PrepareRawBinary(uint32_t start_address, uint32_t end_address) {
|
||||
sdb_ = shared_ptr<sdb::SymbolDatabase>(
|
||||
new sdb::RawSymbolDatabase(memory_, export_resolver_.get(),
|
||||
new sdb::RawSymbolDatabase(memory_, export_resolver_,
|
||||
sym_table_, start_address, end_address));
|
||||
|
||||
code_addr_low_ = start_address;
|
||||
@@ -53,7 +52,7 @@ int ExecModule::PrepareRawBinary(uint32_t start_address, uint32_t end_address) {
|
||||
|
||||
int ExecModule::PrepareXexModule(xe_xex2_ref xex) {
|
||||
sdb_ = shared_ptr<sdb::SymbolDatabase>(
|
||||
new sdb::XexSymbolDatabase(memory_, export_resolver_.get(),
|
||||
new sdb::XexSymbolDatabase(memory_, export_resolver_,
|
||||
sym_table_, xex));
|
||||
|
||||
code_addr_low_ = UINT_MAX;
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/export_resolver.h>
|
||||
#include <xenia/cpu/sdb.h>
|
||||
#include <xenia/kernel/export.h>
|
||||
#include <xenia/kernel/xex2.h>
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace cpu {
|
||||
class ExecModule {
|
||||
public:
|
||||
ExecModule(
|
||||
xe_memory_ref memory, shared_ptr<kernel::ExportResolver> export_resolver,
|
||||
xe_memory_ref memory, ExportResolver* export_resolver,
|
||||
sdb::SymbolTable* sym_table,
|
||||
const char* module_name, const char* module_path);
|
||||
~ExecModule();
|
||||
@@ -43,11 +43,11 @@ private:
|
||||
int Prepare();
|
||||
int Init();
|
||||
|
||||
xe_memory_ref memory_;
|
||||
shared_ptr<kernel::ExportResolver> export_resolver_;
|
||||
sdb::SymbolTable* sym_table_;
|
||||
char* module_name_;
|
||||
char* module_path_;
|
||||
xe_memory_ref memory_;
|
||||
ExportResolver* export_resolver_;
|
||||
sdb::SymbolTable* sym_table_;
|
||||
char* module_name_;
|
||||
char* module_path_;
|
||||
|
||||
shared_ptr<sdb::SymbolDatabase> sdb_;
|
||||
uint32_t code_addr_low_;
|
||||
|
||||
@@ -15,13 +15,12 @@
|
||||
#include <xenia/cpu/sdb.h>
|
||||
#include <xenia/cpu/ppc/instr.h>
|
||||
#include <xenia/cpu/ppc/state.h>
|
||||
#include <xenia/kernel/export.h>
|
||||
#include <xenia/export_resolver.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::cpu;
|
||||
using namespace xe::cpu::sdb;
|
||||
using namespace xe::kernel;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/export_resolver.h>
|
||||
#include <xenia/cpu/ppc/state.h>
|
||||
#include <xenia/cpu/sdb/symbol.h>
|
||||
#include <xenia/kernel/export.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
@@ -33,7 +33,7 @@ typedef struct {
|
||||
xe_ppc_state_t* state, uint64_t cia, uint64_t ea);
|
||||
void (_cdecl *XeTraceKernelCall)(
|
||||
xe_ppc_state_t* state, uint64_t cia, uint64_t call_ia,
|
||||
kernel::KernelExport* kernel_export);
|
||||
KernelExport* kernel_export);
|
||||
void (_cdecl *XeTraceUserCall)(
|
||||
xe_ppc_state_t* state, uint64_t cia, uint64_t call_ia,
|
||||
sdb::FunctionSymbol* fn);
|
||||
|
||||
@@ -30,8 +30,8 @@ public:
|
||||
}
|
||||
|
||||
virtual int Setup() = 0;
|
||||
virtual void SetupGpuPointers(void* gpu_this,
|
||||
void* gpu_read, void* gpu_write) = 0;
|
||||
virtual void AddRegisterAccessCallbacks(
|
||||
ppc::RegisterAccessCallbacks callbacks) = 0;
|
||||
|
||||
virtual int InitModule(ExecModule* module) = 0;
|
||||
virtual int UninitModule(ExecModule* module) = 0;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <xenia/common.h>
|
||||
|
||||
#include <xenia/cpu/ppc/instr.h>
|
||||
#include <xenia/cpu/ppc/registers.h>
|
||||
#include <xenia/cpu/ppc/state.h>
|
||||
|
||||
#endif // XENIA_CPU_PPC_H_
|
||||
|
||||
40
src/xenia/cpu/ppc/registers.h
Normal file
40
src/xenia/cpu/ppc/registers.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* 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_PPC_REGISTERS_H_
|
||||
#define XENIA_CPU_PPC_REGISTERS_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
namespace ppc {
|
||||
|
||||
|
||||
typedef bool (*RegisterHandlesCallback)(void* context, uint32_t addr);
|
||||
typedef uint64_t (*RegisterReadCallback)(void* context, uint32_t addr);
|
||||
typedef void (*RegisterWriteCallback)(void* context, uint32_t addr,
|
||||
uint64_t value);
|
||||
|
||||
|
||||
typedef struct {
|
||||
void* context;
|
||||
RegisterHandlesCallback handles;
|
||||
RegisterReadCallback read;
|
||||
RegisterWriteCallback write;
|
||||
} RegisterAccessCallbacks;
|
||||
|
||||
|
||||
} // namespace ppc
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_CPU_PPC_REGISTERS_H_
|
||||
@@ -10,6 +10,7 @@
|
||||
'instr.cc',
|
||||
'instr.h',
|
||||
'instr_tables.h',
|
||||
'registers.h',
|
||||
'state.cc',
|
||||
'state.h',
|
||||
],
|
||||
|
||||
@@ -13,12 +13,8 @@
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
class Processor;
|
||||
class ThreadState;
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
XEDECLARECLASS2(xe, cpu, Processor);
|
||||
XEDECLARECLASS2(xe, cpu, ThreadState);
|
||||
|
||||
|
||||
// namespace FPRF {
|
||||
|
||||
@@ -9,16 +9,15 @@
|
||||
|
||||
#include <xenia/cpu/processor.h>
|
||||
|
||||
#include <xenia/emulator.h>
|
||||
#include <xenia/cpu/jit.h>
|
||||
#include <xenia/cpu/ppc/disasm.h>
|
||||
#include <xenia/cpu/ppc/state.h>
|
||||
#include <xenia/gpu/graphics_system.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::cpu;
|
||||
using namespace xe::cpu::sdb;
|
||||
using namespace xe::kernel;
|
||||
|
||||
|
||||
namespace {
|
||||
@@ -46,11 +45,14 @@ namespace {
|
||||
}
|
||||
|
||||
|
||||
Processor::Processor(xe_memory_ref memory, shared_ptr<Backend> backend) :
|
||||
Processor::Processor(Emulator* emulator, Backend* backend) :
|
||||
sym_table_(NULL), jit_(NULL),
|
||||
interrupt_thread_lock_(NULL), interrupt_thread_state_(NULL) {
|
||||
memory_ = xe_memory_retain(memory);
|
||||
emulator_ = emulator;
|
||||
backend_ = backend;
|
||||
memory_ = xe_memory_retain(emulator->memory());
|
||||
export_resolver_ = emulator->export_resolver();
|
||||
|
||||
sym_lock_ = xe_mutex_alloc(10000);
|
||||
|
||||
InitializeIfNeeded();
|
||||
@@ -76,34 +78,9 @@ Processor::~Processor() {
|
||||
delete sym_table_;
|
||||
xe_mutex_free(sym_lock_);
|
||||
|
||||
graphics_system_.reset();
|
||||
export_resolver_.reset();
|
||||
backend_.reset();
|
||||
xe_memory_release(memory_);
|
||||
}
|
||||
|
||||
xe_memory_ref Processor::memory() {
|
||||
return xe_memory_retain(memory_);
|
||||
}
|
||||
|
||||
shared_ptr<gpu::GraphicsSystem> Processor::graphics_system() {
|
||||
return graphics_system_;
|
||||
}
|
||||
|
||||
void Processor::set_graphics_system(
|
||||
shared_ptr<gpu::GraphicsSystem> graphics_system) {
|
||||
graphics_system_ = graphics_system;
|
||||
}
|
||||
|
||||
shared_ptr<ExportResolver> Processor::export_resolver() {
|
||||
return export_resolver_;
|
||||
}
|
||||
|
||||
void Processor::set_export_resolver(
|
||||
shared_ptr<ExportResolver> export_resolver) {
|
||||
export_resolver_ = export_resolver;
|
||||
}
|
||||
|
||||
int Processor::Setup() {
|
||||
XEASSERTNULL(jit_);
|
||||
|
||||
@@ -121,15 +98,15 @@ int Processor::Setup() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
XEASSERTNOTNULL(graphics_system_.get());
|
||||
jit_->SetupGpuPointers(
|
||||
graphics_system_.get(),
|
||||
(void*)&xe::gpu::GraphicsSystem::ReadRegisterThunk,
|
||||
(void*)&xe::gpu::GraphicsSystem::WriteRegisterThunk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Processor::AddRegisterAccessCallbacks(
|
||||
ppc::RegisterAccessCallbacks callbacks) {
|
||||
XEASSERTNOTNULL(jit_);
|
||||
jit_->AddRegisterAccessCallbacks(callbacks);
|
||||
}
|
||||
|
||||
int Processor::LoadRawBinary(const xechar_t* path, uint32_t start_address) {
|
||||
ExecModule* exec_module = NULL;
|
||||
const xechar_t* name = xestrrchr(path, XE_PATH_SEPARATOR) + 1;
|
||||
|
||||
@@ -18,15 +18,10 @@
|
||||
#include <xenia/cpu/exec_module.h>
|
||||
#include <xenia/cpu/thread_state.h>
|
||||
#include <xenia/cpu/sdb/symbol_table.h>
|
||||
#include <xenia/kernel/export.h>
|
||||
#include <xenia/kernel/xex2.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
class GraphicsSystem;
|
||||
} // namespace gpu
|
||||
} // namespace xe
|
||||
XEDECLARECLASS1(xe, Emulator);
|
||||
XEDECLARECLASS1(xe, ExportResolver);
|
||||
|
||||
|
||||
namespace xe {
|
||||
@@ -37,17 +32,16 @@ class JIT;
|
||||
|
||||
class Processor {
|
||||
public:
|
||||
Processor(xe_memory_ref memory, shared_ptr<Backend> backend);
|
||||
Processor(Emulator* emulator, Backend* backend);
|
||||
~Processor();
|
||||
|
||||
xe_memory_ref memory();
|
||||
shared_ptr<gpu::GraphicsSystem> graphics_system();
|
||||
void set_graphics_system(shared_ptr<gpu::GraphicsSystem> graphics_system);
|
||||
shared_ptr<kernel::ExportResolver> export_resolver();
|
||||
void set_export_resolver(shared_ptr<kernel::ExportResolver> export_resolver);
|
||||
xe_memory_ref memory() const { return memory_; }
|
||||
ExportResolver* export_resolver() const { return export_resolver_; }
|
||||
|
||||
int Setup();
|
||||
|
||||
void AddRegisterAccessCallbacks(ppc::RegisterAccessCallbacks callbacks);
|
||||
|
||||
int LoadRawBinary(const xechar_t* path, uint32_t start_address);
|
||||
int LoadXexModule(const char* name, const char* path, xe_xex2_ref xex);
|
||||
|
||||
@@ -69,19 +63,19 @@ public:
|
||||
void* GetFunctionPointer(uint32_t address);
|
||||
|
||||
private:
|
||||
xe_memory_ref memory_;
|
||||
shared_ptr<Backend> backend_;
|
||||
shared_ptr<gpu::GraphicsSystem> graphics_system_;
|
||||
shared_ptr<kernel::ExportResolver> export_resolver_;
|
||||
Emulator* emulator_;
|
||||
Backend* backend_;
|
||||
xe_memory_ref memory_;
|
||||
ExportResolver* export_resolver_;
|
||||
|
||||
sdb::SymbolTable* sym_table_;
|
||||
JIT* jit_;
|
||||
sdb::SymbolTable* sym_table_;
|
||||
JIT* jit_;
|
||||
std::vector<ExecModule*> modules_;
|
||||
xe_mutex_t* sym_lock_;
|
||||
xe_mutex_t* sym_lock_;
|
||||
|
||||
xe_mutex_t* interrupt_thread_lock_;
|
||||
ThreadState* interrupt_thread_state_;
|
||||
uint32_t interrupt_thread_block_;
|
||||
xe_mutex_t* interrupt_thread_lock_;
|
||||
ThreadState* interrupt_thread_state_;
|
||||
uint32_t interrupt_thread_block_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ using namespace xe;
|
||||
using namespace xe::cpu;
|
||||
using namespace xe::cpu::ppc;
|
||||
using namespace xe::cpu::sdb;
|
||||
using namespace xe::kernel;
|
||||
|
||||
|
||||
RawSymbolDatabase::RawSymbolDatabase(
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace sdb {
|
||||
class RawSymbolDatabase : public SymbolDatabase {
|
||||
public:
|
||||
RawSymbolDatabase(xe_memory_ref memory,
|
||||
kernel::ExportResolver* export_resolver,
|
||||
ExportResolver* export_resolver,
|
||||
SymbolTable* sym_table,
|
||||
uint32_t start_address, uint32_t end_address);
|
||||
virtual ~RawSymbolDatabase();
|
||||
|
||||
@@ -17,7 +17,6 @@ using namespace xe;
|
||||
using namespace xe::cpu;
|
||||
using namespace xe::cpu::ppc;
|
||||
using namespace xe::cpu::sdb;
|
||||
using namespace xe::kernel;
|
||||
|
||||
|
||||
Symbol::Symbol(SymbolType type) :
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <xenia/kernel/export.h>
|
||||
#include <xenia/export_resolver.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
@@ -125,7 +125,7 @@ public:
|
||||
FunctionType type;
|
||||
uint32_t flags;
|
||||
|
||||
kernel::KernelExport* kernel_export;
|
||||
KernelExport* kernel_export;
|
||||
ExceptionEntrySymbol* ee;
|
||||
|
||||
// Implementation-specific value. This could be a JIT'ed function ref
|
||||
@@ -147,9 +147,9 @@ public:
|
||||
VariableSymbol();
|
||||
virtual ~VariableSymbol();
|
||||
|
||||
uint32_t address;
|
||||
uint32_t address;
|
||||
|
||||
kernel::KernelExport* kernel_export;
|
||||
KernelExport* kernel_export;
|
||||
};
|
||||
|
||||
class ExceptionEntrySymbol : public Symbol {
|
||||
|
||||
@@ -20,12 +20,12 @@ using namespace xe;
|
||||
using namespace xe::cpu;
|
||||
using namespace xe::cpu::ppc;
|
||||
using namespace xe::cpu::sdb;
|
||||
using namespace xe::kernel;
|
||||
|
||||
|
||||
SymbolDatabase::SymbolDatabase(xe_memory_ref memory,
|
||||
ExportResolver* export_resolver,
|
||||
SymbolTable* sym_table) {
|
||||
SymbolTable* sym_table) :
|
||||
function_count_(0), variable_count_(0) {
|
||||
memory_ = xe_memory_retain(memory);
|
||||
export_resolver_ = export_resolver;
|
||||
sym_table_ = sym_table;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <xenia/kernel/export.h>
|
||||
#include <xenia/export_resolver.h>
|
||||
#include <xenia/cpu/sdb/symbol.h>
|
||||
#include <xenia/cpu/sdb/symbol_table.h>
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace sdb {
|
||||
|
||||
class SymbolDatabase {
|
||||
public:
|
||||
SymbolDatabase(xe_memory_ref memory, kernel::ExportResolver* export_resolver,
|
||||
SymbolDatabase(xe_memory_ref memory, ExportResolver* export_resolver,
|
||||
SymbolTable* sym_table);
|
||||
virtual ~SymbolDatabase();
|
||||
|
||||
@@ -64,7 +64,7 @@ protected:
|
||||
virtual bool IsValueInTextRange(uint32_t value) = 0;
|
||||
|
||||
xe_memory_ref memory_;
|
||||
kernel::ExportResolver* export_resolver_;
|
||||
ExportResolver* export_resolver_;
|
||||
SymbolTable* sym_table_;
|
||||
size_t function_count_;
|
||||
size_t variable_count_;
|
||||
|
||||
@@ -17,7 +17,6 @@ using namespace xe;
|
||||
using namespace xe::cpu;
|
||||
using namespace xe::cpu::ppc;
|
||||
using namespace xe::cpu::sdb;
|
||||
using namespace xe::kernel;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace sdb {
|
||||
class XexSymbolDatabase : public SymbolDatabase {
|
||||
public:
|
||||
XexSymbolDatabase(xe_memory_ref memory,
|
||||
kernel::ExportResolver* export_resolver,
|
||||
ExportResolver* export_resolver,
|
||||
SymbolTable* sym_table, xe_xex2_ref xex);
|
||||
virtual ~XexSymbolDatabase();
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#include <xenia/cpu/thread_state.h>
|
||||
|
||||
#include <xenia/core/memory.h>
|
||||
#include <xenia/memory.h>
|
||||
#include <xenia/cpu/processor.h>
|
||||
|
||||
|
||||
|
||||
@@ -454,8 +454,8 @@ XEEMITTER(lwz, 0x80000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
|
||||
uint64_t constant_ea;
|
||||
if (i.D.RA && e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
|
||||
constant_ea += XEEXTS16(i.D.DS);
|
||||
if ((constant_ea & 0xFFFF0000) == 0x7FC80000) {
|
||||
GpVar reg(e.read_gpu_register((uint32_t)constant_ea));
|
||||
GpVar reg;
|
||||
if (e.check_constant_gpr_read((uint32_t)constant_ea, ®)) {
|
||||
e.update_gpr_value(i.D.RT, reg);
|
||||
e.clear_constant_gpr_value(i.D.RT);
|
||||
return 0;
|
||||
@@ -824,8 +824,7 @@ XEEMITTER(stw, 0x90000000, D )(X64Emitter& e, X86Compiler& c, InstrDat
|
||||
uint64_t constant_ea;
|
||||
if (i.D.RA && e.get_constant_gpr_value(i.D.RA, &constant_ea)) {
|
||||
constant_ea += XEEXTS16(i.D.DS);
|
||||
if ((constant_ea & 0xFFFF0000) == 0x7FC80000) {
|
||||
e.write_gpu_register((uint32_t)constant_ea, e.gpr_value(i.D.RT));
|
||||
if (e.check_constant_gpr_write((uint32_t)constant_ea, e.gpr_value(i.D.RT))) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,11 +94,9 @@ X64Emitter::~X64Emitter() {
|
||||
lock_ = NULL;
|
||||
}
|
||||
|
||||
void X64Emitter::SetupGpuPointers(void* gpu_this,
|
||||
void* gpu_read, void* gpu_write) {
|
||||
gpu_this_ = gpu_this;
|
||||
gpu_read_ = gpu_read;
|
||||
gpu_write_ = gpu_write;
|
||||
void X64Emitter::AddRegisterAccessCallbacks(
|
||||
RegisterAccessCallbacks callbacks) {
|
||||
access_callbacks_.push_back(callbacks);
|
||||
}
|
||||
|
||||
void X64Emitter::Lock() {
|
||||
@@ -1155,44 +1153,6 @@ int X64Emitter::GenerateIndirectionBranch(uint32_t cia, GpVar& target,
|
||||
return 0;
|
||||
}
|
||||
|
||||
GpVar X64Emitter::read_gpu_register(uint32_t r) {
|
||||
X86Compiler& c = compiler_;
|
||||
|
||||
GpVar this_imm(c.newGpVar());
|
||||
c.mov(this_imm, imm((uint64_t)gpu_this_));
|
||||
GpVar reg_imm(c.newGpVar());
|
||||
c.mov(reg_imm, imm(r & 0xFFFF));
|
||||
|
||||
X86CompilerFuncCall* call = c.call(gpu_read_);
|
||||
call->setPrototype(kX86FuncConvDefault,
|
||||
FuncBuilder2<uint64_t, void*, uint32_t>());
|
||||
call->setArgument(0, this_imm);
|
||||
call->setArgument(1, reg_imm);
|
||||
GpVar res(c.newGpVar());
|
||||
call->setReturn(res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void X64Emitter::write_gpu_register(uint32_t r, GpVar& v) {
|
||||
X86Compiler& c = compiler_;
|
||||
|
||||
GpVar this_imm(c.newGpVar());
|
||||
c.alloc(this_imm, rcx);
|
||||
c.mov(this_imm, imm((uint64_t)gpu_this_));
|
||||
GpVar reg_imm(c.newGpVar());
|
||||
c.alloc(reg_imm, rdx);
|
||||
c.mov(reg_imm, imm(r & 0xFFFF));
|
||||
c.alloc(v, r8);
|
||||
|
||||
X86CompilerFuncCall* call = c.call(gpu_write_);
|
||||
call->setPrototype(kX86FuncConvDefault,
|
||||
FuncBuilder3<void, void*, uint32_t, uint64_t>());
|
||||
call->setArgument(0, this_imm);
|
||||
call->setArgument(1, reg_imm);
|
||||
call->setArgument(2, v);
|
||||
}
|
||||
|
||||
void X64Emitter::SetupLocals() {
|
||||
X86Compiler& c = compiler_;
|
||||
|
||||
@@ -1505,6 +1465,69 @@ void X64Emitter::clear_all_constant_gpr_values() {
|
||||
}
|
||||
}
|
||||
|
||||
bool X64Emitter::check_constant_gpr_read(uint32_t addr, GpVar* reg) {
|
||||
X86Compiler& c = compiler_;
|
||||
|
||||
for (std::vector<RegisterAccessCallbacks>::const_iterator it =
|
||||
access_callbacks_.begin(); it != access_callbacks_.end(); ++it) {
|
||||
if (!it->handles(it->context, addr)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
GpVar this_imm(c.newGpVar());
|
||||
c.mov(this_imm, imm((uint64_t)it->context));
|
||||
GpVar reg_imm(c.newGpVar());
|
||||
c.mov(reg_imm, imm(addr));
|
||||
|
||||
X86CompilerFuncCall* call = c.call(it->read);
|
||||
call->setPrototype(
|
||||
kX86FuncConvDefault,
|
||||
FuncBuilder2<uint64_t, void*, uint32_t>());
|
||||
call->setArgument(0, this_imm);
|
||||
call->setArgument(1, reg_imm);
|
||||
GpVar res(c.newGpVar());
|
||||
call->setReturn(res);
|
||||
*reg = res;
|
||||
|
||||
// Don't let the caller handle the write.
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool X64Emitter::check_constant_gpr_write(uint32_t addr, GpVar& reg) {
|
||||
X86Compiler& c = compiler_;
|
||||
|
||||
for (std::vector<RegisterAccessCallbacks>::const_iterator it =
|
||||
access_callbacks_.begin(); it != access_callbacks_.end(); ++it) {
|
||||
if (!it->handles(it->context, addr)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
GpVar this_imm(c.newGpVar());
|
||||
c.alloc(this_imm, rcx);
|
||||
c.mov(this_imm, imm((uint64_t)it->context));
|
||||
GpVar reg_imm(c.newGpVar());
|
||||
c.alloc(reg_imm, rdx);
|
||||
c.mov(reg_imm, imm(addr));
|
||||
c.alloc(reg, r8);
|
||||
|
||||
X86CompilerFuncCall* call = c.call(it->write);
|
||||
call->setPrototype(
|
||||
kX86FuncConvDefault,
|
||||
FuncBuilder3<void, void*, uint32_t, uint64_t>());
|
||||
call->setArgument(0, this_imm);
|
||||
call->setArgument(1, reg_imm);
|
||||
call->setArgument(2, reg);
|
||||
|
||||
// Don't let the caller handle the write.
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
GpVar X64Emitter::xer_value() {
|
||||
X86Compiler& c = compiler_;
|
||||
if (FLAGS_cache_registers) {
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
#define XENIA_CPU_X64_X64_EMITTER_H_
|
||||
|
||||
#include <xenia/cpu/global_exports.h>
|
||||
#include <xenia/cpu/ppc.h>
|
||||
#include <xenia/cpu/sdb.h>
|
||||
#include <xenia/cpu/ppc/instr.h>
|
||||
|
||||
#include <asmjit/asmjit.h>
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
X64Emitter(xe_memory_ref memory);
|
||||
~X64Emitter();
|
||||
|
||||
void SetupGpuPointers(void* gpu_this, void* gpu_read, void* gpu_write);
|
||||
void AddRegisterAccessCallbacks(ppc::RegisterAccessCallbacks callbacks);
|
||||
|
||||
void Lock();
|
||||
void Unlock();
|
||||
@@ -75,6 +75,9 @@ public:
|
||||
void clear_constant_gpr_value(uint32_t n);
|
||||
void clear_all_constant_gpr_values();
|
||||
|
||||
bool check_constant_gpr_read(uint32_t addr, AsmJit::GpVar* reg);
|
||||
bool check_constant_gpr_write(uint32_t addr, AsmJit::GpVar& reg);
|
||||
|
||||
AsmJit::GpVar xer_value();
|
||||
void update_xer_value(AsmJit::GpVar& value);
|
||||
void update_xer_with_overflow(AsmJit::GpVar& value);
|
||||
@@ -139,9 +142,7 @@ private:
|
||||
xe_mutex_t* lock_;
|
||||
uint32_t cpu_feature_mask_;
|
||||
|
||||
void* gpu_this_;
|
||||
void* gpu_read_;
|
||||
void* gpu_write_;
|
||||
std::vector<ppc::RegisterAccessCallbacks> access_callbacks_;
|
||||
|
||||
static uint64_t reserved_addr_;
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::cpu;
|
||||
using namespace xe::cpu::ppc;
|
||||
using namespace xe::cpu::sdb;
|
||||
using namespace xe::cpu::x64;
|
||||
|
||||
@@ -53,9 +54,8 @@ XECLEANUP:
|
||||
return result_code;
|
||||
}
|
||||
|
||||
void X64JIT::SetupGpuPointers(void* gpu_this,
|
||||
void* gpu_read, void* gpu_write) {
|
||||
emitter_->SetupGpuPointers(gpu_this, gpu_read, gpu_write);
|
||||
void X64JIT::AddRegisterAccessCallbacks(RegisterAccessCallbacks callbacks) {
|
||||
emitter_->AddRegisterAccessCallbacks(callbacks);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -29,8 +29,8 @@ public:
|
||||
virtual ~X64JIT();
|
||||
|
||||
virtual int Setup();
|
||||
virtual void SetupGpuPointers(void* gpu_this,
|
||||
void* gpu_read, void* gpu_write);
|
||||
virtual void AddRegisterAccessCallbacks(
|
||||
ppc::RegisterAccessCallbacks callbacks);
|
||||
|
||||
virtual int InitModule(ExecModule* module);
|
||||
virtual int UninitModule(ExecModule* module);
|
||||
|
||||
Reference in New Issue
Block a user