MemFault: move RISC-V and LoongArch fault analysis out of HandleFault

The RISC-V branch had its instruction-decode logic (including a locally
defined info struct) written directly inline in HandleFault(), unlike
the other three architectures which each delegate to a dedicated
AnalyzeLoadStore function in their disassembler file. Move it into
ext/riscv-disas.h/.cpp as RiscVAnalyzeLoadStore, matching the existing
X86AnalyzeMOV/Arm64AnalyzeLoadStore/ArmAnalyzeLoadStore pattern.
This commit is contained in:
Henrik Rydgård committed 2026-08-11 22:36:47 +02:00
1 parent 2c315be708
commit 22ac7ad119
3 files changed
+66 -57

No files matched your search

+51
View File
@@ -2526,3 +2526,54 @@ void riscv_disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_ins
decode_inst_lift_pseudo(&dec);
decode_inst_format(buf, buflen, 32, &dec);
}
/* PPSSPP: analyze a load/store instruction, used by the JIT crash handler */
bool RiscVAnalyzeLoadStore(uint64_t addr, uint32_t word, RiscVLSInstructionInfo *info)
{
*info = {};
// Compressed instructions have low bits 00, 01, or 10.
info->instructionSize = (word & 3) == 3 ? 4 : 2;
switch (word & 0x7F) {
case 3:
info->isIntegerLoadStore = true;
info->size = 1 << ((word >> 12) & 3);
return true;
case 7:
info->isFPLoadStore = true;
info->size = 1 << ((word >> 12) & 3);
return true;
case 35:
info->isIntegerLoadStore = true;
info->isMemoryWrite = true;
info->size = 1 << ((word >> 12) & 3);
return true;
case 39:
info->isFPLoadStore = true;
info->isMemoryWrite = true;
info->size = 1 << ((word >> 12) & 3);
return true;
default:
// Compressed instruction.
switch (word & 0x6003) {
case 0x4000:
case 0x4002:
case 0x6000:
case 0x6002:
info->isIntegerLoadStore = true;
info->size = (word & 0x2000) != 0 ? 8 : 4;
info->isMemoryWrite = (word & 0x8000) != 0;
return true;
case 0x2000:
case 0x2002:
info->isFPLoadStore = true;
info->size = 8;
info->isMemoryWrite = (word & 0x8000) != 0;
return true;
default:
// Not a read or a write.
return false;
}
}
}
+11
View File
@@ -594,4 +594,15 @@ size_t riscv_inst_length(rv_inst inst);
void riscv_inst_fetch(const uint8_t *data, rv_inst *instp, size_t *length);
void riscv_disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst);
// PPSSPP: information about a load/store instruction, used by the JIT crash handler.
struct RiscVLSInstructionInfo {
int instructionSize;
bool isIntegerLoadStore;
bool isFPLoadStore;
int size; // Size of the access, in bytes (1, 2, 4, or 8).
bool isMemoryWrite;
};
bool RiscVAnalyzeLoadStore(uint64_t addr, uint32_t word, RiscVLSInstructionInfo *info);
#endif