diff options
author | John Darrington <john@darrington.wattle.id.au> | 2018-11-20 18:50:30 +0100 |
---|---|---|
committer | John Darrington <john@darrington.wattle.id.au> | 2018-11-21 21:34:47 +0100 |
commit | 27f42a4ddb28514fde3d01083120674fc8c0c107 (patch) | |
tree | 3e064190c801dd9e278edcdfa81481133f620968 /opcodes/s12z-dis.c | |
parent | 51534d7ab8c77fdf2af52f409cc4e348e4213bb7 (diff) | |
download | gdb-27f42a4ddb28514fde3d01083120674fc8c0c107.zip gdb-27f42a4ddb28514fde3d01083120674fc8c0c107.tar.gz gdb-27f42a4ddb28514fde3d01083120674fc8c0c107.tar.bz2 |
S12Z opcodes: Fix bug disassembling certain shift instructions.
Shift and rotate instructions when the number of bit positions
was an immediate value greater than 1 were incorrectly disassembled.
This change fixes that problem and extends the test to check for
it.
gas/ChangeLog:
testsuite/gas/s12z/shift.s: Add new test case.
testsuite/gas/s12z/shift.d: Add expected result.
opcodes/ChangeLog:
s12z-dis.c (print_insn_shift) [SB_REG_REG_N]: Enter special case
if the postbyte matches the appropriate pattern.
Diffstat (limited to 'opcodes/s12z-dis.c')
-rw-r--r-- | opcodes/s12z-dis.c | 44 |
1 files changed, 25 insertions, 19 deletions
diff --git a/opcodes/s12z-dis.c b/opcodes/s12z-dis.c index ad39e05..719f172 100644 --- a/opcodes/s12z-dis.c +++ b/opcodes/s12z-dis.c @@ -2363,25 +2363,31 @@ print_insn_shift (bfd_vma memaddr, struct disassemble_info* info, uint8_t byte) break; case SB_REG_REG_N: - if (sb & 0x08) - { - operand_separator (info); - if (byte & 0x10) - { - uint8_t xb; - read_memory (memaddr + 1, &xb, 1, info); - int shift = ((sb & 0x08) >> 3) | ((xb & 0x0f) << 1); - (*info->fprintf_func) (info->stream, "#%d", shift); - } - else - { - (*info->fprintf_func) (info->stream, "%s:%d", __FILE__, __LINE__); - } - } - else - { - opr_decode (memaddr + 1, info); - } + { + uint8_t xb; + read_memory (memaddr + 1, &xb, 1, info); + /* This case is slightly unusual. + If XB matches the binary pattern 0111XXXX, then instead of + interpreting this as a general OPR postbyte in the IMMe4 mode, + the XB byte is interpreted in s special way. */ + if ((xb & 0xF0) == 0x70) + { + operand_separator (info); + if (byte & 0x10) + { + int shift = ((sb & 0x08) >> 3) | ((xb & 0x0f) << 1); + (*info->fprintf_func) (info->stream, "#%d", shift); + } + else + { + (*info->fprintf_func) (info->stream, "%s:%d", __FILE__, __LINE__); + } + } + else + { + opr_decode (memaddr + 1, info); + } + } break; case SB_REG_OPR_OPR: { |