summaryrefslogtreecommitdiff
path: root/opcodes/sh-dis.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2019-12-20 17:56:35 +1030
committerAlan Modra <amodra@gmail.com>2019-12-20 17:57:58 +1030
commitcda8d785b37cbcbe286675c48527f0b3e6233809 (patch)
tree86c8a1f34f97088e152333ec6622a3cdccb2cd60 /opcodes/sh-dis.c
parentbcd9f578a96b9776e34e5cec963928f5a96b80e7 (diff)
downloadbinutils-gdb-cda8d785b37cbcbe286675c48527f0b3e6233809.tar.gz
PR25281, sh disassembler abort
PR 25281 * sh-dis.c (print_insn_ddt): Properly check validity of MOVX_NOPY and MOVY_NOPX insns. For invalid cases include 0xf000 in the word printed. Print .word in more cases.
Diffstat (limited to 'opcodes/sh-dis.c')
-rw-r--r--opcodes/sh-dis.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/opcodes/sh-dis.c b/opcodes/sh-dis.c
index 126cb5ba992..03c1e3a5ba2 100644
--- a/opcodes/sh-dis.c
+++ b/opcodes/sh-dis.c
@@ -102,8 +102,7 @@ print_movxy (const sh_opcode_info *op,
/* Print a double data transfer insn. INSN is just the lower three
nibbles of the insn, i.e. field a and the bit that indicates if
- a parallel processing insn follows.
- Return nonzero if a field b of a parallel processing insns follows. */
+ a parallel processing insn follows. */
static void
print_insn_ddt (int insn, struct disassemble_info *info)
@@ -113,7 +112,10 @@ print_insn_ddt (int insn, struct disassemble_info *info)
/* If this is just a nop, make sure to emit something. */
if (insn == 0x000)
- fprintf_fn (stream, "nopx\tnopy");
+ {
+ fprintf_fn (stream, "nopx\tnopy");
+ return;
+ }
/* If a parallel processing insn was printed before,
and we got a non-nop, emit a tab. */
@@ -121,8 +123,8 @@ print_insn_ddt (int insn, struct disassemble_info *info)
fprintf_fn (stream, "\t");
/* Check if either the x or y part is invalid. */
- if (((insn & 0xc) == 0 && (insn & 0x2a0))
- || ((insn & 3) == 0 && (insn & 0x150)))
+ if (((insn & 3) != 0 && (insn & 0xc) == 0 && (insn & 0x2a0))
+ || ((insn & 3) == 0 && (insn & 0xc) != 0 && (insn & 0x150)))
if (info->mach != bfd_mach_sh_dsp
&& info->mach != bfd_mach_sh3_dsp)
{
@@ -157,7 +159,7 @@ print_insn_ddt (int insn, struct disassemble_info *info)
fprintf_fn, stream);
}
else
- fprintf_fn (stream, ".word 0x%x", insn);
+ fprintf_fn (stream, ".word 0x%x", insn | 0xf000);
else
{
static const sh_opcode_info *first_movx, *first_movy;
@@ -189,6 +191,8 @@ print_insn_ddt (int insn, struct disassemble_info *info)
print_movxy (opy, ((insn >> 8) & 1) + 6, (insn >> 6) & 1,
fprintf_fn, stream);
}
+ if (!insn_x && !insn_y && ((insn & 0x3ff) != 0 || (insn & 0x800) == 0))
+ fprintf_fn (stream, ".word 0x%x", insn | 0xf000);
}
}