From fc318c02987ff87222d94a9f30d0f44d97554f0e Mon Sep 17 00:00:00 2001 From: oharboe Date: Sun, 26 Jul 2009 19:56:58 +0000 Subject: David Brownell More instruction decoding fixes: A5.3.5 Load/store multiple A5.3.7 Load word There was a longstanding bug in Thumb-1 LDM; the rest of the LDM/STM fixes are just using width specs to match UAL syntax, except for two opcode name typos. Load word had two bitmask goofs. git-svn-id: svn://svn.berlios.de/openocd/trunk@2565 b42882b7-edfa-0310-969c-e2dbd0fdcd60 --- src/target/arm_disassembler.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'src/target') diff --git a/src/target/arm_disassembler.c b/src/target/arm_disassembler.c index 03a27a1b..d961f96a 100644 --- a/src/target/arm_disassembler.c +++ b/src/target/arm_disassembler.c @@ -1944,17 +1944,21 @@ int evaluate_load_store_multiple_thumb(uint16_t opcode, uint32_t address, arm_in if ((opcode & 0xf000) == 0xc000) { /* generic load/store multiple */ + char *wback = "!"; + if (L) { instruction->type = ARM_LDM; mnemonic = "LDM"; + if (opcode & (1 << Rn)) + wback = ""; } else { instruction->type = ARM_STM; mnemonic = "STM"; } - snprintf(ptr_name,7,"r%i!, ",Rn); + snprintf(ptr_name, sizeof ptr_name, "r%i%s, ", Rn, wback); } else { /* push/pop */ @@ -2965,22 +2969,22 @@ static int t2ev_ldm_stm(uint32_t opcode, uint32_t address, switch (op) { case 2: - sprintf(cp, "STMB\tr%d%s, ", rn, t ? "!" : ""); + sprintf(cp, "STM.W\tr%d%s, ", rn, t ? "!" : ""); break; case 3: if (rn == 13 && t) - sprintf(cp, "POP\t"); + sprintf(cp, "POP.W\t"); else sprintf(cp, "LDM.W\tr%d%s, ", rn, t ? "!" : ""); break; case 4: if (rn == 13 && t) - sprintf(cp, "PUSH\t"); + sprintf(cp, "PUSH.W\t"); else - sprintf(cp, "STM.W\tr%d%s, ", rn, t ? "!" : ""); + sprintf(cp, "STMDB\tr%d%s, ", rn, t ? "!" : ""); break; case 5: - sprintf(cp, "LDMB\tr%d%s, ", rn, t ? "!" : ""); + sprintf(cp, "LDMDB.W\tr%d%s, ", rn, t ? "!" : ""); break; default: return ERROR_INVALID_ARGUMENTS; @@ -3279,7 +3283,7 @@ static int t2ev_load_word(uint32_t opcode, uint32_t address, if (rn == 0xf) { immed = opcode & 0x0fff; - if (opcode & (1 << 23)) + if ((opcode & (1 << 23)) == 0) immed = -immed; sprintf(cp, "LDR\tr%d, %#8.8" PRIx32, (int) (opcode >> 12) & 0xf, @@ -3317,7 +3321,7 @@ static int t2ev_load_word(uint32_t opcode, uint32_t address, if (((opcode >> 8) & 0xf) == 0xc || (opcode & 0x0900) == 0x0900) { char *p1 = "]", *p2 = ""; - if (!(opcode & 0x0600)) + if (!(opcode & 0x0500)) return ERROR_INVALID_ARGUMENTS; immed = opcode & 0x00ff; -- cgit v1.2.3