This is the mail archive of the binutils@sources.redhat.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]
Other format: [Raw text]

[PATCH]: Fix HC12 disassembler


Hi!

The HC12 disassembler was disassembling 'call' instructions incorrectly.
I've committed this patch on mainline to fix this.

	Stephane

ChangeLog for opcodes

2002-08-13  Stephane Carrez  <stcarrez@nerim.fr>

	* m68hc11-dis.c (print_insn): Take into account 68HC12 memory
	banks and fix disassembling of call instruction.
	(print_indexed_operand): New param to tell whether
	it was an indirect addressing operand (for disassembling call).

ChangeLog for include/opcodes

2002-08-13  Stephane Carrez  <stcarrez@nerim.fr>

	* m68hc11.h (M6812_OP_PAGE): Define to identify call operand.
	(M68HC12_BANK_VIRT, M68HC12_BANK_MASK, M68HC12_BANK_BASE,
	M68HC12_BANK_SHIFT, M68HC12_BANK_PAGE_MASK): Define for 68HC12
	memory banks.
	(M6811_OC1M5, M6811_OC1M4, M6811_MODF): Fix value.
Index: include/opcode/m68hc11.h
===================================================================
RCS file: /cvs/src/src/include/opcode/m68hc11.h,v
retrieving revision 1.1
diff -u -p -r1.1 m68hc11.h
--- include/opcode/m68hc11.h	19 Jun 2000 01:22:42 -0000	1.1
+++ include/opcode/m68hc11.h	13 Aug 2002 18:15:29 -0000
@@ -1,6 +1,6 @@
 /* m68hc11.h -- Header file for Motorola 68HC11 & 68HC12 opcode table
-   Copyright 1999, 2000 Free Software Foundation, Inc.
-   Written by Stephane Carrez (stcarrez@worldnet.fr)
+   Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
+   Written by Stephane Carrez (stcarrez@nerim.fr)
 
 This file is part of GDB, GAS, and the GNU binutils.
 
@@ -191,7 +191,7 @@ Software Foundation, 59 Temple Place - S
 /* Flags of the SPSR register.  */
 #define M6811_SPIF	0x80	/* SPI Transfer Complete flag */
 #define M6811_WCOL	0x40	/* Write Collision */
-#define M6811_MODF	0x20	/* Mode Fault */
+#define M6811_MODF	0x10	/* Mode Fault */
 
 /* Flags of the ADCTL register.  */
 #define M6811_CCF	0x80	/* Conversions Complete Flag */
@@ -212,8 +212,8 @@ Software Foundation, 59 Temple Place - S
 /* Flags of the OC1M register.  */
 #define M6811_OC1M7	0x80	/* Output Compare 7 */
 #define M6811_OC1M6	0x40	/*                6 */
-#define M6811_OC1M5	0x40	/*                5 */
-#define M6811_OC1M4	0x40	/*                4 */
+#define M6811_OC1M5	0x20	/*                5 */
+#define M6811_OC1M4	0x10	/*                4 */
 #define M6811_OC1M3	0x08	/*                3 */
 
 /* Flags of the OC1D register.  */
@@ -341,7 +341,9 @@ Software Foundation, 59 Temple Place - S
 #define M6812_OP_IDX_2        0x0800   /* N,r N:16-bits */
 #define M6812_OP_D_IDX        0x1000   /* Indirect indexed: [D,r] */
 #define M6812_OP_D_IDX_2      0x2000   /* [N,r] N:16-bits */
-#define M6811_OP_MASK         0x0FFFF
+#define M6812_OP_PAGE         0x4000   /* Page number */
+#define M6811_OP_MASK         0x07FFF
+#define M6811_OP_BRANCH       0x00008000 /* Branch, jsr, call */
 #define M6811_OP_BITMASK      0x00010000 /* Bitmask:             #<val-8>    */
 #define M6811_OP_JUMP_REL     0x00020000 /* Pc-Relative:         <val-8>     */
 #define M6812_OP_JUMP_REL16   0x00040000 /* Pc-relative:         <val-16>    */
@@ -375,6 +377,13 @@ Software Foundation, 59 Temple Place - S
 
 #define M6811_OP_HIGH_ADDR    0x01000000 /* Used internally by gas.  */
 #define M6811_OP_LOW_ADDR     0x02000000
+
+#define M68HC12_BANK_VIRT 0x01000000
+#define M68HC12_BANK_MASK 0x00003fff
+#define M68HC12_BANK_BASE 0x00008000
+#define M68HC12_BANK_SHIFT 14
+#define M68HC12_BANK_PAGE_MASK 0x0ff
+
 
 /* CPU identification.  */
 #define cpu6811 0x01
Index: opcodes/m68hc11-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/m68hc11-dis.c,v
retrieving revision 1.4
diff -u -p -r1.4 m68hc11-dis.c
--- opcodes/m68hc11-dis.c	1 Nov 2001 09:48:57 -0000	1.4
+++ opcodes/m68hc11-dis.c	13 Aug 2002 18:15:31 -0000
@@ -1,6 +1,6 @@
 /* m68hc11-dis.c -- Motorola 68HC11 & 68HC12 disassembly
-   Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
-   Written by Stephane Carrez (stcarrez@worldnet.fr)
+   Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   Written by Stephane Carrez (stcarrez@nerim.fr)
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -40,7 +40,7 @@ static const char *const reg_dst_table[]
 static int read_memory
   PARAMS ((bfd_vma, bfd_byte *, int, struct disassemble_info *));
 static int print_indexed_operand
-  PARAMS ((bfd_vma, struct disassemble_info *, int));
+  PARAMS ((bfd_vma, struct disassemble_info *, int*, int));
 static int print_insn
   PARAMS ((bfd_vma, struct disassemble_info *, int));
 
@@ -68,9 +68,10 @@ read_memory (memaddr, buffer, size, info
 /* Read the 68HC12 indexed operand byte and print the corresponding mode.
    Returns the number of bytes read or -1 if failure.  */
 static int
-print_indexed_operand (memaddr, info, mov_insn)
+print_indexed_operand (memaddr, info, indirect, mov_insn)
      bfd_vma memaddr;
      struct disassemble_info *info;
+     int *indirect;
      int mov_insn;
 {
   bfd_byte buffer[4];
@@ -79,6 +80,9 @@ print_indexed_operand (memaddr, info, mo
   short sval;
   int pos = 1;
 
+  if (indirect)
+    *indirect = 0;
+
   status = read_memory (memaddr, &buffer[0], 1, info);
   if (status != 0)
     {
@@ -140,6 +144,8 @@ print_indexed_operand (memaddr, info, mo
       sval = ((buffer[0] << 8) | (buffer[1] & 0x0FF));
       (*info->fprintf_func) (info->stream, "[%u,%s]",
 			     sval & 0x0ffff, reg_name[reg]);
+      if (indirect)
+        *indirect = 1;
     }
   else if ((buffer[0] & 0x4) == 0)
     {
@@ -189,6 +195,8 @@ print_indexed_operand (memaddr, info, mo
 	case 3:
 	default:
 	  (*info->fprintf_func) (info->stream, "[D,%s]", reg_name[reg]);
+          if (indirect)
+            *indirect = 1;
 	  break;
 	}
     }
@@ -440,12 +448,19 @@ print_insn (memaddr, info, arch)
       /* Analyze the 68HC12 indexed byte.  */
       if (format & M6812_INDEXED_FLAGS)
 	{
-	  status = print_indexed_operand (memaddr + pos, info, 0);
+          int indirect;
+
+	  status = print_indexed_operand (memaddr + pos, info, &indirect, 0);
 	  if (status < 0)
 	    {
 	      return status;
 	    }
 	  pos += status;
+
+          /* The indirect addressing mode of the call instruction does
+             not need the page code.  */
+          if ((format & M6812_OP_PAGE) && indirect)
+            format &= ~M6812_OP_PAGE;
 	}
 
       /* 68HC12 dbcc/ibcc/tbcc operands.  */
@@ -532,6 +547,8 @@ print_insn (memaddr, info, arch)
       if (format & (M6811_OP_IMM16 | M6811_OP_IND16))
 	{
 	  int val;
+          bfd_vma addr;
+          unsigned page = 0;
 
 	  status = read_memory (memaddr + pos + offset, &buffer[0], 2, info);
 	  if (status != 0)
@@ -546,6 +563,38 @@ print_insn (memaddr, info, arch)
 
 	  val = ((buffer[0] << 8) | (buffer[1] & 0x0FF));
 	  val &= 0x0FFFF;
+          addr = val;
+          if (format & M6812_OP_PAGE)
+            {
+              status = read_memory (memaddr + pos + offset, buffer, 1, info);
+              if (status != 0)
+                return status;
+
+              page = (unsigned) buffer[0];
+              if (addr >= M68HC12_BANK_BASE && addr < 0x0c000)
+                addr = ((val - M68HC12_BANK_BASE)
+                        | (page << M68HC12_BANK_SHIFT))
+                   + M68HC12_BANK_VIRT;
+            }
+          else if ((arch & cpu6812)
+                   && addr >= M68HC12_BANK_BASE && addr < 0x0c000)
+             {
+                int cur_page;
+                bfd_vma vaddr;
+                
+                if (memaddr >= M68HC12_BANK_VIRT)
+                   cur_page = ((memaddr - M68HC12_BANK_VIRT)
+                               >> M68HC12_BANK_SHIFT);
+                else
+                   cur_page = 0;
+
+                vaddr = ((addr - M68HC12_BANK_BASE)
+                         + (cur_page << M68HC12_BANK_SHIFT))
+                   + M68HC12_BANK_VIRT;
+                if (!info->symbol_at_address_func (addr, info)
+                    && info->symbol_at_address_func (vaddr, info))
+                   addr = vaddr;
+             }
 	  if (format & M6811_OP_IMM16)
 	    {
 	      format &= ~M6811_OP_IMM16;
@@ -554,13 +603,21 @@ print_insn (memaddr, info, arch)
 	  else
 	    format &= ~M6811_OP_IND16;
 
-	  (*info->print_address_func) (val, info);
+	  (*info->print_address_func) (addr, info);
+          if (format & M6812_OP_PAGE)
+            {
+              (* info->fprintf_func) (info->stream, " {");
+              (* info->print_address_func) (val, info);
+              (* info->fprintf_func) (info->stream, ", %d}", page);
+              format &= ~M6812_OP_PAGE;
+              pos += 1;
+            }
 	}
 
       if (format & M6812_OP_IDX_P2)
 	{
 	  (*info->fprintf_func) (info->stream, ", ");
-	  status = print_indexed_operand (memaddr + pos + offset, info, 1);
+	  status = print_indexed_operand (memaddr + pos + offset, info, 0, 1);
 	  if (status < 0)
 	    return status;
 	  pos += status;
@@ -584,6 +641,21 @@ print_insn (memaddr, info, arch)
 	  (*info->print_address_func) (val, info);
 	}
 
+      if (format & M6812_OP_PAGE)
+	{
+	  int val;
+
+	  status = read_memory (memaddr + pos + offset, &buffer[0], 1, info);
+	  if (status != 0)
+	    {
+	      return status;
+	    }
+	  pos += 1;
+
+	  val = buffer[0] & 0x0ff;
+	  (*info->fprintf_func) (info->stream, ", %d", val);
+	}
+      
 #ifdef DEBUG
       /* Consistency check.  'format' must be 0, so that we have handled
          all formats; and the computed size of the insn must match the

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