mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
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:
1 parent
2c315be708
commit
22ac7ad119
3 files changed
+66
-57
No files matched your search
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
Reference in new issue
Block a user