David Brownell <david-b@pacbell.net>:
authorzwelch <zwelch@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Wed, 15 Jul 2009 23:48:21 +0000 (23:48 +0000)
committerzwelch <zwelch@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Wed, 15 Jul 2009 23:48:21 +0000 (23:48 +0000)
Make the Thumb2 disassembler handle more 32-bit instructions:

  A5.3.3 Data processing (plain binary immediate)

These use mostly twelve bit literals, but there are also bitfield
and saturated add primitives.

git-svn-id: svn://svn.berlios.de/openocd/trunk@2534 b42882b7-edfa-0310-969c-e2dbd0fdcd60

src/target/arm_disassembler.c

index 25b273780ba2c0cee523864aa4457073eca62147..a3b61b58e6f8c8030d837cf606b2d7a9570801eb 100644 (file)
@@ -2671,6 +2671,101 @@ static int t2ev_data_mod_immed(uint32_t opcode, uint32_t address,
        return ERROR_OK;
 }
 
+static int t2ev_data_immed(uint32_t opcode, uint32_t address,
+               arm_instruction_t *instruction, char *cp)
+{
+       char *mnemonic = NULL;
+       int rn = (opcode >> 16) & 0xf;
+       int rd = (opcode >> 8) & 0xf;
+       unsigned immed;
+       bool add = false;
+       bool is_signed = false;
+
+       immed = (opcode & 0x0ff) | ((opcode & 0x7000) >> 12);
+       if (opcode & (1 << 27))
+               immed |= (1 << 11);
+
+       switch ((opcode >> 20) & 0x1f) {
+       case 0:
+               if (rn == 0xf) {
+                       add = true;
+                       goto do_adr;
+               }
+               mnemonic = "ADD.W";
+               break;
+       case 4:
+               mnemonic = "MOV.W";
+               break;
+       case 0x0a:
+               if (rn == 0xf)
+                       goto do_adr;
+               mnemonic = "SUB.W";
+               break;
+       case 0x0c:
+               /* move constant to top 16 bits of register */
+               immed |= (opcode >> 4) & 0xf000;
+               sprintf(cp, "MOVT\tr%d, #%d\t; %#4.4x", rn, immed, immed);
+               return ERROR_OK;
+       case 0x10:
+       case 0x12:
+               is_signed = true;
+       case 0x18:
+       case 0x1a:
+               /* signed/unsigned saturated add */
+               immed = (opcode >> 6) & 0x03;
+               immed |= (opcode >> 10) & 0x1c;
+               sprintf(cp, "%sSAT\tr%d, #%d, r%d, %s #%d\t",
+                               is_signed ? "S" : "U",
+                               rd, (opcode & 0x1f) + 1, rn,
+                               (opcode & (1 << 21)) ? "ASR" : "LSL",
+                               immed ? immed : 32);
+               return ERROR_OK;
+       case 0x14:
+               is_signed = true;
+               /* FALLTHROUGH */
+       case 0x1c:
+               /* signed/unsigned bitfield extract */
+               immed = (opcode >> 6) & 0x03;
+               immed |= (opcode >> 10) & 0x1c;
+               sprintf(cp, "%sBFX\tr%d, r%d, #%d, #%d\t",
+                               is_signed ? "S" : "U",
+                               rd, rn, immed,
+                               (opcode & 0x1f) + 1);
+               return ERROR_OK;
+       case 0x16:
+               immed = (opcode >> 6) & 0x03;
+               immed |= (opcode >> 10) & 0x1c;
+               if (rn == 0xf)          /* bitfield clear */
+                       sprintf(cp, "BFC\tr%d, #%d, #%d\t",
+                                       rd, immed,
+                                       (opcode & 0x1f) + 1 - immed);
+               else                    /* bitfield insert */
+                       sprintf(cp, "BFI\tr%d, r%d, #%d, #%d\t",
+                                       rd, rn, immed,
+                                       (opcode & 0x1f) + 1 - immed);
+               return ERROR_OK;
+       default:
+               return ERROR_INVALID_ARGUMENTS;
+       }
+
+       sprintf(cp, "%s\tr%d, r%d, #%d\t; %#3.3x", mnemonic,
+                       rd, rn, immed, immed);
+       return ERROR_OK;
+
+do_adr:
+       address &= ~0x03;
+       address += 4;
+       if (add)
+               address += immed;
+       else
+               address -= immed;
+       /* REVISIT "ADD/SUB Rd, PC, #const ; 0x..." might be better;
+        * not hiding the pc-relative stuff will sometimes be useful.
+        */
+       sprintf(cp, "ADR.W\tr%d, %#8.8" PRIx32, rd, address);
+       return ERROR_OK;
+}
+
 /*
  * REVISIT for Thumb2 instructions, instruction->type and friends aren't
  * always set.  That means eventual arm_simulate_step() support for Thumb2
@@ -2722,6 +2817,10 @@ int thumb2_opcode(target_t *target, uint32_t address, arm_instruction_t *instruc
        if ((opcode & 0x1a008000) == 0x10000000)
                retval = t2ev_data_mod_immed(opcode, address, instruction, cp);
 
+       /* ARMv7-M: A5.3.3 Data processing (plain binary immediate) */
+       else if ((opcode & 0x1a008000) == 0x12000000)
+               retval = t2ev_data_immed(opcode, address, instruction, cp);
+
        /* ARMv7-M: A5.3.4 Branches and miscellaneous control */
        else if ((opcode & 0x18008000) == 0x10008000)
                retval = t2ev_b_misc(opcode, address, instruction, cp);

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)