aboutsummaryrefslogtreecommitdiff
path: root/opcodes/s12z-dis.c
diff options
context:
space:
mode:
authorJohn Darrington <john@darrington.wattle.id.au>2018-11-20 18:50:30 +0100
committerJohn Darrington <john@darrington.wattle.id.au>2018-11-21 21:34:47 +0100
commit27f42a4ddb28514fde3d01083120674fc8c0c107 (patch)
tree3e064190c801dd9e278edcdfa81481133f620968 /opcodes/s12z-dis.c
parent51534d7ab8c77fdf2af52f409cc4e348e4213bb7 (diff)
downloadgdb-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.c44
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:
{