David Brownell <david-b@pacbell.net> More testcase work:
authoroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Sun, 26 Jul 2009 20:00:39 +0000 (20:00 +0000)
committeroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Sun, 26 Jul 2009 20:00:39 +0000 (20:00 +0000)
       A5.3.11 Data processing (shifted register)

The usual kinds of problems; the most noteworthy were that
the "S"et flags bit was mis-handled in these instructions.
---
This is the last patch from a quickie set of tests covering all
encodings of the instructions with 32-bit opcodes.  There may
be some corner cases left, plus the instructions that aren't
yet handled, but the Thumb2 disassembler is no longer just
"lightly" tested with GCC output ... the new code paths have
mostly been verified.

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

src/target/arm_disassembler.c

index 0478ee9c6797ce35a1f347f8720ce61749c574e5..f963b999103689eb42e63fcbcb95880ac9d2c23c 100644 (file)
@@ -1395,6 +1395,7 @@ int evaluate_add_sub_thumb(uint16_t opcode, uint32_t address, arm_instruction_t
        }
        else
        {
+               /* REVISIT:  if reg_imm == 0, display as "MOVS" */
                instruction->type = ARM_ADD;
                mnemonic = "ADDS";
        }
@@ -3017,17 +3018,18 @@ static int t2ev_data_shift(uint32_t opcode, uint32_t address,
        char *mnemonic;
        char *suffix = "";
 
-       immed |= (opcode >> 10) & 0x7;
-       if (opcode & (1 << 21))
+       immed |= (opcode >> 10) & 0x1c;
+       if (opcode & (1 << 20))
                suffix = "S";
 
        switch (op) {
        case 0:
                if (rd == 0xf) {
-                       if (!(opcode & (1 << 21)))
+                       if (!(opcode & (1 << 20)))
                                return ERROR_INVALID_ARGUMENTS;
                        instruction->type = ARM_TST;
                        mnemonic = "TST";
+                       suffix = "";
                        goto two;
                }
                instruction->type = ARM_AND;
@@ -3058,7 +3060,7 @@ static int t2ev_data_shift(uint32_t opcode, uint32_t address,
                                break;
                        default:
                                if (immed == 0) {
-                                       sprintf(cp, "RRX%s.W\tr%d, r%d",
+                                       sprintf(cp, "RRX%s\tr%d, r%d",
                                                suffix, rd,
                                                (int) (opcode & 0xf));
                                        return ERROR_OK;
@@ -3085,10 +3087,11 @@ static int t2ev_data_shift(uint32_t opcode, uint32_t address,
                break;
        case 4:
                if (rd == 0xf) {
-                       if (!(opcode & (1 << 21)))
+                       if (!(opcode & (1 << 20)))
                                return ERROR_INVALID_ARGUMENTS;
                        instruction->type = ARM_TEQ;
                        mnemonic = "TEQ";
+                       suffix = "";
                        goto two;
                }
                instruction->type = ARM_EOR;
@@ -3096,10 +3099,11 @@ static int t2ev_data_shift(uint32_t opcode, uint32_t address,
                break;
        case 8:
                if (rd == 0xf) {
-                       if (!(opcode & (1 << 21)))
+                       if (!(opcode & (1 << 20)))
                                return ERROR_INVALID_ARGUMENTS;
                        instruction->type = ARM_CMN;
                        mnemonic = "CMN";
+                       suffix = "";
                        goto two;
                }
                instruction->type = ARM_ADD;
@@ -3119,6 +3123,7 @@ static int t2ev_data_shift(uint32_t opcode, uint32_t address,
                                return ERROR_INVALID_ARGUMENTS;
                        instruction->type = ARM_CMP;
                        mnemonic = "CMP";
+                       suffix = "";
                        goto two;
                }
                instruction->type = ARM_SUB;
@@ -3146,13 +3151,17 @@ shift:
                break;
        case 1:
                suffix = "LSR";
+               if (immed == 32)
+                       immed = 0;
                break;
        case 2:
                suffix = "ASR";
+               if (immed == 32)
+                       immed = 0;
                break;
        case 3:
                if (immed == 0) {
-                       strcpy(cp, "RRX");
+                       strcpy(cp, "RRX");
                        return ERROR_OK;
                }
                suffix = "ROR";