This is the mail archive of the cgen@sources.redhat.com mailing list for the CGEN project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

opcodes/cgen-dis.in patch


Hi -

I'm about to commit the following patch to opcodes/cgen-dis.in.
It fixes a long-standing bug in the m32r disassembler, and enables
other ports with variable-length instructions to do the right thing.

It is not necessary to regenerate the other targets' opcodes files
right away.

- FChE


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.

 
Index: cgen-dis.in
===================================================================
RCS file: /cvs/src/src/opcodes/cgen-dis.in,v
retrieving revision 1.7
diff -u -r1.7 cgen-dis.in
--- cgen-dis.in	2001/03/20 20:56:34	1.7
+++ cgen-dis.in	2001/05/04 17:41:03
@@ -233,10 +233,16 @@
   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 @@
       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 @@
       /* 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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]