PR25281, sh disassembler abort
authorAlan Modra <amodra@gmail.com>
Fri, 20 Dec 2019 07:26:35 +0000 (17:56 +1030)
committerAlan Modra <amodra@gmail.com>
Fri, 20 Dec 2019 07:27:58 +0000 (17:57 +1030)
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.

opcodes/ChangeLog
opcodes/sh-dis.c

index 377f548e9cf5d0ab7ce4cfa534ddcf65b879af7a..d6d731113201c86f31013607c0fd5c9bfed9962b 100644 (file)
@@ -1,3 +1,10 @@
+2019-12-20  Alan Modra  <amodra@gmail.com>
+
+       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  <amodra@gmail.com>
 
        * or1k-ibld.c: Regenerate.
index 126cb5ba992ef4c8a514c013f4f7ae8ad89b3e93..03c1e3a5ba206964d27fd0ae5788398e89ea5bc0 100644 (file)
@@ -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);
     }
 }