diff options
author | oharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60> | 2009-07-26 20:00:39 +0000 |
---|---|---|
committer | oharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60> | 2009-07-26 20:00:39 +0000 |
commit | e31e6a10dedd7680de231dcfdc700c695d5e4844 (patch) | |
tree | 11860ab1ad4c335d42aa2431aa62714e27e42764 /src/target | |
parent | 49e2267f1f0a689eadbf44da7852659326324044 (diff) | |
download | openocd+libswd-e31e6a10dedd7680de231dcfdc700c695d5e4844.tar.gz openocd+libswd-e31e6a10dedd7680de231dcfdc700c695d5e4844.tar.bz2 openocd+libswd-e31e6a10dedd7680de231dcfdc700c695d5e4844.tar.xz openocd+libswd-e31e6a10dedd7680de231dcfdc700c695d5e4844.zip |
David Brownell <david-b@pacbell.net> More testcase work:
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
Diffstat (limited to 'src/target')
-rw-r--r-- | src/target/arm_disassembler.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/src/target/arm_disassembler.c b/src/target/arm_disassembler.c index 0478ee9c..f963b999 100644 --- a/src/target/arm_disassembler.c +++ b/src/target/arm_disassembler.c @@ -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"; |