* i386b-nat.c: Comment changes.
[deliverable/binutils-gdb.git] / gdb / ns32k-pinsn.c
index 3247edb6f5a60a3e1423f18b7825310e8e17dd38..820517368b693be40f19ac0b1030e9992e789008 100644 (file)
@@ -1,29 +1,26 @@
-/* Print 32000 instructions for GDB, the GNU debugger.
-   Copyright (C) 1986,1988 Free Software Foundation, Inc.
+/* Print National Semiconductor 32000 instructions for GDB, the GNU debugger.
+   Copyright 1986, 1988, 1991, 1992 Free Software Foundation, Inc.
 
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY.  No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
+This file is part of GDB.
 
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License.  A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities.  It
-should be in a file named COPYING.  Among other things, the copyright
-notice and this notice must be preserved on all copies.
+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
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
 
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther.  Help stamp out software hoarding!
-*/
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
 
-#include <stdio.h>
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "defs.h"
-#include "param.h"
 #include "symtab.h"
-#include "opcode.h"
+#include "ns32k-opcode.h"
+#include "gdbcore.h"
 
 /* 32000 instructions are never longer than this.  */
 #define MAXLEN 62
@@ -31,8 +28,6 @@ anyone else from sharing it farther.  Help stamp out software hoarding!
 /* Number of elements in the opcode table.  */
 #define NOPCODES (sizeof notstrs / sizeof notstrs[0])
 
-extern char *reg_names[];
-
 #define NEXT_IS_ADDR   '|'
 
 /*
@@ -116,6 +111,24 @@ flip_bytes (ptr, count)
       count -= 2;
     }
 }
+\f
+/* Given a character C, does it represent a general addressing mode?  */
+#define Is_gen(c) \
+  ((c) == 'F' || (c) == 'L' || (c) == 'B' \
+   || (c) == 'W' || (c) == 'D' || (c) == 'A')
+
+/* Adressing modes.  */
+#define Adrmod_index_byte 0x1c
+#define Adrmod_index_word 0x1d
+#define Adrmod_index_doubleword 0x1e
+#define Adrmod_index_quadword 0x1f
+
+/* Is MODE an indexed addressing mode?  */
+#define Adrmod_is_index(mode) \
+  (mode == Adrmod_index_byte \
+   || mode == Adrmod_index_word \
+   || mode == Adrmod_index_doubleword \
+   || mode == Adrmod_index_quadword)
 
 \f
 /* Print the 32000 instruction at address MEMADDR in debugged memory,
@@ -123,8 +136,8 @@ flip_bytes (ptr, count)
 
 int
 print_insn (memaddr, stream)
-CORE_ADDR memaddr;
-FILE *stream;
+     CORE_ADDR memaddr;
+     FILE *stream;
 {
   unsigned char buffer[MAXLEN];
   register int i;
@@ -161,9 +174,44 @@ FILE *stream;
 
   if (*d)
     {
+      /* Offset in bits of the first thing beyond each index byte.
+        Element 0 is for operand A and element 1 is for operand B.
+        The rest are irrelevant, but we put them here so we don't
+        index outside the array.  */
+      int index_offset[MAX_ARGS];
+
+      /* 0 for operand A, 1 for operand B, greater for other args.  */
+      int whicharg = 0;
+      
       fputc ('\t', stream);
 
       maxarg = 0;
+
+      /* First we have to find and keep track of the index bytes,
+        if we are using scaled indexed addressing mode, since the index
+        bytes occur right after the basic instruction, not as part
+        of the addressing extension.  */
+      if (Is_gen(d[1]))
+       {
+         int addr_mode = bit_extract (buffer, ioffset - 5, 5);
+
+         if (Adrmod_is_index (addr_mode))
+           {
+             aoffset += 8;
+             index_offset[0] = aoffset;
+           }
+       }
+      if (d[2] && Is_gen(d[3]))
+       {
+         int addr_mode = bit_extract (buffer, ioffset - 10, 5);
+
+         if (Adrmod_is_index (addr_mode))
+           {
+             aoffset += 8;
+             index_offset[1] = aoffset;
+           }
+       }
+
       while (*d)
        {
          argnum = *d - '1';
@@ -171,8 +219,10 @@ FILE *stream;
          if (argnum > maxarg && argnum < MAX_ARGS)
            maxarg = argnum;
          ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
-                                   memaddr, arg_bufs[argnum]);
+                                   memaddr, arg_bufs[argnum],
+                                   index_offset[whicharg]);
          d++;
+         whicharg++;
        }
       for (argnum = 0; argnum <= maxarg; argnum++)
        {
@@ -200,12 +250,23 @@ FILE *stream;
   return aoffset / 8;
 }
 
-print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result)
+/* Print an instruction operand of category given by d.  IOFFSET is
+   the bit position below which small (<1 byte) parts of the operand can
+   be found (usually in the basic instruction, but for indexed
+   addressing it can be in the index byte).  AOFFSETP is a pointer to the
+   bit position of the addressing extension.  BUFFER contains the
+   instruction.  ADDR is where BUFFER was read from.  Put the disassembled
+   version of the operand in RESULT.  INDEX_OFFSET is the bit position
+   of the index byte (it contains garbage if this operand is not a
+   general operand using scaled indexed addressing mode).  */
+
+print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset)
      char d;
      int ioffset, *aoffsetp;
      char *buffer;
      CORE_ADDR addr;
      char *result;
+     int index_offset;
 {
   int addr_mode;
   float Fvalue;
@@ -328,16 +389,15 @@ print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result)
        case 0x1d:
        case 0x1e:
        case 0x1f:
-         index = bit_extract (buffer, *aoffsetp, 8);
-         *aoffsetp += 8;
-         print_insn_arg (d, *aoffsetp, aoffsetp, buffer, addr,
-                         result);
+         index = bit_extract (buffer, index_offset - 8, 3);
+         print_insn_arg (d, index_offset, aoffsetp, buffer, addr,
+                         result, 0);
          {
            static char *ind[] = {"b", "w", "d", "q"};
            char *off;
 
            off = result + strlen (result);
-           sprintf (off, "[r%d:%s]", index & 7,
+           sprintf (off, "[r%d:%s]", index,
                     ind[addr_mode & 3]);
          }
          break;
This page took 0.02631 seconds and 4 git commands to generate.