JIT documentation!
This commit is contained in:
parent
ef93161114
commit
f530ef749a
71
docs/cpu.md
71
docs/cpu.md
|
@ -1,15 +1,70 @@
|
|||
# CPU Documentation
|
||||
|
||||
## Code
|
||||
## The JIT
|
||||
|
||||
Xenia uses a dynamic recompiler to recompile PPC instructions to host
|
||||
architecture instructions at runtime. Functions are converted as they
|
||||
are called by the guest/host and stored in a code cache. Currently, the
|
||||
only backend that exists is the x64 backend.
|
||||
![JIT Diagram](images/CPU-JIT.png?raw=true)
|
||||
|
||||
Unfortunately, one problem with this approach is that code usually never
|
||||
ends up in the same spot across reruns due to multithreading. Host code
|
||||
may also morph depending on which spots of a function are called first.
|
||||
The JIT is the core of Xenia. It translates Xenon PowerPC code into native
|
||||
code runnable on the host computer.
|
||||
|
||||
There are 3 phases to translation:
|
||||
1. Translation to IR (intermediate representation)
|
||||
2. IR compilation/optimization
|
||||
3. Backend emission
|
||||
|
||||
PowerPC instructions are translated to Xenia's intermediate representation
|
||||
format in src/xenia/cpu/ppc/ppc_emit_*.cc (e.g. processor control is done in
|
||||
[ppc_emit_control.cc](../src/xenia/cpu/ppc/ppc_emit_control.cc)). HIR opcodes
|
||||
are relatively simple opcodes such that any host can define an implementation.
|
||||
|
||||
After the HIR is generated, it is ran through a compiler to prep it for generation.
|
||||
The compiler is ran in a series of passes, the order of which is defined in
|
||||
[ppc_translator.cc](../src/xenia/cpu/ppc/ppc_translator.cc). Some passes are
|
||||
essential to the successful generation, while others are merely for optimization
|
||||
purposes. Compiler passes are defined in src/xenia/cpu/compiler/passes with
|
||||
descriptive class names.
|
||||
|
||||
Finally, the backend consumes the HIR and emits code that runs natively on the
|
||||
host. Currently, the only backend that exists is the x64 backend, with all the
|
||||
emission done in
|
||||
[x64_sequences.cc](../src/xenia/cpu/backend/x64/x64_sequences.cc).
|
||||
|
||||
## ABI
|
||||
|
||||
Xenia guest functions are not directly callable, but rather must be called
|
||||
through APIs provided by Xenia. Xenia will first execute a thunk to transition
|
||||
the host context to a state dependent on the JIT backend, and that will call the
|
||||
guest code.
|
||||
|
||||
### x64
|
||||
|
||||
Transition thunks defined in [x64_backend.cc](../src/xenia/cpu/backend/x64/x64_backend.cc#L389).
|
||||
Registers are stored on the stack as defined by [StackLayout::Thunk](../src/xenia/cpu/backend/x64/x64_stack_layout.h#L96)
|
||||
for later transitioning back to the host.
|
||||
|
||||
Some registers are reserved for usage by the JIT to store temporary variables.
|
||||
See: [X64Emitter::gpr_reg_map_ and X64Emitter::xmm_reg_map_](../src/xenia/cpu/backend/x64/x64_backend.cc#L57).
|
||||
|
||||
#### Integer Registers
|
||||
|
||||
Register | Usage
|
||||
--- | ---
|
||||
RAX | Scratch
|
||||
RBX | JIT temp
|
||||
RCX | Scratch
|
||||
RDX | Scratch
|
||||
RSP | Stack Pointer
|
||||
RBP | Unused
|
||||
RSI | PowerPC Context
|
||||
RDI | Virtual Memory Base
|
||||
R8-R11 | Unused (parameters)
|
||||
R12-R15 | JIT temp
|
||||
|
||||
#### Floating Point Registers
|
||||
Register | Usage
|
||||
--- | ---
|
||||
XMM0-XMM5 | Scratch
|
||||
XMM6-XMM15 | JIT temp
|
||||
|
||||
## Memory
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
Loading…
Reference in New Issue