diff options
author | oharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60> | 2009-07-26 19:56:58 +0000 |
---|---|---|
committer | oharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60> | 2009-07-26 19:56:58 +0000 |
commit | fc318c02987ff87222d94a9f30d0f44d97554f0e (patch) | |
tree | 216319ad484ad1f2d6753624347bd2f748bc9d35 /src | |
parent | 67dbf35896f359b64f88f54314f5779676411644 (diff) | |
download | openocd+libswd-fc318c02987ff87222d94a9f30d0f44d97554f0e.tar.gz openocd+libswd-fc318c02987ff87222d94a9f30d0f44d97554f0e.tar.bz2 openocd+libswd-fc318c02987ff87222d94a9f30d0f44d97554f0e.tar.xz openocd+libswd-fc318c02987ff87222d94a9f30d0f44d97554f0e.zip |
David Brownell <david-b@pacbell.net> 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
Diffstat (limited to 'src')
-rw-r--r-- | src/target/arm_disassembler.c | 20 |
1 files changed, 12 insertions, 8 deletions
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; |