diff options
author | zwelch <zwelch@b42882b7-edfa-0310-969c-e2dbd0fdcd60> | 2009-07-15 23:48:54 +0000 |
---|---|---|
committer | zwelch <zwelch@b42882b7-edfa-0310-969c-e2dbd0fdcd60> | 2009-07-15 23:48:54 +0000 |
commit | 930269b4835c3206f22e9c195bd8f61f36fe03e2 (patch) | |
tree | c1ca664bbac99d953b89b5182fd57903b3a4266b | |
parent | 421b8e133aa4dfc01dba53ac769afbcec00ab3c3 (diff) | |
download | openocd+libswd-930269b4835c3206f22e9c195bd8f61f36fe03e2.tar.gz openocd+libswd-930269b4835c3206f22e9c195bd8f61f36fe03e2.tar.bz2 openocd+libswd-930269b4835c3206f22e9c195bd8f61f36fe03e2.tar.xz openocd+libswd-930269b4835c3206f22e9c195bd8f61f36fe03e2.zip |
David Brownell <david-b@pacbell.net>:
More instructions decoded:
A5.3.5 Load/store multiple
The preferred PUSH/POP syntax is shown when appropriate.
git-svn-id: svn://svn.berlios.de/openocd/trunk@2539 b42882b7-edfa-0310-969c-e2dbd0fdcd60
-rw-r--r-- | src/target/arm_disassembler.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/target/arm_disassembler.c b/src/target/arm_disassembler.c index 63166932..29bc0394 100644 --- a/src/target/arm_disassembler.c +++ b/src/target/arm_disassembler.c @@ -2940,6 +2940,55 @@ static int t2ev_mul64_div(uint32_t opcode, uint32_t address, return ERROR_OK; } +static int t2ev_ldm_stm(uint32_t opcode, uint32_t address, + arm_instruction_t *instruction, char *cp) +{ + int rn = (opcode >> 16) & 0xf; + int op = (opcode >> 22) & 0x6; + int t = (opcode >> 21) & 1; + unsigned registers = opcode & 0xffff; + + if (opcode & (1 << 20)) + op |= 1; + + switch (op) { + case 2: + sprintf(cp, "STMB\tr%d%s, ", rn, t ? "!" : ""); + break; + case 3: + if (rn == 13 && t) + sprintf(cp, "POP\t"); + else + sprintf(cp, "LDM\tr%d%s, ", rn, t ? "!" : ""); + break; + case 4: + if (rn == 13 && t) + sprintf(cp, "PUSH\t"); + else + sprintf(cp, "STM\tr%d%s, ", rn, t ? "!" : ""); + break; + case 5: + sprintf(cp, "LDMB\tr%d%s, ", rn, t ? "!" : ""); + break; + default: + return ERROR_INVALID_ARGUMENTS; + } + + cp = strchr(cp, 0); + *cp++ = '{'; + for (t = 0; registers; t++, registers >>= 1) { + if ((registers & 1) == 0) + continue; + registers &= ~1; + sprintf(cp, "r%d%s", t, registers ? "," : ""); + cp = strchr(cp, 0); + } + *cp++ = '}'; + *cp++ = 0; + + return ERROR_OK; +} + /* * REVISIT for Thumb2 instructions, instruction->type and friends aren't * always set. That means eventual arm_simulate_step() support for Thumb2 @@ -2999,6 +3048,10 @@ int thumb2_opcode(target_t *target, uint32_t address, arm_instruction_t *instruc else if ((opcode & 0x18008000) == 0x10008000) retval = t2ev_b_misc(opcode, address, instruction, cp); + /* ARMv7-M: A5.3.5 Load/store multiple */ + else if ((opcode & 0x1e400000) == 0x08000000) + retval = t2ev_ldm_stm(opcode, address, instruction, cp); + /* ARMv7-M: A5.3.10 Store single data item */ else if ((opcode & 0x1f100000) == 0x18000000) retval = t2ev_store_single(opcode, address, instruction, cp); |