opcodes/mips: disassemble unknown micromips instructions as two shorts
authorAndrew Burgess <aburgess@redhat.com>
Fri, 6 Jan 2023 16:42:23 +0000 (16:42 +0000)
committerAndrew Burgess <aburgess@redhat.com>
Mon, 13 Feb 2023 12:05:32 +0000 (12:05 +0000)
Before commit:

  commit 2438b771ee07be19d5b01ea55e077dd8b7cef445
  Date:   Wed Nov 2 15:53:43 2022 +0000

      opcodes/mips: use .word/.short for undefined instructions

unknown 32-bit microMIPS instructions were disassembled as a raw
32-bit number with no '.word' directive.  The above commit changed
this and added a '.word' directive before the 32-bit number.

It was pointed out on the mailing list, that for microMIPS it would be
better to display such 32-bit instructions using a '.short' directive
followed by two 16-bit values.

This commit updates the mips disassembler to do this, and adds a new
test that validates this output.

binutils/testsuite/binutils-all/mips/micromips-reserved-enc-n32.d [new file with mode: 0644]
binutils/testsuite/binutils-all/mips/micromips-reserved-enc-n64.d [new file with mode: 0644]
binutils/testsuite/binutils-all/mips/micromips-reserved-enc-o32.d [new file with mode: 0644]
binutils/testsuite/binutils-all/mips/micromips-reserved-enc.s [new file with mode: 0644]
binutils/testsuite/binutils-all/mips/mips.exp
opcodes/mips-dis.c

diff --git a/binutils/testsuite/binutils-all/mips/micromips-reserved-enc-n32.d b/binutils/testsuite/binutils-all/mips/micromips-reserved-enc-n32.d
new file mode 100644 (file)
index 0000000..e6608f3
--- /dev/null
@@ -0,0 +1,5 @@
+#PROG: objcopy
+#objdump: -d --prefix-addresses --show-raw-insn
+#name: microMIPS source file contains reserved encoding (n32)
+#source: micromips-reserved-enc.s
+#dump: micromips-reserved-enc-o32.d
diff --git a/binutils/testsuite/binutils-all/mips/micromips-reserved-enc-n64.d b/binutils/testsuite/binutils-all/mips/micromips-reserved-enc-n64.d
new file mode 100644 (file)
index 0000000..f892bfa
--- /dev/null
@@ -0,0 +1,5 @@
+#PROG: objcopy
+#objdump: -d --prefix-addresses --show-raw-insn
+#name: microMIPS source file contains reserved encoding (n64)
+#source: micromips-reserved-enc.s
+#dump: micromips-reserved-enc-o32.d
diff --git a/binutils/testsuite/binutils-all/mips/micromips-reserved-enc-o32.d b/binutils/testsuite/binutils-all/mips/micromips-reserved-enc-o32.d
new file mode 100644 (file)
index 0000000..3de3989
--- /dev/null
@@ -0,0 +1,10 @@
+#PROG: objcopy
+#objdump: -d --prefix-addresses --show-raw-insn
+#name: microMIPS source file contains reserved encoding (o32)
+#source: micromips-reserved-enc.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 7f6e 5d4c    \.short 0x7f6e, 0x5d4c
+       \.\.\.
diff --git a/binutils/testsuite/binutils-all/mips/micromips-reserved-enc.s b/binutils/testsuite/binutils-all/mips/micromips-reserved-enc.s
new file mode 100644 (file)
index 0000000..d4918f3
--- /dev/null
@@ -0,0 +1,9 @@
+       .module mips64r3
+       .module micromips
+foo:
+       .insn
+       .short  0x7f6e, 0x5d4c
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+       .align  4, 0
+       .space  16
index 6a0ec25a06f4ba1a23e506a14c58c9d548cb724e..91bf32745925e9a449217c2e79ba69850c05e06e 100644 (file)
@@ -266,3 +266,7 @@ run_dump_test_n64 "global-local-symtab-sort-n64${tmips}"
 run_dump_test_o32 "global-local-symtab-final-o32" useld
 run_dump_test_n32 "global-local-symtab-final-n32" useld
 run_dump_test_n64 "global-local-symtab-final-n64" useld
+
+run_dump_test_o32 "micromips-reserved-enc-o32"
+run_dump_test_n32 "micromips-reserved-enc-n32"
+run_dump_test_n64 "micromips-reserved-enc-n64"
index 6a513cd8946bc0ee4d330eb362c8a5b61f958f2f..859d4e3806fa506468d5074645ef777a4d5b4550 100644 (file)
@@ -2600,12 +2600,15 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
        }
     }
 
-  if (length == 2)
-    infprintf (is, dis_style_assembler_directive, ".short");
-  else
-    infprintf (is, dis_style_assembler_directive, ".word");
+  infprintf (is, dis_style_assembler_directive, ".short");
   infprintf (is, dis_style_text, "\t");
-  infprintf (is, dis_style_immediate, "0x%x", insn);
+  if (length != 2)
+    {
+      infprintf (is, dis_style_immediate, "0x%x", (insn >> 16) & 0xffff);
+      infprintf (is, dis_style_text, ", ");
+    }
+  infprintf (is, dis_style_immediate, "0x%x", (insn & 0xffff));
+
   info->insn_type = dis_noninsn;
 
   return length;