diff --git a/binutils/objdump.c b/binutils/objdump.c
index 5972da1..81d47a0 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -2386,7 +2386,9 @@ disassemble_data (bfd *abfd)
     }
 
   /* Use libopcodes to locate a suitable disassembler.  */
-  aux.disassemble_fn = disassembler (abfd);
+  aux.disassemble_fn = disassembler (bfd_get_arch (abfd),
+				     bfd_big_endian (abfd),
+				     bfd_get_mach (abfd), abfd);
   if (!aux.disassemble_fn)
     {
       non_fatal (_("can't disassemble for architecture %s\n"),
diff --git a/include/dis-asm.h b/include/dis-asm.h
index 6f1801d..dd93504 100644
--- a/include/dis-asm.h
+++ b/include/dis-asm.h
@@ -354,8 +354,12 @@ extern const disasm_options_t *disassembler_options_powerpc (void);
 extern const disasm_options_t *disassembler_options_arm (void);
 extern const disasm_options_t *disassembler_options_s390 (void);
 
-/* Fetch the disassembler for a given BFD, if that support is available.  */
-extern disassembler_ftype disassembler (bfd *);
+/* Fetch the disassembler for a given architecture ARC, endianess (big
+   endian if BIG is true), bfd_mach value MACH, and ABFD, if that support
+   is available.  ABFD may be NULL.  */
+extern disassembler_ftype disassembler (enum bfd_architecture arc,
+					bfd_boolean big, unsigned long mach,
+					bfd *abfd);
 
 /* Amend the disassemble_info structure as necessary for the target architecture.
    Should only be called after initialising the info->arch field.  */
diff --git a/opcodes/disassemble.c b/opcodes/disassemble.c
index dd7d3a3..e79b5c7 100644
--- a/opcodes/disassemble.c
+++ b/opcodes/disassemble.c
@@ -21,6 +21,7 @@
 #include "sysdep.h"
 #include "dis-asm.h"
 #include "safe-ctype.h"
+#include <assert.h>
 
 #ifdef ARCH_all
 #define ARCH_aarch64
@@ -109,11 +110,22 @@
 #endif
 
 disassembler_ftype
-disassembler (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
@@ -135,7 +147,7 @@ disassembler (bfd *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;
@@ -184,13 +196,12 @@ disassembler (bfd *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;
@@ -326,7 +337,7 @@ disassembler (bfd *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;
@@ -349,7 +360,7 @@ disassembler (bfd *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;
@@ -372,7 +383,7 @@ disassembler (bfd *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;
@@ -390,7 +401,7 @@ disassembler (bfd *abfd)
 #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;
@@ -413,7 +424,7 @@ disassembler (bfd *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;
@@ -507,7 +518,7 @@ disassembler (bfd *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;
diff --git a/sim/common/sim-trace.c b/sim/common/sim-trace.c
index da19b82..ff11d20 100644
--- a/sim/common/sim-trace.c
+++ b/sim/common/sim-trace.c
@@ -919,7 +919,11 @@ trace_disasm (SIM_DESC sd, sim_cpu *cpu, address_word addr)
   if (trace_data->dis_bfd != bfd)
     {
       trace_data->dis_bfd = bfd;
-      trace_data->disassembler = disassembler (trace_data->dis_bfd);
+      trace_data->disassembler
+	= disassembler (bfd_get_arch (trace_data->dis_bfd),
+			bfd_big_endian (trace_data->dis_bfd),
+			bfd_get_mach (trace_data->dis_bfd),
+			trace_data->dis_bfd);
       INIT_DISASSEMBLE_INFO (*info, cpu, dis_printf);
       info->read_memory_func = dis_read;
       info->arch = bfd_get_arch (bfd);
