This is the mail archive of the binutils@sourceware.cygnus.com mailing list for the binutils project.


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

[patch] opcodes/h8300-dis.c


Hi,

Attached is a patch for opcodes/h8300-dis.c. It fixes a bug that I
introduced in:

http://sourceware.cygnus.com/ml/binutils/2000-05/msg00719.html

The bug causes the disassembler not to distinguish adds, inc.w, and
inc.l correcly. The same thing happens with subs, dec.w, and dec.l.

H8/300[HS] has very similar opcodes for adds, inc.w, and inc.l. They
all begin with 0x0b. To correctly distinguish them, we have to look at
all of bits 4-6 of the second byte. Originally (before my first
patch), bfd_h8_disassemble () in h8300-dis.c looked at bit 4 and bit
6. With my first patch applied, it looked at bit 5 only. This patch,
which should settle things down, looks at all of bits 4-6.

The same applies to subs, dec.w, and dec.l. The only difference is
that they begin with 0x1b. All the rest is the same.

The following can be used as a test.

/* h8300-hms-gcc -mh -Wall -O2 -fomit-frame-pointer -o bug.o -c bug.c */
void
test ()
{
  /* All insns that begin with 0x0b.  */
  asm ("adds\t#1,er0");
  asm ("adds\t#2,er1");
  asm ("adds\t#4,er2");
  asm ("inc.w\t#1,r3");
  asm ("inc.w\t#2,r4");
  asm ("inc.l\t#1,er5");
  asm ("inc.l\t#2,er6");

  /* All insns that begin with 0x1b.  */
  asm ("subs\t#1,er0");
  asm ("subs\t#2,er1");
  asm ("subs\t#4,er2");
  asm ("dec.w\t#1,r3");
  asm ("dec.w\t#2,r4");
  asm ("dec.l\t#1,er5");
  asm ("dec.l\t#2,er6");
}

With the patch applied, the following command shuold show the same
assembly code as above.

h8300-hms-objdump --no-show-raw-insn -d bug.o

By the way, the patch includes a lot of formatting changes. That is
because I think it's good to make the following two functions look
similar.

  bfd_h8_disassemble () in opcodes/h8300-dis.c
  decode () in sim/h8300/compile.c

One is a disassembler; the other is a simulator. Thus, the opcode
interpretation part should be identical. Right now, taking a diff
between the two functions gives lots of white-space differences, which
are meaningless. So, if you could, please apply the patch as it is.

Thanks,

Kazu Hirata

===File ~/h8300-hms/binutils/ChangeLog-h8300-dis============
2000-06-04  Kazu Hirata  <kazu@hxi.com>

	* h8300-dis.c: Fix formatting.
	(bfd_h8_disassemble): Distinguish adds/subs, inc/dec.[wl]
	correctly.

============================================================

===File ~/h8300-hms/binutils/h8300-dis.patch================
Index: opcodes/h8300-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/h8300-dis.c,v
retrieving revision 1.5
diff -u -r1.5 h8300-dis.c
--- h8300-dis.c	2000/06/02 18:09:28	1.5
+++ h8300-dis.c	2000/06/07 17:18:25
@@ -23,7 +23,6 @@
 #include "dis-asm.h"
 #include "opintl.h"
 
-
 /* Run through the opcodes and sort them into order to make them easy
    to disassemble.  */
 static void
@@ -41,7 +40,7 @@
 	n1 = (int) p->data.nib[0];
       else
 	n1 = 0;
-      
+
       if ((int) p->data.nib[1] < 16)
 	n2 = (int) p->data.nib[1];
       else
@@ -50,16 +49,15 @@
       /* Just make sure there are an even number of nibbles in it, and
 	 that the count is the same as the length.  */
       for (i = 0; p->data.nib[i] != E; i++)
-	/*EMPTY*/;
-      
+	;
+
       if (i & 1)
 	abort ();
-      
+
       p->length = i / 2;
     }
 }
 
-
 unsigned int
 bfd_h8_disassemble (addr, info, mode)
      bfd_vma addr;
@@ -109,9 +107,9 @@
       info->memory_error_func (status, addr, info);
       return -1;
     }
-  
+
   for (l = 2; status == 0 && l < 10; l += 2)
-    status = info->read_memory_func (addr + l, data+l, 2, info);
+    status = info->read_memory_func (addr + l, data + l, 2, info);
 
   /* Find the exact opcode/arg combo.  */
   while (q->name)
@@ -120,14 +118,14 @@
       unsigned int len = 0;
 
       nib = q->data.nib;
-      
+
       while (1)
 	{
 	  op_type looking_for = *nib;
 	  int thisnib = data[len >> 1];
-	  
+
 	  thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib >> 4) & 0xf);
-	  
+
 	  if (looking_for < 16 && looking_for >= 0)
 	    {
 	      if (looking_for != thisnib)
@@ -137,25 +135,28 @@
 	    {
 	      if ((int) looking_for & (int) B31)
 		{
-		  if (! (((int) thisnib & 0x8) != 0))
+		  if (!(((int) thisnib & 0x8) != 0))
 		    goto fail;
-		  
+
 		  looking_for = (op_type) ((int) looking_for & ~(int) B31);
 		}
-	      
+
 	      if ((int) looking_for & (int) B30)
 		{
 		  if (!(((int) thisnib & 0x8) == 0))
 		    goto fail;
-		  
+
 		  looking_for = (op_type) ((int) looking_for & ~(int) B30);
 		}
 
 	      if (looking_for & DBIT)
 		{
-		  if ((looking_for & 2) != (thisnib & 2))
+		  /* Exclude adds/subs by looking at bit 0 and 2, and
+                     make sure the operand size, either w or l,
+                     matches by looking at bit 1.  */
+		  if ((looking_for & 7) != (thisnib & 7))
 		    goto fail;
-		  
+
 		  abs = (thisnib & 0x8) ? 2 : 1;
 		}
 	      else if (looking_for & (REG | IND | INC | DEC))
@@ -181,18 +182,18 @@
 	      else if (looking_for & L_32)
 		{
 		  int i = len >> 1;
-		  
+
 		  abs = (data[i] << 24)
 		    | (data[i + 1] << 16)
 		    | (data[i + 2] << 8)
-		    | (data[i+ 3]);
+		    | (data[i + 3]);
 
 		  plen = 32;
 		}
 	      else if (looking_for & L_24)
 		{
 		  int i = len >> 1;
-		  
+
 		  abs = (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]);
 		  plen = 24;
 		}
@@ -245,10 +246,10 @@
 
 		  for (i = 0; i < q->length; i++)
 		    fprintf (stream, "%02x ", data[i]);
-		  
+
 		  for (; i < 6; i++)
 		    fprintf (stream, "   ");
-		  
+
 		  fprintf (stream, "%s\t", q->name);
 
 		  /* Gross.  Disgusting.  */
@@ -282,7 +283,7 @@
 		    while (*args != E)
 		      {
 			int x = *args;
-			
+
 			if (hadone)
 			  fprintf (stream, ",");
 
@@ -301,7 +302,7 @@
 			else if (x & REG)
 			  {
 			    int rn = (x & DST) ? rd : rs;
-			    
+
 			    switch (x & SIZE)
 			      {
 			      case L_8:
@@ -351,20 +352,22 @@
 			      {
 				abs += 2;
 				fprintf (stream,
-					 ".%s%d (%x)", (short) abs > 0 ? "+" : "",
+					 ".%s%d (%x)",
+					 (short) abs > 0 ? "+" : "",
 					 (short) abs, addr + (short) abs + 2);
 			      }
 			    else
 			      {
 				fprintf (stream,
-					 ".%s%d (%x)", (char) abs > 0 ? "+" : "",
+					 ".%s%d (%x)",
+					 (char) abs > 0 ? "+" : "",
 					 (char) abs, addr + (char) abs + 2);
 			      }
 			  }
 			else if (x & DISP)
 			  {
 			    fprintf (stream, "@(0x%x:%d,%s)",
-				     abs,plen, pregnames[rdisp]);
+				     abs, plen, pregnames[rdisp]);
 			  }
 			else if (x & CCR)
 			  {
@@ -377,23 +380,23 @@
 			else
 			  /* xgettext:c-format */
 			  fprintf (stream, _("Hmmmm %x"), x);
-			
+
 			hadone = 1;
 			args++;
 		      }
 		  }
-		  
+
 		  return q->length;
 		}
 	      else
 		/* xgettext:c-format */
 		fprintf (stream, _("Don't understand %x \n"), looking_for);
 	    }
-	  
+
 	  len++;
 	  nib++;
 	}
-      
+
     fail:
       q++;
     }
@@ -402,7 +405,6 @@
   fprintf (stream, "%02x %02x        .word\tH'%x,H'%x",
 	   data[0], data[1],
 	   data[0], data[1]);
-  
   return 2;
 }
 
============================================================


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