]> git.sur5r.net Git - openocd/commitdiff
David Brownell <david-b@pacbell.net>:
authorzwelch <zwelch@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Wed, 15 Jul 2009 23:48:54 +0000 (23:48 +0000)
committerzwelch <zwelch@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Wed, 15 Jul 2009 23:48:54 +0000 (23:48 +0000)
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

src/target/arm_disassembler.c

index 63166932f0b270d5f8467dcc2c01195b3d992698..29bc039410b9968bd7cb608bce6bf8eb7e0cfec2 100644 (file)
@@ -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);