From: Alan Modra Date: Fri, 20 Dec 2019 07:26:35 +0000 (+1030) Subject: PR25281, sh disassembler abort X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cda8d785b37cbcbe286675c48527f0b3e6233809;p=binutils-gdb.git 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. --- diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 377f548e9cf..d6d73111320 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,10 @@ +2019-12-20 Alan Modra + + 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. + 2019-12-20 Alan Modra * or1k-ibld.c: Regenerate. 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); } }