Files
Xenia-Canary/RUST_PORT_CODEMAP.md
2026-04-12 18:25:46 +02:00

164 lines
6.3 KiB
Markdown

## Xenia Xbox 360 Emulator: JIT vs Interpreter Architecture Analysis
Analysis of Xenia's architecture comparing JIT vs interpreter approaches for Rust porting. Key findings: JIT pipeline [1a-1d] uses Xbyak with no Rust equivalent, MMIO relies on hardware exceptions [2a-2d], while interpreter approach uses explicit MMIO checking [3a-3d]. The PPC context [4a-4d] and opcode infrastructure [5a-5d] support both approaches. Memory system [6a-6c] requires unsafe Rust regardless. Kernel HLE [7a-7c] and GPU shader translation [8a-8c] present additional challenges.
### 1. JIT Code Generation Pipeline
The current PPC-to-x64 JIT compilation pipeline using HIR and Xbyak
### 1a. JIT Pipeline Initialization (`ppc_translator.cc:44`)
Sets up scanner, HIR builder, compiler, and Xbyak assembler
```text
PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) {
```
### 1b. HIR Optimization Passes (`ppc_translator.cc:57`)
Adds multiple optimization passes to the compiler pipeline
```text
compiler_->AddPass(std::make_unique<passes::ControlFlowAnalysisPass>());
```
### 1c. Xbyak-based Code Emitter (`x64_emitter.h:208`)
X64Emitter inherits from Xbyak for runtime x64 code generation
```text
class X64Emitter : public Xbyak::CodeGenerator {
```
### 1d. Host-to-Guest Thunk (`x64_backend.cc:656`)
Raw x64 assembly emitted for host↔guest ABI transitions
```text
mov(rdi, ptr[rsi + offsetof(ppc::PPCContext, virtual_membase)]); // membase
```
### 2. MMIO Exception Handling
Hardware exception-based MMIO interception used by the JIT
### 2a. Exception Handler Entry (`mmio_handler.cc:402`)
Catches access violations to handle MMIO operations
```text
bool MMIOHandler::ExceptionCallback(Exception* ex) {
```
### 2b. Filter Access Violations (`mmio_handler.cc:403`)
Only processes memory access violations
```text
if (ex->code() != Exception::Code::kAccessViolation) {
```
### 2c. Address Translation (`mmio_handler.cc:427`)
Translates host fault address back to guest virtual address
```text
fault_guest_virtual_address = host_to_guest_virtual_(
```
### 2d. Instruction Decoding (`mmio_handler.cc:449`)
Decodes the faulting x64 instruction to determine the operation
```text
if (!TryDecodeLoadStore(p, decoded_load_store)) {
```
### 3. Interpreter Alternative Approach
Explicit MMIO checking pattern that enables interpreter implementation
### 3a. Explicit MMIO Check Function (`x64_seq_memory.cc:1216`)
Pattern for checking MMIO ranges without exceptions
```text
static T MMIOAwareLoad(void* _ctx, unsigned int guestaddr) {
```
### 3b. Range Lookup (`x64_seq_memory.cc:1225`)
Explicitly checks if address is in mapped MMIO range
```text
auto gaddr = ctx->processor->memory()->LookupVirtualMappedRange(guestaddr);
```
### 3c. MMIO Callback Invocation (`x64_seq_memory.cc:1236`)
Calls MMIO read callback instead of accessing memory directly
```text
value = gaddr->read(nullptr, gaddr->callback_context, guestaddr);
```
### 3d. MMIO Handler Interface (`mmio_handler.h:73`)
Public API for explicit MMIO checking in interpreter mode
```text
bool CheckLoad(uint32_t virtual_address, uint32_t* out_value);
```
### 4. PPC Context and State Management
Register file and thread state structures that would need Rust porting
### 4a. PPC Register File (`ppc_context.h:378`)
32 GPRs, CTR, LR, MSR in the context structure
```text
uint64_t r[32]; // 0x20 General purpose registers
```
### 4b. Floating-Point and Vector Registers (`ppc_context.h:384`)
32 FPRs and 128 VMX128 vector registers
```text
double f[32]; // 0x120 Floating-point registers
```
### 4c. Thread State Context (`thread_state.h:49`)
Each guest thread owns a PPCContext pointer
```text
ppc::PPCContext* context_;
```
### 4d. Big-Endian Wrapper (`byte_order.h:134`)
Type that handles big-endian conversion for guest structures
```text
template <typename T>
using be = endian_store<T, std::endian::big>;
```
### 5. Opcode Dispatch Infrastructure
PPC opcode enumeration and lookup that enables interpreter implementation
### 5a. PPC Opcode Enumeration (`ppc_opcode.h:14`)
Complete enum of all PPC opcodes including VMX128 extensions
```text
enum class PPCOpcode : uint32_t {
```
### 5b. Opcode Dispatch Table (`ppc_opcode_lookup_gen.cc:262`)
Fast lookup table for opcode decoding
```text
case 0b000101: PPC_DECODER_HIT(vrlw128);
```
### 5c. VMX128 Instruction Encoding (`ppc_emit_altivec.cc:37`)
Macros for decoding Xbox 360-specific VMX128 instructions
```text
#define VX128(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x3d0))
```
### 5d. Basic Block Discovery (`ppc_scanner.h:36`)
Finds basic block boundaries for potential interpreter caching
```text
std::vector<BlockInfo> FindBlocks(GuestFunction* function);
```
### 6. Memory System Architecture
4GB virtual address space management required for both approaches
### 6a. Virtual Memory Allocation (`memory.cc:142`)
Creates 4GB+ file-backed mapping for guest address space
```text
mapping_ = xe::memory::CreateFileMappingHandle(
```
### 6b. Virtual Memory Base (`memory.cc:167`)
Sets up virtual and physical memory base addresses
```text
virtual_membase_ = mapping_base_;
```
### 6c. Guest Address Translation (`ppc_context.h:433`)
Fast inline function for translating guest to host addresses
```text
inline T TranslateVirtual(uint32_t guest_address) const {
```
### 7. Kernel HLE System
Massive kernel export table that would need Rust porting
### 7a. Kernel Export Table (`xboxkrnl_table.inc:15`)
96KB+ table of all xboxkrnl exports
```text
XE_EXPORT(xboxkrnl, 0x00000001, DbgBreakPoint, kFunction),
```
### 7b. Guest Thread Structure (`xthread.h:256`)
Packed big-endian X_KTHREAD structure living in guest memory
```text
xe::be<uint32_t> stack_base; // 0x5C
```
### 7c. Kernel State Management (`emulator.h:349`)
Central kernel object tracking all guest kernel state
```text
std::unique_ptr<kernel::KernelState> kernel_state_;
```
### 8. GPU Shader Translation
Complex shader translation pipeline that poses challenges for Rust porting
### 8a. SPIR-V Builder Initialization (`spirv_shader_translator.cc:155`)
Uses glslang C++ API for SPIR-V generation
```text
builder_ = std::make_unique<SpirvBuilder>(
```
### 8b. Shader Interpreter (`shader_interpreter.h:51`)
Existing interpreter for simple shaders without texture fetches
```text
static bool CanInterpretShader(const Shader& shader) {
```
### 8c. C++ Dependency (`premake5.lua:31`)
glslang dependency with no direct Rust equivalent
```text
"glslang-spirv",
```