* m32r disasm bug fix
[deliverable/binutils-gdb.git] / opcodes / m32r-dis.c
index 7164a40cf5c27760f1f2dbbbf76ee05ef6b87b4e..477a85b9dae6faa44532af476039a2b5ef5572c0 100644 (file)
@@ -438,9 +438,15 @@ print_insn (cd, pc, info, buf, buflen)
   const CGEN_INSN_LIST *insn_list;
   CGEN_EXTRACT_INFO ex_info;
 
-  int rc = read_insn (cd, pc, info, buf, buflen, & ex_info, & insn_value);
-  if (rc != 0)
-    return rc;
+  /* Extract base part of instruction, just in case CGEN_DIS_* uses it. */
+  insn_value = bfd_get_bits (buf, buflen * 8, info->endian == BFD_ENDIAN_BIG);
+
+  /* Fill in ex_info fields like read_insn would.  Don't actually call
+     read_insn, since the incoming buffer is already read (and possibly
+     modified a la m32r).  */
+  ex_info.valid = (1 << buflen) - 1;
+  ex_info.dis_info = info;
+  ex_info.insn_bytes = buf;
 
   /* The instructions are stored in hash lists.
      Pick the first one and keep trying until we find the right one.  */
@@ -451,6 +457,7 @@ print_insn (cd, pc, info, buf, buflen)
       const CGEN_INSN *insn = insn_list->insn;
       CGEN_FIELDS fields;
       int length;
+      unsigned long insn_value_cropped;
 
 #ifdef CGEN_VALIDATE_INSN_SUPPORTED 
       /* not needed as insn shouldn't be in hash lists if not supported */
@@ -465,7 +472,17 @@ print_insn (cd, pc, info, buf, buflen)
       /* Basic bit mask must be correct.  */
       /* ??? May wish to allow target to defer this check until the extract
         handler.  */
-      if ((insn_value & CGEN_INSN_BASE_MASK (insn))
+
+      /* Base size may exceed this instruction's size.  Extract the
+         relevant part from the buffer. */
+      if ((CGEN_INSN_BITSIZE (insn) / 8) < buflen &&
+         (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
+       insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn), 
+                                          info->endian == BFD_ENDIAN_BIG);
+      else
+       insn_value_cropped = insn_value;
+
+      if ((insn_value_cropped & CGEN_INSN_BASE_MASK (insn))
          == CGEN_INSN_BASE_VALUE (insn))
        {
          /* Printing is handled in two passes.  The first pass parses the
This page took 0.026706 seconds and 4 git commands to generate.