[Rust] Implement FPU/VMX128 opcodes, XEX LZX decompression, XISO browsing, and memory safety
Some checks failed
Orchestrator / Commit Message Validation (push) Has been skipped
Orchestrator / Lint (push) Successful in 2m5s
Orchestrator / Windows (x86-64) (push) Failing after 6m13s
Orchestrator / Linux (x86-64) (push) Failing after 20m59s
Orchestrator / Create Release (push) Has been skipped

Major additions to the xenia-rs Rust port:

- CPU: ~170 new PPC opcode implementations (FPU, VMX128, 64-bit ALU, load/store variants)
- XEX: Full LZX (normal) decompression pipeline with AES-128-CBC decryption via mspack FFI
- XEX: Parse file format info, import libraries, and security info AES key from headers
- VFS: Rewrite XISO disc image to use seek-based I/O (handles 7GB+ images without loading into memory)
- App: Auto-detect ISO files and extract default.xex for all CLI commands
- App: Add `info` and `browse` CLI subcommands
- Kernel: Expand HLE exports from 14 to 40 stubs (memory, threading, TLS, I/O, video)
- Memory: Add bounds checking on all guest memory accesses to prevent segfaults
- Types: Add Vec128 array-based accessors (from_u32x4_array, from_f32x4_array, etc.)

Tested against Project Sylpheed (USA) disc image - all four CLI commands
(browse, info, disasm, exec) work correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-04-12 21:32:46 +02:00
parent 06a23212fb
commit a519c76800
16 changed files with 2509 additions and 51 deletions

View File

@@ -93,6 +93,51 @@ impl Vec128 {
let off = i * 8;
self.bytes[off..off + 8].copy_from_slice(&val.to_be_bytes());
}
/// Get all 4 u32 elements as an array.
pub fn as_u32x4(&self) -> [u32; 4] {
[self.u32x4(0), self.u32x4(1), self.u32x4(2), self.u32x4(3)]
}
/// Get all 4 f32 elements as an array.
pub fn as_f32x4(&self) -> [f32; 4] {
[self.f32x4(0), self.f32x4(1), self.f32x4(2), self.f32x4(3)]
}
/// Get all 8 u16 elements as an array.
pub fn as_u16x8(&self) -> [u16; 8] {
[
self.u16x8(0), self.u16x8(1), self.u16x8(2), self.u16x8(3),
self.u16x8(4), self.u16x8(5), self.u16x8(6), self.u16x8(7),
]
}
/// Get all 16 bytes as an array.
pub fn as_bytes(&self) -> [u8; 16] {
self.bytes
}
/// Create from a byte array.
pub fn from_bytes(bytes: [u8; 16]) -> Self {
Self { bytes }
}
/// Create from a u32 array (big-endian elements).
pub fn from_u32x4_array(arr: [u32; 4]) -> Self {
Self::from_u32x4(arr[0], arr[1], arr[2], arr[3])
}
/// Create from an f32 array (big-endian elements).
pub fn from_f32x4_array(arr: [f32; 4]) -> Self {
Self::from_f32x4(arr[0], arr[1], arr[2], arr[3])
}
/// Create from a u16 array (big-endian elements).
pub fn from_u16x8_array(arr: [u16; 8]) -> Self {
let mut v = Self::ZERO;
for i in 0..8 { v.set_u16x8(i, arr[i]); }
v
}
}
impl Default for Vec128 {