Moving cpu/runtime/ to cpu/.
This commit is contained in:
parent
29912f44c0
commit
9281d62106
|
@ -11,8 +11,7 @@
|
||||||
|
|
||||||
#include "xenia/emulator.h"
|
#include "xenia/emulator.h"
|
||||||
#include "xenia/cpu/processor.h"
|
#include "xenia/cpu/processor.h"
|
||||||
#include "xenia/cpu/xenon_thread_state.h"
|
#include "xenia/cpu/thread_state.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace xe;
|
using namespace xe;
|
||||||
using namespace xe::apu;
|
using namespace xe::apu;
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include "xenia/apu/audio_driver.h"
|
#include "xenia/apu/audio_driver.h"
|
||||||
#include "xenia/emulator.h"
|
#include "xenia/emulator.h"
|
||||||
#include "xenia/cpu/processor.h"
|
#include "xenia/cpu/processor.h"
|
||||||
#include "xenia/cpu/xenon_thread_state.h"
|
#include "xenia/cpu/thread_state.h"
|
||||||
|
|
||||||
// As with normal Microsoft, there are like twelve different ways to access
|
// As with normal Microsoft, there are like twelve different ways to access
|
||||||
// the audio APIs. Early games use XMA*() methods almost exclusively to touch
|
// the audio APIs. Early games use XMA*() methods almost exclusively to touch
|
||||||
|
@ -90,7 +90,7 @@ X_STATUS AudioSystem::Setup() {
|
||||||
|
|
||||||
// Setup worker thread state. This lets us make calls into guest code.
|
// Setup worker thread state. This lets us make calls into guest code.
|
||||||
thread_state_ =
|
thread_state_ =
|
||||||
new XenonThreadState(emulator_->processor()->runtime(), 0, 16 * 1024, 0);
|
new ThreadState(emulator_->processor()->runtime(), 0, 0, 16 * 1024, 0);
|
||||||
thread_state_->set_name("Audio Worker");
|
thread_state_->set_name("Audio Worker");
|
||||||
thread_block_ = (uint32_t)memory()->HeapAlloc(0, 2048, MEMORY_FLAG_ZERO);
|
thread_block_ = (uint32_t)memory()->HeapAlloc(0, 2048, MEMORY_FLAG_ZERO);
|
||||||
thread_state_->context()->r[13] = thread_block_;
|
thread_state_->context()->r[13] = thread_block_;
|
||||||
|
|
|
@ -75,7 +75,7 @@ class AudioSystem {
|
||||||
cpu::Processor* processor_;
|
cpu::Processor* processor_;
|
||||||
|
|
||||||
std::thread thread_;
|
std::thread thread_;
|
||||||
cpu::XenonThreadState* thread_state_;
|
cpu::ThreadState* thread_state_;
|
||||||
uint32_t thread_block_;
|
uint32_t thread_block_;
|
||||||
std::atomic<bool> running_;
|
std::atomic<bool> running_;
|
||||||
|
|
||||||
|
|
|
@ -14,15 +14,13 @@
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace hir {
|
|
||||||
class HIRBuilder;
|
|
||||||
} // namespace hir
|
|
||||||
namespace runtime {
|
|
||||||
class DebugInfo;
|
class DebugInfo;
|
||||||
class Function;
|
class Function;
|
||||||
class FunctionInfo;
|
class FunctionInfo;
|
||||||
class Runtime;
|
class Runtime;
|
||||||
} // namespace runtime
|
namespace hir {
|
||||||
|
class HIRBuilder;
|
||||||
|
} // namespace hir
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
|
@ -41,11 +39,10 @@ class Assembler {
|
||||||
|
|
||||||
virtual void Reset();
|
virtual void Reset();
|
||||||
|
|
||||||
virtual int Assemble(runtime::FunctionInfo* symbol_info,
|
virtual int Assemble(FunctionInfo* symbol_info, hir::HIRBuilder* builder,
|
||||||
hir::HIRBuilder* builder, uint32_t debug_info_flags,
|
uint32_t debug_info_flags,
|
||||||
std::unique_ptr<runtime::DebugInfo> debug_info,
|
std::unique_ptr<DebugInfo> debug_info,
|
||||||
uint32_t trace_flags,
|
uint32_t trace_flags, Function** out_function) = 0;
|
||||||
runtime::Function** out_function) = 0;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Backend* backend_;
|
Backend* backend_;
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
using xe::cpu::runtime::Runtime;
|
using xe::cpu::Runtime;
|
||||||
|
|
||||||
Backend::Backend(Runtime* runtime) : runtime_(runtime) {
|
Backend::Backend(Runtime* runtime) : runtime_(runtime) {
|
||||||
memset(&machine_info_, 0, sizeof(machine_info_));
|
memset(&machine_info_, 0, sizeof(machine_info_));
|
||||||
|
|
|
@ -16,9 +16,7 @@
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
class Runtime;
|
class Runtime;
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
|
@ -30,10 +28,10 @@ class Assembler;
|
||||||
|
|
||||||
class Backend {
|
class Backend {
|
||||||
public:
|
public:
|
||||||
Backend(runtime::Runtime* runtime);
|
Backend(Runtime* runtime);
|
||||||
virtual ~Backend();
|
virtual ~Backend();
|
||||||
|
|
||||||
runtime::Runtime* runtime() const { return runtime_; }
|
Runtime* runtime() const { return runtime_; }
|
||||||
const MachineInfo* machine_info() const { return &machine_info_; }
|
const MachineInfo* machine_info() const { return &machine_info_; }
|
||||||
|
|
||||||
virtual int Initialize();
|
virtual int Initialize();
|
||||||
|
@ -44,7 +42,7 @@ class Backend {
|
||||||
virtual std::unique_ptr<Assembler> CreateAssembler() = 0;
|
virtual std::unique_ptr<Assembler> CreateAssembler() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
runtime::Runtime* runtime_;
|
Runtime* runtime_;
|
||||||
MachineInfo machine_info_;
|
MachineInfo machine_info_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include "xenia/cpu/backend/x64/x64_function.h"
|
#include "xenia/cpu/backend/x64/x64_function.h"
|
||||||
#include "xenia/cpu/hir/hir_builder.h"
|
#include "xenia/cpu/hir/hir_builder.h"
|
||||||
#include "xenia/cpu/hir/label.h"
|
#include "xenia/cpu/hir/label.h"
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
#include "poly/reset_scope.h"
|
#include "poly/reset_scope.h"
|
||||||
#include "xenia/profiling.h"
|
#include "xenia/profiling.h"
|
||||||
|
|
||||||
|
@ -28,12 +28,9 @@ namespace backend {
|
||||||
namespace x64 {
|
namespace x64 {
|
||||||
|
|
||||||
// TODO(benvanik): remove when enums redefined.
|
// TODO(benvanik): remove when enums redefined.
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
|
|
||||||
using xe::cpu::hir::HIRBuilder;
|
using xe::cpu::hir::HIRBuilder;
|
||||||
using xe::cpu::runtime::DebugInfo;
|
|
||||||
using xe::cpu::runtime::Function;
|
|
||||||
using xe::cpu::runtime::FunctionInfo;
|
|
||||||
|
|
||||||
X64Assembler::X64Assembler(X64Backend* backend)
|
X64Assembler::X64Assembler(X64Backend* backend)
|
||||||
: Assembler(backend), x64_backend_(backend) {}
|
: Assembler(backend), x64_backend_(backend) {}
|
||||||
|
|
|
@ -33,13 +33,12 @@ class X64Assembler : public Assembler {
|
||||||
|
|
||||||
void Reset() override;
|
void Reset() override;
|
||||||
|
|
||||||
int Assemble(runtime::FunctionInfo* symbol_info, hir::HIRBuilder* builder,
|
int Assemble(FunctionInfo* symbol_info, hir::HIRBuilder* builder,
|
||||||
uint32_t debug_info_flags,
|
uint32_t debug_info_flags, std::unique_ptr<DebugInfo> debug_info,
|
||||||
std::unique_ptr<runtime::DebugInfo> debug_info,
|
uint32_t trace_flags, Function** out_function) override;
|
||||||
uint32_t trace_flags, runtime::Function** out_function) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void DumpMachineCode(runtime::DebugInfo* debug_info, void* machine_code,
|
void DumpMachineCode(DebugInfo* debug_info, void* machine_code,
|
||||||
size_t code_size, poly::StringBuffer* str);
|
size_t code_size, poly::StringBuffer* str);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace cpu {
|
||||||
namespace backend {
|
namespace backend {
|
||||||
namespace x64 {
|
namespace x64 {
|
||||||
|
|
||||||
using xe::cpu::runtime::Runtime;
|
using xe::cpu::Runtime;
|
||||||
|
|
||||||
X64Backend::X64Backend(Runtime* runtime) : Backend(runtime), code_cache_(0) {}
|
X64Backend::X64Backend(Runtime* runtime) : Backend(runtime), code_cache_(0) {}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ typedef void* (*GuestToHostThunk)(void* target, void* arg0, void* arg1);
|
||||||
|
|
||||||
class X64Backend : public Backend {
|
class X64Backend : public Backend {
|
||||||
public:
|
public:
|
||||||
X64Backend(runtime::Runtime* runtime);
|
X64Backend(Runtime* runtime);
|
||||||
~X64Backend() override;
|
~X64Backend() override;
|
||||||
|
|
||||||
X64CodeCache* code_cache() const { return code_cache_; }
|
X64CodeCache* code_cache() const { return code_cache_; }
|
||||||
|
|
|
@ -16,10 +16,10 @@
|
||||||
#include "xenia/cpu/backend/x64/x64_thunk_emitter.h"
|
#include "xenia/cpu/backend/x64/x64_thunk_emitter.h"
|
||||||
#include "xenia/cpu/cpu-private.h"
|
#include "xenia/cpu/cpu-private.h"
|
||||||
#include "xenia/cpu/hir/hir_builder.h"
|
#include "xenia/cpu/hir/hir_builder.h"
|
||||||
#include "xenia/cpu/runtime/debug_info.h"
|
#include "xenia/cpu/debug_info.h"
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
#include "xenia/cpu/runtime/symbol_info.h"
|
#include "xenia/cpu/symbol_info.h"
|
||||||
#include "xenia/cpu/runtime/thread_state.h"
|
#include "xenia/cpu/thread_state.h"
|
||||||
#include "poly/vec128.h"
|
#include "poly/vec128.h"
|
||||||
#include "xdb/protocol.h"
|
#include "xdb/protocol.h"
|
||||||
#include "xenia/profiling.h"
|
#include "xenia/profiling.h"
|
||||||
|
@ -31,7 +31,7 @@ namespace x64 {
|
||||||
|
|
||||||
// TODO(benvanik): remove when enums redefined.
|
// TODO(benvanik): remove when enums redefined.
|
||||||
using namespace xe::cpu::hir;
|
using namespace xe::cpu::hir;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
|
|
||||||
using poly::vec128b;
|
using poly::vec128b;
|
||||||
using poly::vec128f;
|
using poly::vec128f;
|
||||||
|
@ -40,10 +40,6 @@ using poly::vec128i;
|
||||||
using namespace Xbyak;
|
using namespace Xbyak;
|
||||||
using xe::cpu::hir::HIRBuilder;
|
using xe::cpu::hir::HIRBuilder;
|
||||||
using xe::cpu::hir::Instr;
|
using xe::cpu::hir::Instr;
|
||||||
using xe::cpu::runtime::Function;
|
|
||||||
using xe::cpu::runtime::FunctionInfo;
|
|
||||||
using xe::cpu::runtime::SourceMapEntry;
|
|
||||||
using xe::cpu::runtime::ThreadState;
|
|
||||||
|
|
||||||
static const size_t MAX_CODE_SIZE = 1 * 1024 * 1024;
|
static const size_t MAX_CODE_SIZE = 1 * 1024 * 1024;
|
||||||
|
|
||||||
|
@ -76,7 +72,7 @@ X64Emitter::~X64Emitter() {}
|
||||||
int X64Emitter::Initialize() { return 0; }
|
int X64Emitter::Initialize() { return 0; }
|
||||||
|
|
||||||
int X64Emitter::Emit(HIRBuilder* builder, uint32_t debug_info_flags,
|
int X64Emitter::Emit(HIRBuilder* builder, uint32_t debug_info_flags,
|
||||||
runtime::DebugInfo* debug_info, uint32_t trace_flags,
|
DebugInfo* debug_info, uint32_t trace_flags,
|
||||||
void*& out_code_address, size_t& out_code_size) {
|
void*& out_code_address, size_t& out_code_size) {
|
||||||
SCOPE_profile_cpu_f("cpu");
|
SCOPE_profile_cpu_f("cpu");
|
||||||
|
|
||||||
|
@ -439,8 +435,7 @@ uint64_t ResolveFunctionSymbol(void* raw_context, uint64_t symbol_info_ptr) {
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void X64Emitter::Call(const hir::Instr* instr,
|
void X64Emitter::Call(const hir::Instr* instr, FunctionInfo* symbol_info) {
|
||||||
runtime::FunctionInfo* symbol_info) {
|
|
||||||
auto fn = reinterpret_cast<X64Function*>(symbol_info->function());
|
auto fn = reinterpret_cast<X64Function*>(symbol_info->function());
|
||||||
// Resolve address to the function to call and store in rax.
|
// Resolve address to the function to call and store in rax.
|
||||||
if (fn) {
|
if (fn) {
|
||||||
|
|
|
@ -16,16 +16,14 @@
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace hir {
|
|
||||||
class HIRBuilder;
|
|
||||||
class Instr;
|
|
||||||
} // namespace hir
|
|
||||||
namespace runtime {
|
|
||||||
class DebugInfo;
|
class DebugInfo;
|
||||||
class FunctionInfo;
|
class FunctionInfo;
|
||||||
class Runtime;
|
class Runtime;
|
||||||
class SymbolInfo;
|
class SymbolInfo;
|
||||||
} // namespace runtime
|
namespace hir {
|
||||||
|
class HIRBuilder;
|
||||||
|
class Instr;
|
||||||
|
} // namespace hir
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
|
@ -103,14 +101,14 @@ class X64Emitter : public Xbyak::CodeGenerator {
|
||||||
X64Emitter(X64Backend* backend, XbyakAllocator* allocator);
|
X64Emitter(X64Backend* backend, XbyakAllocator* allocator);
|
||||||
virtual ~X64Emitter();
|
virtual ~X64Emitter();
|
||||||
|
|
||||||
runtime::Runtime* runtime() const { return runtime_; }
|
Runtime* runtime() const { return runtime_; }
|
||||||
X64Backend* backend() const { return backend_; }
|
X64Backend* backend() const { return backend_; }
|
||||||
|
|
||||||
int Initialize();
|
int Initialize();
|
||||||
|
|
||||||
int Emit(hir::HIRBuilder* builder, uint32_t debug_info_flags,
|
int Emit(hir::HIRBuilder* builder, uint32_t debug_info_flags,
|
||||||
runtime::DebugInfo* debug_info, uint32_t trace_flags,
|
DebugInfo* debug_info, uint32_t trace_flags, void*& out_code_address,
|
||||||
void*& out_code_address, size_t& out_code_size);
|
size_t& out_code_size);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Reserved: rsp
|
// Reserved: rsp
|
||||||
|
@ -149,10 +147,9 @@ class X64Emitter : public Xbyak::CodeGenerator {
|
||||||
void UnimplementedInstr(const hir::Instr* i);
|
void UnimplementedInstr(const hir::Instr* i);
|
||||||
void UnimplementedExtern(const hir::Instr* i);
|
void UnimplementedExtern(const hir::Instr* i);
|
||||||
|
|
||||||
void Call(const hir::Instr* instr, runtime::FunctionInfo* symbol_info);
|
void Call(const hir::Instr* instr, FunctionInfo* symbol_info);
|
||||||
void CallIndirect(const hir::Instr* instr, const Xbyak::Reg64& reg);
|
void CallIndirect(const hir::Instr* instr, const Xbyak::Reg64& reg);
|
||||||
void CallExtern(const hir::Instr* instr,
|
void CallExtern(const hir::Instr* instr, const FunctionInfo* symbol_info);
|
||||||
const runtime::FunctionInfo* symbol_info);
|
|
||||||
void CallNative(void* fn);
|
void CallNative(void* fn);
|
||||||
void CallNative(uint64_t (*fn)(void* raw_context));
|
void CallNative(uint64_t (*fn)(void* raw_context));
|
||||||
void CallNative(uint64_t (*fn)(void* raw_context, uint64_t arg0));
|
void CallNative(uint64_t (*fn)(void* raw_context, uint64_t arg0));
|
||||||
|
@ -191,7 +188,7 @@ class X64Emitter : public Xbyak::CodeGenerator {
|
||||||
void EmitTraceUserCallReturn();
|
void EmitTraceUserCallReturn();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
runtime::Runtime* runtime_;
|
Runtime* runtime_;
|
||||||
X64Backend* backend_;
|
X64Backend* backend_;
|
||||||
X64CodeCache* code_cache_;
|
X64CodeCache* code_cache_;
|
||||||
XbyakAllocator* allocator_;
|
XbyakAllocator* allocator_;
|
||||||
|
|
|
@ -10,19 +10,14 @@
|
||||||
#include "xenia/cpu/backend/x64/x64_function.h"
|
#include "xenia/cpu/backend/x64/x64_function.h"
|
||||||
|
|
||||||
#include "xenia/cpu/backend/x64/x64_backend.h"
|
#include "xenia/cpu/backend/x64/x64_backend.h"
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
#include "xenia/cpu/runtime/thread_state.h"
|
#include "xenia/cpu/thread_state.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace backend {
|
namespace backend {
|
||||||
namespace x64 {
|
namespace x64 {
|
||||||
|
|
||||||
using xe::cpu::runtime::Breakpoint;
|
|
||||||
using xe::cpu::runtime::Function;
|
|
||||||
using xe::cpu::runtime::FunctionInfo;
|
|
||||||
using xe::cpu::runtime::ThreadState;
|
|
||||||
|
|
||||||
X64Function::X64Function(FunctionInfo* symbol_info)
|
X64Function::X64Function(FunctionInfo* symbol_info)
|
||||||
: Function(symbol_info), machine_code_(nullptr), code_size_(0) {}
|
: Function(symbol_info), machine_code_(nullptr), code_size_(0) {}
|
||||||
|
|
||||||
|
|
|
@ -10,17 +10,18 @@
|
||||||
#ifndef XENIA_BACKEND_X64_X64_FUNCTION_H_
|
#ifndef XENIA_BACKEND_X64_X64_FUNCTION_H_
|
||||||
#define XENIA_BACKEND_X64_X64_FUNCTION_H_
|
#define XENIA_BACKEND_X64_X64_FUNCTION_H_
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/function.h"
|
#include "xenia/cpu/function.h"
|
||||||
#include "xenia/cpu/runtime/symbol_info.h"
|
#include "xenia/cpu/symbol_info.h"
|
||||||
|
#include "xenia/cpu/thread_state.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace backend {
|
namespace backend {
|
||||||
namespace x64 {
|
namespace x64 {
|
||||||
|
|
||||||
class X64Function : public runtime::Function {
|
class X64Function : public Function {
|
||||||
public:
|
public:
|
||||||
X64Function(runtime::FunctionInfo* symbol_info);
|
X64Function(FunctionInfo* symbol_info);
|
||||||
virtual ~X64Function();
|
virtual ~X64Function();
|
||||||
|
|
||||||
void* machine_code() const { return machine_code_; }
|
void* machine_code() const { return machine_code_; }
|
||||||
|
@ -29,10 +30,9 @@ class X64Function : public runtime::Function {
|
||||||
void Setup(void* machine_code, size_t code_size);
|
void Setup(void* machine_code, size_t code_size);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int AddBreakpointImpl(runtime::Breakpoint* breakpoint);
|
virtual int AddBreakpointImpl(Breakpoint* breakpoint);
|
||||||
virtual int RemoveBreakpointImpl(runtime::Breakpoint* breakpoint);
|
virtual int RemoveBreakpointImpl(Breakpoint* breakpoint);
|
||||||
virtual int CallImpl(runtime::ThreadState* thread_state,
|
virtual int CallImpl(ThreadState* thread_state, uint64_t return_address);
|
||||||
uint64_t return_address);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void* machine_code_;
|
void* machine_code_;
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include "xenia/cpu/backend/x64/x64_emitter.h"
|
#include "xenia/cpu/backend/x64/x64_emitter.h"
|
||||||
#include "xenia/cpu/backend/x64/x64_tracers.h"
|
#include "xenia/cpu/backend/x64/x64_tracers.h"
|
||||||
#include "xenia/cpu/hir/hir_builder.h"
|
#include "xenia/cpu/hir/hir_builder.h"
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
|
@ -38,7 +38,7 @@ using namespace Xbyak;
|
||||||
|
|
||||||
// TODO(benvanik): direct usings.
|
// TODO(benvanik): direct usings.
|
||||||
using namespace xe::cpu::hir;
|
using namespace xe::cpu::hir;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
|
|
||||||
using poly::vec128b;
|
using poly::vec128b;
|
||||||
|
|
||||||
|
|
|
@ -10,12 +10,12 @@
|
||||||
#include "xenia/cpu/backend/x64/x64_tracers.h"
|
#include "xenia/cpu/backend/x64/x64_tracers.h"
|
||||||
|
|
||||||
#include "xenia/cpu/backend/x64/x64_emitter.h"
|
#include "xenia/cpu/backend/x64/x64_emitter.h"
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
#include "xenia/cpu/runtime/thread_state.h"
|
#include "xenia/cpu/thread_state.h"
|
||||||
|
|
||||||
using namespace xe;
|
using namespace xe;
|
||||||
using namespace xe::cpu::backend::x64;
|
using namespace xe::cpu::backend::x64;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace cpu {
|
||||||
namespace compiler {
|
namespace compiler {
|
||||||
|
|
||||||
using xe::cpu::hir::HIRBuilder;
|
using xe::cpu::hir::HIRBuilder;
|
||||||
using xe::cpu::runtime::Runtime;
|
using xe::cpu::Runtime;
|
||||||
|
|
||||||
Compiler::Compiler(Runtime* runtime) : runtime_(runtime) {}
|
Compiler::Compiler(Runtime* runtime) : runtime_(runtime) {}
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,7 @@
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
class Runtime;
|
class Runtime;
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
|
@ -32,10 +30,10 @@ class CompilerPass;
|
||||||
|
|
||||||
class Compiler {
|
class Compiler {
|
||||||
public:
|
public:
|
||||||
Compiler(runtime::Runtime* runtime);
|
Compiler(Runtime* runtime);
|
||||||
~Compiler();
|
~Compiler();
|
||||||
|
|
||||||
runtime::Runtime* runtime() const { return runtime_; }
|
Runtime* runtime() const { return runtime_; }
|
||||||
poly::Arena* scratch_arena() { return &scratch_arena_; }
|
poly::Arena* scratch_arena() { return &scratch_arena_; }
|
||||||
|
|
||||||
void AddPass(std::unique_ptr<CompilerPass> pass);
|
void AddPass(std::unique_ptr<CompilerPass> pass);
|
||||||
|
@ -45,7 +43,7 @@ class Compiler {
|
||||||
int Compile(hir::HIRBuilder* builder);
|
int Compile(hir::HIRBuilder* builder);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
runtime::Runtime* runtime_;
|
Runtime* runtime_;
|
||||||
poly::Arena scratch_arena_;
|
poly::Arena scratch_arena_;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<CompilerPass>> passes_;
|
std::vector<std::unique_ptr<CompilerPass>> passes_;
|
||||||
|
|
|
@ -15,9 +15,7 @@
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
class Runtime;
|
class Runtime;
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
|
@ -40,7 +38,7 @@ class CompilerPass {
|
||||||
poly::Arena* scratch_arena() const;
|
poly::Arena* scratch_arena() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
runtime::Runtime* runtime_;
|
Runtime* runtime_;
|
||||||
Compiler* compiler_;
|
Compiler* compiler_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
|
|
||||||
#include "xenia/cpu/compiler/passes/constant_propagation_pass.h"
|
#include "xenia/cpu/compiler/passes/constant_propagation_pass.h"
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/function.h"
|
#include "xenia/cpu/function.h"
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
#include "xenia/profiling.h"
|
#include "xenia/profiling.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
@ -96,7 +96,7 @@ int ConstantPropagationPass::Run(HIRBuilder* builder) {
|
||||||
break;
|
break;
|
||||||
case OPCODE_CALL_INDIRECT:
|
case OPCODE_CALL_INDIRECT:
|
||||||
if (i->src1.value->IsConstant()) {
|
if (i->src1.value->IsConstant()) {
|
||||||
runtime::FunctionInfo* symbol_info;
|
FunctionInfo* symbol_info;
|
||||||
if (runtime_->LookupFunctionInfo(
|
if (runtime_->LookupFunctionInfo(
|
||||||
(uint32_t)i->src1.value->constant.i32, &symbol_info)) {
|
(uint32_t)i->src1.value->constant.i32, &symbol_info)) {
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include <gflags/gflags.h>
|
#include <gflags/gflags.h>
|
||||||
|
|
||||||
#include "xenia/cpu/compiler/compiler.h"
|
#include "xenia/cpu/compiler/compiler.h"
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
#include "xenia/profiling.h"
|
#include "xenia/profiling.h"
|
||||||
|
|
||||||
DEFINE_bool(store_all_context_values, false,
|
DEFINE_bool(store_all_context_values, false,
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
#include "xenia/cpu/backend/backend.h"
|
#include "xenia/cpu/backend/backend.h"
|
||||||
#include "xenia/cpu/compiler/compiler.h"
|
#include "xenia/cpu/compiler/compiler.h"
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
#include "xenia/profiling.h"
|
#include "xenia/profiling.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
#include "xenia/cpu/backend/backend.h"
|
#include "xenia/cpu/backend/backend.h"
|
||||||
#include "xenia/cpu/compiler/compiler.h"
|
#include "xenia/cpu/compiler/compiler.h"
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
#include "xenia/profiling.h"
|
#include "xenia/profiling.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
#include "xenia/cpu/backend/backend.h"
|
#include "xenia/cpu/backend/backend.h"
|
||||||
#include "xenia/cpu/compiler/compiler.h"
|
#include "xenia/cpu/compiler/compiler.h"
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
#include "xenia/profiling.h"
|
#include "xenia/profiling.h"
|
||||||
|
|
||||||
#if XE_COMPILER_MSVC
|
#if XE_COMPILER_MSVC
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
#include "xenia/cpu/backend/backend.h"
|
#include "xenia/cpu/backend/backend.h"
|
||||||
#include "xenia/cpu/compiler/compiler.h"
|
#include "xenia/cpu/compiler/compiler.h"
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
#include "xenia/profiling.h"
|
#include "xenia/profiling.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
#include "xenia/cpu/backend/backend.h"
|
#include "xenia/cpu/backend/backend.h"
|
||||||
#include "xenia/cpu/compiler/compiler.h"
|
#include "xenia/cpu/compiler/compiler.h"
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
#include "xenia/profiling.h"
|
#include "xenia/profiling.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
#include "xenia/cpu/backend/backend.h"
|
#include "xenia/cpu/backend/backend.h"
|
||||||
#include "xenia/cpu/compiler/compiler.h"
|
#include "xenia/cpu/compiler/compiler.h"
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
#include "xenia/profiling.h"
|
#include "xenia/profiling.h"
|
||||||
|
|
||||||
#if XE_COMPILER_MSVC
|
#if XE_COMPILER_MSVC
|
||||||
|
|
|
@ -11,12 +11,12 @@
|
||||||
#define XENIA_CPU_CPU_H_
|
#define XENIA_CPU_CPU_H_
|
||||||
|
|
||||||
#include "xenia/cpu/processor.h"
|
#include "xenia/cpu/processor.h"
|
||||||
#include "xenia/cpu/runtime/function.h"
|
#include "xenia/cpu/function.h"
|
||||||
#include "xenia/cpu/runtime/module.h"
|
#include "xenia/cpu/module.h"
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
#include "xenia/cpu/runtime/thread_state.h"
|
#include "xenia/cpu/thread_state.h"
|
||||||
#include "xenia/cpu/xenon_runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
#include "xenia/cpu/xenon_thread_state.h"
|
#include "xenia/cpu/thread_state.h"
|
||||||
#include "xenia/cpu/xex_module.h"
|
#include "xenia/cpu/xex_module.h"
|
||||||
|
|
||||||
#endif // XENIA_CPU_CPU_H_
|
#endif // XENIA_CPU_CPU_H_
|
||||||
|
|
|
@ -7,13 +7,12 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/debug_info.h"
|
#include "xenia/cpu/debug_info.h"
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
|
|
||||||
DebugInfo::DebugInfo()
|
DebugInfo::DebugInfo()
|
||||||
: source_disasm_(nullptr),
|
: source_disasm_(nullptr),
|
||||||
|
@ -72,6 +71,5 @@ SourceMapEntry* DebugInfo::LookupCodeOffset(uint64_t offset) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
|
@ -7,15 +7,14 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XENIA_RUNTIME_DEBUG_INFO_H_
|
#ifndef XENIA_CPU_DEBUG_INFO_H_
|
||||||
#define XENIA_RUNTIME_DEBUG_INFO_H_
|
#define XENIA_CPU_DEBUG_INFO_H_
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
|
|
||||||
enum DebugInfoFlags {
|
enum DebugInfoFlags {
|
||||||
DEBUG_INFO_NONE = 0,
|
DEBUG_INFO_NONE = 0,
|
||||||
|
@ -72,8 +71,7 @@ class DebugInfo {
|
||||||
SourceMapEntry* source_map_;
|
SourceMapEntry* source_map_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
#endif // XENIA_RUNTIME_DEBUG_INFO_H_
|
#endif // XENIA_CPU_DEBUG_INFO_H_
|
|
@ -7,15 +7,15 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/debugger.h"
|
#include "xenia/cpu/debugger.h"
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/function.h"
|
||||||
|
#include "xenia/cpu/runtime.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
|
|
||||||
Breakpoint::Breakpoint(Type type, uint64_t address)
|
Breakpoint::Breakpoint(Type type, uint64_t address)
|
||||||
: type_(type), address_(address) {}
|
: type_(type), address_(address) {}
|
||||||
|
@ -195,6 +195,5 @@ void Debugger::OnBreakpointHit(ThreadState* thread_state,
|
||||||
// Note that we stay suspended.
|
// Note that we stay suspended.
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
|
@ -7,8 +7,8 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XENIA_RUNTIME_DEBUGGER_H_
|
#ifndef XENIA_CPU_DEBUGGER_H_
|
||||||
#define XENIA_RUNTIME_DEBUGGER_H_
|
#define XENIA_CPU_DEBUGGER_H_
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
@ -16,16 +16,15 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "poly/delegate.h"
|
#include "poly/delegate.h"
|
||||||
|
#include "xenia/cpu/thread_state.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
|
|
||||||
class Debugger;
|
class Debugger;
|
||||||
class Function;
|
class Function;
|
||||||
class FunctionInfo;
|
class FunctionInfo;
|
||||||
class Runtime;
|
class Runtime;
|
||||||
class ThreadState;
|
|
||||||
|
|
||||||
class Breakpoint {
|
class Breakpoint {
|
||||||
public:
|
public:
|
||||||
|
@ -117,8 +116,7 @@ class Debugger {
|
||||||
std::multimap<uint64_t, Breakpoint*> breakpoints_;
|
std::multimap<uint64_t, Breakpoint*> breakpoints_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
#endif // XENIA_RUNTIME_DEBUGGER_H_
|
#endif // XENIA_CPU_DEBUGGER_H_
|
|
@ -7,14 +7,13 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/entry_table.h"
|
#include "xenia/cpu/entry_table.h"
|
||||||
|
|
||||||
#include "poly/poly.h"
|
#include "poly/poly.h"
|
||||||
#include "xenia/profiling.h"
|
#include "xenia/profiling.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
|
|
||||||
EntryTable::EntryTable() = default;
|
EntryTable::EntryTable() = default;
|
||||||
|
|
||||||
|
@ -88,6 +87,5 @@ std::vector<Function*> EntryTable::FindWithAddress(uint64_t address) {
|
||||||
return fns;
|
return fns;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
|
@ -7,8 +7,8 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XENIA_RUNTIME_ENTRY_TABLE_H_
|
#ifndef XENIA_CPU_ENTRY_TABLE_H_
|
||||||
#define XENIA_RUNTIME_ENTRY_TABLE_H_
|
#define XENIA_CPU_ENTRY_TABLE_H_
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
|
|
||||||
class Function;
|
class Function;
|
||||||
|
|
||||||
|
@ -50,8 +49,7 @@ class EntryTable {
|
||||||
std::unordered_map<uint64_t, Entry*> map_;
|
std::unordered_map<uint64_t, Entry*> map_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
#endif // XENIA_RUNTIME_ENTRY_TABLE_H_
|
#endif // XENIA_CPU_ENTRY_TABLE_H_
|
|
@ -9,13 +9,13 @@
|
||||||
|
|
||||||
#include "xenia/cpu/frontend/frontend.h"
|
#include "xenia/cpu/frontend/frontend.h"
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace frontend {
|
namespace frontend {
|
||||||
|
|
||||||
Frontend::Frontend(runtime::Runtime* runtime) : runtime_(runtime) {}
|
Frontend::Frontend(Runtime* runtime) : runtime_(runtime) {}
|
||||||
|
|
||||||
Frontend::~Frontend() = default;
|
Frontend::~Frontend() = default;
|
||||||
|
|
||||||
|
|
|
@ -14,14 +14,12 @@
|
||||||
|
|
||||||
#include "xenia/cpu/frontend/context_info.h"
|
#include "xenia/cpu/frontend/context_info.h"
|
||||||
#include "xenia/memory.h"
|
#include "xenia/memory.h"
|
||||||
#include "xenia/cpu/runtime/function.h"
|
#include "xenia/cpu/function.h"
|
||||||
#include "xenia/cpu/runtime/symbol_info.h"
|
#include "xenia/cpu/symbol_info.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
class Runtime;
|
class Runtime;
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
|
@ -31,22 +29,22 @@ namespace frontend {
|
||||||
|
|
||||||
class Frontend {
|
class Frontend {
|
||||||
public:
|
public:
|
||||||
Frontend(runtime::Runtime* runtime);
|
Frontend(Runtime* runtime);
|
||||||
virtual ~Frontend();
|
virtual ~Frontend();
|
||||||
|
|
||||||
runtime::Runtime* runtime() const { return runtime_; }
|
Runtime* runtime() const { return runtime_; }
|
||||||
Memory* memory() const;
|
Memory* memory() const;
|
||||||
ContextInfo* context_info() const { return context_info_.get(); }
|
ContextInfo* context_info() const { return context_info_.get(); }
|
||||||
|
|
||||||
virtual int Initialize();
|
virtual int Initialize();
|
||||||
|
|
||||||
virtual int DeclareFunction(runtime::FunctionInfo* symbol_info) = 0;
|
virtual int DeclareFunction(FunctionInfo* symbol_info) = 0;
|
||||||
virtual int DefineFunction(runtime::FunctionInfo* symbol_info,
|
virtual int DefineFunction(FunctionInfo* symbol_info,
|
||||||
uint32_t debug_info_flags, uint32_t trace_flags,
|
uint32_t debug_info_flags, uint32_t trace_flags,
|
||||||
runtime::Function** out_function) = 0;
|
Function** out_function) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
runtime::Runtime* runtime_;
|
Runtime* runtime_;
|
||||||
std::unique_ptr<ContextInfo> context_info_;
|
std::unique_ptr<ContextInfo> context_info_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,8 @@
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
class Runtime;
|
class Runtime;
|
||||||
class ThreadState;
|
class ThreadState;
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
|
@ -45,7 +43,7 @@ using vec128_t = poly::vec128_t;
|
||||||
typedef struct alignas(64) PPCContext_s {
|
typedef struct alignas(64) PPCContext_s {
|
||||||
// Must be stored at 0x0 for now.
|
// Must be stored at 0x0 for now.
|
||||||
// TODO(benvanik): find a nice way to describe this to the JIT.
|
// TODO(benvanik): find a nice way to describe this to the JIT.
|
||||||
runtime::ThreadState* thread_state;
|
ThreadState* thread_state;
|
||||||
// TODO(benvanik): this is getting nasty. Must be here.
|
// TODO(benvanik): this is getting nasty. Must be here.
|
||||||
uint8_t* membase;
|
uint8_t* membase;
|
||||||
|
|
||||||
|
@ -211,7 +209,7 @@ typedef struct alignas(64) PPCContext_s {
|
||||||
|
|
||||||
// Runtime-specific data pointer. Used on callbacks to get access to the
|
// Runtime-specific data pointer. Used on callbacks to get access to the
|
||||||
// current runtime and its data.
|
// current runtime and its data.
|
||||||
runtime::Runtime* runtime;
|
Runtime* runtime;
|
||||||
|
|
||||||
void SetRegFromString(const char* name, const char* value);
|
void SetRegFromString(const char* name, const char* value);
|
||||||
bool CompareRegWithString(const char* name, const char* value,
|
bool CompareRegWithString(const char* name, const char* value,
|
||||||
|
|
|
@ -13,16 +13,14 @@
|
||||||
#include "xenia/cpu/frontend/ppc/ppc_disasm.h"
|
#include "xenia/cpu/frontend/ppc/ppc_disasm.h"
|
||||||
#include "xenia/cpu/frontend/ppc/ppc_emit.h"
|
#include "xenia/cpu/frontend/ppc/ppc_emit.h"
|
||||||
#include "xenia/cpu/frontend/ppc/ppc_translator.h"
|
#include "xenia/cpu/frontend/ppc/ppc_translator.h"
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace frontend {
|
namespace frontend {
|
||||||
namespace ppc {
|
namespace ppc {
|
||||||
|
|
||||||
using xe::cpu::runtime::Function;
|
using xe::cpu::Runtime;
|
||||||
using xe::cpu::runtime::FunctionInfo;
|
|
||||||
using xe::cpu::runtime::Runtime;
|
|
||||||
|
|
||||||
void InitializeIfNeeded();
|
void InitializeIfNeeded();
|
||||||
void CleanupOnShutdown();
|
void CleanupOnShutdown();
|
||||||
|
|
|
@ -25,23 +25,22 @@ class PPCTranslator;
|
||||||
struct PPCBuiltins {
|
struct PPCBuiltins {
|
||||||
std::mutex global_lock;
|
std::mutex global_lock;
|
||||||
bool global_lock_taken;
|
bool global_lock_taken;
|
||||||
runtime::FunctionInfo* check_global_lock;
|
FunctionInfo* check_global_lock;
|
||||||
runtime::FunctionInfo* handle_global_lock;
|
FunctionInfo* handle_global_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PPCFrontend : public Frontend {
|
class PPCFrontend : public Frontend {
|
||||||
public:
|
public:
|
||||||
PPCFrontend(runtime::Runtime* runtime);
|
PPCFrontend(Runtime* runtime);
|
||||||
~PPCFrontend() override;
|
~PPCFrontend() override;
|
||||||
|
|
||||||
int Initialize() override;
|
int Initialize() override;
|
||||||
|
|
||||||
PPCBuiltins* builtins() { return &builtins_; }
|
PPCBuiltins* builtins() { return &builtins_; }
|
||||||
|
|
||||||
int DeclareFunction(runtime::FunctionInfo* symbol_info) override;
|
int DeclareFunction(FunctionInfo* symbol_info) override;
|
||||||
int DefineFunction(runtime::FunctionInfo* symbol_info,
|
int DefineFunction(FunctionInfo* symbol_info, uint32_t debug_info_flags,
|
||||||
uint32_t debug_info_flags, uint32_t trace_flags,
|
uint32_t trace_flags, Function** out_function) override;
|
||||||
runtime::Function** out_function) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
poly::TypePool<PPCTranslator, PPCFrontend*> translator_pool_;
|
poly::TypePool<PPCTranslator, PPCFrontend*> translator_pool_;
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include "xenia/cpu/frontend/ppc/ppc_frontend.h"
|
#include "xenia/cpu/frontend/ppc/ppc_frontend.h"
|
||||||
#include "xenia/cpu/frontend/ppc/ppc_instr.h"
|
#include "xenia/cpu/frontend/ppc/ppc_instr.h"
|
||||||
#include "xenia/cpu/hir/label.h"
|
#include "xenia/cpu/hir/label.h"
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
#include "xenia/profiling.h"
|
#include "xenia/profiling.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
@ -29,8 +29,6 @@ using namespace xe::cpu::hir;
|
||||||
using xe::cpu::hir::Label;
|
using xe::cpu::hir::Label;
|
||||||
using xe::cpu::hir::TypeName;
|
using xe::cpu::hir::TypeName;
|
||||||
using xe::cpu::hir::Value;
|
using xe::cpu::hir::Value;
|
||||||
using xe::cpu::runtime::Runtime;
|
|
||||||
using xe::cpu::runtime::FunctionInfo;
|
|
||||||
|
|
||||||
PPCHIRBuilder::PPCHIRBuilder(PPCFrontend* frontend)
|
PPCHIRBuilder::PPCHIRBuilder(PPCFrontend* frontend)
|
||||||
: HIRBuilder(), frontend_(frontend), comment_buffer_(4096) {}
|
: HIRBuilder(), frontend_(frontend), comment_buffer_(4096) {}
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
#define XENIA_FRONTEND_PPC_PPC_HIR_BUILDER_H_
|
#define XENIA_FRONTEND_PPC_PPC_HIR_BUILDER_H_
|
||||||
|
|
||||||
#include "xenia/cpu/hir/hir_builder.h"
|
#include "xenia/cpu/hir/hir_builder.h"
|
||||||
#include "xenia/cpu/runtime/function.h"
|
#include "xenia/cpu/function.h"
|
||||||
#include "xenia/cpu/runtime/symbol_info.h"
|
#include "xenia/cpu/symbol_info.h"
|
||||||
#include "poly/string_buffer.h"
|
#include "poly/string_buffer.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
@ -41,10 +41,10 @@ class PPCHIRBuilder : public hir::HIRBuilder {
|
||||||
// Emit TraceSource nodes with the resulting values of the operations.
|
// Emit TraceSource nodes with the resulting values of the operations.
|
||||||
EMIT_TRACE_SOURCE_VALUES = EMIT_TRACE_SOURCE | (1 << 2),
|
EMIT_TRACE_SOURCE_VALUES = EMIT_TRACE_SOURCE | (1 << 2),
|
||||||
};
|
};
|
||||||
int Emit(runtime::FunctionInfo* symbol_info, uint32_t flags);
|
int Emit(FunctionInfo* symbol_info, uint32_t flags);
|
||||||
|
|
||||||
runtime::FunctionInfo* symbol_info() const { return symbol_info_; }
|
FunctionInfo* symbol_info() const { return symbol_info_; }
|
||||||
runtime::FunctionInfo* LookupFunction(uint64_t address);
|
FunctionInfo* LookupFunction(uint64_t address);
|
||||||
Label* LookupLabel(uint64_t address);
|
Label* LookupLabel(uint64_t address);
|
||||||
|
|
||||||
Value* LoadLR();
|
Value* LoadLR();
|
||||||
|
@ -96,7 +96,7 @@ class PPCHIRBuilder : public hir::HIRBuilder {
|
||||||
|
|
||||||
// Reset each Emit:
|
// Reset each Emit:
|
||||||
bool with_debug_info_;
|
bool with_debug_info_;
|
||||||
runtime::FunctionInfo* symbol_info_;
|
FunctionInfo* symbol_info_;
|
||||||
uint64_t start_address_;
|
uint64_t start_address_;
|
||||||
uint64_t instr_count_;
|
uint64_t instr_count_;
|
||||||
Instr** instr_offset_list_;
|
Instr** instr_offset_list_;
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#include "xenia/cpu/frontend/ppc/ppc_frontend.h"
|
#include "xenia/cpu/frontend/ppc/ppc_frontend.h"
|
||||||
#include "xenia/cpu/frontend/ppc/ppc_instr.h"
|
#include "xenia/cpu/frontend/ppc/ppc_instr.h"
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
#include "poly/logging.h"
|
#include "poly/logging.h"
|
||||||
#include "poly/memory.h"
|
#include "poly/memory.h"
|
||||||
#include "xenia/profiling.h"
|
#include "xenia/profiling.h"
|
||||||
|
@ -30,8 +30,6 @@ namespace cpu {
|
||||||
namespace frontend {
|
namespace frontend {
|
||||||
namespace ppc {
|
namespace ppc {
|
||||||
|
|
||||||
using xe::cpu::runtime::FunctionInfo;
|
|
||||||
|
|
||||||
PPCScanner::PPCScanner(PPCFrontend* frontend) : frontend_(frontend) {}
|
PPCScanner::PPCScanner(PPCFrontend* frontend) : frontend_(frontend) {}
|
||||||
|
|
||||||
PPCScanner::~PPCScanner() {}
|
PPCScanner::~PPCScanner() {}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/symbol_info.h"
|
#include "xenia/cpu/symbol_info.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
|
@ -31,9 +31,9 @@ class PPCScanner {
|
||||||
PPCScanner(PPCFrontend* frontend);
|
PPCScanner(PPCFrontend* frontend);
|
||||||
~PPCScanner();
|
~PPCScanner();
|
||||||
|
|
||||||
int FindExtents(runtime::FunctionInfo* symbol_info);
|
int FindExtents(FunctionInfo* symbol_info);
|
||||||
|
|
||||||
std::vector<BlockInfo> FindBlocks(runtime::FunctionInfo* symbol_info);
|
std::vector<BlockInfo> FindBlocks(FunctionInfo* symbol_info);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool IsRestGprLr(uint64_t address);
|
bool IsRestGprLr(uint64_t address);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include "xenia/cpu/frontend/ppc/ppc_hir_builder.h"
|
#include "xenia/cpu/frontend/ppc/ppc_hir_builder.h"
|
||||||
#include "xenia/cpu/frontend/ppc/ppc_instr.h"
|
#include "xenia/cpu/frontend/ppc/ppc_instr.h"
|
||||||
#include "xenia/cpu/frontend/ppc/ppc_scanner.h"
|
#include "xenia/cpu/frontend/ppc/ppc_scanner.h"
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
#include "poly/reset_scope.h"
|
#include "poly/reset_scope.h"
|
||||||
#include "xenia/profiling.h"
|
#include "xenia/profiling.h"
|
||||||
|
|
||||||
|
@ -26,12 +26,10 @@ namespace frontend {
|
||||||
namespace ppc {
|
namespace ppc {
|
||||||
|
|
||||||
// TODO(benvanik): remove when enums redefined.
|
// TODO(benvanik): remove when enums redefined.
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
|
|
||||||
using xe::cpu::backend::Backend;
|
using xe::cpu::backend::Backend;
|
||||||
using xe::cpu::compiler::Compiler;
|
using xe::cpu::compiler::Compiler;
|
||||||
using xe::cpu::runtime::Function;
|
|
||||||
using xe::cpu::runtime::FunctionInfo;
|
|
||||||
namespace passes = xe::cpu::compiler::passes;
|
namespace passes = xe::cpu::compiler::passes;
|
||||||
|
|
||||||
PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) {
|
PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) {
|
||||||
|
@ -175,7 +173,7 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info,
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
void PPCTranslator::DumpSource(runtime::FunctionInfo* symbol_info,
|
void PPCTranslator::DumpSource(FunctionInfo* symbol_info,
|
||||||
poly::StringBuffer* string_buffer) {
|
poly::StringBuffer* string_buffer) {
|
||||||
Memory* memory = frontend_->memory();
|
Memory* memory = frontend_->memory();
|
||||||
const uint8_t* p = memory->membase();
|
const uint8_t* p = memory->membase();
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#include "xenia/cpu/backend/assembler.h"
|
#include "xenia/cpu/backend/assembler.h"
|
||||||
#include "xenia/cpu/compiler/compiler.h"
|
#include "xenia/cpu/compiler/compiler.h"
|
||||||
#include "xenia/cpu/runtime/symbol_info.h"
|
#include "xenia/cpu/symbol_info.h"
|
||||||
#include "poly/string_buffer.h"
|
#include "poly/string_buffer.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
@ -31,12 +31,11 @@ class PPCTranslator {
|
||||||
PPCTranslator(PPCFrontend* frontend);
|
PPCTranslator(PPCFrontend* frontend);
|
||||||
~PPCTranslator();
|
~PPCTranslator();
|
||||||
|
|
||||||
int Translate(runtime::FunctionInfo* symbol_info, uint32_t debug_info_flags,
|
int Translate(FunctionInfo* symbol_info, uint32_t debug_info_flags,
|
||||||
uint32_t trace_flags, runtime::Function** out_function);
|
uint32_t trace_flags, Function** out_function);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void DumpSource(runtime::FunctionInfo* symbol_info,
|
void DumpSource(FunctionInfo* symbol_info, poly::StringBuffer* string_buffer);
|
||||||
poly::StringBuffer* string_buffer);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PPCFrontend* frontend_;
|
PPCFrontend* frontend_;
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "xenia/cpu/backend/x64/x64_backend.h"
|
#include "xenia/cpu/backend/x64/x64_backend.h"
|
||||||
#include "xenia/cpu/frontend/ppc/ppc_context.h"
|
#include "xenia/cpu/frontend/ppc/ppc_context.h"
|
||||||
#include "xenia/cpu/frontend/ppc/ppc_frontend.h"
|
#include "xenia/cpu/frontend/ppc/ppc_frontend.h"
|
||||||
#include "xenia/cpu/runtime/raw_module.h"
|
#include "xenia/cpu/raw_module.h"
|
||||||
#include "poly/main.h"
|
#include "poly/main.h"
|
||||||
#include "poly/poly.h"
|
#include "poly/poly.h"
|
||||||
|
|
||||||
|
@ -30,61 +30,12 @@ namespace cpu {
|
||||||
namespace test {
|
namespace test {
|
||||||
|
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
using xe::cpu::runtime::Runtime;
|
using xe::cpu::Runtime;
|
||||||
|
|
||||||
typedef std::vector<std::pair<std::string, std::string>> AnnotationList;
|
typedef std::vector<std::pair<std::string, std::string>> AnnotationList;
|
||||||
|
|
||||||
const uint32_t START_ADDRESS = 0x100000;
|
const uint32_t START_ADDRESS = 0x100000;
|
||||||
|
|
||||||
class ThreadState : public xe::cpu::runtime::ThreadState {
|
|
||||||
public:
|
|
||||||
ThreadState(Runtime* runtime, uint32_t thread_id, uint64_t stack_address,
|
|
||||||
size_t stack_size, uint64_t thread_state_address)
|
|
||||||
: xe::cpu::runtime::ThreadState(runtime, thread_id),
|
|
||||||
stack_address_(stack_address),
|
|
||||||
stack_size_(stack_size),
|
|
||||||
thread_state_address_(thread_state_address) {
|
|
||||||
memset(memory_->Translate(stack_address_), 0, stack_size_);
|
|
||||||
|
|
||||||
// Allocate with 64b alignment.
|
|
||||||
context_ = (PPCContext*)calloc(1, sizeof(PPCContext));
|
|
||||||
assert_true((reinterpret_cast<uint64_t>(context_) & 0xF) == 0);
|
|
||||||
|
|
||||||
// Stash pointers to common structures that callbacks may need.
|
|
||||||
context_->reserve_address = memory_->reserve_address();
|
|
||||||
context_->reserve_value = memory_->reserve_value();
|
|
||||||
context_->membase = memory_->membase();
|
|
||||||
context_->runtime = runtime;
|
|
||||||
context_->thread_state = this;
|
|
||||||
|
|
||||||
// Set initial registers.
|
|
||||||
context_->r[1] = stack_address_ + stack_size;
|
|
||||||
context_->r[13] = thread_state_address_;
|
|
||||||
|
|
||||||
// Pad out stack a bit, as some games seem to overwrite the caller by about
|
|
||||||
// 16 to 32b.
|
|
||||||
context_->r[1] -= 64;
|
|
||||||
|
|
||||||
raw_context_ = context_;
|
|
||||||
|
|
||||||
runtime_->debugger()->OnThreadCreated(this);
|
|
||||||
}
|
|
||||||
~ThreadState() override {
|
|
||||||
runtime_->debugger()->OnThreadDestroyed(this);
|
|
||||||
free(context_);
|
|
||||||
}
|
|
||||||
|
|
||||||
PPCContext* context() const { return context_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint64_t stack_address_;
|
|
||||||
size_t stack_size_;
|
|
||||||
uint64_t thread_state_address_;
|
|
||||||
|
|
||||||
// NOTE: must be 64b aligned for SSE ops.
|
|
||||||
PPCContext* context_;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TestCase {
|
struct TestCase {
|
||||||
TestCase(uint64_t address, std::string& name)
|
TestCase(uint64_t address, std::string& name)
|
||||||
: address(address), name(name) {}
|
: address(address), name(name) {}
|
||||||
|
@ -224,10 +175,8 @@ class TestRunner {
|
||||||
memory.reset(new Memory());
|
memory.reset(new Memory());
|
||||||
memory->Initialize();
|
memory->Initialize();
|
||||||
|
|
||||||
runtime.reset(new Runtime(memory.get()));
|
runtime.reset(new Runtime(memory.get(), nullptr, 0, 0));
|
||||||
auto frontend =
|
runtime->Initialize(nullptr);
|
||||||
std::make_unique<xe::cpu::frontend::ppc::PPCFrontend>(runtime.get());
|
|
||||||
runtime->Initialize(std::move(frontend), nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~TestRunner() {
|
~TestRunner() {
|
||||||
|
@ -238,7 +187,7 @@ class TestRunner {
|
||||||
|
|
||||||
bool Setup(TestSuite& suite) {
|
bool Setup(TestSuite& suite) {
|
||||||
// Load the binary module.
|
// Load the binary module.
|
||||||
auto module = std::make_unique<xe::cpu::runtime::RawModule>(runtime.get());
|
auto module = std::make_unique<xe::cpu::RawModule>(runtime.get());
|
||||||
if (module->LoadFile(START_ADDRESS, suite.bin_file_path)) {
|
if (module->LoadFile(START_ADDRESS, suite.bin_file_path)) {
|
||||||
PLOGE("Unable to load test binary %ls", suite.bin_file_path.c_str());
|
PLOGE("Unable to load test binary %ls", suite.bin_file_path.c_str());
|
||||||
return false;
|
return false;
|
||||||
|
@ -263,7 +212,7 @@ class TestRunner {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute test.
|
// Execute test.
|
||||||
xe::cpu::runtime::Function* fn;
|
xe::cpu::Function* fn;
|
||||||
runtime->ResolveFunction(test_case.address, &fn);
|
runtime->ResolveFunction(test_case.address, &fn);
|
||||||
if (!fn) {
|
if (!fn) {
|
||||||
PLOGE("Entry function not found");
|
PLOGE("Entry function not found");
|
||||||
|
|
|
@ -7,17 +7,16 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/function.h"
|
#include "xenia/cpu/function.h"
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/debugger.h"
|
#include "xenia/cpu/debugger.h"
|
||||||
#include "xenia/cpu/runtime/symbol_info.h"
|
#include "xenia/cpu/symbol_info.h"
|
||||||
#include "xenia/cpu/runtime/thread_state.h"
|
#include "xenia/cpu/thread_state.h"
|
||||||
#include "poly/logging.h"
|
#include "poly/logging.h"
|
||||||
#include "xdb/protocol.h"
|
#include "xdb/protocol.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
|
|
||||||
Function::Function(FunctionInfo* symbol_info)
|
Function::Function(FunctionInfo* symbol_info)
|
||||||
: address_(symbol_info->address()), symbol_info_(symbol_info) {}
|
: address_(symbol_info->address()), symbol_info_(symbol_info) {}
|
||||||
|
@ -126,6 +125,5 @@ int Function::Call(ThreadState* thread_state, uint64_t return_address) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
|
@ -7,22 +7,21 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XENIA_RUNTIME_FUNCTION_H_
|
#ifndef XENIA_CPU_FUNCTION_H_
|
||||||
#define XENIA_RUNTIME_FUNCTION_H_
|
#define XENIA_CPU_FUNCTION_H_
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/debug_info.h"
|
#include "xenia/cpu/debug_info.h"
|
||||||
|
#include "xenia/cpu/thread_state.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
|
|
||||||
class Breakpoint;
|
class Breakpoint;
|
||||||
class FunctionInfo;
|
class FunctionInfo;
|
||||||
class ThreadState;
|
|
||||||
|
|
||||||
class Function {
|
class Function {
|
||||||
public:
|
public:
|
||||||
|
@ -58,8 +57,7 @@ class Function {
|
||||||
std::vector<Breakpoint*> breakpoints_;
|
std::vector<Breakpoint*> breakpoints_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
#endif // XENIA_RUNTIME_FUNCTION_H_
|
#endif // XENIA_CPU_FUNCTION_H_
|
|
@ -12,15 +12,13 @@
|
||||||
#include "xenia/cpu/hir/block.h"
|
#include "xenia/cpu/hir/block.h"
|
||||||
#include "xenia/cpu/hir/instr.h"
|
#include "xenia/cpu/hir/instr.h"
|
||||||
#include "xenia/cpu/hir/label.h"
|
#include "xenia/cpu/hir/label.h"
|
||||||
#include "xenia/cpu/runtime/symbol_info.h"
|
#include "xenia/cpu/symbol_info.h"
|
||||||
#include "xenia/profiling.h"
|
#include "xenia/profiling.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace hir {
|
namespace hir {
|
||||||
|
|
||||||
using xe::cpu::runtime::FunctionInfo;
|
|
||||||
|
|
||||||
#define ASSERT_ADDRESS_TYPE(value)
|
#define ASSERT_ADDRESS_TYPE(value)
|
||||||
#define ASSERT_INTEGER_TYPE(value)
|
#define ASSERT_INTEGER_TYPE(value)
|
||||||
#define ASSERT_FLOAT_TYPE(value)
|
#define ASSERT_FLOAT_TYPE(value)
|
||||||
|
|
|
@ -81,12 +81,12 @@ class HIRBuilder {
|
||||||
void Trap(uint16_t trap_code = 0);
|
void Trap(uint16_t trap_code = 0);
|
||||||
void TrapTrue(Value* cond, uint16_t trap_code = 0);
|
void TrapTrue(Value* cond, uint16_t trap_code = 0);
|
||||||
|
|
||||||
void Call(runtime::FunctionInfo* symbol_info, uint32_t call_flags = 0);
|
void Call(FunctionInfo* symbol_info, uint32_t call_flags = 0);
|
||||||
void CallTrue(Value* cond, runtime::FunctionInfo* symbol_info,
|
void CallTrue(Value* cond, FunctionInfo* symbol_info,
|
||||||
uint32_t call_flags = 0);
|
uint32_t call_flags = 0);
|
||||||
void CallIndirect(Value* value, uint32_t call_flags = 0);
|
void CallIndirect(Value* value, uint32_t call_flags = 0);
|
||||||
void CallIndirectTrue(Value* cond, Value* value, uint32_t call_flags = 0);
|
void CallIndirectTrue(Value* cond, Value* value, uint32_t call_flags = 0);
|
||||||
void CallExtern(runtime::FunctionInfo* symbol_info);
|
void CallExtern(FunctionInfo* symbol_info);
|
||||||
void Return();
|
void Return();
|
||||||
void ReturnTrue(Value* cond);
|
void ReturnTrue(Value* cond);
|
||||||
void SetReturnAddress(Value* value);
|
void SetReturnAddress(Value* value);
|
||||||
|
|
|
@ -15,9 +15,7 @@
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
class FunctionInfo;
|
class FunctionInfo;
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
|
@ -39,7 +37,7 @@ class Instr {
|
||||||
uint32_t ordinal;
|
uint32_t ordinal;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
runtime::FunctionInfo* symbol_info;
|
FunctionInfo* symbol_info;
|
||||||
Label* label;
|
Label* label;
|
||||||
Value* value;
|
Value* value;
|
||||||
uint64_t offset;
|
uint64_t offset;
|
||||||
|
|
|
@ -7,15 +7,14 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/instrument.h"
|
#include "xenia/cpu/instrument.h"
|
||||||
|
|
||||||
#include "xenia/memory.h"
|
#include "xenia/memory.h"
|
||||||
#include "xenia/cpu/runtime/function.h"
|
#include "xenia/cpu/function.h"
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
|
|
||||||
Instrument::Instrument(Runtime* runtime)
|
Instrument::Instrument(Runtime* runtime)
|
||||||
: runtime_(runtime), memory_(runtime->memory()), is_attached_(false) {}
|
: runtime_(runtime), memory_(runtime->memory()), is_attached_(false) {}
|
||||||
|
@ -109,6 +108,5 @@ void MemoryInstrument::Access(ThreadState* thread_state, uint64_t address,
|
||||||
// TODO(benvanik): get thread local instance
|
// TODO(benvanik): get thread local instance
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
|
@ -7,24 +7,23 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XENIA_RUNTIME_INSTRUMENT_H_
|
#ifndef XENIA_CPU_INSTRUMENT_H_
|
||||||
#define XENIA_RUNTIME_INSTRUMENT_H_
|
#define XENIA_CPU_INSTRUMENT_H_
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
class Memory;
|
class Memory;
|
||||||
|
class ThreadState;
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
|
|
||||||
class Function;
|
class Function;
|
||||||
class Runtime;
|
class Runtime;
|
||||||
class ThreadState;
|
|
||||||
|
|
||||||
class Instrument {
|
class Instrument {
|
||||||
public:
|
public:
|
||||||
|
@ -141,8 +140,7 @@ class MemoryInstrument : public Instrument {
|
||||||
// v OnUnload(context)
|
// v OnUnload(context)
|
||||||
// // get proc address?
|
// // get proc address?
|
||||||
|
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
#endif // XENIA_RUNTIME_INSTRUMENT_H_
|
#endif // XENIA_CPU_INSTRUMENT_H_
|
|
@ -7,18 +7,17 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/module.h"
|
#include "xenia/cpu/module.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
#include "poly/poly.h"
|
#include "poly/poly.h"
|
||||||
#include "xenia/profiling.h"
|
#include "xenia/profiling.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
|
|
||||||
Module::Module(Runtime* runtime)
|
Module::Module(Runtime* runtime)
|
||||||
: runtime_(runtime), memory_(runtime->memory()) {}
|
: runtime_(runtime), memory_(runtime->memory()) {}
|
||||||
|
@ -247,6 +246,5 @@ int Module::ReadMap(const char* file_name) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
|
@ -7,8 +7,8 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XENIA_RUNTIME_MODULE_H_
|
#ifndef XENIA_CPU_MODULE_H_
|
||||||
#define XENIA_RUNTIME_MODULE_H_
|
#define XENIA_CPU_MODULE_H_
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -17,11 +17,10 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "xenia/memory.h"
|
#include "xenia/memory.h"
|
||||||
#include "xenia/cpu/runtime/symbol_info.h"
|
#include "xenia/cpu/symbol_info.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
|
|
||||||
class Function;
|
class Function;
|
||||||
class Runtime;
|
class Runtime;
|
||||||
|
@ -68,8 +67,7 @@ class Module {
|
||||||
std::vector<std::unique_ptr<SymbolInfo>> list_;
|
std::vector<std::unique_ptr<SymbolInfo>> list_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
#endif // XENIA_RUNTIME_MODULE_H_
|
#endif // XENIA_CPU_MODULE_H_
|
|
@ -10,15 +10,18 @@
|
||||||
#include "xenia/cpu/processor.h"
|
#include "xenia/cpu/processor.h"
|
||||||
|
|
||||||
#include "xenia/cpu/cpu-private.h"
|
#include "xenia/cpu/cpu-private.h"
|
||||||
#include "xenia/cpu/xenon_runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
#include "xenia/cpu/xex_module.h"
|
#include "xenia/cpu/xex_module.h"
|
||||||
#include "xenia/export_resolver.h"
|
#include "xenia/export_resolver.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
|
|
||||||
|
// TODO(benvanik): remove when enums converted.
|
||||||
|
using namespace xe::cpu;
|
||||||
using namespace xe::cpu::backend;
|
using namespace xe::cpu::backend;
|
||||||
using namespace xe::cpu::runtime;
|
|
||||||
|
using PPCContext = xe::cpu::frontend::ppc::PPCContext;
|
||||||
|
|
||||||
void InitializeIfNeeded();
|
void InitializeIfNeeded();
|
||||||
void CleanupOnShutdown();
|
void CleanupOnShutdown();
|
||||||
|
@ -80,8 +83,8 @@ int Processor::Setup() {
|
||||||
trace_flags |= TRACE_SOURCE_VALUES;
|
trace_flags |= TRACE_SOURCE_VALUES;
|
||||||
}
|
}
|
||||||
|
|
||||||
runtime_ = new XenonRuntime(memory_, export_resolver_, debug_info_flags,
|
runtime_ =
|
||||||
trace_flags);
|
new Runtime(memory_, export_resolver_, debug_info_flags, trace_flags);
|
||||||
if (!runtime_) {
|
if (!runtime_) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +96,7 @@ int Processor::Setup() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
interrupt_thread_state_ = new XenonThreadState(runtime_, 0, 16 * 1024, 0);
|
interrupt_thread_state_ = new ThreadState(runtime_, 0, 0, 16 * 1024, 0);
|
||||||
interrupt_thread_state_->set_name("Interrupt");
|
interrupt_thread_state_->set_name("Interrupt");
|
||||||
interrupt_thread_block_ = memory_->HeapAlloc(0, 2048, MEMORY_FLAG_ZERO);
|
interrupt_thread_block_ = memory_->HeapAlloc(0, 2048, MEMORY_FLAG_ZERO);
|
||||||
interrupt_thread_state_->context()->r[13] = interrupt_thread_block_;
|
interrupt_thread_state_->context()->r[13] = interrupt_thread_block_;
|
||||||
|
@ -101,7 +104,7 @@ int Processor::Setup() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Processor::Execute(XenonThreadState* thread_state, uint64_t address) {
|
int Processor::Execute(ThreadState* thread_state, uint64_t address) {
|
||||||
SCOPE_profile_cpu_f("cpu");
|
SCOPE_profile_cpu_f("cpu");
|
||||||
|
|
||||||
// Attempt to get the function.
|
// Attempt to get the function.
|
||||||
|
@ -126,7 +129,7 @@ int Processor::Execute(XenonThreadState* thread_state, uint64_t address) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t Processor::Execute(XenonThreadState* thread_state, uint64_t address,
|
uint64_t Processor::Execute(ThreadState* thread_state, uint64_t address,
|
||||||
uint64_t args[], size_t arg_count) {
|
uint64_t args[], size_t arg_count) {
|
||||||
SCOPE_profile_cpu_f("cpu");
|
SCOPE_profile_cpu_f("cpu");
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
|
|
||||||
class XenonRuntime;
|
class Runtime;
|
||||||
class XenonThreadState;
|
class ThreadState;
|
||||||
class XexModule;
|
class XexModule;
|
||||||
|
|
||||||
enum class Irql : uint32_t {
|
enum class Irql : uint32_t {
|
||||||
|
@ -37,14 +37,14 @@ class Processor {
|
||||||
~Processor();
|
~Processor();
|
||||||
|
|
||||||
ExportResolver* export_resolver() const { return export_resolver_; }
|
ExportResolver* export_resolver() const { return export_resolver_; }
|
||||||
XenonRuntime* runtime() const { return runtime_; }
|
Runtime* runtime() const { return runtime_; }
|
||||||
Memory* memory() const { return memory_; }
|
Memory* memory() const { return memory_; }
|
||||||
|
|
||||||
int Setup();
|
int Setup();
|
||||||
|
|
||||||
int Execute(XenonThreadState* thread_state, uint64_t address);
|
int Execute(ThreadState* thread_state, uint64_t address);
|
||||||
uint64_t Execute(XenonThreadState* thread_state, uint64_t address,
|
uint64_t Execute(ThreadState* thread_state, uint64_t address, uint64_t args[],
|
||||||
uint64_t args[], size_t arg_count);
|
size_t arg_count);
|
||||||
|
|
||||||
Irql RaiseIrql(Irql new_value);
|
Irql RaiseIrql(Irql new_value);
|
||||||
void LowerIrql(Irql old_value);
|
void LowerIrql(Irql old_value);
|
||||||
|
@ -55,12 +55,12 @@ class Processor {
|
||||||
private:
|
private:
|
||||||
ExportResolver* export_resolver_;
|
ExportResolver* export_resolver_;
|
||||||
|
|
||||||
XenonRuntime* runtime_;
|
Runtime* runtime_;
|
||||||
Memory* memory_;
|
Memory* memory_;
|
||||||
|
|
||||||
Irql irql_;
|
Irql irql_;
|
||||||
std::mutex interrupt_thread_lock_;
|
std::mutex interrupt_thread_lock_;
|
||||||
XenonThreadState* interrupt_thread_state_;
|
ThreadState* interrupt_thread_state_;
|
||||||
uint64_t interrupt_thread_block_;
|
uint64_t interrupt_thread_block_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,14 +7,13 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/raw_module.h"
|
#include "xenia/cpu/raw_module.h"
|
||||||
|
|
||||||
#include "poly/platform.h"
|
#include "poly/platform.h"
|
||||||
#include "poly/string.h"
|
#include "poly/string.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
|
|
||||||
RawModule::RawModule(Runtime* runtime)
|
RawModule::RawModule(Runtime* runtime)
|
||||||
: Module(runtime), base_address_(0), low_address_(0), high_address_(0) {}
|
: Module(runtime), base_address_(0), low_address_(0), high_address_(0) {}
|
||||||
|
@ -57,6 +56,5 @@ bool RawModule::ContainsAddress(uint64_t address) {
|
||||||
return address >= low_address_ && address < high_address_;
|
return address >= low_address_ && address < high_address_;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
|
@ -7,16 +7,15 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XENIA_RUNTIME_RAW_MODULE_H_
|
#ifndef XENIA_CPU_RAW_MODULE_H_
|
||||||
#define XENIA_RUNTIME_RAW_MODULE_H_
|
#define XENIA_CPU_RAW_MODULE_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/module.h"
|
#include "xenia/cpu/module.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
|
|
||||||
class RawModule : public Module {
|
class RawModule : public Module {
|
||||||
public:
|
public:
|
||||||
|
@ -36,8 +35,7 @@ class RawModule : public Module {
|
||||||
uint64_t high_address_;
|
uint64_t high_address_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
#endif // XENIA_RUNTIME_RAW_MODULE_H_
|
#endif // XENIA_CPU_RAW_MODULE_H_
|
|
@ -7,13 +7,15 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
#include <gflags/gflags.h>
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/module.h"
|
|
||||||
#include "poly/poly.h"
|
#include "poly/poly.h"
|
||||||
#include "xdb/protocol.h"
|
#include "xdb/protocol.h"
|
||||||
|
#include "xenia/cpu/frontend/ppc/ppc_frontend.h"
|
||||||
|
#include "xenia/cpu/module.h"
|
||||||
|
#include "xenia/cpu/thread_state.h"
|
||||||
|
|
||||||
// TODO(benvanik): based on compiler support
|
// TODO(benvanik): based on compiler support
|
||||||
#include "xenia/cpu/backend/x64/x64_backend.h"
|
#include "xenia/cpu/backend/x64/x64_backend.h"
|
||||||
|
@ -22,7 +24,6 @@ DEFINE_string(runtime_backend, "any", "Runtime backend [any, x64].");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
|
|
||||||
using xe::cpu::backend::Backend;
|
using xe::cpu::backend::Backend;
|
||||||
using xe::cpu::frontend::Frontend;
|
using xe::cpu::frontend::Frontend;
|
||||||
|
@ -39,13 +40,14 @@ class BuiltinModule : public Module {
|
||||||
std::string name_;
|
std::string name_;
|
||||||
};
|
};
|
||||||
|
|
||||||
Runtime::Runtime(Memory* memory, uint32_t debug_info_flags,
|
Runtime::Runtime(Memory* memory, ExportResolver* export_resolver,
|
||||||
uint32_t trace_flags)
|
uint32_t debug_info_flags, uint32_t trace_flags)
|
||||||
: memory_(memory),
|
: memory_(memory),
|
||||||
debug_info_flags_(debug_info_flags),
|
debug_info_flags_(debug_info_flags),
|
||||||
trace_flags_(trace_flags),
|
trace_flags_(trace_flags),
|
||||||
builtin_module_(nullptr),
|
builtin_module_(nullptr),
|
||||||
next_builtin_address_(0x100000000ull) {}
|
next_builtin_address_(0x100000000ull),
|
||||||
|
export_resolver_(export_resolver) {}
|
||||||
|
|
||||||
Runtime::~Runtime() {
|
Runtime::~Runtime() {
|
||||||
{
|
{
|
||||||
|
@ -58,8 +60,10 @@ Runtime::~Runtime() {
|
||||||
backend_.reset();
|
backend_.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Runtime::Initialize(std::unique_ptr<Frontend> frontend,
|
int Runtime::Initialize(std::unique_ptr<xe::cpu::backend::Backend> backend) {
|
||||||
std::unique_ptr<Backend> backend) {
|
auto frontend = std::make_unique<xe::cpu::frontend::ppc::PPCFrontend>(this);
|
||||||
|
// TODO(benvanik): set options/etc.
|
||||||
|
|
||||||
// Must be initialized by subclass before calling into this.
|
// Must be initialized by subclass before calling into this.
|
||||||
assert_not_null(memory_);
|
assert_not_null(memory_);
|
||||||
|
|
||||||
|
@ -145,7 +149,7 @@ FunctionInfo* Runtime::DefineBuiltin(const std::string& name,
|
||||||
fn_info->set_end_address(address + 4);
|
fn_info->set_end_address(address + 4);
|
||||||
fn_info->set_name(name);
|
fn_info->set_name(name);
|
||||||
fn_info->SetupExtern(handler, arg0, arg1);
|
fn_info->SetupExtern(handler, arg0, arg1);
|
||||||
fn_info->set_status(runtime::SymbolInfo::STATUS_DECLARED);
|
fn_info->set_status(SymbolInfo::STATUS_DECLARED);
|
||||||
|
|
||||||
return fn_info;
|
return fn_info;
|
||||||
}
|
}
|
||||||
|
@ -280,6 +284,5 @@ int Runtime::DemandFunction(FunctionInfo* symbol_info,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
|
@ -7,39 +7,36 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XENIA_RUNTIME_RUNTIME_H_
|
#ifndef XENIA_CPU_RUNTIME_H_
|
||||||
#define XENIA_RUNTIME_RUNTIME_H_
|
#define XENIA_CPU_RUNTIME_H_
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <mutex>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
|
#include "xenia/common.h"
|
||||||
#include "xenia/cpu/backend/backend.h"
|
#include "xenia/cpu/backend/backend.h"
|
||||||
|
#include "xenia/cpu/debugger.h"
|
||||||
|
#include "xenia/cpu/entry_table.h"
|
||||||
#include "xenia/cpu/frontend/frontend.h"
|
#include "xenia/cpu/frontend/frontend.h"
|
||||||
|
#include "xenia/cpu/function.h"
|
||||||
|
#include "xenia/cpu/module.h"
|
||||||
|
#include "xenia/cpu/thread_state.h"
|
||||||
|
#include "xenia/export_resolver.h"
|
||||||
#include "xenia/memory.h"
|
#include "xenia/memory.h"
|
||||||
#include "xenia/cpu/runtime/debugger.h"
|
|
||||||
#include "xenia/cpu/runtime/entry_table.h"
|
|
||||||
#include "xenia/cpu/runtime/module.h"
|
|
||||||
#include "xenia/cpu/runtime/symbol_info.h"
|
|
||||||
#include "xenia/cpu/runtime/thread_state.h"
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
|
|
||||||
class Runtime {
|
class Runtime {
|
||||||
public:
|
public:
|
||||||
explicit Runtime(Memory* memory, uint32_t debug_info_flags = 0,
|
Runtime(Memory* memory, ExportResolver* export_resolver,
|
||||||
uint32_t trace_flags = 0);
|
uint32_t debug_info_flags, uint32_t trace_flags);
|
||||||
virtual ~Runtime();
|
~Runtime();
|
||||||
|
|
||||||
Memory* memory() const { return memory_; }
|
Memory* memory() const { return memory_; }
|
||||||
Debugger* debugger() const { return debugger_.get(); }
|
Debugger* debugger() const { return debugger_.get(); }
|
||||||
frontend::Frontend* frontend() const { return frontend_.get(); }
|
frontend::Frontend* frontend() const { return frontend_.get(); }
|
||||||
backend::Backend* backend() const { return backend_.get(); }
|
backend::Backend* backend() const { return backend_.get(); }
|
||||||
|
ExportResolver* export_resolver() const { return export_resolver_; }
|
||||||
|
|
||||||
int Initialize(std::unique_ptr<frontend::Frontend> frontend,
|
int Initialize(std::unique_ptr<backend::Backend> backend = 0);
|
||||||
std::unique_ptr<backend::Backend> backend = 0);
|
|
||||||
|
|
||||||
int AddModule(std::unique_ptr<Module> module);
|
int AddModule(std::unique_ptr<Module> module);
|
||||||
Module* GetModule(const char* name);
|
Module* GetModule(const char* name);
|
||||||
|
@ -63,7 +60,6 @@ class Runtime {
|
||||||
private:
|
private:
|
||||||
int DemandFunction(FunctionInfo* symbol_info, Function** out_function);
|
int DemandFunction(FunctionInfo* symbol_info, Function** out_function);
|
||||||
|
|
||||||
protected:
|
|
||||||
Memory* memory_;
|
Memory* memory_;
|
||||||
|
|
||||||
uint32_t debug_info_flags_;
|
uint32_t debug_info_flags_;
|
||||||
|
@ -73,6 +69,7 @@ class Runtime {
|
||||||
|
|
||||||
std::unique_ptr<frontend::Frontend> frontend_;
|
std::unique_ptr<frontend::Frontend> frontend_;
|
||||||
std::unique_ptr<backend::Backend> backend_;
|
std::unique_ptr<backend::Backend> backend_;
|
||||||
|
ExportResolver* export_resolver_;
|
||||||
|
|
||||||
EntryTable entry_table_;
|
EntryTable entry_table_;
|
||||||
std::mutex modules_lock_;
|
std::mutex modules_lock_;
|
||||||
|
@ -81,8 +78,7 @@ class Runtime {
|
||||||
uint64_t next_builtin_address_;
|
uint64_t next_builtin_address_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
#endif // XENIA_RUNTIME_RUNTIME_H_
|
#endif // XENIA_CPU_RUNTIME_H_
|
|
@ -1,30 +0,0 @@
|
||||||
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
|
||||||
{
|
|
||||||
'sources': [
|
|
||||||
'debug_info.cc',
|
|
||||||
'debug_info.h',
|
|
||||||
'debugger.cc',
|
|
||||||
'debugger.h',
|
|
||||||
'entry_table.cc',
|
|
||||||
'entry_table.h',
|
|
||||||
'function.cc',
|
|
||||||
'function.h',
|
|
||||||
'instrument.cc',
|
|
||||||
'instrument.h',
|
|
||||||
'module.cc',
|
|
||||||
'module.h',
|
|
||||||
'raw_module.cc',
|
|
||||||
'raw_module.h',
|
|
||||||
'runtime.cc',
|
|
||||||
'runtime.h',
|
|
||||||
'symbol_info.cc',
|
|
||||||
'symbol_info.h',
|
|
||||||
'test_module.cc',
|
|
||||||
'test_module.h',
|
|
||||||
'thread_state.cc',
|
|
||||||
'thread_state.h',
|
|
||||||
],
|
|
||||||
|
|
||||||
'includes': [
|
|
||||||
],
|
|
||||||
}
|
|
|
@ -1,56 +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/runtime/thread_state.h"
|
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
|
||||||
#include "poly/poly.h"
|
|
||||||
|
|
||||||
namespace xe {
|
|
||||||
namespace cpu {
|
|
||||||
namespace runtime {
|
|
||||||
|
|
||||||
thread_local ThreadState* thread_state_ = nullptr;
|
|
||||||
|
|
||||||
ThreadState::ThreadState(Runtime* runtime, uint32_t thread_id)
|
|
||||||
: runtime_(runtime),
|
|
||||||
memory_(runtime->memory()),
|
|
||||||
thread_id_(thread_id),
|
|
||||||
name_(""),
|
|
||||||
backend_data_(0),
|
|
||||||
raw_context_(0) {
|
|
||||||
if (thread_id_ == UINT_MAX) {
|
|
||||||
// System thread. Assign the system thread ID with a high bit
|
|
||||||
// set so people know what's up.
|
|
||||||
uint32_t system_thread_handle = poly::threading::current_thread_id();
|
|
||||||
thread_id_ = 0x80000000 | system_thread_handle;
|
|
||||||
}
|
|
||||||
backend_data_ = runtime->backend()->AllocThreadData();
|
|
||||||
}
|
|
||||||
|
|
||||||
ThreadState::~ThreadState() {
|
|
||||||
if (backend_data_) {
|
|
||||||
runtime_->backend()->FreeThreadData(backend_data_);
|
|
||||||
}
|
|
||||||
if (thread_state_ == this) {
|
|
||||||
thread_state_ = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadState::Bind(ThreadState* thread_state) {
|
|
||||||
thread_state_ = thread_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
ThreadState* ThreadState::Get() { return thread_state_; }
|
|
||||||
|
|
||||||
uint32_t ThreadState::GetThreadID() { return thread_state_->thread_id_; }
|
|
||||||
|
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
|
||||||
} // namespace xe
|
|
|
@ -4,14 +4,32 @@
|
||||||
'cpu-private.h',
|
'cpu-private.h',
|
||||||
'cpu.cc',
|
'cpu.cc',
|
||||||
'cpu.h',
|
'cpu.h',
|
||||||
|
'debug_info.cc',
|
||||||
|
'debug_info.h',
|
||||||
|
'debugger.cc',
|
||||||
|
'debugger.h',
|
||||||
|
'entry_table.cc',
|
||||||
|
'entry_table.h',
|
||||||
|
'function.cc',
|
||||||
|
'function.h',
|
||||||
|
'instrument.cc',
|
||||||
|
'instrument.h',
|
||||||
'mmio_handler.cc',
|
'mmio_handler.cc',
|
||||||
'mmio_handler.h',
|
'mmio_handler.h',
|
||||||
|
'module.cc',
|
||||||
|
'module.h',
|
||||||
'processor.cc',
|
'processor.cc',
|
||||||
'processor.h',
|
'processor.h',
|
||||||
'xenon_runtime.cc',
|
'raw_module.cc',
|
||||||
'xenon_runtime.h',
|
'raw_module.h',
|
||||||
'xenon_thread_state.cc',
|
'runtime.cc',
|
||||||
'xenon_thread_state.h',
|
'runtime.h',
|
||||||
|
'symbol_info.cc',
|
||||||
|
'symbol_info.h',
|
||||||
|
'test_module.cc',
|
||||||
|
'test_module.h',
|
||||||
|
'thread_state.cc',
|
||||||
|
'thread_state.h',
|
||||||
'xex_module.cc',
|
'xex_module.cc',
|
||||||
'xex_module.h',
|
'xex_module.h',
|
||||||
],
|
],
|
||||||
|
@ -42,6 +60,5 @@
|
||||||
'compiler/sources.gypi',
|
'compiler/sources.gypi',
|
||||||
'frontend/sources.gypi',
|
'frontend/sources.gypi',
|
||||||
'hir/sources.gypi',
|
'hir/sources.gypi',
|
||||||
'runtime/sources.gypi',
|
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,10 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/symbol_info.h"
|
#include "xenia/cpu/symbol_info.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
|
|
||||||
SymbolInfo::SymbolInfo(Type type, Module* module, uint64_t address)
|
SymbolInfo::SymbolInfo(Type type, Module* module, uint64_t address)
|
||||||
: type_(type),
|
: type_(type),
|
||||||
|
@ -44,6 +43,5 @@ VariableInfo::VariableInfo(Module* module, uint64_t address)
|
||||||
|
|
||||||
VariableInfo::~VariableInfo() = default;
|
VariableInfo::~VariableInfo() = default;
|
||||||
|
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
|
@ -7,15 +7,14 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XENIA_RUNTIME_SYMBOL_INFO_H_
|
#ifndef XENIA_CPU_SYMBOL_INFO_H_
|
||||||
#define XENIA_RUNTIME_SYMBOL_INFO_H_
|
#define XENIA_CPU_SYMBOL_INFO_H_
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
|
|
||||||
class Function;
|
class Function;
|
||||||
class Module;
|
class Module;
|
||||||
|
@ -104,8 +103,7 @@ class VariableInfo : public SymbolInfo {
|
||||||
~VariableInfo() override;
|
~VariableInfo() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
#endif // XENIA_RUNTIME_SYMBOL_INFO_H_
|
#endif // XENIA_CPU_SYMBOL_INFO_H_
|
|
@ -12,7 +12,7 @@
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
|
|
||||||
using namespace xe::cpu::hir;
|
using namespace xe::cpu::hir;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
using namespace xe::cpu::test;
|
using namespace xe::cpu::test;
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "xenia/cpu/test/util.h"
|
#include "xenia/cpu/test/util.h"
|
||||||
|
|
||||||
using namespace xe::cpu::hir;
|
using namespace xe::cpu::hir;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
using namespace xe::cpu::test;
|
using namespace xe::cpu::test;
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
using namespace poly;
|
using namespace poly;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
|
|
||||||
using namespace xe::cpu::hir;
|
using namespace xe::cpu::hir;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
using namespace xe::cpu::test;
|
using namespace xe::cpu::test;
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
using namespace poly;
|
using namespace poly;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
|
|
||||||
using namespace xe::cpu::hir;
|
using namespace xe::cpu::hir;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
using namespace xe::cpu::test;
|
using namespace xe::cpu::test;
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
using namespace poly;
|
using namespace poly;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "xenia/cpu/test/util.h"
|
#include "xenia/cpu/test/util.h"
|
||||||
|
|
||||||
using namespace xe::cpu::hir;
|
using namespace xe::cpu::hir;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
using namespace xe::cpu::test;
|
using namespace xe::cpu::test;
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
using namespace poly;
|
using namespace poly;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "xenia/cpu/test/util.h"
|
#include "xenia/cpu/test/util.h"
|
||||||
|
|
||||||
using namespace xe::cpu::hir;
|
using namespace xe::cpu::hir;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
using namespace xe::cpu::test;
|
using namespace xe::cpu::test;
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
using namespace poly;
|
using namespace poly;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "xenia/cpu/test/util.h"
|
#include "xenia/cpu/test/util.h"
|
||||||
|
|
||||||
using namespace xe::cpu::hir;
|
using namespace xe::cpu::hir;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
using namespace xe::cpu::test;
|
using namespace xe::cpu::test;
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
using namespace poly;
|
using namespace poly;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "xenia/cpu/test/util.h"
|
#include "xenia/cpu/test/util.h"
|
||||||
|
|
||||||
using namespace xe::cpu::hir;
|
using namespace xe::cpu::hir;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
using namespace xe::cpu::test;
|
using namespace xe::cpu::test;
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "xenia/cpu/test/util.h"
|
#include "xenia/cpu/test/util.h"
|
||||||
|
|
||||||
using namespace xe::cpu::hir;
|
using namespace xe::cpu::hir;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
using namespace xe::cpu::test;
|
using namespace xe::cpu::test;
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "xenia/cpu/test/util.h"
|
#include "xenia/cpu/test/util.h"
|
||||||
|
|
||||||
using namespace xe::cpu::hir;
|
using namespace xe::cpu::hir;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
using namespace xe::cpu::test;
|
using namespace xe::cpu::test;
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
using namespace poly;
|
using namespace poly;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "xenia/cpu/test/util.h"
|
#include "xenia/cpu/test/util.h"
|
||||||
|
|
||||||
using namespace xe::cpu::hir;
|
using namespace xe::cpu::hir;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
using namespace xe::cpu::test;
|
using namespace xe::cpu::test;
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
using namespace poly;
|
using namespace poly;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "xenia/cpu/test/util.h"
|
#include "xenia/cpu/test/util.h"
|
||||||
|
|
||||||
using namespace xe::cpu::hir;
|
using namespace xe::cpu::hir;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
using namespace xe::cpu::test;
|
using namespace xe::cpu::test;
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
using namespace poly;
|
using namespace poly;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
|
|
||||||
using namespace xe::cpu::hir;
|
using namespace xe::cpu::hir;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
using namespace xe::cpu::test;
|
using namespace xe::cpu::test;
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
using namespace poly;
|
using namespace poly;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
|
|
||||||
using namespace xe::cpu::hir;
|
using namespace xe::cpu::hir;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
using namespace xe::cpu::test;
|
using namespace xe::cpu::test;
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
using namespace poly;
|
using namespace poly;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
|
|
||||||
using namespace xe::cpu::hir;
|
using namespace xe::cpu::hir;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
using namespace xe::cpu::test;
|
using namespace xe::cpu::test;
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
using namespace poly;
|
using namespace poly;
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "xenia/cpu/test/util.h"
|
#include "xenia/cpu/test/util.h"
|
||||||
|
|
||||||
using namespace xe::cpu::hir;
|
using namespace xe::cpu::hir;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
using namespace xe::cpu::test;
|
using namespace xe::cpu::test;
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
using namespace poly;
|
using namespace poly;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "xenia/cpu/test/util.h"
|
#include "xenia/cpu/test/util.h"
|
||||||
|
|
||||||
using namespace xe::cpu::hir;
|
using namespace xe::cpu::hir;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
using namespace xe::cpu::test;
|
using namespace xe::cpu::test;
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
using namespace poly;
|
using namespace poly;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "xenia/cpu/test/util.h"
|
#include "xenia/cpu/test/util.h"
|
||||||
|
|
||||||
using namespace xe::cpu::hir;
|
using namespace xe::cpu::hir;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
using namespace xe::cpu::test;
|
using namespace xe::cpu::test;
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
using namespace poly;
|
using namespace poly;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "xenia/cpu/test/util.h"
|
#include "xenia/cpu/test/util.h"
|
||||||
|
|
||||||
using namespace xe::cpu::hir;
|
using namespace xe::cpu::hir;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
using namespace xe::cpu::test;
|
using namespace xe::cpu::test;
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
using namespace poly;
|
using namespace poly;
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include "xenia/cpu/frontend/ppc/ppc_context.h"
|
#include "xenia/cpu/frontend/ppc/ppc_context.h"
|
||||||
#include "xenia/cpu/frontend/ppc/ppc_frontend.h"
|
#include "xenia/cpu/frontend/ppc/ppc_frontend.h"
|
||||||
#include "xenia/cpu/hir/hir_builder.h"
|
#include "xenia/cpu/hir/hir_builder.h"
|
||||||
#include "xenia/cpu/runtime/test_module.h"
|
#include "xenia/cpu/test_module.h"
|
||||||
#include "poly/main.h"
|
#include "poly/main.h"
|
||||||
#include "poly/poly.h"
|
#include "poly/poly.h"
|
||||||
|
|
||||||
|
@ -28,56 +28,7 @@ namespace cpu {
|
||||||
namespace test {
|
namespace test {
|
||||||
|
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
using xe::cpu::runtime::Runtime;
|
using xe::cpu::Runtime;
|
||||||
|
|
||||||
class ThreadState : public xe::cpu::runtime::ThreadState {
|
|
||||||
public:
|
|
||||||
ThreadState(Runtime* runtime, uint32_t thread_id, uint64_t stack_address,
|
|
||||||
size_t stack_size, uint64_t thread_state_address)
|
|
||||||
: xe::cpu::runtime::ThreadState(runtime, thread_id),
|
|
||||||
stack_address_(stack_address),
|
|
||||||
stack_size_(stack_size),
|
|
||||||
thread_state_address_(thread_state_address) {
|
|
||||||
memset(memory_->Translate(stack_address_), 0, stack_size_);
|
|
||||||
|
|
||||||
// Allocate with 64b alignment.
|
|
||||||
context_ = (PPCContext*)calloc(1, sizeof(PPCContext));
|
|
||||||
assert_true((reinterpret_cast<uint64_t>(context_) & 0xF) == 0);
|
|
||||||
|
|
||||||
// Stash pointers to common structures that callbacks may need.
|
|
||||||
context_->reserve_address = memory_->reserve_address();
|
|
||||||
context_->reserve_value = memory_->reserve_value();
|
|
||||||
context_->membase = memory_->membase();
|
|
||||||
context_->runtime = runtime;
|
|
||||||
context_->thread_state = this;
|
|
||||||
|
|
||||||
// Set initial registers.
|
|
||||||
context_->r[1] = stack_address_ + stack_size;
|
|
||||||
context_->r[13] = thread_state_address_;
|
|
||||||
|
|
||||||
// Pad out stack a bit, as some games seem to overwrite the caller by about
|
|
||||||
// 16 to 32b.
|
|
||||||
context_->r[1] -= 64;
|
|
||||||
|
|
||||||
raw_context_ = context_;
|
|
||||||
|
|
||||||
runtime_->debugger()->OnThreadCreated(this);
|
|
||||||
}
|
|
||||||
~ThreadState() override {
|
|
||||||
runtime_->debugger()->OnThreadDestroyed(this);
|
|
||||||
free(context_);
|
|
||||||
}
|
|
||||||
|
|
||||||
PPCContext* context() const { return context_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint64_t stack_address_;
|
|
||||||
size_t stack_size_;
|
|
||||||
uint64_t thread_state_address_;
|
|
||||||
|
|
||||||
// NOTE: must be 64b aligned for SSE ops.
|
|
||||||
PPCContext* context_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TestFunction {
|
class TestFunction {
|
||||||
public:
|
public:
|
||||||
|
@ -88,18 +39,16 @@ class TestFunction {
|
||||||
|
|
||||||
#if XENIA_TEST_X64
|
#if XENIA_TEST_X64
|
||||||
{
|
{
|
||||||
auto runtime = std::make_unique<Runtime>(memory.get());
|
auto runtime = std::make_unique<Runtime>(memory.get(), nullptr, 0, 0);
|
||||||
auto frontend =
|
|
||||||
std::make_unique<xe::cpu::frontend::ppc::PPCFrontend>(runtime.get());
|
|
||||||
auto backend =
|
auto backend =
|
||||||
std::make_unique<xe::cpu::backend::x64::X64Backend>(runtime.get());
|
std::make_unique<xe::cpu::backend::x64::X64Backend>(runtime.get());
|
||||||
runtime->Initialize(std::move(frontend), std::move(backend));
|
runtime->Initialize(std::move(backend));
|
||||||
runtimes.emplace_back(std::move(runtime));
|
runtimes.emplace_back(std::move(runtime));
|
||||||
}
|
}
|
||||||
#endif // XENIA_TEST_X64
|
#endif // XENIA_TEST_X64
|
||||||
|
|
||||||
for (auto& runtime : runtimes) {
|
for (auto& runtime : runtimes) {
|
||||||
auto module = std::make_unique<xe::cpu::runtime::TestModule>(
|
auto module = std::make_unique<xe::cpu::TestModule>(
|
||||||
runtime.get(), "Test",
|
runtime.get(), "Test",
|
||||||
[](uint64_t address) { return address == 0x1000; },
|
[](uint64_t address) { return address == 0x1000; },
|
||||||
[generator](hir::HIRBuilder& b) {
|
[generator](hir::HIRBuilder& b) {
|
||||||
|
@ -120,7 +69,7 @@ class TestFunction {
|
||||||
for (auto& runtime : runtimes) {
|
for (auto& runtime : runtimes) {
|
||||||
memory->Zero(0, memory_size);
|
memory->Zero(0, memory_size);
|
||||||
|
|
||||||
xe::cpu::runtime::Function* fn;
|
xe::cpu::Function* fn;
|
||||||
runtime->ResolveFunction(0x1000, &fn);
|
runtime->ResolveFunction(0x1000, &fn);
|
||||||
|
|
||||||
uint64_t stack_size = 64 * 1024;
|
uint64_t stack_size = 64 * 1024;
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace cpu {
|
||||||
namespace test {
|
namespace test {
|
||||||
|
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
using xe::cpu::runtime::Runtime;
|
using xe::cpu::Runtime;
|
||||||
|
|
||||||
int main(std::vector<std::wstring>& args) {
|
int main(std::vector<std::wstring>& args) {
|
||||||
std::vector<std::string> narrow_args;
|
std::vector<std::string> narrow_args;
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "xenia/cpu/backend/x64/x64_backend.h"
|
#include "xenia/cpu/backend/x64/x64_backend.h"
|
||||||
#include "xenia/cpu/frontend/ppc/ppc_context.h"
|
#include "xenia/cpu/frontend/ppc/ppc_context.h"
|
||||||
#include "xenia/cpu/frontend/ppc/ppc_frontend.h"
|
#include "xenia/cpu/frontend/ppc/ppc_frontend.h"
|
||||||
#include "xenia/cpu/runtime/raw_module.h"
|
#include "xenia/cpu/raw_module.h"
|
||||||
#include "poly/main.h"
|
#include "poly/main.h"
|
||||||
#include "poly/poly.h"
|
#include "poly/poly.h"
|
||||||
|
|
||||||
|
@ -22,55 +22,7 @@ namespace cpu {
|
||||||
namespace sandbox {
|
namespace sandbox {
|
||||||
|
|
||||||
using xe::cpu::frontend::ppc::PPCContext;
|
using xe::cpu::frontend::ppc::PPCContext;
|
||||||
using xe::cpu::runtime::Runtime;
|
using xe::cpu::Runtime;
|
||||||
|
|
||||||
class ThreadState : public xe::cpu::runtime::ThreadState {
|
|
||||||
public:
|
|
||||||
ThreadState(Runtime* runtime, uint32_t thread_id, uint64_t stack_address,
|
|
||||||
size_t stack_size, uint64_t thread_state_address)
|
|
||||||
: xe::cpu::runtime::ThreadState(runtime, thread_id),
|
|
||||||
stack_address_(stack_address),
|
|
||||||
stack_size_(stack_size),
|
|
||||||
thread_state_address_(thread_state_address) {
|
|
||||||
memset(memory_->Translate(stack_address_), 0, stack_size_);
|
|
||||||
|
|
||||||
// Allocate with 64b alignment.
|
|
||||||
context_ = (PPCContext*)calloc(1, sizeof(PPCContext));
|
|
||||||
assert_true((reinterpret_cast<uint64_t>(context_) & 0xF) == 0);
|
|
||||||
|
|
||||||
// Stash pointers to common structures that callbacks may need.
|
|
||||||
context_->reserve_address = memory_->reserve_address();
|
|
||||||
context_->membase = memory_->membase();
|
|
||||||
context_->runtime = runtime;
|
|
||||||
context_->thread_state = this;
|
|
||||||
|
|
||||||
// Set initial registers.
|
|
||||||
context_->r[1] = stack_address_ + stack_size;
|
|
||||||
context_->r[13] = thread_state_address_;
|
|
||||||
|
|
||||||
// Pad out stack a bit, as some games seem to overwrite the caller by about
|
|
||||||
// 16 to 32b.
|
|
||||||
context_->r[1] -= 64;
|
|
||||||
|
|
||||||
raw_context_ = context_;
|
|
||||||
|
|
||||||
runtime_->debugger()->OnThreadCreated(this);
|
|
||||||
}
|
|
||||||
~ThreadState() override {
|
|
||||||
runtime_->debugger()->OnThreadDestroyed(this);
|
|
||||||
free(context_);
|
|
||||||
}
|
|
||||||
|
|
||||||
PPCContext* context() const { return context_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint64_t stack_address_;
|
|
||||||
size_t stack_size_;
|
|
||||||
uint64_t thread_state_address_;
|
|
||||||
|
|
||||||
// NOTE: must be 64b aligned for SSE ops.
|
|
||||||
PPCContext* context_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO(benvanik): simple memory? move more into core?
|
// TODO(benvanik): simple memory? move more into core?
|
||||||
|
|
||||||
|
@ -93,7 +45,7 @@ int main(std::vector<std::wstring>& args) {
|
||||||
// std::make_unique<xe::cpu::backend::x64::X64Backend>(runtime.get());
|
// std::make_unique<xe::cpu::backend::x64::X64Backend>(runtime.get());
|
||||||
runtime->Initialize(std::move(frontend), std::move(backend));
|
runtime->Initialize(std::move(frontend), std::move(backend));
|
||||||
|
|
||||||
auto module = std::make_unique<xe::cpu::runtime::RawModule>(runtime.get());
|
auto module = std::make_unique<xe::cpu::RawModule>(runtime.get());
|
||||||
module->LoadFile(0x00001000, L"test\\codegen\\instr_add.bin");
|
module->LoadFile(0x00001000, L"test\\codegen\\instr_add.bin");
|
||||||
runtime->AddModule(std::move(module));
|
runtime->AddModule(std::move(module));
|
||||||
|
|
||||||
|
@ -104,7 +56,7 @@ int main(std::vector<std::wstring>& args) {
|
||||||
auto thread_state = std::make_unique<ThreadState>(
|
auto thread_state = std::make_unique<ThreadState>(
|
||||||
runtime.get(), 100, stack_address, stack_size, thread_state_address);
|
runtime.get(), 100, stack_address, stack_size, thread_state_address);
|
||||||
|
|
||||||
xe::cpu::runtime::Function* fn;
|
xe::cpu::Function* fn;
|
||||||
runtime->ResolveFunction(0x1000, &fn);
|
runtime->ResolveFunction(0x1000, &fn);
|
||||||
auto ctx = thread_state->context();
|
auto ctx = thread_state->context();
|
||||||
ctx->lr = 0xBEBEBEBE;
|
ctx->lr = 0xBEBEBEBE;
|
||||||
|
|
|
@ -7,23 +7,20 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/test_module.h"
|
#include "xenia/cpu/test_module.h"
|
||||||
|
|
||||||
#include "xenia/cpu/compiler/compiler_passes.h"
|
#include "xenia/cpu/compiler/compiler_passes.h"
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
#include "poly/platform.h"
|
#include "poly/platform.h"
|
||||||
#include "poly/reset_scope.h"
|
#include "poly/reset_scope.h"
|
||||||
#include "poly/string.h"
|
#include "poly/string.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
|
|
||||||
using xe::cpu::backend::Backend;
|
using xe::cpu::backend::Backend;
|
||||||
using xe::cpu::compiler::Compiler;
|
using xe::cpu::compiler::Compiler;
|
||||||
using xe::cpu::hir::HIRBuilder;
|
using xe::cpu::hir::HIRBuilder;
|
||||||
using xe::cpu::runtime::Function;
|
|
||||||
using xe::cpu::runtime::FunctionInfo;
|
|
||||||
namespace passes = xe::cpu::compiler::passes;
|
namespace passes = xe::cpu::compiler::passes;
|
||||||
|
|
||||||
TestModule::TestModule(Runtime* runtime, const std::string& name,
|
TestModule::TestModule(Runtime* runtime, const std::string& name,
|
||||||
|
@ -100,6 +97,5 @@ SymbolInfo::Status TestModule::DeclareFunction(uint64_t address,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
|
@ -7,8 +7,8 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XENIA_RUNTIME_TEST_MODULE_H_
|
#ifndef XENIA_CPU_TEST_MODULE_H_
|
||||||
#define XENIA_RUNTIME_TEST_MODULE_H_
|
#define XENIA_CPU_TEST_MODULE_H_
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -17,11 +17,10 @@
|
||||||
#include "xenia/cpu/backend/assembler.h"
|
#include "xenia/cpu/backend/assembler.h"
|
||||||
#include "xenia/cpu/compiler/compiler.h"
|
#include "xenia/cpu/compiler/compiler.h"
|
||||||
#include "xenia/cpu/hir/hir_builder.h"
|
#include "xenia/cpu/hir/hir_builder.h"
|
||||||
#include "xenia/cpu/runtime/module.h"
|
#include "xenia/cpu/module.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
|
|
||||||
class TestModule : public Module {
|
class TestModule : public Module {
|
||||||
public:
|
public:
|
||||||
|
@ -47,8 +46,7 @@ class TestModule : public Module {
|
||||||
std::unique_ptr<backend::Assembler> assembler_;
|
std::unique_ptr<backend::Assembler> assembler_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
#endif // XENIA_RUNTIME_TEST_MODULE_H_
|
#endif // XENIA_CPU_TEST_MODULE_H_
|
|
@ -7,24 +7,47 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "xenia/cpu/xenon_thread_state.h"
|
#include "xenia/cpu/thread_state.h"
|
||||||
|
|
||||||
#include "xdb/protocol.h"
|
#include "xdb/protocol.h"
|
||||||
#include "xenia/cpu/xenon_runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
|
|
||||||
using namespace xe::cpu::frontend;
|
using namespace xe::cpu::frontend;
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
|
|
||||||
XenonThreadState::XenonThreadState(XenonRuntime* runtime, uint32_t thread_id,
|
using PPCContext = xe::cpu::frontend::ppc::PPCContext;
|
||||||
size_t stack_size,
|
|
||||||
uint64_t thread_state_address)
|
thread_local ThreadState* thread_state_ = nullptr;
|
||||||
: ThreadState(runtime, thread_id),
|
|
||||||
|
ThreadState::ThreadState(Runtime* runtime, uint32_t thread_id,
|
||||||
|
uint64_t stack_address, size_t stack_size,
|
||||||
|
uint64_t thread_state_address)
|
||||||
|
: runtime_(runtime),
|
||||||
|
memory_(runtime->memory()),
|
||||||
|
thread_id_(thread_id),
|
||||||
|
name_(""),
|
||||||
|
backend_data_(0),
|
||||||
|
raw_context_(0),
|
||||||
stack_size_(stack_size),
|
stack_size_(stack_size),
|
||||||
thread_state_address_(thread_state_address) {
|
thread_state_address_(thread_state_address) {
|
||||||
stack_address_ = xenon_memory()->HeapAlloc(0, stack_size, MEMORY_FLAG_ZERO);
|
if (thread_id_ == UINT_MAX) {
|
||||||
|
// System thread. Assign the system thread ID with a high bit
|
||||||
|
// set so people know what's up.
|
||||||
|
uint32_t system_thread_handle = poly::threading::current_thread_id();
|
||||||
|
thread_id_ = 0x80000000 | system_thread_handle;
|
||||||
|
}
|
||||||
|
backend_data_ = runtime->backend()->AllocThreadData();
|
||||||
|
|
||||||
|
if (!stack_address) {
|
||||||
|
stack_address_ = memory()->HeapAlloc(0, stack_size, MEMORY_FLAG_ZERO);
|
||||||
|
stack_allocated_ = true;
|
||||||
|
} else {
|
||||||
|
stack_address_ = stack_address;
|
||||||
|
stack_allocated_ = false;
|
||||||
|
}
|
||||||
assert_not_zero(stack_address_);
|
assert_not_zero(stack_address_);
|
||||||
|
|
||||||
// Allocate with 64b alignment.
|
// Allocate with 64b alignment.
|
||||||
|
@ -52,14 +75,31 @@ XenonThreadState::XenonThreadState(XenonRuntime* runtime, uint32_t thread_id,
|
||||||
runtime_->debugger()->OnThreadCreated(this);
|
runtime_->debugger()->OnThreadCreated(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
XenonThreadState::~XenonThreadState() {
|
ThreadState::~ThreadState() {
|
||||||
runtime_->debugger()->OnThreadDestroyed(this);
|
runtime_->debugger()->OnThreadDestroyed(this);
|
||||||
|
|
||||||
|
if (backend_data_) {
|
||||||
|
runtime_->backend()->FreeThreadData(backend_data_);
|
||||||
|
}
|
||||||
|
if (thread_state_ == this) {
|
||||||
|
thread_state_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
free(context_);
|
free(context_);
|
||||||
xenon_memory()->HeapFree(stack_address_, stack_size_);
|
if (stack_allocated_) {
|
||||||
|
memory()->HeapFree(stack_address_, stack_size_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XenonThreadState::WriteRegisters(xdb::protocol::Registers* registers) {
|
void ThreadState::Bind(ThreadState* thread_state) {
|
||||||
|
thread_state_ = thread_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadState* ThreadState::Get() { return thread_state_; }
|
||||||
|
|
||||||
|
uint32_t ThreadState::GetThreadID() { return thread_state_->thread_id_; }
|
||||||
|
|
||||||
|
void ThreadState::WriteRegisters(xdb::protocol::Registers* registers) {
|
||||||
registers->lr = context_->lr;
|
registers->lr = context_->lr;
|
||||||
registers->ctr = context_->ctr;
|
registers->ctr = context_->ctr;
|
||||||
registers->xer = 0xFEFEFEFE;
|
registers->xer = 0xFEFEFEFE;
|
|
@ -7,23 +7,30 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XENIA_RUNTIME_THREAD_STATE_H_
|
#ifndef XENIA_CPU_thread_state_H_
|
||||||
#define XENIA_RUNTIME_THREAD_STATE_H_
|
#define XENIA_CPU_thread_state_H_
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
|
#include "xenia/cpu/frontend/ppc/ppc_context.h"
|
||||||
|
#include "xenia/cpu/thread_state.h"
|
||||||
|
#include "xenia/common.h"
|
||||||
#include "xenia/memory.h"
|
#include "xenia/memory.h"
|
||||||
|
|
||||||
|
namespace xdb {
|
||||||
|
namespace protocol {
|
||||||
|
struct Registers;
|
||||||
|
} // namespace protocol
|
||||||
|
} // namespace xdb
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace runtime {
|
|
||||||
|
|
||||||
class Runtime;
|
class Runtime;
|
||||||
|
|
||||||
class ThreadState {
|
class ThreadState {
|
||||||
public:
|
public:
|
||||||
ThreadState(Runtime* runtime, uint32_t thread_id);
|
ThreadState(Runtime* runtime, uint32_t thread_id, uint64_t stack_address,
|
||||||
virtual ~ThreadState();
|
size_t stack_size, uint64_t thread_state_address);
|
||||||
|
~ThreadState();
|
||||||
|
|
||||||
Runtime* runtime() const { return runtime_; }
|
Runtime* runtime() const { return runtime_; }
|
||||||
Memory* memory() const { return memory_; }
|
Memory* memory() const { return memory_; }
|
||||||
|
@ -32,26 +39,38 @@ class ThreadState {
|
||||||
void set_name(const std::string& value) { name_ = value; }
|
void set_name(const std::string& value) { name_ = value; }
|
||||||
void* backend_data() const { return backend_data_; }
|
void* backend_data() const { return backend_data_; }
|
||||||
void* raw_context() const { return raw_context_; }
|
void* raw_context() const { return raw_context_; }
|
||||||
|
uint64_t stack_address() const { return stack_address_; }
|
||||||
|
size_t stack_size() const { return stack_size_; }
|
||||||
|
uint64_t thread_state_address() const { return thread_state_address_; }
|
||||||
|
xe::cpu::frontend::ppc::PPCContext* context() const { return context_; }
|
||||||
|
|
||||||
int Suspend() { return Suspend(~0); }
|
int Suspend() { return Suspend(~0); }
|
||||||
virtual int Suspend(uint32_t timeout_ms) { return 1; }
|
int Suspend(uint32_t timeout_ms) { return 1; }
|
||||||
virtual int Resume(bool force = false) { return 1; }
|
int Resume(bool force = false) { return 1; }
|
||||||
|
|
||||||
static void Bind(ThreadState* thread_state);
|
static void Bind(ThreadState* thread_state);
|
||||||
static ThreadState* Get();
|
static ThreadState* Get();
|
||||||
static uint32_t GetThreadID();
|
static uint32_t GetThreadID();
|
||||||
|
|
||||||
protected:
|
void WriteRegisters(xdb::protocol::Registers* registers);
|
||||||
|
|
||||||
|
private:
|
||||||
Runtime* runtime_;
|
Runtime* runtime_;
|
||||||
Memory* memory_;
|
Memory* memory_;
|
||||||
uint32_t thread_id_;
|
uint32_t thread_id_;
|
||||||
std::string name_;
|
std::string name_;
|
||||||
void* backend_data_;
|
void* backend_data_;
|
||||||
void* raw_context_;
|
void* raw_context_;
|
||||||
|
uint64_t stack_address_;
|
||||||
|
bool stack_allocated_;
|
||||||
|
size_t stack_size_;
|
||||||
|
uint64_t thread_state_address_;
|
||||||
|
|
||||||
|
// NOTE: must be 64b aligned for SSE ops.
|
||||||
|
xe::cpu::frontend::ppc::PPCContext* context_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace runtime
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
#endif // XENIA_RUNTIME_THREAD_STATE_H_
|
#endif // XENIA_CPU_thread_state_H_
|
|
@ -1,39 +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/xenon_runtime.h"
|
|
||||||
|
|
||||||
#include "xenia/cpu/frontend/ppc/ppc_frontend.h"
|
|
||||||
#include "xenia/cpu/xenon_thread_state.h"
|
|
||||||
|
|
||||||
namespace xe {
|
|
||||||
namespace cpu {
|
|
||||||
|
|
||||||
XenonRuntime::XenonRuntime(Memory* memory, ExportResolver* export_resolver,
|
|
||||||
uint32_t debug_info_flags, uint32_t trace_flags)
|
|
||||||
: Runtime(memory, debug_info_flags, trace_flags),
|
|
||||||
export_resolver_(export_resolver) {}
|
|
||||||
|
|
||||||
XenonRuntime::~XenonRuntime() = default;
|
|
||||||
|
|
||||||
int XenonRuntime::Initialize(
|
|
||||||
std::unique_ptr<xe::cpu::backend::Backend> backend) {
|
|
||||||
auto frontend = std::make_unique<xe::cpu::frontend::ppc::PPCFrontend>(this);
|
|
||||||
// TODO(benvanik): set options/etc.
|
|
||||||
|
|
||||||
int result = Runtime::Initialize(std::move(frontend), std::move(backend));
|
|
||||||
if (result) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace cpu
|
|
||||||
} // namespace xe
|
|
|
@ -1,42 +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_XENON_RUNTIME_H_
|
|
||||||
#define XENIA_CPU_XENON_RUNTIME_H_
|
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/runtime.h"
|
|
||||||
#include "xenia/common.h"
|
|
||||||
#include "xenia/cpu/xenon_thread_state.h"
|
|
||||||
#include "xenia/export_resolver.h"
|
|
||||||
#include "xenia/memory.h"
|
|
||||||
|
|
||||||
namespace xe {
|
|
||||||
namespace cpu {
|
|
||||||
|
|
||||||
class XenonThreadState;
|
|
||||||
|
|
||||||
class XenonRuntime : public xe::cpu::runtime::Runtime {
|
|
||||||
public:
|
|
||||||
XenonRuntime(Memory* memory, ExportResolver* export_resolver,
|
|
||||||
uint32_t debug_info_flags, uint32_t trace_flags);
|
|
||||||
virtual ~XenonRuntime();
|
|
||||||
|
|
||||||
ExportResolver* export_resolver() const { return export_resolver_; }
|
|
||||||
|
|
||||||
virtual int Initialize(
|
|
||||||
std::unique_ptr<xe::cpu::backend::Backend> backend = 0);
|
|
||||||
|
|
||||||
private:
|
|
||||||
ExportResolver* export_resolver_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace cpu
|
|
||||||
} // namespace xe
|
|
||||||
|
|
||||||
#endif // XENIA_CPU_XENON_RUNTIME_H_
|
|
|
@ -1,57 +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_XENON_THREAD_STATE_H_
|
|
||||||
#define XENIA_CPU_XENON_THREAD_STATE_H_
|
|
||||||
|
|
||||||
#include "xenia/cpu/frontend/ppc/ppc_context.h"
|
|
||||||
#include "xenia/cpu/runtime/thread_state.h"
|
|
||||||
#include "xenia/common.h"
|
|
||||||
#include "xenia/memory.h"
|
|
||||||
|
|
||||||
namespace xdb {
|
|
||||||
namespace protocol {
|
|
||||||
struct Registers;
|
|
||||||
} // namespace protocol
|
|
||||||
} // namespace xdb
|
|
||||||
|
|
||||||
namespace xe {
|
|
||||||
namespace cpu {
|
|
||||||
|
|
||||||
class XenonRuntime;
|
|
||||||
|
|
||||||
using PPCContext = xe::cpu::frontend::ppc::PPCContext;
|
|
||||||
|
|
||||||
class XenonThreadState : public xe::cpu::runtime::ThreadState {
|
|
||||||
public:
|
|
||||||
XenonThreadState(XenonRuntime* runtime, uint32_t thread_id, size_t stack_size,
|
|
||||||
uint64_t thread_state_address);
|
|
||||||
virtual ~XenonThreadState();
|
|
||||||
|
|
||||||
Memory* xenon_memory() { return static_cast<Memory*>(memory_); }
|
|
||||||
uint64_t stack_address() const { return stack_address_; }
|
|
||||||
size_t stack_size() const { return stack_size_; }
|
|
||||||
uint64_t thread_state_address() const { return thread_state_address_; }
|
|
||||||
PPCContext* context() const { return context_; }
|
|
||||||
|
|
||||||
void WriteRegisters(xdb::protocol::Registers* registers);
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint64_t stack_address_;
|
|
||||||
size_t stack_size_;
|
|
||||||
uint64_t thread_state_address_;
|
|
||||||
|
|
||||||
// NOTE: must be 64b aligned for SSE ops.
|
|
||||||
PPCContext* context_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace cpu
|
|
||||||
} // namespace xe
|
|
||||||
|
|
||||||
#endif // XENIA_CPU_XENON_THREAD_STATE_H_
|
|
|
@ -13,19 +13,21 @@
|
||||||
|
|
||||||
#include "poly/math.h"
|
#include "poly/math.h"
|
||||||
#include "xenia/cpu/cpu-private.h"
|
#include "xenia/cpu/cpu-private.h"
|
||||||
#include "xenia/cpu/xenon_runtime.h"
|
#include "xenia/cpu/runtime.h"
|
||||||
#include "xenia/export_resolver.h"
|
#include "xenia/export_resolver.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
|
|
||||||
using namespace xe::cpu::runtime;
|
using namespace xe::cpu;
|
||||||
|
|
||||||
|
using PPCContext = xe::cpu::frontend::ppc::PPCContext;
|
||||||
|
|
||||||
void UndefinedImport(PPCContext* ppc_state, void* arg0, void* arg1) {
|
void UndefinedImport(PPCContext* ppc_state, void* arg0, void* arg1) {
|
||||||
XELOGE("call to undefined kernel import");
|
XELOGE("call to undefined kernel import");
|
||||||
}
|
}
|
||||||
|
|
||||||
XexModule::XexModule(XenonRuntime* runtime)
|
XexModule::XexModule(Runtime* runtime)
|
||||||
: Module(runtime),
|
: Module(runtime),
|
||||||
runtime_(runtime),
|
runtime_(runtime),
|
||||||
xex_(nullptr),
|
xex_(nullptr),
|
||||||
|
|
|
@ -12,18 +12,18 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "xenia/cpu/runtime/module.h"
|
#include "xenia/cpu/module.h"
|
||||||
#include "xenia/common.h"
|
#include "xenia/common.h"
|
||||||
#include "xenia/kernel/util/xex2.h"
|
#include "xenia/kernel/util/xex2.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
|
|
||||||
class XenonRuntime;
|
class Runtime;
|
||||||
|
|
||||||
class XexModule : public xe::cpu::runtime::Module {
|
class XexModule : public xe::cpu::Module {
|
||||||
public:
|
public:
|
||||||
XexModule(XenonRuntime* runtime);
|
XexModule(Runtime* runtime);
|
||||||
virtual ~XexModule();
|
virtual ~XexModule();
|
||||||
|
|
||||||
xe_xex2_ref xex() const { return xex_; }
|
xe_xex2_ref xex() const { return xex_; }
|
||||||
|
@ -40,7 +40,7 @@ private:
|
||||||
int FindSaveRest();
|
int FindSaveRest();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
XenonRuntime* runtime_;
|
Runtime* runtime_;
|
||||||
std::string name_;
|
std::string name_;
|
||||||
std::string path_;
|
std::string path_;
|
||||||
xe_xex2_ref xex_;
|
xe_xex2_ref xex_;
|
||||||
|
|
|
@ -25,7 +25,7 @@ class AudioSystem;
|
||||||
} // namespace apu
|
} // namespace apu
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
class Processor;
|
class Processor;
|
||||||
class XenonThreadState;
|
class ThreadState;
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
class GraphicsSystem;
|
class GraphicsSystem;
|
||||||
|
|
|
@ -194,8 +194,8 @@ X_STATUS XThread::Create() {
|
||||||
// Allocate processor thread state.
|
// Allocate processor thread state.
|
||||||
// This is thread safe.
|
// This is thread safe.
|
||||||
thread_state_ =
|
thread_state_ =
|
||||||
new XenonThreadState(kernel_state()->processor()->runtime(), thread_id_,
|
new ThreadState(kernel_state()->processor()->runtime(), thread_id_, 0,
|
||||||
creation_params_.stack_size, thread_state_address_);
|
creation_params_.stack_size, thread_state_address_);
|
||||||
|
|
||||||
X_STATUS return_code = PlatformCreate();
|
X_STATUS return_code = PlatformCreate();
|
||||||
if (XFAILED(return_code)) {
|
if (XFAILED(return_code)) {
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "xenia/cpu/xenon_thread_state.h"
|
#include "xenia/cpu/thread_state.h"
|
||||||
#include "xenia/kernel/xobject.h"
|
#include "xenia/kernel/xobject.h"
|
||||||
#include "xenia/xbox.h"
|
#include "xenia/xbox.h"
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ class XThread : public XObject {
|
||||||
uint32_t scratch_size_;
|
uint32_t scratch_size_;
|
||||||
uint32_t tls_address_;
|
uint32_t tls_address_;
|
||||||
uint32_t thread_state_address_;
|
uint32_t thread_state_address_;
|
||||||
cpu::XenonThreadState* thread_state_;
|
cpu::ThreadState* thread_state_;
|
||||||
|
|
||||||
std::string name_;
|
std::string name_;
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue