diff --git a/tools/alloy-sandbox/alloy-sandbox.cc b/tools/alloy-sandbox/alloy-sandbox.cc index db1886d26..162721ddb 100644 --- a/tools/alloy-sandbox/alloy-sandbox.cc +++ b/tools/alloy-sandbox/alloy-sandbox.cc @@ -10,62 +10,119 @@ #include #include #include +#include +#include #include #include -#include #include -#include -#include #include -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::runtime; -using namespace xe; -using namespace xe::cpu; +namespace alloy { +namespace sandbox { -int alloy_sandbox(int argc, xechar_t** argv) { - Profiler::Initialize(); +using alloy::frontend::ppc::PPCContext; +using alloy::runtime::Runtime; + +class ThreadState : public alloy::runtime::ThreadState { + public: + ThreadState(Runtime* runtime, uint32_t thread_id, size_t stack_size, + uint64_t thread_state_address) + : alloy::runtime::ThreadState(runtime, thread_id), + stack_size_(stack_size), + thread_state_address_(thread_state_address) { + stack_address_ = memory_->HeapAlloc(0, stack_size, MEMORY_FLAG_ZERO); + + // Allocate with 64b alignment. + context_ = (PPCContext*)xe_malloc_aligned(sizeof(PPCContext)); + assert_true((reinterpret_cast(context_) & 0xF) == 0); + memset(&context_, 0, sizeof(PPCContext)); + + // 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); + xe_free_aligned(context_); + memory_->HeapFree(stack_address_, stack_size_); + } + + 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? + +int main(int argc, xechar_t** argv) { + xe::Profiler::Initialize(); xe::Profiler::ThreadEnter("main"); - XenonMemory* memory = new XenonMemory(); + auto memory = std::make_unique(); + auto runtime = std::make_unique(memory.get()); - ExportResolver* export_resolver = new ExportResolver(); - XenonRuntime* runtime = new XenonRuntime(memory, export_resolver); + auto frontend = + std::make_unique(runtime.get()); + std::unique_ptr backend; + // auto backend = + // std::make_unique(runtime.get()); + // auto backend = + // std::make_unique(runtime.get()); + runtime->Initialize(std::move(frontend), std::move(backend)); - std::unique_ptr backend; - // backend.reset(new alloy::backend::ivm::IVMBackend(runtime)); - // backend.reset(new alloy::backend::x64::X64Backend(runtime)); - runtime->Initialize(std::move(backend)); - - auto module = std::make_unique(runtime); + auto module = std::make_unique(runtime.get()); module->LoadFile(0x82000000, "test\\codegen\\instr_add.bin"); runtime->AddModule(std::move(module)); - XenonThreadState* thread_state = - new XenonThreadState(runtime, 100, 64 * 1024, 0); + { + auto thread_state = + std::make_unique(runtime.get(), 100, 64 * 1024, 0); - Function* fn; - runtime->ResolveFunction(0x82000000, &fn); - auto ctx = thread_state->context(); - ctx->lr = 0xBEBEBEBE; - ctx->r[5] = 10; - ctx->r[25] = 25; - fn->Call(thread_state, ctx->lr); - auto result = ctx->r[11]; - printf("%llu", result); + alloy::runtime::Function* fn; + runtime->ResolveFunction(0x82000000, &fn); + auto ctx = thread_state->context(); + ctx->lr = 0xBEBEBEBE; + ctx->r[5] = 10; + ctx->r[25] = 25; + fn->Call(thread_state.get(), ctx->lr); + auto result = ctx->r[11]; + printf("%llu", result); + } - delete thread_state; - - delete runtime; - delete memory; + runtime.reset(); + memory.reset(); xe::Profiler::Dump(); xe::Profiler::ThreadExit(); return 0; } + +} // namespace sandbox +} // namespace alloy + +// TODO(benvanik): move main thunk into poly // ehhh #include -XE_MAIN_THUNK(alloy_sandbox, "alloy-sandbox"); +XE_MAIN_THUNK(alloy::sandbox::main, "alloy-sandbox");