summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzwelch <zwelch@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2009-07-15 23:49:12 +0000
committerzwelch <zwelch@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2009-07-15 23:49:12 +0000
commit0c2ff267aadc8997e2a337d43eb3a3510f2bd2a1 (patch)
tree1017e1aa6bc720b09a7fe94d912bcf0258032a5f /src
parentfdfd434c247236c5b3d388ef06f9b21c089a3051 (diff)
downloadopenocd+libswd-0c2ff267aadc8997e2a337d43eb3a3510f2bd2a1.tar.gz
openocd+libswd-0c2ff267aadc8997e2a337d43eb3a3510f2bd2a1.tar.bz2
openocd+libswd-0c2ff267aadc8997e2a337d43eb3a3510f2bd2a1.tar.xz
openocd+libswd-0c2ff267aadc8997e2a337d43eb3a3510f2bd2a1.zip
David Brownell <david-b@pacbell.net>:
More 32-bit Thumb2 instruction decoding: A5.3.7 Load word git-svn-id: svn://svn.berlios.de/openocd/trunk@2542 b42882b7-edfa-0310-969c-e2dbd0fdcd60
Diffstat (limited to 'src')
-rw-r--r--src/target/arm_disassembler.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/target/arm_disassembler.c b/src/target/arm_disassembler.c
index 064bfa59..9d154435 100644
--- a/src/target/arm_disassembler.c
+++ b/src/target/arm_disassembler.c
@@ -3254,6 +3254,80 @@ static int t2ev_data_reg(uint32_t opcode, uint32_t address,
return ERROR_OK;
}
+static int t2ev_load_word(uint32_t opcode, uint32_t address,
+ arm_instruction_t *instruction, char *cp)
+{
+ int rn = (opcode >> 16) & 0xf;
+ int immed;
+
+ instruction->type = ARM_LDR;
+
+ if (rn == 0xf) {
+ immed = opcode & 0x0fff;
+ if (opcode & (1 << 23))
+ immed = -immed;
+ sprintf(cp, "LDR\tr%d, %#8.8" PRIx32,
+ (opcode >> 12) & 0xf,
+ thumb_alignpc4(address) + immed);
+ return ERROR_OK;
+ }
+
+ if (opcode & (1 << 23)) {
+ immed = opcode & 0x0fff;
+ sprintf(cp, "LDR.W\tr%d, [r%d, #%d]\t; %#3.3x",
+ (opcode >> 12) & 0xf,
+ rn, immed, immed);
+ return ERROR_OK;
+ }
+
+ if (!(opcode & (0x3f << 6))) {
+ sprintf(cp, "LDR.W\tr%d, [r%d, r%d, LSL #%d]",
+ (opcode >> 12) & 0xf,
+ rn,
+ (opcode >> 0) & 0xf,
+ (opcode >> 4) & 0x3);
+ return ERROR_OK;
+ }
+
+
+ if (((opcode >> 8) & 0xf) == 0xe) {
+ immed = opcode & 0x00ff;
+
+ sprintf(cp, "LDRT\tr%d, [r%d, #%d]\t; %#2.2x",
+ (opcode >> 12) & 0xf,
+ rn, immed, immed);
+ return ERROR_OK;
+ }
+
+ if (((opcode >> 8) & 0xf) == 0xc || (opcode & 0x0900) == 0x0900) {
+ char *p1 = "]", *p2 = "";
+
+ if (!(opcode & 0x0600))
+ return ERROR_INVALID_ARGUMENTS;
+
+ immed = opcode & 0x00ff;
+
+ /* two indexed modes will write back rn */
+ if (opcode & 0x100) {
+ if (opcode & 0x400) /* pre-indexed */
+ p2 = "]!";
+ else { /* post-indexed */
+ p1 = "]";
+ p2 = "";
+ }
+ }
+
+ sprintf(cp, "LDR\tr%d, [r%d%s, #%s%u%s\t; %#2.2x",
+ (opcode >> 12) & 0xf,
+ rn, p1,
+ (opcode & 0x200) ? "" : "-",
+ immed, p2, immed);
+ return ERROR_OK;
+ }
+
+ return ERROR_INVALID_ARGUMENTS;
+}
+
/*
* REVISIT for Thumb2 instructions, instruction->type and friends aren't
* always set. That means eventual arm_simulate_step() support for Thumb2
@@ -3317,6 +3391,10 @@ int thumb2_opcode(target_t *target, uint32_t address, arm_instruction_t *instruc
else if ((opcode & 0x1e400000) == 0x08000000)
retval = t2ev_ldm_stm(opcode, address, instruction, cp);
+ /* ARMv7-M: A5.3.7 Load word */
+ else if ((opcode & 0x1f700000) == 0x18500000)
+ retval = t2ev_load_word(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);