mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-22 19:06:15 +08:00
52d2874fa8
## What The native backend runs guest code directly on the host CPU. When the host doesn't implement a BMI1/BMI2/ABM instruction that the PS5's Zen 2 cores do, it raises #UD (STATUS_ILLEGAL_INSTRUCTION). Today the vectored handler just logs the faulting bytes and gives up, so the title dies. This adds a software fallback. On an illegal-instruction fault we decode the opcode with Iced (the decoder already used elsewhere in the backend), evaluate it against the trapped register/memory state, write the result and flags back into the CONTEXT record, step RIP past the instruction, and resume. Instructions covered (32- and 64-bit): ANDN, BLSI, BLSMSK, BLSR, BEXTR, BZHI, TZCNT, LZCNT, RORX, SARX, SHLX, SHRX, PDEP, PEXT. ## Why Users on CPUs without these extensions currently can't get past code that uses them. This is a generic fix (no game-specific hacks) that improves compatibility on older hosts. MULX is intentionally left out for now — its dest_hi/dest_lo operand ordering is easy to get subtly wrong, so I'd rather add it separately with its own tests. ## How it's structured - `BmiInstructionEmulator` holds the pure bit/flag semantics with no dependency on the unsafe CONTEXT plumbing, so it can be unit-tested directly. - `DirectExecutionBackend.IllegalInstruction.cs` is the thin unsafe adapter (decode → read operands → emulate → write back → advance RIP). Anything it doesn't fully model returns false and falls through to the existing diagnostics unchanged, so it can never mis-handle an opcode it doesn't recognize. - One hook in `DirectExecutionBackend.Exceptions.cs`, next to the other TryRecover* calls. - Emits a single one-time "emulating in software" log line, not per-instruction spam. ## How I verified - Added xUnit tests covering every instruction in both widths plus the CF/ZF/SF/OF edge cases (src == 0, shift-count masking, index beyond operand width, etc.). - Cross-checked all the expected values against an independent reference implementation written from the Intel/AMD definitions; results match. - `dotnet build` + `dotnet test` pass locally. ## Notes New files follow .editorconfig (4-space, SPDX headers, REUSE-compliant).