ARM: Disassemble Thumb mov pseudo-instruction properly

This commit is contained in:
Vicki Pfau 2022-06-05 20:59:30 -07:00
parent 3687863cbc
commit 11837ffc15
3 changed files with 31 additions and 23 deletions

View File

@ -42,6 +42,7 @@ Emulation fixes:
- GBA Video: Fix rare crash in modes 3-5 - GBA Video: Fix rare crash in modes 3-5
- GBA Video: Fix sprites with mid-frame palette changes in GL (fixes mgba.io/i/2476) - GBA Video: Fix sprites with mid-frame palette changes in GL (fixes mgba.io/i/2476)
Other fixes: Other fixes:
- ARM: Disassemble Thumb mov pseudo-instruction properly
- Core: Don't attempt to restore rewind diffs past start of rewind - Core: Don't attempt to restore rewind diffs past start of rewind
- Core: Fix the runloop resuming after a game has crashed (fixes mgba.io/i/2451) - Core: Fix the runloop resuming after a game has crashed (fixes mgba.io/i/2451)
- Core: Fix crash if library can't be opened - Core: Fix crash if library can't be opened

View File

@ -223,7 +223,7 @@ uint32_t ARMResolveMemoryAccess(struct ARMInstructionInfo* info, struct ARMRegis
#ifdef USE_DEBUGGERS #ifdef USE_DEBUGGERS
struct mDebuggerSymbols; struct mDebuggerSymbols;
int ARMDisassemble(struct ARMInstructionInfo* info, struct ARMCore* core, const struct mDebuggerSymbols* symbols, uint32_t pc, char* buffer, int blen); int ARMDisassemble(const struct ARMInstructionInfo* info, struct ARMCore* core, const struct mDebuggerSymbols* symbols, uint32_t pc, char* buffer, int blen);
#endif #endif
CXX_GUARD_END CXX_GUARD_END

View File

@ -378,10 +378,11 @@ static const char* _armAccessTypeStrings[] = {
"" ""
}; };
int ARMDisassemble(struct ARMInstructionInfo* info, struct ARMCore* cpu, const struct mDebuggerSymbols* symbols, uint32_t pc, char* buffer, int blen) { int ARMDisassemble(const struct ARMInstructionInfo* info, struct ARMCore* cpu, const struct mDebuggerSymbols* symbols, uint32_t pc, char* buffer, int blen) {
const char* mnemonic = _armMnemonicStrings[info->mnemonic]; const char* mnemonic = _armMnemonicStrings[info->mnemonic];
int written; int written;
int total = 0; int total = 0;
bool skip3 = false;
const char* cond = ""; const char* cond = "";
if (info->condition != ARM_CONDITION_AL && info->condition < ARM_CONDITION_NV) { if (info->condition != ARM_CONDITION_AL && info->condition < ARM_CONDITION_NV) {
cond = _armConditions[info->condition]; cond = _armConditions[info->condition];
@ -398,6 +399,11 @@ int ARMDisassemble(struct ARMInstructionInfo* info, struct ARMCore* cpu, const s
flags = _armAccessTypeStrings[info->memory.width]; flags = _armAccessTypeStrings[info->memory.width];
break; break;
case ARM_MN_ADD: case ARM_MN_ADD:
if ((info->operandFormat & (ARM_OPERAND_3 | ARM_OPERAND_4)) == ARM_OPERAND_IMMEDIATE_3 && info->op3.immediate == 0 && info->execMode == MODE_THUMB) {
skip3 = true;
mnemonic = "mov";
}
// Fall through
case ARM_MN_ADC: case ARM_MN_ADC:
case ARM_MN_AND: case ARM_MN_AND:
case ARM_MN_ASR: case ARM_MN_ASR:
@ -406,7 +412,6 @@ int ARMDisassemble(struct ARMInstructionInfo* info, struct ARMCore* cpu, const s
case ARM_MN_LSL: case ARM_MN_LSL:
case ARM_MN_LSR: case ARM_MN_LSR:
case ARM_MN_MLA: case ARM_MN_MLA:
case ARM_MN_MOV:
case ARM_MN_MUL: case ARM_MN_MUL:
case ARM_MN_MVN: case ARM_MN_MVN:
case ARM_MN_ORR: case ARM_MN_ORR:
@ -497,26 +502,28 @@ int ARMDisassemble(struct ARMInstructionInfo* info, struct ARMCore* cpu, const s
written = _decodeShift(info->op2, false, buffer, blen); written = _decodeShift(info->op2, false, buffer, blen);
ADVANCE(written); ADVANCE(written);
} }
if (info->operandFormat & ARM_OPERAND_3) { if (!skip3) {
strlcpy(buffer, ", ", blen); if (info->operandFormat & ARM_OPERAND_3) {
ADVANCE(2); strlcpy(buffer, ", ", blen);
} ADVANCE(2);
if (info->operandFormat & ARM_OPERAND_IMMEDIATE_3) { }
written = snprintf(buffer, blen, "#%i", info->op3.immediate); if (info->operandFormat & ARM_OPERAND_IMMEDIATE_3) {
ADVANCE(written); written = snprintf(buffer, blen, "#%i", info->op3.immediate);
} else if (info->operandFormat & ARM_OPERAND_MEMORY_3) { ADVANCE(written);
written = _decodeMemory(info->memory, cpu, symbols, pc, buffer, blen); } else if (info->operandFormat & ARM_OPERAND_MEMORY_3) {
ADVANCE(written); written = _decodeMemory(info->memory, cpu, symbols, pc, buffer, blen);
} else if (info->operandFormat & ARM_OPERAND_REGISTER_3) { ADVANCE(written);
written = _decodeRegister(info->op3.reg, buffer, blen); } else if (info->operandFormat & ARM_OPERAND_REGISTER_3) {
ADVANCE(written); written = _decodeRegister(info->op3.reg, buffer, blen);
} ADVANCE(written);
if (info->operandFormat & ARM_OPERAND_SHIFT_REGISTER_3) { }
written = _decodeShift(info->op3, true, buffer, blen); if (info->operandFormat & ARM_OPERAND_SHIFT_REGISTER_3) {
ADVANCE(written); written = _decodeShift(info->op3, true, buffer, blen);
} else if (info->operandFormat & ARM_OPERAND_SHIFT_IMMEDIATE_3) { ADVANCE(written);
written = _decodeShift(info->op3, false, buffer, blen); } else if (info->operandFormat & ARM_OPERAND_SHIFT_IMMEDIATE_3) {
ADVANCE(written); written = _decodeShift(info->op3, false, buffer, blen);
ADVANCE(written);
}
} }
if (info->operandFormat & ARM_OPERAND_4) { if (info->operandFormat & ARM_OPERAND_4) {
strlcpy(buffer, ", ", blen); strlcpy(buffer, ", ", blen);