From 96bc5b9bc71aff5040ac0022e987ba33442f2487 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Mon, 26 Jan 2015 01:41:06 -0800 Subject: [PATCH] Debugger: Disassembly now lists PSR bitmasks (fixes #191) --- CHANGES | 1 + src/arm/decoder-arm.c | 6 ++++++ src/arm/decoder.c | 31 +++++++++++++++++++++++++++++++ src/arm/decoder.h | 7 +++++++ 4 files changed, 45 insertions(+) diff --git a/CHANGES b/CHANGES index 1162b0a57..b598b23fc 100644 --- a/CHANGES +++ b/CHANGES @@ -31,6 +31,7 @@ Bugfixes: - GBA Thread: Fix possible hang when loading an archive - Perf: Fix crash when the GBA thread fails to start - SDL: Properly clean up if a game doesn't launch + - Debugger: Disassembly now lists PSR bitmasks (fixes #191) Misc: - GBA Audio: Change internal audio sample buffer from 32-bit to 16-bit samples - GBA Memory: Simplify memory API and use fixed bus width diff --git a/src/arm/decoder-arm.c b/src/arm/decoder-arm.c index 756a01155..255a631c8 100644 --- a/src/arm/decoder-arm.c +++ b/src/arm/decoder-arm.c @@ -386,6 +386,7 @@ DEFINE_DECODER_ARM(ILL, ILL, info->operandFormat = ARM_OPERAND_NONE;) // Illegal DEFINE_DECODER_ARM(MSR, MSR, info->affectsCPSR = 1; info->op1.reg = ARM_CPSR; + info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK; info->op2.reg = opcode & 0x0000000F; info->operandFormat = ARM_OPERAND_REGISTER_1 | ARM_OPERAND_AFFECTED_1 | @@ -393,6 +394,7 @@ DEFINE_DECODER_ARM(MSR, MSR, DEFINE_DECODER_ARM(MSRR, MSR, info->op1.reg = ARM_SPSR; + info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK; info->op2.reg = opcode & 0x0000000F; info->operandFormat = ARM_OPERAND_REGISTER_1 | ARM_OPERAND_AFFECTED_1 | @@ -402,6 +404,7 @@ DEFINE_DECODER_ARM(MRS, MRS, info->affectsCPSR = 1; info->affectsCPSR = 1; info->op1.reg = (opcode >> 12) & 0xF; info->op2.reg = ARM_CPSR; + info->op2.psrBits = 0; info->operandFormat = ARM_OPERAND_REGISTER_1 | ARM_OPERAND_AFFECTED_1 | ARM_OPERAND_REGISTER_2;) @@ -410,6 +413,7 @@ DEFINE_DECODER_ARM(MRSR, MRS, info->affectsCPSR = 1; info->affectsCPSR = 1; info->op1.reg = (opcode >> 12) & 0xF; info->op2.reg = ARM_SPSR; + info->op2.psrBits = 0; info->operandFormat = ARM_OPERAND_REGISTER_1 | ARM_OPERAND_AFFECTED_1 | ARM_OPERAND_REGISTER_2;) @@ -419,6 +423,7 @@ DEFINE_DECODER_ARM(MSRI, MSR, info->affectsCPSR = 1; int32_t operand = ROR(opcode & 0x000000FF, rotate); info->affectsCPSR = 1; info->op1.reg = ARM_CPSR; + info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK; info->op2.immediate = operand; info->operandFormat = ARM_OPERAND_REGISTER_1 | ARM_OPERAND_AFFECTED_1 | @@ -429,6 +434,7 @@ DEFINE_DECODER_ARM(MSRRI, MSR, info->affectsCPSR = 1; int32_t operand = ROR(opcode & 0x000000FF, rotate); info->affectsCPSR = 1; info->op1.reg = ARM_SPSR; + info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK; info->op2.immediate = operand; info->operandFormat = ARM_OPERAND_REGISTER_1 | ARM_OPERAND_AFFECTED_1 | diff --git a/src/arm/decoder.c b/src/arm/decoder.c index 94974fcec..8e5ef3f8d 100644 --- a/src/arm/decoder.c +++ b/src/arm/decoder.c @@ -18,6 +18,7 @@ static int _decodeRegister(int reg, char* buffer, int blen); static int _decodeRegisterList(int list, char* buffer, int blen); +static int _decodePSR(int bits, char* buffer, int blen); static int _decodePCRelative(uint32_t address, uint32_t pc, char* buffer, int blen); static int _decodeMemory(struct ARMMemoryAccess memory, int pc, char* buffer, int blen); static int _decodeShift(union ARMOperand operand, bool reg, char* buffer, int blen); @@ -113,6 +114,32 @@ static int _decodeRegisterList(int list, char* buffer, int blen) { return total; } +static int _decodePSR(int psrBits, char* buffer, int blen) { + if (!psrBits) { + return 0; + } + int total = 0; + strncpy(buffer, "_", blen - 1); + ADVANCE(1); + if (psrBits & ARM_PSR_C) { + strncpy(buffer, "c", blen - 1); + ADVANCE(1); + } + if (psrBits & ARM_PSR_X) { + strncpy(buffer, "x", blen - 1); + ADVANCE(1); + } + if (psrBits & ARM_PSR_S) { + strncpy(buffer, "s", blen - 1); + ADVANCE(1); + } + if (psrBits & ARM_PSR_F) { + strncpy(buffer, "f", blen - 1); + ADVANCE(1); + } + return total; +} + static int _decodePCRelative(uint32_t address, uint32_t pc, char* buffer, int blen) { return snprintf(buffer, blen - 1, "$%08X", address + pc); } @@ -370,6 +397,10 @@ int ARMDisassemble(struct ARMInstructionInfo* info, uint32_t pc, char* buffer, i } else if (info->operandFormat & ARM_OPERAND_REGISTER_1) { written = _decodeRegister(info->op1.reg, buffer, blen); ADVANCE(written); + if (info->op1.reg > ARM_PC) { + written = _decodePSR(info->op1.psrBits, buffer, blen); + ADVANCE(written); + } } if (info->operandFormat & ARM_OPERAND_SHIFT_REGISTER_1) { written = _decodeShift(info->op1, true, buffer, blen); diff --git a/src/arm/decoder.h b/src/arm/decoder.h index 75f30e33c..57187dd13 100644 --- a/src/arm/decoder.h +++ b/src/arm/decoder.h @@ -62,6 +62,12 @@ #define ARM_MEMORY_INCREMENT_BEFORE 0x0300 #define ARM_MEMORY_SPSR_SWAP 0x0400 +#define ARM_PSR_C 1 +#define ARM_PSR_X 2 +#define ARM_PSR_S 4 +#define ARM_PSR_F 8 +#define ARM_PSR_MASK 0xF + #define MEMORY_FORMAT_TO_DIRECTION(F) (((F) >> 8) & 0x3) enum ARMCondition { @@ -99,6 +105,7 @@ union ARMOperand { union { uint8_t shifterReg; uint8_t shifterImm; + uint8_t psrBits; }; }; int32_t immediate;