mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
RISC-V: mask the register number in the compressed encoders
EncodeCR, EncodeCI and EncodeCSS shifted the RiscVReg enum value straight into the instruction without DecodeReg(), which every 32-bit encoder in the file uses. FPRs are 0x20..0x3F in that enum, so bit 5 is set for all of them and spilled into a neighbouring field - for the CI format, into bit 12, which holds imm[5]. The visible effect: the dispatcher's epilogue restores the callee-saved FP registers with c.fldsp, and every offset whose bit 5 was clear came out 32 bytes too high. fs3-fs6 were restored from the wrong slots and fs11 from 224(sp), past the 208-byte frame. So the native JIT corrupted whatever the C++ caller had in those registers - which, in the headless test runner, was the wall-clock deadline, making every test report an instant TIMEOUT. pspautotests on riscv64 under qemu goes from 0/342 to 338/342 with this, matching the IR interpreter exactly. Found with the disassembly the enableDisasm flag in RiscVAsm.cpp emits - the save offsets and the restore offsets simply didn't match. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
1 parent
e86b2dcc81
commit
f3d63f3c7e
1 file changed
+3
-3
@@ -842,7 +842,7 @@ static inline u32 EncodeFVF(RiscVReg vd, RiscVReg rs1, RiscVReg vs2, VUseMask vm
|
||||
|
||||
static inline u16 EncodeCR(Opcode16 op, RiscVReg rs2, RiscVReg rd, Funct4 funct4) {
|
||||
_assert_msg_(SupportsCompressed(), "Compressed instructions unsupported");
|
||||
return (u16)op | ((u16)rs2 << 2) | ((u16)rd << 7) | ((u16)funct4 << 12);
|
||||
return (u16)op | ((u16)DecodeReg(rs2) << 2) | ((u16)DecodeReg(rd) << 7) | ((u16)funct4 << 12);
|
||||
}
|
||||
|
||||
static inline u16 EncodeCI(Opcode16 op, u8 uimm6, RiscVReg rd, Funct3 funct3) {
|
||||
@@ -850,13 +850,13 @@ static inline u16 EncodeCI(Opcode16 op, u8 uimm6, RiscVReg rd, Funct3 funct3) {
|
||||
_assert_msg_(uimm6 <= 0x3F, "CI immediate overflow: %04x", uimm6);
|
||||
u16 imm4_0 = ImmBits16(uimm6, 0, 5);
|
||||
u16 imm5 = ImmBit16(uimm6, 5);
|
||||
return (u16)op | (imm4_0 << 2) | ((u16)rd << 7) | (imm5 << 12) | ((u16)funct3 << 13);
|
||||
return (u16)op | (imm4_0 << 2) | ((u16)DecodeReg(rd) << 7) | (imm5 << 12) | ((u16)funct3 << 13);
|
||||
}
|
||||
|
||||
static inline u16 EncodeCSS(Opcode16 op, RiscVReg rs2, u8 uimm6, Funct3 funct3) {
|
||||
_assert_msg_(SupportsCompressed(), "Compressed instructions unsupported");
|
||||
_assert_msg_(uimm6 <= 0x3F, "CI immediate overflow: %04x", uimm6);
|
||||
return (u16)op | ((u16)rs2 << 2) | ((u16)uimm6 << 7) | ((u16)funct3 << 13);
|
||||
return (u16)op | ((u16)DecodeReg(rs2) << 2) | ((u16)uimm6 << 7) | ((u16)funct3 << 13);
|
||||
}
|
||||
|
||||
static inline u16 EncodeCIW(Opcode16 op, RiscCReg rd, u8 uimm8, Funct3 funct3) {
|
||||
|
||||
Reference in new issue
Block a user