* m32r disasm bug fix
authorFrank Ch. Eigler <fche@redhat.com>
Fri, 4 May 2001 17:45:19 +0000 (17:45 +0000)
committerFrank Ch. Eigler <fche@redhat.com>
Fri, 4 May 2001 17:45:19 +0000 (17:45 +0000)
2001-05-04  Frank Ch. Eigler  <fche@redhat.com>

* m32r-dis.c, -asm.c, -ibld.c: Regenerated with disassembler fixes.

2001-05-04  Frank Ch. Eigler  <fche@redhat.com>

* cgen-dis.in (print_insn): Remove call to read_insn.  Instead,
assume incoming buffer already has the base insn loaded.  Handle
case of smaller-than-base instructions for variable-length case.

opcodes/ChangeLog
opcodes/cgen-dis.in
opcodes/m32r-asm.c
opcodes/m32r-dis.c
opcodes/m32r-ibld.c

index 1a483c7..06f9ff8 100644 (file)
@@ -1,3 +1,13 @@
+2001-05-04  Frank Ch. Eigler  <fche@redhat.com>
+
+       * m32r-dis.c, -asm.c, -ibld.c: Regenerated with disassembler fixes.
+
+2001-05-04  Frank Ch. Eigler  <fche@redhat.com>
+
+       * cgen-dis.in (print_insn): Remove call to read_insn.  Instead,
+       assume incoming buffer already has the base insn loaded.  Handle
+       case of smaller-than-base instructions for variable-length case.
+
 2001-05-04  Alan Modra  <amodra@one.net.au>
 
        * i386-dis.c (Ev, Ed): Remove duplicate define.
index 1cb8ea3..b2865f8 100644 (file)
@@ -233,9 +233,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.  */
@@ -246,6 +252,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 */
@@ -260,7 +267,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
index 1fb8638..4d18d64 100644 (file)
@@ -550,9 +550,9 @@ m32r_cgen_assemble_insn (cd, str, fields, buf, errmsg)
 
   {
     static char errbuf[150];
+#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
     const char *tmp_errmsg;
 
-#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
     /* If requesting verbose error messages, use insert_errmsg.
        Failing that, use parse_errmsg */
     tmp_errmsg = (insert_errmsg ? insert_errmsg :
index 7164a40..477a85b 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
index a3c7624..f999bcd 100644 (file)
@@ -202,10 +202,10 @@ insert_normal (cd, value, attrs, word_offset, start, length, word_length,
 }
 
 /* Default insn builder (insert handler).
-   The instruction is recorded in CGEN_INT_INSN_P byte order
-   (meaning that if CGEN_INT_INSN_P BUFFER is an int * and thus the value is
-   recorded in host byte order, otherwise BUFFER is an array of bytes and the
-   value is recorded in target byte order).
+   The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
+   that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
+   recorded in host byte order, otherwise BUFFER is an array of bytes
+   and the value is recorded in target byte order).
    The result is an error message or NULL if success.  */
 
 static const char *
@@ -265,7 +265,7 @@ insert_insn_normal (cd, insn, fields, buffer, pc)
 
 static void
 put_insn_int_value (cd, buf, length, insn_length, value)
-     CGEN_CPU_DESC cd;
+     CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
      CGEN_INSN_BYTES_PTR buf;
      int length;
      int insn_length;