Refactor disassembler selection
[deliverable/binutils-gdb.git] / opcodes / disassemble.c
index 0c1d7e01749c7e0e8b746cfe5b78ac281bc3a2db..e79b5c7d3836c994fcaaf05203bd1c43e848f573 100644 (file)
@@ -1,5 +1,5 @@
 /* Select disassembly routine for specified architecture.
-   Copyright (C) 1994-2015 Free Software Foundation, Inc.
+   Copyright (C) 1994-2017 Free Software Foundation, Inc.
 
    This file is part of the GNU opcodes library.
 
@@ -20,6 +20,8 @@
 
 #include "sysdep.h"
 #include "dis-asm.h"
+#include "safe-ctype.h"
+#include <assert.h>
 
 #ifdef ARCH_all
 #define ARCH_aarch64
@@ -37,6 +39,7 @@
 #define ARCH_epiphany
 #define ARCH_fr30
 #define ARCH_frv
+#define ARCH_ft32
 #define ARCH_h8300
 #define ARCH_h8500
 #define ARCH_hppa
@@ -72,6 +75,7 @@
 #define ARCH_pdp11
 #define ARCH_pj
 #define ARCH_powerpc
+#define ARCH_pru
 #define ARCH_rs6000
 #define ARCH_rl78
 #define ARCH_rx
@@ -91,6 +95,7 @@
 #define ARCH_vax
 #define ARCH_visium
 #define ARCH_w65
+#define ARCH_wasm32
 #define ARCH_xstormy16
 #define ARCH_xc16x
 #define ARCH_xgate
 #endif
 
 disassembler_ftype
-disassembler (abfd)
-     bfd *abfd;
+disassembler (enum bfd_architecture a, bfd_boolean big, unsigned long mach,
+             bfd *abfd)
 {
-  enum bfd_architecture a = bfd_get_arch (abfd);
   disassembler_ftype disassemble;
 
+  if (abfd != NULL)
+    {
+      /* Do some asserts that the first three parameters should equal
+        to what we can get from ABFD.  On the other hand, these
+        asserts help removing some compiler errors on unused
+        parameter.  */
+      assert (a == bfd_get_arch (abfd));
+      assert (big == bfd_big_endian (abfd));
+      assert (mach == bfd_get_mach (abfd));
+    }
+
   switch (a)
     {
       /* If you add a case to this table, also add it to the
@@ -132,7 +147,7 @@ disassembler (abfd)
 #endif
 #ifdef ARCH_arm
     case bfd_arch_arm:
-      if (bfd_big_endian (abfd))
+      if (big)
        disassemble = print_insn_big_arm;
       else
        disassemble = print_insn_little_arm;
@@ -181,13 +196,12 @@ disassembler (abfd)
 #endif
 #ifdef ARCH_h8300
     case bfd_arch_h8300:
-      if (bfd_get_mach (abfd) == bfd_mach_h8300h
-         || bfd_get_mach (abfd) == bfd_mach_h8300hn)
+      if (mach == bfd_mach_h8300h || mach == bfd_mach_h8300hn)
        disassemble = print_insn_h8300h;
-      else if (bfd_get_mach (abfd) == bfd_mach_h8300s
-              || bfd_get_mach (abfd) == bfd_mach_h8300sn
-              || bfd_get_mach (abfd) == bfd_mach_h8300sx
-              || bfd_get_mach (abfd) == bfd_mach_h8300sxn)
+      else if (mach == bfd_mach_h8300s
+              || mach == bfd_mach_h8300sn
+              || mach == bfd_mach_h8300sx
+              || mach == bfd_mach_h8300sxn)
        disassemble = print_insn_h8300s;
       else
        disassemble = print_insn_h8300;
@@ -210,6 +224,7 @@ disassembler (abfd)
 #endif
 #ifdef ARCH_i386
     case bfd_arch_i386:
+    case bfd_arch_iamcu:
     case bfd_arch_l1om:
     case bfd_arch_k1om:
       disassemble = print_insn_i386;
@@ -322,7 +337,7 @@ disassembler (abfd)
 #endif
 #ifdef ARCH_mips
     case bfd_arch_mips:
-      if (bfd_big_endian (abfd))
+      if (big)
        disassemble = print_insn_big_mips;
       else
        disassemble = print_insn_little_mips;
@@ -345,7 +360,7 @@ disassembler (abfd)
 #endif
 #ifdef ARCH_nios2
     case bfd_arch_nios2:
-      if (bfd_big_endian (abfd))
+      if (big)
        disassemble = print_insn_big_nios2;
       else
        disassemble = print_insn_little_nios2;
@@ -368,15 +383,25 @@ disassembler (abfd)
 #endif
 #ifdef ARCH_powerpc
     case bfd_arch_powerpc:
-      if (bfd_big_endian (abfd))
+      if (big)
        disassemble = print_insn_big_powerpc;
       else
        disassemble = print_insn_little_powerpc;
       break;
 #endif
+#ifdef ARCH_pru
+    case bfd_arch_pru:
+      disassemble = print_insn_pru;
+      break;
+#endif
+#ifdef ARCH_riscv
+    case bfd_arch_riscv:
+      disassemble = print_insn_riscv;
+      break;
+#endif
 #ifdef ARCH_rs6000
     case bfd_arch_rs6000:
-      if (bfd_get_mach (abfd) == bfd_mach_ppc_620)
+      if (mach == bfd_mach_ppc_620)
        disassemble = print_insn_big_powerpc;
       else
        disassemble = print_insn_rs6000;
@@ -384,7 +409,7 @@ disassembler (abfd)
 #endif
 #ifdef ARCH_rl78
     case bfd_arch_rl78:
-      disassemble = print_insn_rl78;
+      disassemble = rl78_get_disassembler (abfd);
       break;
 #endif
 #ifdef ARCH_rx
@@ -399,7 +424,7 @@ disassembler (abfd)
 #endif
 #ifdef ARCH_score
     case bfd_arch_score:
-      if (bfd_big_endian (abfd))
+      if (big)
        disassemble = print_insn_big_score;
       else
        disassemble = print_insn_little_score;
@@ -445,6 +470,11 @@ disassembler (abfd)
       disassemble = print_insn_tic80;
       break;
 #endif
+#ifdef ARCH_ft32
+    case bfd_arch_ft32:
+      disassemble = print_insn_ft32;
+      break;
+#endif
 #ifdef ARCH_v850
     case bfd_arch_v850:
     case bfd_arch_v850_rh850:
@@ -456,6 +486,11 @@ disassembler (abfd)
       disassemble = print_insn_w65;
       break;
 #endif
+#ifdef ARCH_wasm32
+    case bfd_arch_wasm32:
+      disassemble = print_insn_wasm32;
+      break;
+#endif
 #ifdef ARCH_xgate
     case bfd_arch_xgate:
       disassemble = print_insn_xgate;
@@ -483,7 +518,7 @@ disassembler (abfd)
 #endif
 #ifdef ARCH_z8k
     case bfd_arch_z8k:
-      if (bfd_get_mach(abfd) == bfd_mach_z8001)
+      if (mach == bfd_mach_z8001)
        disassemble = print_insn_z8001;
       else
        disassemble = print_insn_z8002;
@@ -536,12 +571,14 @@ disassembler (abfd)
 }
 
 void
-disassembler_usage (stream)
-     FILE * stream ATTRIBUTE_UNUSED;
+disassembler_usage (FILE *stream ATTRIBUTE_UNUSED)
 {
 #ifdef ARCH_aarch64
   print_aarch64_disassembler_options (stream);
 #endif
+#ifdef ARCH_arc
+  print_arc_disassembler_options (stream);
+#endif
 #ifdef ARCH_arm
   print_arm_disassembler_options (stream);
 #endif
@@ -551,12 +588,18 @@ disassembler_usage (stream)
 #ifdef ARCH_powerpc
   print_ppc_disassembler_options (stream);
 #endif
+#ifdef ARCH_riscv
+  print_riscv_disassembler_options (stream);
+#endif
 #ifdef ARCH_i386
   print_i386_disassembler_options (stream);
 #endif
 #ifdef ARCH_s390
   print_s390_disassembler_options (stream);
 #endif
+#ifdef ARCH_wasm32
+  print_wasm32_disassembler_options (stream);
+#endif
 
   return;
 }
@@ -626,8 +669,82 @@ disassemble_init_for_target (struct disassemble_info * info)
 #if defined (ARCH_powerpc) || defined (ARCH_rs6000)
       disassemble_init_powerpc (info);
       break;
+#endif
+#ifdef ARCH_wasm32
+    case bfd_arch_wasm32:
+      disassemble_init_wasm32 (info);
+      break;
+#endif
+#ifdef ARCH_s390
+    case bfd_arch_s390:
+      disassemble_init_s390 (info);
+      break;
 #endif
     default:
       break;
     }
 }
+
+/* Remove whitespace and consecutive commas from OPTIONS.  */
+
+char *
+remove_whitespace_and_extra_commas (char *options)
+{
+  char *str;
+  size_t i, len;
+
+  if (options == NULL)
+    return NULL;
+
+  /* Strip off all trailing whitespace and commas.  */
+  for (len = strlen (options); len > 0; len--)
+    {
+      if (!ISSPACE (options[len - 1]) && options[len - 1] != ',')
+       break;
+      options[len - 1] = '\0';
+    }
+
+  /* Convert all remaining whitespace to commas.  */
+  for (i = 0; options[i] != '\0'; i++)
+    if (ISSPACE (options[i]))
+      options[i] = ',';
+
+  /* Remove consecutive commas.  */
+  for (str = options; *str != '\0'; str++)
+    if (*str == ',' && (*(str + 1) == ',' || str == options))
+      {
+       char *next = str + 1;
+       while (*next == ',')
+         next++;
+       len = strlen (next);
+       if (str != options)
+         str++;
+       memmove (str, next, len);
+       next[len - (size_t)(next - str)] = '\0';
+      }
+  return (strlen (options) != 0) ? options : NULL;
+}
+
+/* Like STRCMP, but treat ',' the same as '\0' so that we match
+   strings like "foobar" against "foobar,xxyyzz,...".  */
+
+int
+disassembler_options_cmp (const char *s1, const char *s2)
+{
+  unsigned char c1, c2;
+
+  do
+    {
+      c1 = (unsigned char) *s1++;
+      if (c1 == ',')
+       c1 = '\0';
+      c2 = (unsigned char) *s2++;
+      if (c2 == ',')
+       c2 = '\0';
+      if (c1 == '\0')
+       return c1 - c2;
+    }
+  while (c1 == c2);
+
+  return c1 - c2;
+}
This page took 0.031739 seconds and 4 git commands to generate.