New print_address for disassemblers, merge a29k and i960 disassemblers
authorJim Kingdon <jkingdon@engr.sgi.com>
Fri, 2 Apr 1993 00:18:47 +0000 (00:18 +0000)
committerJim Kingdon <jkingdon@engr.sgi.com>
Fri, 2 Apr 1993 00:18:47 +0000 (00:18 +0000)
binutils/.Sanitize
binutils/am29k-pinsn.c [deleted file]
binutils/i960-pinsn.c [deleted file]
gdb/ChangeLog
gdb/a29k-pinsn.c
gdb/core.c
gdb/i960-pinsn.c
opcodes/.Sanitize
opcodes/ChangeLog
opcodes/a29k-dis.c [new file with mode: 0644]

index 83d45edef7278053e57f5703d525b8de70ffb95f..abf48f52654a098381001147549e6c9d825fc5d7 100644 (file)
@@ -31,7 +31,6 @@ NEWS
 README
 TODO
 alloca.c
-am29k-pinsn.c
 ar.1
 ar.c
 arlex.l
@@ -47,7 +46,6 @@ config
 copy.c
 filemode.c
 gmalloc.c
-i960-pinsn.c
 is-ranlib.c
 is-strip.c
 maybe-ranlib.c
diff --git a/binutils/am29k-pinsn.c b/binutils/am29k-pinsn.c
deleted file mode 100644 (file)
index 699a6ad..0000000
+++ /dev/null
@@ -1,350 +0,0 @@
-/* Instruction printing code for the AMD 29000
-   Copyright (C) 1990 Free Software Foundation, Inc.
-   Contributed by Cygnus Support.  Written by Jim Kingdon.
-
-This file is part of GDB.
-
-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 1, or (at your option)
-any later version.
-
-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.
-
-You should have received a copy of the GNU General Public License
-along with this program; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
-#include <stdio.h>
-
-#ifdef GDB
-# include "defs.h"
-# include "target.h"
-# include "opcode/a29k.h"
-#else
-# include "bfd.h"
-# include "sysdep.h"
-# include "objdump.h"
-# include "opcode/a29k.h"
-# define am29k_opcodes a29k_opcodes
-# define am29k_opcode a29k_opcode
-# define NUM_OPCODES num_opcodes
-# define fprintf_filtered fprintf
-#endif
-
-
-/* Print a symbolic representation of a general-purpose
-   register number NUM on STREAM.
-   NUM is a number as found in the instruction, not as found in
-   debugging symbols; it must be in the range 0-255.  */
-static void
-print_general (num, stream)
-     int num;
-     FILE *stream;
-{
-  if (num < 128)
-    fprintf_filtered (stream, "gr%d", num);
-  else
-    fprintf_filtered (stream, "lr%d", num - 128);
-}
-
-/* Like print_general but a special-purpose register.
-   
-   The mnemonics used by the AMD assembler are not quite the same
-   as the ones in the User's Manual.  We use the ones that the
-   assembler uses.  */
-static void
-print_special (num, stream)
-     int num;
-     FILE *stream;
-{
-  /* Register names of registers 0-SPEC0_NUM-1.  */
-  static char *spec0_names[] = {
-    "vab", "ops", "cps", "cfg", "cha", "chd", "chc", "rbp", "tmc", "tmr",
-    "pc0", "pc1", "pc2", "mmu", "lru"
-    };
-#define SPEC0_NUM ((sizeof spec0_names) / (sizeof spec0_names[0]))
-
-  /* Register names of registers 128-128+SPEC128_NUM-1.  */
-  static char *spec128_names[] = {
-    "ipc", "ipa", "ipb", "q", "alu", "bp", "fc", "cr"
-    };
-#define SPEC128_NUM ((sizeof spec128_names) / (sizeof spec128_names[0]))
-
-  /* Register names of registers 160-160+SPEC160_NUM-1.  */
-  static char *spec160_names[] = {
-    "fpe", "inte", "fps", "sr163", "exop"
-    };
-#define SPEC160_NUM ((sizeof spec160_names) / (sizeof spec160_names[0]))
-
-  if (num < SPEC0_NUM)
-    fprintf_filtered (stream, spec0_names[num]);
-  else if (num >= 128 && num < 128 + SPEC128_NUM)
-    fprintf_filtered (stream, spec128_names[num-128]);
-  else if (num >= 160 && num < 160 + SPEC160_NUM)
-    fprintf_filtered (stream, spec160_names[num-160]);
-  else
-    fprintf_filtered (stream, "sr%d", num);
-}
-
-/* Is an instruction with OPCODE a delayed branch?  */
-static int
-is_delayed_branch (opcode)
-     int opcode;
-{
-  return (opcode == 0xa8 || opcode == 0xa9 || opcode == 0xa0 || opcode == 0xa1
-         || opcode == 0xa4 || opcode == 0xa5
-         || opcode == 0xb4 || opcode == 0xb5
-         || opcode == 0xc4 || opcode == 0xc0
-         || opcode == 0xac || opcode == 0xad
-         || opcode == 0xcc);
-}
-
-/* Now find the four bytes of INSN and put them in *INSN{0,8,16,24}.
-   Note that the amd can be set up as either
-   big or little-endian (the tm file says which) and we can't assume
-   the host machine is the same.  */
-static void
-find_bytes (insn, insn0, insn8, insn16, insn24)
-     char *insn;
-     unsigned char *insn0;
-     unsigned char *insn8;
-     unsigned char *insn16;
-     unsigned char *insn24;
-{
-#if TARGET_BYTE_ORDER == BIG_ENDIAN
-  *insn24 = insn[0];
-  *insn16 = insn[1];
-  *insn8  = insn[2];
-  *insn0  = insn[3];
-#else /* Little-endian.  */
-  *insn24 = insn[3];
-  *insn16 = insn[2];
-  *insn8 = insn[1];
-  *insn0 = insn[0];
-#endif /* Little-endian.  */
-}
-
-/* Print one instruction from MEMADDR on STREAM.
-   Return the size of the instruction (always 4 on am29k).  */
-#ifdef GDB
-print_insn (memaddr, stream)
-     CORE_ADDR memaddr;
-     FILE *stream;
-#else
-int
-print_insn_a29k (memaddr, buffer, stream)
-     bfd_vma memaddr;
-     uint8e_type *buffer;
-     FILE *stream;
-#endif
-{
-  /* The raw instruction.  */
-  char insn[4];
-
-  /* The four bytes of the instruction.  */
-  unsigned char insn24, insn16, insn8, insn0;
-       unsigned long value;
-  CONST struct am29k_opcode *opcode;
-
-#ifdef GDB
-  read_memory (memaddr, &insn[0], 4);
-#else
-  insn[0] = ((char*)buffer)[0];
-  insn[1] = ((char*)buffer)[1];
-  insn[2] = ((char*)buffer)[2];
-  insn[3] = ((char*)buffer)[3];
-#endif
-
-  find_bytes (insn, &insn0, &insn8, &insn16, &insn24);
-
-  value = (insn24 << 24) + (insn16 << 16) + (insn8 << 8) + insn0;
-  /* Handle the nop (aseq 0x40,gr1,gr1) specially */
-  if ((insn24==0x70) && (insn16==0x40) && (insn8==0x01) && (insn0==0x01)) {
-    fprintf_filtered (stream,"nop");
-    return 4;
-  }
-
-
-  /* The opcode is always in insn24.  */
-  for (opcode = &am29k_opcodes[0];
-       opcode < &am29k_opcodes[NUM_OPCODES];
-       ++opcode)
-    {
-#ifdef GDB
-      if (insn24 == opcode->opcode)
-#else
-      if (insn24 == (opcode->opcode >> 24))
-#endif
-       {
-         char *s;
-         
-         fprintf_filtered (stream, "%s ", opcode->name);
-         for (s = opcode->args; *s != '\0'; ++s)
-           {
-             switch (*s)
-               {
-               case 'a':
-                 print_general (insn8, stream);
-                 break;
-                 
-               case 'b':
-                 print_general (insn0, stream);
-                 break;
-
-               case 'c':
-                 print_general (insn16, stream);
-                 break;
-
-               case 'i':
-                 fprintf_filtered (stream, "%d", insn0);
-                 break;
-
-               case 'x':
-                 fprintf_filtered (stream, "%d", (insn16 << 8) + insn0);
-                 break;
-
-               case 'h':
-                 fprintf_filtered (stream, "0x%x",
-                                   (insn16 << 24) + (insn0 << 16));
-                 break;
-
-               case 'X':
-                 fprintf_filtered (stream, "%d",
-                                   ((insn16 << 8) + insn0) | 0xffff0000);
-                 break;
-
-               case 'P':
-                 /* This output looks just like absolute addressing, but
-                    maybe that's OK (it's what the GDB 68k and EBMON
-                    29k disassemblers do).  */
-                 /* All the shifting is to sign-extend it.  p*/
-                 print_address
-                   (memaddr +
-                    (((int)((insn16 << 10) + (insn0 << 2)) << 14) >> 14),
-                    stream);
-                 break;
-
-               case 'A':
-                 print_address ((insn16 << 10) + (insn0 << 2), stream);
-                 break;
-
-               case 'e':
-                 fprintf_filtered (stream, "%d", insn16 >> 7);
-                 break;
-
-               case 'n':
-                 fprintf_filtered (stream, "0x%x", insn16 & 0x7f);
-                 break;
-
-               case 'v':
-                 fprintf_filtered (stream, "%x", insn16);
-                 break;
-
-               case 's':
-                 print_special (insn8, stream);
-                 break;
-
-               case 'u':
-                 fprintf_filtered (stream, "%d", insn0 >> 7);
-                 break;
-
-               case 'r':
-                 fprintf_filtered (stream, "%d", (insn0 >> 4) & 7);
-                 break;
-
-               case 'd':
-                 fprintf_filtered (stream, "%d", (insn0 >> 2) & 3);
-                 break;
-
-               case 'f':
-                 fprintf_filtered (stream, "%d", insn0 & 3);
-                 break;
-
-               case 'F':
-                 fprintf_filtered (stream, "%d", (value >> 18) & 0xf);
-                 break;
-
-               case 'C':
-                 fprintf_filtered (stream, "%d", (value >> 16)  & 3);
-                 break;
-
-               default:
-                 fprintf_filtered (stream, "%c", *s);
-               }
-           }
-
-         /* Now we look for a const,consth pair of instructions,
-            in which case we try to print the symbolic address.  */
-         if (insn24 == 2)  /* consth */
-           {
-             int errcode;
-             char prev_insn[4];
-             unsigned char prev_insn0, prev_insn8, prev_insn16, prev_insn24;
-             
-#ifdef GDB
-             errcode = target_read_memory (memaddr - 4,
-                                           &prev_insn[0],
-                                           4);
-#else
-               prev_insn[0] = ((char*)buffer)[0-4];
-               prev_insn[1] = ((char*)buffer)[1-4];
-               prev_insn[2] = ((char*)buffer)[2-4];
-               prev_insn[3] = ((char*)buffer)[3-4];
-               errcode = 0;
-#endif
-             if (errcode == 0)
-               {
-                 /* If it is a delayed branch, we need to look at the
-                    instruction before the delayed brach to handle
-                    things like
-                    
-                    const _foo
-                    call _printf
-                    consth _foo
-                    */
-                 find_bytes (prev_insn, &prev_insn0, &prev_insn8,
-                             &prev_insn16, &prev_insn24);
-                 if (is_delayed_branch (prev_insn24))
-                   {
-#ifdef GDB
-                     errcode = target_read_memory
-                       (memaddr - 8, &prev_insn[0], 4);
-#else
-                       prev_insn[0] = ((char*)buffer)[0-8];
-                       prev_insn[1] = ((char*)buffer)[1-8];
-                       prev_insn[2] = ((char*)buffer)[2-8];
-                       prev_insn[3] = ((char*)buffer)[3-8];
-                       errcode = 0;
-#endif
-                     find_bytes (prev_insn, &prev_insn0, &prev_insn8,
-                                 &prev_insn16, &prev_insn24);
-                   }
-               }
-                 
-             /* If there was a problem reading memory, then assume
-                the previous instruction was not const.  */
-             if (errcode == 0)
-               {
-                 /* Is it const to the same register?  */
-                 if (prev_insn24 == 3
-                     && prev_insn8 == insn8)
-                   {
-                     fprintf_filtered (stream, "\t; ");
-                     print_address (((insn16 << 24) + (insn0 << 16)
-                                     + (prev_insn16 << 8) + (prev_insn0)),
-                                    stream);
-                   }
-               }
-           }
-
-         return 4;
-       }
-    }
-  fprintf_filtered (stream, ".word %8x",
-                   (insn24 << 24) + (insn16 << 16) + (insn8 << 8) + insn0);
-  return 4;
-}
diff --git a/binutils/i960-pinsn.c b/binutils/i960-pinsn.c
deleted file mode 100644 (file)
index a346064..0000000
+++ /dev/null
@@ -1,814 +0,0 @@
-/* Disassemble i80960 instructions.
-   Copyright (C) 1990, 1991 Free Software Foundation, Inc.
-
-This file is part of BFD, the Binary File Diddler.
-
-BFD 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, or (at your option)
-any later version.
-
-BFD 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.
-
-You should have received a copy of the GNU General Public License
-along with BFD; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
-#include "bfd.h"
-#include "sysdep.h"
-#include "bucomm.h"
-
-static char *reg_names[] = {
-/*  0 */       "pfp", "sp",  "rip", "r3",  "r4",  "r5",  "r6",  "r7", 
-/*  8 */       "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",
-/* 16 */       "g0",  "g1",  "g2",  "g3",  "g4",  "g5",  "g6",  "g7", 
-/* 24 */       "g8",  "g9",  "g10", "g11", "g12", "g13", "g14", "fp", 
-/* 32 */       "pc",  "ac",  "ip",  "tc",  "fp0", "fp1", "fp2", "fp3" 
-};
-
-
-static FILE *stream;           /* Output goes here */
-static void print_addr();
-static void ctrl();
-static void cobr();
-static void reg();
-static int mem();
-static void ea();
-static void dstop();
-static void regop();
-static void invalid();
-static int pinsn();
-static void put_abs();
-
-
-/* Print the i960 instruction at address 'memaddr' in debugged memory,
- * on stream 's'.  Returns length of the instruction, in bytes.
- */
-int
-print_insn_i960( memaddr, buffer, s )
-    bfd_vma memaddr;
-    uint8e_type *buffer;
-    FILE *s;
-{
-    unsigned int word1, word2;
-
-    stream = s;
-    word1 =buffer [0] |( buffer[1]<< 8) | (buffer[2] << 16) | ( buffer[3] <<24);
-    word2 =buffer [4] |( buffer[5]<< 8) | (buffer[6] << 16) | ( buffer[7] <<24);
-    return pinsn( memaddr, word1, word2 );
-}
-\f
-#define IN_GDB
-
-/*****************************************************************************
- *     All code below this point should be identical with that of
- *     the disassembler in gdmp960.
- *****************************************************************************/
-
-struct tabent {
-       char    *name;
-       char    numops;
-};
-
-static int
-pinsn( memaddr, word1, word2 )
-    unsigned long memaddr;
-    unsigned long word1, word2;
-{
-       int instr_len;
-
-       instr_len = 4;
-       put_abs( word1, word2 );
-
-       /* Divide instruction set into classes based on high 4 bits of opcode*/
-       switch ( (word1 >> 28) & 0xf ){
-       case 0x0:
-       case 0x1:
-               ctrl( memaddr, word1, word2 );
-               break;
-       case 0x2:
-       case 0x3:
-               cobr( memaddr, word1, word2 );
-               break;
-       case 0x5:
-       case 0x6:
-       case 0x7:
-               reg( word1 );
-               break;
-       case 0x8:
-       case 0x9:
-       case 0xa:
-       case 0xb:
-       case 0xc:
-               instr_len = mem( memaddr, word1, word2, 0 );
-               break;
-       default:
-               /* invalid instruction, print as data word */ 
-               invalid( word1 );
-               break;
-       }
-       return instr_len;
-}
-
-/****************************************/
-/* CTRL format                         */
-/****************************************/
-static void
-ctrl( memaddr, word1, word2 )
-    unsigned long memaddr;
-    unsigned long word1, word2;
-{
-       int i;
-       static struct tabent ctrl_tab[] = {
-               NULL,           0,      /* 0x00 */
-               NULL,           0,      /* 0x01 */
-               NULL,           0,      /* 0x02 */
-               NULL,           0,      /* 0x03 */
-               NULL,           0,      /* 0x04 */
-               NULL,           0,      /* 0x05 */
-               NULL,           0,      /* 0x06 */
-               NULL,           0,      /* 0x07 */
-               "b",            1,      /* 0x08 */
-               "call",         1,      /* 0x09 */
-               "ret",          0,      /* 0x0a */
-               "bal",          1,      /* 0x0b */
-               NULL,           0,      /* 0x0c */
-               NULL,           0,      /* 0x0d */
-               NULL,           0,      /* 0x0e */
-               NULL,           0,      /* 0x0f */
-               "bno",          1,      /* 0x10 */
-               "bg",           1,      /* 0x11 */
-               "be",           1,      /* 0x12 */
-               "bge",          1,      /* 0x13 */
-               "bl",           1,      /* 0x14 */
-               "bne",          1,      /* 0x15 */
-               "ble",          1,      /* 0x16 */
-               "bo",           1,      /* 0x17 */
-               "faultno",      0,      /* 0x18 */
-               "faultg",       0,      /* 0x19 */
-               "faulte",       0,      /* 0x1a */
-               "faultge",      0,      /* 0x1b */
-               "faultl",       0,      /* 0x1c */
-               "faultne",      0,      /* 0x1d */
-               "faultle",      0,      /* 0x1e */
-               "faulto",       0,      /* 0x1f */
-       };
-
-       i = (word1 >> 24) & 0xff;
-       if ( (ctrl_tab[i].name == NULL) || ((word1 & 1) != 0) ){
-               invalid( word1 );
-               return;
-       }
-
-       fputs( ctrl_tab[i].name, stream );
-       if ( word1 & 2 ){               /* Predicts branch not taken */
-               fputs( ".f", stream );
-       }
-
-       if ( ctrl_tab[i].numops == 1 ){
-               /* EXTRACT DISPLACEMENT AND CONVERT TO ADDRESS */
-               word1 &= 0x00ffffff;
-               if ( word1 & 0x00800000 ){              /* Sign bit is set */
-                       word1 |= (-1 & ~0xffffff);      /* Sign extend */
-               }
-               putc( '\t', stream );
-               print_addr( word1 + memaddr );
-       }
-}
-
-/****************************************/
-/* COBR format                         */
-/****************************************/
-static void
-cobr( memaddr, word1, word2 )
-    unsigned long memaddr;
-    unsigned long word1, word2;
-{
-       int src1;
-       int src2;
-       int i;
-
-       static struct tabent cobr_tab[] = {
-               "testno",       1,      /* 0x20 */
-               "testg",        1,      /* 0x21 */
-               "teste",        1,      /* 0x22 */
-               "testge",       1,      /* 0x23 */
-               "testl",        1,      /* 0x24 */
-               "testne",       1,      /* 0x25 */
-               "testle",       1,      /* 0x26 */
-               "testo",        1,      /* 0x27 */
-               NULL,           0,      /* 0x28 */
-               NULL,           0,      /* 0x29 */
-               NULL,           0,      /* 0x2a */
-               NULL,           0,      /* 0x2b */
-               NULL,           0,      /* 0x2c */
-               NULL,           0,      /* 0x2d */
-               NULL,           0,      /* 0x2e */
-               NULL,           0,      /* 0x2f */
-               "bbc",          3,      /* 0x30 */
-               "cmpobg",       3,      /* 0x31 */
-               "cmpobe",       3,      /* 0x32 */
-               "cmpobge",      3,      /* 0x33 */
-               "cmpobl",       3,      /* 0x34 */
-               "cmpobne",      3,      /* 0x35 */
-               "cmpoble",      3,      /* 0x36 */
-               "bbs",          3,      /* 0x37 */
-               "cmpibno",      3,      /* 0x38 */
-               "cmpibg",       3,      /* 0x39 */
-               "cmpibe",       3,      /* 0x3a */
-               "cmpibge",      3,      /* 0x3b */
-               "cmpibl",       3,      /* 0x3c */
-               "cmpibne",      3,      /* 0x3d */
-               "cmpible",      3,      /* 0x3e */
-               "cmpibo",       3,      /* 0x3f */
-       };
-
-       i = ((word1 >> 24) & 0xff) - 0x20;
-       if ( cobr_tab[i].name == NULL ){
-               invalid( word1 );
-               return;
-       }
-
-       fputs( cobr_tab[i].name, stream );
-       if ( word1 & 2 ){               /* Predicts branch not taken */
-               fputs( ".f", stream );
-       }
-       putc( '\t', stream );
-
-       src1 = (word1 >> 19) & 0x1f;
-       src2 = (word1 >> 14) & 0x1f;
-
-       if ( word1 & 0x02000 ){         /* M1 is 1 */
-               fprintf( stream, "%d", src1 );
-       } else {                        /* M1 is 0 */
-               fputs( reg_names[src1], stream );
-       }
-
-       if ( cobr_tab[i].numops > 1 ){
-               if ( word1 & 1 ){               /* S2 is 1 */
-                       fprintf( stream, ",sf%d,", src2 );
-               } else {                        /* S1 is 0 */
-                       fprintf( stream, ",%s,", reg_names[src2] );
-               }
-
-               /* Extract displacement and convert to address
-                */
-               word1 &= 0x00001ffc;
-               if ( word1 & 0x00001000 ){      /* Negative displacement */
-                       word1 |= (-1 & ~0x1fff);        /* Sign extend */
-               }
-               print_addr( memaddr + word1 );
-       }
-}
-
-/****************************************/
-/* MEM format                          */
-/****************************************/
-static int                             /* returns instruction length: 4 or 8 */
-mem( memaddr, word1, word2, noprint )
-    unsigned long memaddr;
-    unsigned long word1, word2;
-    int noprint;               /* If TRUE, return instruction length, but
-                                * don't output any text.
-                                */
-{
-       int i, j;
-       int len;
-       int mode;
-       int offset;
-       char *reg1, *reg2, *reg3;
-
-       /* This lookup table is too sparse to make it worth typing in, but not
-        * so large as to make a sparse array necessary.  We allocate the
-        * table at runtime, initialize all entries to empty, and copy the
-        * real ones in from an initialization table.
-        *
-        * NOTE: In this table, the meaning of 'numops' is:
-        *       1: single operand
-        *       2: 2 operands, load instruction
-        *      -2: 2 operands, store instruction
-        */
-       static struct tabent *mem_tab = NULL;
-/* Opcodes of 0x8X, 9X, aX, bX, and cX must be in the table.  */
-#define MEM_MIN        0x80
-#define MEM_MAX        0xcf
-#define MEM_SIZ        ((MEM_MAX-MEM_MIN+1) * sizeof(struct tabent))
-
-       static struct { int opcode; char *name; char numops; } mem_init[] = {
-               0x80,   "ldob",  2,
-               0x82,   "stob", -2,
-               0x84,   "bx",    1,
-               0x85,   "balx",  2,
-               0x86,   "callx", 1,
-               0x88,   "ldos",  2,
-               0x8a,   "stos", -2,
-               0x8c,   "lda",   2,
-               0x90,   "ld",    2,
-               0x92,   "st",   -2,
-               0x98,   "ldl",   2,
-               0x9a,   "stl",  -2,
-               0xa0,   "ldt",   2,
-               0xa2,   "stt",  -2,
-               0xb0,   "ldq",   2,
-               0xb2,   "stq",  -2,
-               0xc0,   "ldib",  2,
-               0xc2,   "stib", -2,
-               0xc8,   "ldis",  2,
-               0xca,   "stis", -2,
-               0,      NULL,   0
-       };
-
-       if ( mem_tab == NULL ){
-               mem_tab = (struct tabent *) xmalloc( MEM_SIZ );
-               memset( (void *) mem_tab, 0, MEM_SIZ );
-               for ( i = 0; mem_init[i].opcode != 0; i++ ){
-                       j = mem_init[i].opcode - MEM_MIN;
-                       mem_tab[j].name = mem_init[i].name;
-                       mem_tab[j].numops = mem_init[i].numops;
-               }
-       }
-
-       i = ((word1 >> 24) & 0xff) - MEM_MIN;
-       mode = (word1 >> 10) & 0xf;
-
-       if ( (mem_tab[i].name != NULL)          /* Valid instruction */
-       &&   ((mode == 5) || (mode >=12)) ){    /* With 32-bit displacement */
-               len = 8;
-       } else {
-               len = 4;
-       }
-
-       if ( noprint ){
-               return len;
-       }
-
-       if ( (mem_tab[i].name == NULL) || (mode == 6) ){
-               invalid( word1 );
-               return len;
-       }
-
-       fprintf( stream, "%s\t", mem_tab[i].name );
-
-       reg1 = reg_names[ (word1 >> 19) & 0x1f ];       /* MEMB only */
-       reg2 = reg_names[ (word1 >> 14) & 0x1f ];
-       reg3 = reg_names[ word1 & 0x1f ];               /* MEMB only */
-       offset = word1 & 0xfff;                         /* MEMA only  */
-
-       switch ( mem_tab[i].numops ){
-
-       case 2: /* LOAD INSTRUCTION */
-               if ( mode & 4 ){                        /* MEMB FORMAT */
-                       ea( memaddr, mode, reg2, reg3, word1, word2 );
-                       fprintf( stream, ",%s", reg1 );
-               } else {                                /* MEMA FORMAT */
-                       fprintf( stream, "0x%x", (unsigned) offset );
-                       if (mode & 8) {
-                               fprintf( stream, "(%s)", reg2 );
-                       }
-                       fprintf( stream, ",%s", reg1 );
-               }
-               break;
-
-       case -2: /* STORE INSTRUCTION */
-               if ( mode & 4 ){                        /* MEMB FORMAT */
-                       fprintf( stream, "%s,", reg1 );
-                       ea( memaddr, mode, reg2, reg3, word1, word2 );
-               } else {                                /* MEMA FORMAT */
-                       fprintf( stream, "%s,0x%x", reg1, (unsigned) offset );
-                       if (mode & 8) {
-                               fprintf( stream, "(%s)", reg2 );
-                       }
-               }
-               break;
-
-       case 1: /* BX/CALLX INSTRUCTION */
-               if ( mode & 4 ){                        /* MEMB FORMAT */
-                       ea( memaddr, mode, reg2, reg3, word1, word2 );
-               } else {                                /* MEMA FORMAT */
-                       fprintf( stream, "0x%x", (unsigned) offset );
-                       if (mode & 8) {
-                               fprintf( stream, "(%s)", reg2 );
-                       }
-               }
-               break;
-       }
-
-       return len;
-}
-
-/****************************************/
-/* REG format                          */
-/****************************************/
-static void
-reg( word1 )
-    unsigned long word1;
-{
-       int i, j;
-       int opcode;
-       int fp;
-       int m1, m2, m3;
-       int s1, s2;
-       int src, src2, dst;
-       char *mnemp;
-
-       /* This lookup table is too sparse to make it worth typing in, but not
-        * so large as to make a sparse array necessary.  We allocate the
-        * table at runtime, initialize all entries to empty, and copy the
-        * real ones in from an initialization table.
-        *
-        * NOTE: In this table, the meaning of 'numops' is:
-        *       1: single operand, which is NOT a destination.
-        *      -1: single operand, which IS a destination.
-        *       2: 2 operands, the 2nd of which is NOT a destination.
-        *      -2: 2 operands, the 2nd of which IS a destination.
-        *       3: 3 operands
-        *
-        *      If an opcode mnemonic begins with "F", it is a floating-point
-        *      opcode (the "F" is not printed).
-        */
-
-       static struct tabent *reg_tab = NULL;
-       static struct { int opcode; char *name; char numops; } reg_init[] = {
-#define REG_MIN        0x580
-               0x580,  "notbit",       3,
-               0x581,  "and",          3,
-               0x582,  "andnot",       3,
-               0x583,  "setbit",       3,
-               0x584,  "notand",       3,
-               0x586,  "xor",          3,
-               0x587,  "or",           3,
-               0x588,  "nor",          3,
-               0x589,  "xnor",         3,
-               0x58a,  "not",          -2,
-               0x58b,  "ornot",        3,
-               0x58c,  "clrbit",       3,
-               0x58d,  "notor",        3,
-               0x58e,  "nand",         3,
-               0x58f,  "alterbit",     3,
-               0x590,  "addo",         3,
-               0x591,  "addi",         3,
-               0x592,  "subo",         3,
-               0x593,  "subi",         3,
-               0x598,  "shro",         3,
-               0x59a,  "shrdi",        3,
-               0x59b,  "shri",         3,
-               0x59c,  "shlo",         3,
-               0x59d,  "rotate",       3,
-               0x59e,  "shli",         3,
-               0x5a0,  "cmpo",         2,
-               0x5a1,  "cmpi",         2,
-               0x5a2,  "concmpo",      2,
-               0x5a3,  "concmpi",      2,
-               0x5a4,  "cmpinco",      3,
-               0x5a5,  "cmpinci",      3,
-               0x5a6,  "cmpdeco",      3,
-               0x5a7,  "cmpdeci",      3,
-               0x5ac,  "scanbyte",     2,
-               0x5ae,  "chkbit",       2,
-               0x5b0,  "addc",         3,
-               0x5b2,  "subc",         3,
-               0x5cc,  "mov",          -2,
-               0x5d8,  "eshro",        3,
-               0x5dc,  "movl",         -2,
-               0x5ec,  "movt",         -2,
-               0x5fc,  "movq",         -2,
-               0x600,  "synmov",       2,
-               0x601,  "synmovl",      2,
-               0x602,  "synmovq",      2,
-               0x603,  "cmpstr",       3,
-               0x604,  "movqstr",      3,
-               0x605,  "movstr",       3,
-               0x610,  "atmod",        3,
-               0x612,  "atadd",        3,
-               0x613,  "inspacc",      -2,
-               0x614,  "ldphy",        -2,
-               0x615,  "synld",        -2,
-               0x617,  "fill",         3,
-               0x630,  "sdma",         3,
-               0x631,  "udma",         0,
-               0x640,  "spanbit",      -2,
-               0x641,  "scanbit",      -2,
-               0x642,  "daddc",        3,
-               0x643,  "dsubc",        3,
-               0x644,  "dmovt",        -2,
-               0x645,  "modac",        3,
-               0x646,  "condrec",      -2,
-               0x650,  "modify",       3,
-               0x651,  "extract",      3,
-               0x654,  "modtc",        3,
-               0x655,  "modpc",        3,
-               0x656,  "receive",      -2,
-               0x659,  "sysctl",       3,
-               0x660,  "calls",        1,
-               0x662,  "send",         3,
-               0x663,  "sendserv",     1,
-               0x664,  "resumprcs",    1,
-               0x665,  "schedprcs",    1,
-               0x666,  "saveprcs",     0,
-               0x668,  "condwait",     1,
-               0x669,  "wait",         1,
-               0x66a,  "signal",       1,
-               0x66b,  "mark",         0,
-               0x66c,  "fmark",        0,
-               0x66d,  "flushreg",     0,
-               0x66f,  "syncf",        0,
-               0x670,  "emul",         3,
-               0x671,  "ediv",         3,
-               0x673,  "ldtime",       -1,
-               0x674,  "Fcvtir",       -2,
-               0x675,  "Fcvtilr",      -2,
-               0x676,  "Fscalerl",     3,
-               0x677,  "Fscaler",      3,
-               0x680,  "Fatanr",       3,
-               0x681,  "Flogepr",      3,
-               0x682,  "Flogr",        3,
-               0x683,  "Fremr",        3,
-               0x684,  "Fcmpor",       2,
-               0x685,  "Fcmpr",        2,
-               0x688,  "Fsqrtr",       -2,
-               0x689,  "Fexpr",        -2,
-               0x68a,  "Flogbnr",      -2,
-               0x68b,  "Froundr",      -2,
-               0x68c,  "Fsinr",        -2,
-               0x68d,  "Fcosr",        -2,
-               0x68e,  "Ftanr",        -2,
-               0x68f,  "Fclassr",      1,
-               0x690,  "Fatanrl",      3,
-               0x691,  "Flogeprl",     3,
-               0x692,  "Flogrl",       3,
-               0x693,  "Fremrl",       3,
-               0x694,  "Fcmporl",      2,
-               0x695,  "Fcmprl",       2,
-               0x698,  "Fsqrtrl",      -2,
-               0x699,  "Fexprl",       -2,
-               0x69a,  "Flogbnrl",     -2,
-               0x69b,  "Froundrl",     -2,
-               0x69c,  "Fsinrl",       -2,
-               0x69d,  "Fcosrl",       -2,
-               0x69e,  "Ftanrl",       -2,
-               0x69f,  "Fclassrl",     1,
-               0x6c0,  "Fcvtri",       -2,
-               0x6c1,  "Fcvtril",      -2,
-               0x6c2,  "Fcvtzri",      -2,
-               0x6c3,  "Fcvtzril",     -2,
-               0x6c9,  "Fmovr",        -2,
-               0x6d9,  "Fmovrl",       -2,
-               0x6e1,  "Fmovre",       -2,
-               0x6e2,  "Fcpysre",      3,
-               0x6e3,  "Fcpyrsre",     3,
-               0x701,  "mulo",         3,
-               0x708,  "remo",         3,
-               0x70b,  "divo",         3,
-               0x741,  "muli",         3,
-               0x748,  "remi",         3,
-               0x749,  "modi",         3,
-               0x74b,  "divi",         3,
-               0x78b,  "Fdivr",        3,
-               0x78c,  "Fmulr",        3,
-               0x78d,  "Fsubr",        3,
-               0x78f,  "Faddr",        3,
-               0x79b,  "Fdivrl",       3,
-               0x79c,  "Fmulrl",       3,
-               0x79d,  "Fsubrl",       3,
-               0x79f,  "Faddrl",       3,
-#define REG_MAX        0x79f
-#define REG_SIZ        ((REG_MAX-REG_MIN+1) * sizeof(struct tabent))
-               0,      NULL,   0
-       };
-
-       if ( reg_tab == NULL ){
-               reg_tab = (struct tabent *) xmalloc( REG_SIZ );
-               memset( (void *) reg_tab, 0, REG_SIZ );
-               for ( i = 0; reg_init[i].opcode != 0; i++ ){
-                       j = reg_init[i].opcode - REG_MIN;
-                       reg_tab[j].name = reg_init[i].name;
-                       reg_tab[j].numops = reg_init[i].numops;
-               }
-       }
-
-       opcode = ((word1 >> 20) & 0xff0) | ((word1 >> 7) & 0xf);
-       i = opcode - REG_MIN;
-
-       if ( (opcode<REG_MIN) || (opcode>REG_MAX) || (reg_tab[i].name==NULL) ){
-               invalid( word1 );
-               return;
-       }
-
-       mnemp = reg_tab[i].name;
-       if ( *mnemp == 'F' ){
-               fp = 1;
-               mnemp++;
-       } else {
-               fp = 0;
-       }
-
-       fputs( mnemp, stream );
-
-       s1   = (word1 >> 5)  & 1;
-       s2   = (word1 >> 6)  & 1;
-       m1   = (word1 >> 11) & 1;
-       m2   = (word1 >> 12) & 1;
-       m3   = (word1 >> 13) & 1;
-       src  =  word1        & 0x1f;
-       src2 = (word1 >> 14) & 0x1f;
-       dst  = (word1 >> 19) & 0x1f;
-
-       if  ( reg_tab[i].numops != 0 ){
-               putc( '\t', stream );
-
-               switch ( reg_tab[i].numops ){
-               case 1:
-                       regop( m1, s1, src, fp );
-                       break;
-               case -1:
-                       dstop( m3, dst, fp );
-                       break;
-               case 2:
-                       regop( m1, s1, src, fp );
-                       putc( ',', stream );
-                       regop( m2, s2, src2, fp );
-                       break;
-               case -2:
-                       regop( m1, s1, src, fp );
-                       putc( ',', stream );
-                       dstop( m3, dst, fp );
-                       break;
-               case 3:
-                       regop( m1, s1, src, fp );
-                       putc( ',', stream );
-                       regop( m2, s2, src2, fp );
-                       putc( ',', stream );
-                       dstop( m3, dst, fp );
-                       break;
-               }
-       }
-}
-
-
-/*
- * Print out effective address for memb instructions.
- */
-static void
-ea( memaddr, mode, reg2, reg3, word1, word2 )
-    unsigned long memaddr;
-    int mode;
-    char *reg2, *reg3;
-int word1;
-    unsigned int word2;
-{
-       int scale;
-       static int scale_tab[] = { 1, 2, 4, 8, 16 };
-
-       scale = (word1 >> 7) & 0x07;
-       if ( (scale > 4) || ((word1 >> 5) & 0x03 != 0) ){
-               invalid( word1 );
-               return;
-       }
-       scale = scale_tab[scale];
-
-       switch (mode) {
-       case 4:                                         /* (reg) */
-               fprintf( stream, "(%s)", reg2 );
-               break;
-       case 5:                                         /* displ+8(ip) */
-               print_addr( word2+8+memaddr );
-               break;
-       case 7:                                         /* (reg)[index*scale] */
-               if (scale == 1) {
-                       fprintf( stream, "(%s)[%s]", reg2, reg3 );
-               } else {
-                       fprintf( stream, "(%s)[%s*%d]",reg2,reg3,scale);
-               }
-               break;
-       case 12:                                        /* displacement */
-               print_addr( word2 );
-               break;
-       case 13:                                        /* displ(reg) */
-               print_addr( word2 );
-               fprintf( stream, "(%s)", reg2 );
-               break;
-       case 14:                                        /* displ[index*scale] */
-               print_addr( word2 );
-               if (scale == 1) {
-                       fprintf( stream, "[%s]", reg3 );
-               } else {
-                       fprintf( stream, "[%s*%d]", reg3, scale );
-               }
-               break;
-       case 15:                                /* displ(reg)[index*scale] */
-               print_addr( word2 );
-               if (scale == 1) {
-                       fprintf( stream, "(%s)[%s]", reg2, reg3 );
-               } else {
-                       fprintf( stream, "(%s)[%s*%d]",reg2,reg3,scale );
-               }
-               break;
-       default:
-               invalid( word1 );
-               return;
-       }
-}
-
-
-/************************************************/
-/* Register Instruction Operand                */
-/************************************************/
-static void
-regop( mode, spec, reg, fp )
-    int mode, spec, reg, fp;
-{
-       if ( fp ){                              /* FLOATING POINT INSTRUCTION */
-               if ( mode == 1 ){                       /* FP operand */
-                       switch ( reg ){
-                       case 0:  fputs( "fp0", stream );        break;
-                       case 1:  fputs( "fp1", stream );        break;
-                       case 2:  fputs( "fp2", stream );        break;
-                       case 3:  fputs( "fp3", stream );        break;
-                       case 16: fputs( "0f0.0", stream );      break;
-                       case 22: fputs( "0f1.0", stream );      break;
-                       default: putc( '?', stream );           break;
-                       }
-               } else {                                /* Non-FP register */
-                       fputs( reg_names[reg], stream );
-               }
-       } else {                                /* NOT FLOATING POINT */
-               if ( mode == 1 ){                       /* Literal */
-                       fprintf( stream, "%d", reg );
-               } else {                                /* Register */
-                       if ( spec == 0 ){
-                               fputs( reg_names[reg], stream );
-                       } else {
-                               fprintf( stream, "sf%d", reg );
-                       }
-               }
-       }
-}
-
-/************************************************/
-/* Register Instruction Destination Operand    */
-/************************************************/
-static void
-dstop( mode, reg, fp )
-    int mode, reg, fp;
-{
-       /* 'dst' operand can't be a literal. On non-FP instructions,  register
-        * mode is assumed and "m3" acts as if were "s3";  on FP-instructions,
-        * sf registers are not allowed so m3 acts normally.
-        */
-        if ( fp ){
-               regop( mode, 0, reg, fp );
-        } else {
-               regop( 0, mode, reg, fp );
-        }
-}
-
-
-static void
-invalid( word1 )
-    int word1;
-{
-       fprintf( stream, ".word\t0x%08x", (unsigned) word1 );
-}      
-
-static void
-print_addr(a)
-int a;
-{
-       fprintf( stream, "0x%x", (unsigned) a );
-}
-
-static void
-put_abs( word1, word2 )
-    unsigned long word1, word2;
-{
-#ifdef IN_GDB
-       return;
-#else
-       int len;
-
-       switch ( (word1 >> 28) & 0xf ){
-       case 0x8:
-       case 0x9:
-       case 0xa:
-       case 0xb:
-       case 0xc:
-               /* MEM format instruction */
-               len = mem( 0, word1, word2, 1 );
-               break;
-       default:
-               len = 4;
-               break;
-       }
-
-       if ( len == 8 ){
-               fprintf( stream, "%08x %08x\t", word1, word2 );
-       } else {
-               fprintf( stream, "%08x         \t", word1 );
-       }
-;
-
-#endif
-}
index ef4c16bf986345b00923ddcda94f7ef49eebfbbc..add428204b3e0825ce9ed3f53d34a8a203a443af 100644 (file)
@@ -1,5 +1,9 @@
 Thu Apr  1 09:01:38 1993  Jim Kingdon  (kingdon@cygnus.com)
 
+       * i960-pinsn.c, a29k-pinsn.c: Much abridged, just use libopcodes.a.
+
+       * core.c (dis_asm_print_address): New function.
+
        * core.c (dis_asm_read_memory): Reinstate 4th arg.  The prototype
        has been fixed.
 
index db9cb249d347842d8abf60f3f5f1364b476d58aa..867a1d0230872c57ea33539b32dd8f5216a90686 100644 (file)
@@ -1,5 +1,5 @@
 /* Instruction printing code for the AMD 29000
-   Copyright (C) 1990 Free Software Foundation, Inc.
+   Copyright (C) 1993 Free Software Foundation, Inc.
    Contributed by Cygnus Support.  Written by Jim Kingdon.
 
 This file is part of GDB.
@@ -19,282 +19,23 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "defs.h"
-#include "target.h"
-#include "opcode/a29k.h"
+#include "dis-asm.h"
 
-/* Print a symbolic representation of a general-purpose
-   register number NUM on STREAM.
-   NUM is a number as found in the instruction, not as found in
-   debugging symbols; it must be in the range 0-255.  */
-static void
-print_general (num, stream)
-     int num;
-     FILE *stream;
-{
-  if (num < 128)
-    fprintf_filtered (stream, "gr%d", num);
-  else
-    fprintf_filtered (stream, "lr%d", num - 128);
-}
-
-/* Like print_general but a special-purpose register.
-   
-   The mnemonics used by the AMD assembler are not quite the same
-   as the ones in the User's Manual.  We use the ones that the
-   assembler uses.  */
-static void
-print_special (num, stream)
-     int num;
-     FILE *stream;
-{
-  /* Register names of registers 0-SPEC0_NUM-1.  */
-  static char *spec0_names[] = {
-    "vab", "ops", "cps", "cfg", "cha", "chd", "chc", "rbp", "tmc", "tmr",
-    "pc0", "pc1", "pc2", "mmu", "lru"
-    };
-#define SPEC0_NUM ((sizeof spec0_names) / (sizeof spec0_names[0]))
+/* Print the m68k instruction at address MEMADDR in debugged memory,
+   on STREAM.  Returns length of the instruction, in bytes.  */
 
-  /* Register names of registers 128-128+SPEC128_NUM-1.  */
-  static char *spec128_names[] = {
-    "ipc", "ipa", "ipb", "q", "alu", "bp", "fc", "cr"
-    };
-#define SPEC128_NUM ((sizeof spec128_names) / (sizeof spec128_names[0]))
-
-  /* Register names of registers 160-160+SPEC160_NUM-1.  */
-  static char *spec160_names[] = {
-    "fpe", "inte", "fps", "sr163", "exop"
-    };
-#define SPEC160_NUM ((sizeof spec160_names) / (sizeof spec160_names[0]))
-
-  if (num < SPEC0_NUM)
-    fprintf_filtered (stream, spec0_names[num]);
-  else if (num >= 128 && num < 128 + SPEC128_NUM)
-    fprintf_filtered (stream, spec128_names[num-128]);
-  else if (num >= 160 && num < 160 + SPEC160_NUM)
-    fprintf_filtered (stream, spec160_names[num-160]);
-  else
-    fprintf_filtered (stream, "sr%d", num);
-}
-
-/* Is an instruction with OPCODE a delayed branch?  */
-static int
-is_delayed_branch (opcode)
-     int opcode;
-{
-  return (opcode == 0xa8 || opcode == 0xa9 || opcode == 0xa0 || opcode == 0xa1
-         || opcode == 0xa4 || opcode == 0xa5
-         || opcode == 0xb4 || opcode == 0xb5
-         || opcode == 0xc4 || opcode == 0xc0
-         || opcode == 0xac || opcode == 0xad
-         || opcode == 0xcc);
-}
-
-/* Now find the four bytes of INSN and put them in *INSN{0,8,16,24}.
-   Note that the amd can be set up as either
-   big or little-endian (the tm file says which) and we can't assume
-   the host machine is the same.  */
-static void
-find_bytes (insn, insn0, insn8, insn16, insn24)
-     char *insn;
-     unsigned char *insn0;
-     unsigned char *insn8;
-     unsigned char *insn16;
-     unsigned char *insn24;
-{
-#if TARGET_BYTE_ORDER == BIG_ENDIAN
-  *insn24 = insn[0];
-  *insn16 = insn[1];
-  *insn8  = insn[2];
-  *insn0  = insn[3];
-#else /* Little-endian.  */
-  *insn24 = insn[3];
-  *insn16 = insn[2];
-  *insn8 = insn[1];
-  *insn0 = insn[0];
-#endif /* Little-endian.  */
-}
-
-/* Print one instruction from MEMADDR on STREAM.
-   Return the size of the instruction (always 4 on a29k).  */
 int
 print_insn (memaddr, stream)
      CORE_ADDR memaddr;
      FILE *stream;
 {
-  /* The raw instruction.  */
-  char insn[4];
-
-  /* The four bytes of the instruction.  */
-  unsigned char insn24, insn16, insn8, insn0;
-
-  struct a29k_opcode const * opcode;
-
-  read_memory (memaddr, &insn[0], 4);
-
-  find_bytes (insn, &insn0, &insn8, &insn16, &insn24);
+  disassemble_info info;
 
-  /* Handle the nop (aseq 0x40,gr1,gr1) specially */
-  if ((insn24==0x70) && (insn16==0x40) && (insn8==0x01) && (insn0==0x01)) {
-    fprintf_filtered (stream,"nop");
-    return 4;
-  }
+  GDB_INIT_DISASSEMBLE_INFO(info, stream);
 
-  /* The opcode is always in insn24.  */
-  for (opcode = &a29k_opcodes[0];
-       opcode < &a29k_opcodes[num_opcodes];
-       ++opcode)
-    {
-      if ((insn24<<24) == opcode->opcode)
-       {
-         char *s;
-         
-         fprintf_filtered (stream, "%s ", opcode->name);
-         for (s = opcode->args; *s != '\0'; ++s)
-           {
-             switch (*s)
-               {
-               case 'a':
-                 print_general (insn8, stream);
-                 break;
-                 
-               case 'b':
-                 print_general (insn0, stream);
-                 break;
-
-               case 'c':
-                 print_general (insn16, stream);
-                 break;
-
-               case 'i':
-                 fprintf_filtered (stream, "%d", insn0);
-                 break;
-
-               case 'x':
-                 fprintf_filtered (stream, "%d", (insn16 << 8) + insn0);
-                 break;
-
-               case 'h':
-                 fprintf_filtered (stream, "0x%x",
-                                   (insn16 << 24) + (insn0 << 16));
-                 break;
-
-               case 'X':
-                 fprintf_filtered (stream, "%d",
-                                   ((insn16 << 8) + insn0) | 0xffff0000);
-                 break;
-
-               case 'P':
-                 /* This output looks just like absolute addressing, but
-                    maybe that's OK (it's what the GDB m68k and EBMON
-                    a29k disassemblers do).  */
-                 /* All the shifting is to sign-extend it.  p*/
-                 print_address
-                   (memaddr +
-                    (((int)((insn16 << 10) + (insn0 << 2)) << 14) >> 14),
-                    stream);
-                 break;
-
-               case 'A':
-                 print_address ((insn16 << 10) + (insn0 << 2), stream);
-                 break;
-
-               case 'e':
-                 fprintf_filtered (stream, "%d", insn16 >> 7);
-                 break;
-
-               case 'n':
-                 fprintf_filtered (stream, "0x%x", insn16 & 0x7f);
-                 break;
-
-               case 'v':
-                 fprintf_filtered (stream, "0x%x", insn16);
-                 break;
-
-               case 's':
-                 print_special (insn8, stream);
-                 break;
-
-               case 'u':
-                 fprintf_filtered (stream, "%d", insn0 >> 7);
-                 break;
-
-               case 'r':
-                 fprintf_filtered (stream, "%d", (insn0 >> 4) & 7);
-                 break;
-
-               case 'd':
-                 fprintf_filtered (stream, "%d", (insn0 >> 2) & 3);
-                 break;
-
-               case 'f':
-                 fprintf_filtered (stream, "%d", insn0 & 3);
-                 break;
-
-               case 'F':
-                 fprintf_filtered (stream, "%d", (insn16 >> 2) & 15);
-                 break;
-
-               case 'C':
-                 fprintf_filtered (stream, "%d", insn16 & 3);
-                 break;
-
-               default:
-                 fprintf_filtered (stream, "%c", *s);
-               }
-           }
-
-         /* Now we look for a const,consth pair of instructions,
-            in which case we try to print the symbolic address.  */
-         if (insn24 == 2)  /* consth */
-           {
-             int errcode;
-             char prev_insn[4];
-             unsigned char prev_insn0, prev_insn8, prev_insn16, prev_insn24;
-             
-             errcode = target_read_memory (memaddr - 4,
-                                           &prev_insn[0],
-                                           4);
-             if (errcode == 0)
-               {
-                 /* If it is a delayed branch, we need to look at the
-                    instruction before the delayed brach to handle
-                    things like
-                    
-                    const _foo
-                    call _printf
-                    consth _foo
-                    */
-                 find_bytes (prev_insn, &prev_insn0, &prev_insn8,
-                             &prev_insn16, &prev_insn24);
-                 if (is_delayed_branch (prev_insn24))
-                   {
-                     errcode = target_read_memory
-                       (memaddr - 8, &prev_insn[0], 4);
-                     find_bytes (prev_insn, &prev_insn0, &prev_insn8,
-                                 &prev_insn16, &prev_insn24);
-                   }
-               }
-                 
-             /* If there was a problem reading memory, then assume
-                the previous instruction was not const.  */
-             if (errcode == 0)
-               {
-                 /* Is it const to the same register?  */
-                 if (prev_insn24 == 3
-                     && prev_insn8 == insn8)
-                   {
-                     fprintf_filtered (stream, "\t; ");
-                     print_address (((insn16 << 24) + (insn0 << 16)
-                                     + (prev_insn16 << 8) + (prev_insn0)),
-                                    stream);
-                   }
-               }
-           }
-
-         return 4;
-       }
-    }
-  fprintf_filtered (stream, ".word 0x%8x",
-                   (insn24 << 24) + (insn16 << 16) + (insn8 << 8) + insn0);
-  return 4;
+#if TARGET_BYTE_ORDER == BIG_ENDIAN
+  return print_insn_big_a29k (memaddr, &info);
+#else
+  return print_insn_little_a29k (memaddr, &info);
+#endif
 }
index a513dbc1e0a4d45eefd859944f86f46b86a35e83..f80f66c8f9984f2b9bdc176f828306d05981595b 100644 (file)
@@ -161,9 +161,7 @@ read_memory (memaddr, myaddr, len)
     memory_error (status, memaddr);
 }
 
-/* Like target_read_memory, but slightly different parameters. 
-
-   FIXME: not according to it's prototype.  930331 krp. */
+/* Like target_read_memory, but slightly different parameters.  */
 
 int
 dis_asm_read_memory (memaddr, myaddr, len, info)
@@ -185,6 +183,15 @@ dis_asm_memory_error (status, memaddr, info)
   memory_error (status, memaddr);
 }
 
+/* Like print_address with slightly different parameters.  */
+void
+dis_asm_print_address (addr, info)
+     bfd_vma addr;
+     struct disassemble_info *info;
+{
+  print_address (addr, info->stream);
+}
+
 /* Same as target_write_memory, but report an error if can't write.  */
 void
 write_memory (memaddr, myaddr, len)
index 590770baeb54639356e341aefa257cae7ccacbd1..68ea9f0bad92a54b8dd60e480388cc40792bd405 100644 (file)
@@ -18,300 +18,21 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "defs.h"
-#include "frame.h"
-#include "inferior.h"
+#include "dis-asm.h"
 
-static FILE *stream;           /* Output goes here */
-static void print_addr();
-static void ctrl();
-static void cobr();
-static void reg();
-static int mem();
-static void ea();
-static void dstop();
-static void regop();
-static void invalid();
-static int pinsn();
-static void put_abs();
+/* Print the instruction at address MEMADDR in debugged memory,
+   on STREAM.  Returns length of the instruction, in bytes.  */
 
-
-/* Print the i960 instruction at address 'memaddr' in debugged memory,
-   on stream 's'.  Returns length of the instruction, in bytes.  */
 int
-print_insn( memaddr, s )
-    CORE_ADDR memaddr;
-    FILE *s;
-{
-       unsigned int word1, word2;
-
-       stream = s;
-       word1 = read_memory_integer( memaddr, 4 );
-       word2 = read_memory_integer( memaddr+4, 4 );
-       return pinsn( memaddr, word1, word2 );
-}
-
-
-/* Read the i960 instruction at 'memaddr' and return the address of 
-   the next instruction after that, or 0 if 'memaddr' is not the
-   address of a valid instruction.  The first word of the instruction
-   is stored at 'pword1', and the second word, if any, is stored at
-   'pword2'.  */
-
-CORE_ADDR
-next_insn (memaddr, pword1, pword2)
-     unsigned long *pword1, *pword2;
+print_insn (memaddr, stream)
      CORE_ADDR memaddr;
+     FILE *stream;
 {
-  int len;
-  unsigned long buf[2];
-
-  /* Read the two (potential) words of the instruction at once,
-     to eliminate the overhead of two calls to read_memory ().
-     TODO: read more instructions at once and cache them.  */
-
-  read_memory (memaddr, buf, sizeof (buf));
-  *pword1 = buf[0];
-  SWAP_TARGET_AND_HOST (pword1, sizeof (long));
-  *pword2 = buf[1];
-  SWAP_TARGET_AND_HOST (pword2, sizeof (long));
-
-  /* Divide instruction set into classes based on high 4 bits of opcode*/
-
-  switch ((*pword1 >> 28) & 0xf)
-    {
-    case 0x0:
-    case 0x1:  /* ctrl */
-
-    case 0x2:
-    case 0x3:  /* cobr */
-
-    case 0x5:
-    case 0x6:
-    case 0x7:  /* reg */
-      len = 4;
-      break;
-
-    case 0x8:
-    case 0x9:
-    case 0xa:
-    case 0xb:
-    case 0xc:
-      len = mem (memaddr, *pword1, *pword2, 1);
-      break;
-
-    default:   /* invalid instruction */
-      len = 0;
-      break;
-    }
-
-  if (len)
-    return memaddr + len;
-  else
-    return 0;
-}
-\f
-#define IN_GDB
-
-/*****************************************************************************
- *     All code below this point should be identical with that of
- *     the disassembler in gdmp960.
- *****************************************************************************/
-
-struct tabent {
-       char    *name;
-       char    numops;
-};
-
-static int
-pinsn( memaddr, word1, word2 )
-    unsigned long memaddr;
-    unsigned long word1, word2;
-{
-       int instr_len;
-
-       instr_len = 4;
-       put_abs( word1, word2 );
+  disassemble_info info;
 
-       /* Divide instruction set into classes based on high 4 bits of opcode*/
+  GDB_INIT_DISASSEMBLE_INFO(info, stream);
 
-       switch ( (word1 >> 28) & 0xf ){
-       case 0x0:
-       case 0x1:
-               ctrl( memaddr, word1, word2 );
-               break;
-       case 0x2:
-       case 0x3:
-               cobr( memaddr, word1, word2 );
-               break;
-       case 0x5:
-       case 0x6:
-       case 0x7:
-               reg( word1 );
-               break;
-       case 0x8:
-       case 0x9:
-       case 0xa:
-       case 0xb:
-       case 0xc:
-               instr_len = mem( memaddr, word1, word2, 0 );
-               break;
-       default:
-               /* invalid instruction, print as data word */ 
-               invalid( word1 );
-               break;
-       }
-       return instr_len;
-}
-
-/****************************************/
-/* CTRL format                         */
-/****************************************/
-static void
-ctrl( memaddr, word1, word2 )
-    unsigned long memaddr;
-    unsigned long word1, word2;
-{
-       int i;
-       static struct tabent ctrl_tab[] = {
-               NULL,           0,      /* 0x00 */
-               NULL,           0,      /* 0x01 */
-               NULL,           0,      /* 0x02 */
-               NULL,           0,      /* 0x03 */
-               NULL,           0,      /* 0x04 */
-               NULL,           0,      /* 0x05 */
-               NULL,           0,      /* 0x06 */
-               NULL,           0,      /* 0x07 */
-               "b",            1,      /* 0x08 */
-               "call",         1,      /* 0x09 */
-               "ret",          0,      /* 0x0a */
-               "bal",          1,      /* 0x0b */
-               NULL,           0,      /* 0x0c */
-               NULL,           0,      /* 0x0d */
-               NULL,           0,      /* 0x0e */
-               NULL,           0,      /* 0x0f */
-               "bno",          1,      /* 0x10 */
-               "bg",           1,      /* 0x11 */
-               "be",           1,      /* 0x12 */
-               "bge",          1,      /* 0x13 */
-               "bl",           1,      /* 0x14 */
-               "bne",          1,      /* 0x15 */
-               "ble",          1,      /* 0x16 */
-               "bo",           1,      /* 0x17 */
-               "faultno",      0,      /* 0x18 */
-               "faultg",       0,      /* 0x19 */
-               "faulte",       0,      /* 0x1a */
-               "faultge",      0,      /* 0x1b */
-               "faultl",       0,      /* 0x1c */
-               "faultne",      0,      /* 0x1d */
-               "faultle",      0,      /* 0x1e */
-               "faulto",       0,      /* 0x1f */
-       };
-
-       i = (word1 >> 24) & 0xff;
-       if ( (ctrl_tab[i].name == NULL) || ((word1 & 1) != 0) ){
-               invalid( word1 );
-               return;
-       }
-
-       fputs_filtered( ctrl_tab[i].name, stream );
-       if ( word1 & 2 ){               /* Predicts branch not taken */
-               fputs_filtered ( ".f", stream );
-       }
-
-       if ( ctrl_tab[i].numops == 1 ){
-               /* EXTRACT DISPLACEMENT AND CONVERT TO ADDRESS */
-               word1 &= 0x00ffffff;
-               if ( word1 & 0x00800000 ){              /* Sign bit is set */
-                       word1 |= (-1 & ~0xffffff);      /* Sign extend */
-               }
-               fputs_filtered ( "\t", stream );
-               print_addr( word1 + memaddr );
-       }
-}
-
-/****************************************/
-/* COBR format                         */
-/****************************************/
-static void
-cobr( memaddr, word1, word2 )
-    unsigned long memaddr;
-    unsigned long word1, word2;
-{
-       int src1;
-       int src2;
-       int i;
-
-       static struct tabent cobr_tab[] = {
-               "testno",       1,      /* 0x20 */
-               "testg",        1,      /* 0x21 */
-               "teste",        1,      /* 0x22 */
-               "testge",       1,      /* 0x23 */
-               "testl",        1,      /* 0x24 */
-               "testne",       1,      /* 0x25 */
-               "testle",       1,      /* 0x26 */
-               "testo",        1,      /* 0x27 */
-               NULL,           0,      /* 0x28 */
-               NULL,           0,      /* 0x29 */
-               NULL,           0,      /* 0x2a */
-               NULL,           0,      /* 0x2b */
-               NULL,           0,      /* 0x2c */
-               NULL,           0,      /* 0x2d */
-               NULL,           0,      /* 0x2e */
-               NULL,           0,      /* 0x2f */
-               "bbc",          3,      /* 0x30 */
-               "cmpobg",       3,      /* 0x31 */
-               "cmpobe",       3,      /* 0x32 */
-               "cmpobge",      3,      /* 0x33 */
-               "cmpobl",       3,      /* 0x34 */
-               "cmpobne",      3,      /* 0x35 */
-               "cmpoble",      3,      /* 0x36 */
-               "bbs",          3,      /* 0x37 */
-               "cmpibno",      3,      /* 0x38 */
-               "cmpibg",       3,      /* 0x39 */
-               "cmpibe",       3,      /* 0x3a */
-               "cmpibge",      3,      /* 0x3b */
-               "cmpibl",       3,      /* 0x3c */
-               "cmpibne",      3,      /* 0x3d */
-               "cmpible",      3,      /* 0x3e */
-               "cmpibo",       3,      /* 0x3f */
-       };
-
-       i = ((word1 >> 24) & 0xff) - 0x20;
-       if ( cobr_tab[i].name == NULL ){
-               invalid( word1 );
-               return;
-       }
-
-       fputs( cobr_tab[i].name, stream );
-       if ( word1 & 2 ){               /* Predicts branch not taken */
-               fputs_filtered ( ".f", stream );
-       }
-       fputs_filtered ( "\t", stream );
-
-       src1 = (word1 >> 19) & 0x1f;
-       src2 = (word1 >> 14) & 0x1f;
-
-       if ( word1 & 0x02000 ){         /* M1 is 1 */
-               fprintf_filtered ( stream, "%d", src1 );
-       } else {                        /* M1 is 0 */
-               fputs_filtered ( reg_names[src1], stream );
-       }
-
-       if ( cobr_tab[i].numops > 1 ){
-               if ( word1 & 1 ){               /* S2 is 1 */
-                       fprintf_filtered ( stream, ",sf%d,", src2 );
-               } else {                        /* S1 is 0 */
-                       fprintf_filtered ( stream, ",%s,", reg_names[src2] );
-               }
-
-               /* Extract displacement and convert to address
-                */
-               word1 &= 0x00001ffc;
-               if ( word1 & 0x00001000 ){      /* Negative displacement */
-                       word1 |= (-1 & ~0x1fff);        /* Sign extend */
-               }
-               print_addr( memaddr + word1 );
-       }
+  return print_insn_i960 (memaddr, &info);
 }
 
 /****************************************/
@@ -393,469 +114,64 @@ mem( memaddr, word1, word2, noprint )
        if ( noprint ){
                return len;
        }
-
-       if ( (mem_tab[i].name == NULL) || (mode == 6) ){
-               invalid( word1 );
-               return len;
-       }
-
-       fprintf_filtered ( stream, "%s\t", mem_tab[i].name );
-
-       reg1 = reg_names[ (word1 >> 19) & 0x1f ];       /* MEMB only */
-       reg2 = reg_names[ (word1 >> 14) & 0x1f ];
-       reg3 = reg_names[ word1 & 0x1f ];               /* MEMB only */
-       offset = word1 & 0xfff;                         /* MEMA only  */
-
-       switch ( mem_tab[i].numops ){
-
-       case 2: /* LOAD INSTRUCTION */
-               if ( mode & 4 ){                        /* MEMB FORMAT */
-                       ea( memaddr, mode, reg2, reg3, word1, word2 );
-                       fprintf_filtered ( stream, ",%s", reg1 );
-               } else {                                /* MEMA FORMAT */
-                       fprintf( stream, "0x%x", offset );
-                       if (mode & 8) {
-                               fprintf_filtered ( stream, "(%s)", reg2 );
-                       }
-                       fprintf_filtered ( stream, ",%s", reg1 );
-               }
-               break;
-
-       case -2: /* STORE INSTRUCTION */
-               if ( mode & 4 ){                        /* MEMB FORMAT */
-                       fprintf_filtered ( stream, "%s,", reg1 );
-                       ea( memaddr, mode, reg2, reg3, word1, word2 );
-               } else {                                /* MEMA FORMAT */
-                       fprintf_filtered ( stream, "%s,0x%x", reg1, offset );
-                       if (mode & 8) {
-                               fprintf_filtered ( stream, "(%s)", reg2 );
-                       }
-               }
-               break;
-
-       case 1: /* BX/CALLX INSTRUCTION */
-               if ( mode & 4 ){                        /* MEMB FORMAT */
-                       ea( memaddr, mode, reg2, reg3, word1, word2 );
-               } else {                                /* MEMA FORMAT */
-                       fprintf_filtered ( stream, "0x%x", offset );
-                       if (mode & 8) {
-                               fprintf_filtered( stream, "(%s)", reg2 );
-                       }
-               }
-               break;
-       }
-
-       return len;
-}
-
-/****************************************/
-/* REG format                          */
-/****************************************/
-static void
-reg( word1 )
-    unsigned long word1;
-{
-       int i, j;
-       int opcode;
-       int fp;
-       int m1, m2, m3;
-       int s1, s2;
-       int src, src2, dst;
-       char *mnemp;
-
-       /* This lookup table is too sparse to make it worth typing in, but not
-        * so large as to make a sparse array necessary.  We allocate the
-        * table at runtime, initialize all entries to empty, and copy the
-        * real ones in from an initialization table.
-        *
-        * NOTE: In this table, the meaning of 'numops' is:
-        *       1: single operand, which is NOT a destination.
-        *      -1: single operand, which IS a destination.
-        *       2: 2 operands, the 2nd of which is NOT a destination.
-        *      -2: 2 operands, the 2nd of which IS a destination.
-        *       3: 3 operands
-        *
-        *      If an opcode mnemonic begins with "F", it is a floating-point
-        *      opcode (the "F" is not printed).
-        */
-
-       static struct tabent *reg_tab = NULL;
-       static struct { int opcode; char *name; char numops; } reg_init[] = {
-#define REG_MIN        0x580
-               0x580,  "notbit",       3,
-               0x581,  "and",          3,
-               0x582,  "andnot",       3,
-               0x583,  "setbit",       3,
-               0x584,  "notand",       3,
-               0x586,  "xor",          3,
-               0x587,  "or",           3,
-               0x588,  "nor",          3,
-               0x589,  "xnor",         3,
-               0x58a,  "not",          -2,
-               0x58b,  "ornot",        3,
-               0x58c,  "clrbit",       3,
-               0x58d,  "notor",        3,
-               0x58e,  "nand",         3,
-               0x58f,  "alterbit",     3,
-               0x590,  "addo",         3,
-               0x591,  "addi",         3,
-               0x592,  "subo",         3,
-               0x593,  "subi",         3,
-               0x598,  "shro",         3,
-               0x59a,  "shrdi",        3,
-               0x59b,  "shri",         3,
-               0x59c,  "shlo",         3,
-               0x59d,  "rotate",       3,
-               0x59e,  "shli",         3,
-               0x5a0,  "cmpo",         2,
-               0x5a1,  "cmpi",         2,
-               0x5a2,  "concmpo",      2,
-               0x5a3,  "concmpi",      2,
-               0x5a4,  "cmpinco",      3,
-               0x5a5,  "cmpinci",      3,
-               0x5a6,  "cmpdeco",      3,
-               0x5a7,  "cmpdeci",      3,
-               0x5ac,  "scanbyte",     2,
-               0x5ae,  "chkbit",       2,
-               0x5b0,  "addc",         3,
-               0x5b2,  "subc",         3,
-               0x5cc,  "mov",          -2,
-               0x5d8,  "eshro",        3,
-               0x5dc,  "movl",         -2,
-               0x5ec,  "movt",         -2,
-               0x5fc,  "movq",         -2,
-               0x600,  "synmov",       2,
-               0x601,  "synmovl",      2,
-               0x602,  "synmovq",      2,
-               0x603,  "cmpstr",       3,
-               0x604,  "movqstr",      3,
-               0x605,  "movstr",       3,
-               0x610,  "atmod",        3,
-               0x612,  "atadd",        3,
-               0x613,  "inspacc",      -2,
-               0x614,  "ldphy",        -2,
-               0x615,  "synld",        -2,
-               0x617,  "fill",         3,
-               0x630,  "sdma",         3,
-               0x631,  "udma",         0,
-               0x640,  "spanbit",      -2,
-               0x641,  "scanbit",      -2,
-               0x642,  "daddc",        3,
-               0x643,  "dsubc",        3,
-               0x644,  "dmovt",        -2,
-               0x645,  "modac",        3,
-               0x646,  "condrec",      -2,
-               0x650,  "modify",       3,
-               0x651,  "extract",      3,
-               0x654,  "modtc",        3,
-               0x655,  "modpc",        3,
-               0x656,  "receive",      -2,
-               0x659,  "sysctl",       3,
-               0x660,  "calls",        1,
-               0x662,  "send",         3,
-               0x663,  "sendserv",     1,
-               0x664,  "resumprcs",    1,
-               0x665,  "schedprcs",    1,
-               0x666,  "saveprcs",     0,
-               0x668,  "condwait",     1,
-               0x669,  "wait",         1,
-               0x66a,  "signal",       1,
-               0x66b,  "mark",         0,
-               0x66c,  "fmark",        0,
-               0x66d,  "flushreg",     0,
-               0x66f,  "syncf",        0,
-               0x670,  "emul",         3,
-               0x671,  "ediv",         3,
-               0x673,  "ldtime",       -1,
-               0x674,  "Fcvtir",       -2,
-               0x675,  "Fcvtilr",      -2,
-               0x676,  "Fscalerl",     3,
-               0x677,  "Fscaler",      3,
-               0x680,  "Fatanr",       3,
-               0x681,  "Flogepr",      3,
-               0x682,  "Flogr",        3,
-               0x683,  "Fremr",        3,
-               0x684,  "Fcmpor",       2,
-               0x685,  "Fcmpr",        2,
-               0x688,  "Fsqrtr",       -2,
-               0x689,  "Fexpr",        -2,
-               0x68a,  "Flogbnr",      -2,
-               0x68b,  "Froundr",      -2,
-               0x68c,  "Fsinr",        -2,
-               0x68d,  "Fcosr",        -2,
-               0x68e,  "Ftanr",        -2,
-               0x68f,  "Fclassr",      1,
-               0x690,  "Fatanrl",      3,
-               0x691,  "Flogeprl",     3,
-               0x692,  "Flogrl",       3,
-               0x693,  "Fremrl",       3,
-               0x694,  "Fcmporl",      2,
-               0x695,  "Fcmprl",       2,
-               0x698,  "Fsqrtrl",      -2,
-               0x699,  "Fexprl",       -2,
-               0x69a,  "Flogbnrl",     -2,
-               0x69b,  "Froundrl",     -2,
-               0x69c,  "Fsinrl",       -2,
-               0x69d,  "Fcosrl",       -2,
-               0x69e,  "Ftanrl",       -2,
-               0x69f,  "Fclassrl",     1,
-               0x6c0,  "Fcvtri",       -2,
-               0x6c1,  "Fcvtril",      -2,
-               0x6c2,  "Fcvtzri",      -2,
-               0x6c3,  "Fcvtzril",     -2,
-               0x6c9,  "Fmovr",        -2,
-               0x6d9,  "Fmovrl",       -2,
-               0x6e1,  "Fmovre",       -2,
-               0x6e2,  "Fcpysre",      3,
-               0x6e3,  "Fcpyrsre",     3,
-               0x701,  "mulo",         3,
-               0x708,  "remo",         3,
-               0x70b,  "divo",         3,
-               0x741,  "muli",         3,
-               0x748,  "remi",         3,
-               0x749,  "modi",         3,
-               0x74b,  "divi",         3,
-               0x78b,  "Fdivr",        3,
-               0x78c,  "Fmulr",        3,
-               0x78d,  "Fsubr",        3,
-               0x78f,  "Faddr",        3,
-               0x79b,  "Fdivrl",       3,
-               0x79c,  "Fmulrl",       3,
-               0x79d,  "Fsubrl",       3,
-               0x79f,  "Faddrl",       3,
-#define REG_MAX        0x79f
-#define REG_SIZ        ((REG_MAX-REG_MIN+1) * sizeof(struct tabent))
-               0,      NULL,   0
-       };
-
-       if ( reg_tab == NULL ){
-               reg_tab = (struct tabent *) xmalloc( REG_SIZ );
-               bzero( reg_tab, REG_SIZ );
-               for ( i = 0; reg_init[i].opcode != 0; i++ ){
-                       j = reg_init[i].opcode - REG_MIN;
-                       reg_tab[j].name = reg_init[i].name;
-                       reg_tab[j].numops = reg_init[i].numops;
-               }
-       }
-
-       opcode = ((word1 >> 20) & 0xff0) | ((word1 >> 7) & 0xf);
-       i = opcode - REG_MIN;
-
-       if ( (opcode<REG_MIN) || (opcode>REG_MAX) || (reg_tab[i].name==NULL) ){
-               invalid( word1 );
-               return;
-       }
-
-       mnemp = reg_tab[i].name;
-       if ( *mnemp == 'F' ){
-               fp = 1;
-               mnemp++;
-       } else {
-               fp = 0;
-       }
-
-       fputs_filtered( mnemp, stream );
-
-       s1   = (word1 >> 5)  & 1;
-       s2   = (word1 >> 6)  & 1;
-       m1   = (word1 >> 11) & 1;
-       m2   = (word1 >> 12) & 1;
-       m3   = (word1 >> 13) & 1;
-       src  =  word1        & 0x1f;
-       src2 = (word1 >> 14) & 0x1f;
-       dst  = (word1 >> 19) & 0x1f;
-
-       if  ( reg_tab[i].numops != 0 ){
-               fputs_filtered( "\t", stream );
-
-               switch ( reg_tab[i].numops ){
-               case 1:
-                       regop( m1, s1, src, fp );
-                       break;
-               case -1:
-                       dstop( m3, dst, fp );
-                       break;
-               case 2:
-                       regop( m1, s1, src, fp );
-                       fputs_filtered( ",", stream );
-                       regop( m2, s2, src2, fp );
-                       break;
-               case -2:
-                       regop( m1, s1, src, fp );
-                       fputs_filtered( ",", stream );
-                       dstop( m3, dst, fp );
-                       break;
-               case 3:
-                       regop( m1, s1, src, fp );
-                       fputs_filtered( ",", stream );
-                       regop( m2, s2, src2, fp );
-                       fputs_filtered( ",", stream );
-                       dstop( m3, dst, fp );
-                       break;
-               }
-       }
+       abort ();
 }
 
+/* Read the i960 instruction at 'memaddr' and return the address of 
+   the next instruction after that, or 0 if 'memaddr' is not the
+   address of a valid instruction.  The first word of the instruction
+   is stored at 'pword1', and the second word, if any, is stored at
+   'pword2'.  */
 
-/*
- * Print out effective address for memb instructions.
- */
-static void
-ea( memaddr, mode, reg2, reg3, word1, word2 )
-    unsigned long memaddr;
-    int mode;
-    char *reg2, *reg3;
-    unsigned int word2;
+CORE_ADDR
+next_insn (memaddr, pword1, pword2)
+     unsigned long *pword1, *pword2;
+     CORE_ADDR memaddr;
 {
-       int scale;
-       static int scale_tab[] = { 1, 2, 4, 8, 16 };
-
-       scale = (word1 >> 7) & 0x07;
-       if ( (scale > 4) || ((word1 >> 5) & 0x03 != 0) ){
-               invalid( word1 );
-               return;
-       }
-       scale = scale_tab[scale];
-
-       switch (mode) {
-       case 4:                                         /* (reg) */
-               fprintf_filtered( stream, "(%s)", reg2 );
-               break;
-       case 5:                                         /* displ+8(ip) */
-               print_addr( word2+8+memaddr );
-               break;
-       case 7:                                         /* (reg)[index*scale] */
-               if (scale == 1) {
-                       fprintf_filtered( stream, "(%s)[%s]", reg2, reg3 );
-               } else {
-                       fprintf_filtered( stream, "(%s)[%s*%d]",reg2,reg3,scale);
-               }
-               break;
-       case 12:                                        /* displacement */
-               print_addr( word2 );
-               break;
-       case 13:                                        /* displ(reg) */
-               print_addr( word2 );
-               fprintf_filtered( stream, "(%s)", reg2 );
-               break;
-       case 14:                                        /* displ[index*scale] */
-               print_addr( word2 );
-               if (scale == 1) {
-                       fprintf_filtered( stream, "[%s]", reg3 );
-               } else {
-                       fprintf_filtered( stream, "[%s*%d]", reg3, scale );
-               }
-               break;
-       case 15:                                /* displ(reg)[index*scale] */
-               print_addr( word2 );
-               if (scale == 1) {
-                       fprintf_filtered( stream, "(%s)[%s]", reg2, reg3 );
-               } else {
-                       fprintf_filtered( stream, "(%s)[%s*%d]",reg2,reg3,scale );
-               }
-               break;
-       default:
-               invalid( word1 );
-               return;
-       }
-}
-
+  int len;
+  unsigned long buf[2];
 
-/************************************************/
-/* Register Instruction Operand                */
-/************************************************/
-static void
-regop( mode, spec, reg, fp )
-    int mode, spec, reg, fp;
-{
-       if ( fp ){                              /* FLOATING POINT INSTRUCTION */
-               if ( mode == 1 ){                       /* FP operand */
-                       switch ( reg ){
-                       case 0:  fputs_filtered( "fp0", stream );       break;
-                       case 1:  fputs_filtered( "fp1", stream );       break;
-                       case 2:  fputs_filtered( "fp2", stream );       break;
-                       case 3:  fputs_filtered( "fp3", stream );       break;
-                       case 16: fputs_filtered( "0f0.0", stream );     break;
-                       case 22: fputs_filtered( "0f1.0", stream );     break;
-                       default: fputs_filtered( "?", stream );         break;
-                       }
-               } else {                                /* Non-FP register */
-                       fputs_filtered( reg_names[reg], stream );
-               }
-       } else {                                /* NOT FLOATING POINT */
-               if ( mode == 1 ){                       /* Literal */
-                       fprintf_filtered( stream, "%d", reg );
-               } else {                                /* Register */
-                       if ( spec == 0 ){
-                               fputs_filtered( reg_names[reg], stream );
-                       } else {
-                               fprintf_filtered( stream, "sf%d", reg );
-                       }
-               }
-       }
-}
+  /* Read the two (potential) words of the instruction at once,
+     to eliminate the overhead of two calls to read_memory ().
+     TODO: read more instructions at once and cache them.  */
 
-/************************************************/
-/* Register Instruction Destination Operand    */
-/************************************************/
-static void
-dstop( mode, reg, fp )
-    int mode, reg, fp;
-{
-       /* 'dst' operand can't be a literal. On non-FP instructions,  register
-        * mode is assumed and "m3" acts as if were "s3";  on FP-instructions,
-        * sf registers are not allowed so m3 acts normally.
-        */
-        if ( fp ){
-               regop( mode, 0, reg, fp );
-        } else {
-               regop( 0, mode, reg, fp );
-        }
-}
+  read_memory (memaddr, buf, sizeof (buf));
+  *pword1 = buf[0];
+  SWAP_TARGET_AND_HOST (pword1, sizeof (long));
+  *pword2 = buf[1];
+  SWAP_TARGET_AND_HOST (pword2, sizeof (long));
 
+  /* Divide instruction set into classes based on high 4 bits of opcode*/
 
-static void
-invalid( word1 )
-    int word1;
-{
-       fprintf_filtered( stream, ".word\t0x%08x", word1 );
-}      
+  switch ((*pword1 >> 28) & 0xf)
+    {
+    case 0x0:
+    case 0x1:  /* ctrl */
 
-static void
-print_addr(a)
-{
-       print_address (a, stream);
-}
+    case 0x2:
+    case 0x3:  /* cobr */
 
-static void
-put_abs( word1, word2 )
-    unsigned long word1, word2;
-{
-#ifdef IN_GDB
-       return;
-#else
-       int len;
+    case 0x5:
+    case 0x6:
+    case 0x7:  /* reg */
+      len = 4;
+      break;
 
-       switch ( (word1 >> 28) & 0xf ){
-       case 0x8:
-       case 0x9:
-       case 0xa:
-       case 0xb:
-       case 0xc:
-               /* MEM format instruction */
-               len = mem( 0, word1, word2, 1 );
-               break;
-       default:
-               len = 4;
-               break;
-       }
+    case 0x8:
+    case 0x9:
+    case 0xa:
+    case 0xb:
+    case 0xc:
+      len = mem (memaddr, *pword1, *pword2, 1);
+      break;
 
-       if ( len == 8 ){
-               fprintf_filtered( stream, "%08x %08x\t", word1, word2 );
-       } else {
-               fprintf_filtered( stream, "%08x         \t", word1 );
-       }
-;
+    default:   /* invalid instruction */
+      len = 0;
+      break;
+    }
 
-#endif
+  if (len)
+    return memaddr + len;
+  else
+    return 0;
 }
index e0588edd64877df6614b4078300c5feb78c05b74..7ec19061b516a08514c81ee6cf403527ecf4eff4 100644 (file)
@@ -24,11 +24,13 @@ Do-first:
 Things-to-keep:
 ChangeLog
 Makefile.in
+a29k-dis.c
 configure.in
 dis-buf.c
 h8500-dis.c
 h8500-opc.h
 i386-dis.c
+i960-dis.c
 m68881-ext.c
 m68k-dis.c
 mips-dis.c
index 1d1fe25e5461eac5377fecd15c8fe93b2d93ff54..70d3e92608e3090d7fa999fae71888e31eaee7a2 100644 (file)
@@ -1,3 +1,15 @@
+Thu Apr  1 11:20:43 1993  Jim Kingdon  (kingdon@cygnus.com)
+
+       * sparc-dis.c: Use fprintf_func a few places where I forgot,
+       and double percent signs a few places.
+
+       * a29k-dis.c, i960-dis.c: New, merged from gdb and binutils.
+
+       * i386-dis.c, m68k-dis.c, mips-dis.c, sparc-dis.c:
+       Use info->print_address_func not print_address.
+
+       * dis-buf.c (generic_print_address): New function.
+
 Wed Mar 31 10:07:04 1993  Jim Kingdon  (kingdon@lioth.cygnus.com)
 
        * Makefile.in: Add sparc-dis.c.
diff --git a/opcodes/a29k-dis.c b/opcodes/a29k-dis.c
new file mode 100644 (file)
index 0000000..7808a8e
--- /dev/null
@@ -0,0 +1,343 @@
+/* Instruction printing code for the AMD 29000
+   Copyright (C) 1990 Free Software Foundation, Inc.
+   Contributed by Cygnus Support.  Written by Jim Kingdon.
+
+This file is part of GDB.
+
+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.
+
+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.
+
+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 "dis-asm.h"
+#include "opcode/a29k.h"
+
+/* Print a symbolic representation of a general-purpose
+   register number NUM on STREAM.
+   NUM is a number as found in the instruction, not as found in
+   debugging symbols; it must be in the range 0-255.  */
+static void
+print_general (num, info)
+     int num;
+     struct disassemble_info *info;
+{
+  if (num < 128)
+    (*info->fprintf_func) (info->stream, "gr%d", num);
+  else
+    (*info->fprintf_func) (info->stream, "lr%d", num - 128);
+}
+
+/* Like print_general but a special-purpose register.
+   
+   The mnemonics used by the AMD assembler are not quite the same
+   as the ones in the User's Manual.  We use the ones that the
+   assembler uses.  */
+static void
+print_special (num, info)
+     int num;
+     struct disassemble_info *info;
+{
+  /* Register names of registers 0-SPEC0_NUM-1.  */
+  static char *spec0_names[] = {
+    "vab", "ops", "cps", "cfg", "cha", "chd", "chc", "rbp", "tmc", "tmr",
+    "pc0", "pc1", "pc2", "mmu", "lru"
+    };
+#define SPEC0_NUM ((sizeof spec0_names) / (sizeof spec0_names[0]))
+
+  /* Register names of registers 128-128+SPEC128_NUM-1.  */
+  static char *spec128_names[] = {
+    "ipc", "ipa", "ipb", "q", "alu", "bp", "fc", "cr"
+    };
+#define SPEC128_NUM ((sizeof spec128_names) / (sizeof spec128_names[0]))
+
+  /* Register names of registers 160-160+SPEC160_NUM-1.  */
+  static char *spec160_names[] = {
+    "fpe", "inte", "fps", "sr163", "exop"
+    };
+#define SPEC160_NUM ((sizeof spec160_names) / (sizeof spec160_names[0]))
+
+  if (num < SPEC0_NUM)
+    (*info->fprintf_func) (info->stream, spec0_names[num]);
+  else if (num >= 128 && num < 128 + SPEC128_NUM)
+    (*info->fprintf_func) (info->stream, spec128_names[num-128]);
+  else if (num >= 160 && num < 160 + SPEC160_NUM)
+    (*info->fprintf_func) (info->stream, spec160_names[num-160]);
+  else
+    (*info->fprintf_func) (info->stream, "sr%d", num);
+}
+
+/* Is an instruction with OPCODE a delayed branch?  */
+static int
+is_delayed_branch (opcode)
+     int opcode;
+{
+  return (opcode == 0xa8 || opcode == 0xa9 || opcode == 0xa0 || opcode == 0xa1
+         || opcode == 0xa4 || opcode == 0xa5
+         || opcode == 0xb4 || opcode == 0xb5
+         || opcode == 0xc4 || opcode == 0xc0
+         || opcode == 0xac || opcode == 0xad
+         || opcode == 0xcc);
+}
+
+/* Now find the four bytes of INSN and put them in *INSN{0,8,16,24}.  */
+static void
+find_bytes_big (insn, insn0, insn8, insn16, insn24)
+     char *insn;
+     unsigned char *insn0;
+     unsigned char *insn8;
+     unsigned char *insn16;
+     unsigned char *insn24;
+{
+  *insn24 = insn[0];
+  *insn16 = insn[1];
+  *insn8  = insn[2];
+  *insn0  = insn[3];
+}
+
+static void
+find_bytes_little (insn, insn0, insn8, insn16, insn24)
+     char *insn;
+     unsigned char *insn0;
+     unsigned char *insn8;
+     unsigned char *insn16;
+     unsigned char *insn24;
+{
+  *insn24 = insn[3];
+  *insn16 = insn[2];
+  *insn8 = insn[1];
+  *insn0 = insn[0];
+}
+
+typedef (*find_byte_func_type)
+     PARAMS ((char *, unsigned char *, unsigned char *,
+             unsigned char *, unsigned char *));
+
+/* Print one instruction from MEMADDR on STREAM.
+   Return the size of the instruction (always 4 on a29k).  */
+static int
+print_insn (memaddr, info)
+     bfd_vma memaddr;
+     struct disassemble_info *info;
+{
+  /* The raw instruction.  */
+  char insn[4];
+
+  /* The four bytes of the instruction.  */
+  unsigned char insn24, insn16, insn8, insn0;
+
+  find_byte_func_type find_byte_func = (find_byte_func_type)info->private_data;
+
+  struct a29k_opcode const * opcode;
+
+  {
+    int status =
+      (*info->read_memory_func) (memaddr, (char *) &insn[0], 4, info);
+    if (status != 0)
+      {
+       (*info->memory_error_func) (status, memaddr, info);
+       return -1;
+      }
+  }
+
+  (*find_byte_func) (insn, &insn0, &insn8, &insn16, &insn24);
+
+  /* Handle the nop (aseq 0x40,gr1,gr1) specially */
+  if ((insn24==0x70) && (insn16==0x40) && (insn8==0x01) && (insn0==0x01)) {
+    (*info->fprintf_func) (info->stream,"nop");
+    return 4;
+  }
+
+  /* The opcode is always in insn24.  */
+  for (opcode = &a29k_opcodes[0];
+       opcode < &a29k_opcodes[num_opcodes];
+       ++opcode)
+    {
+      if ((insn24<<24) == opcode->opcode)
+       {
+         char *s;
+         
+         (*info->fprintf_func) (info->stream, "%s ", opcode->name);
+         for (s = opcode->args; *s != '\0'; ++s)
+           {
+             switch (*s)
+               {
+               case 'a':
+                 print_general (insn8, info);
+                 break;
+                 
+               case 'b':
+                 print_general (insn0, info);
+                 break;
+
+               case 'c':
+                 print_general (insn16, info);
+                 break;
+
+               case 'i':
+                 (*info->fprintf_func) (info->stream, "%d", insn0);
+                 break;
+
+               case 'x':
+                 (*info->fprintf_func) (info->stream, "%d", (insn16 << 8) + insn0);
+                 break;
+
+               case 'h':
+                 /* This used to be %x for binutils.  */
+                 (*info->fprintf_func) (info->stream, "0x%x",
+                                   (insn16 << 24) + (insn0 << 16));
+                 break;
+
+               case 'X':
+                 (*info->fprintf_func) (info->stream, "%d",
+                                   ((insn16 << 8) + insn0) | 0xffff0000);
+                 break;
+
+               case 'P':
+                 /* This output looks just like absolute addressing, but
+                    maybe that's OK (it's what the GDB m68k and EBMON
+                    a29k disassemblers do).  */
+                 /* All the shifting is to sign-extend it.  p*/
+                 (*info->print_address_func)
+                   (memaddr +
+                    (((int)((insn16 << 10) + (insn0 << 2)) << 14) >> 14),
+                    info);
+                 break;
+
+               case 'A':
+                 (*info->print_address_func)
+                   ((insn16 << 10) + (insn0 << 2), info);
+                 break;
+
+               case 'e':
+                 (*info->fprintf_func) (info->stream, "%d", insn16 >> 7);
+                 break;
+
+               case 'n':
+                 (*info->fprintf_func) (info->stream, "0x%x", insn16 & 0x7f);
+                 break;
+
+               case 'v':
+                 (*info->fprintf_func) (info->stream, "0x%x", insn16);
+                 break;
+
+               case 's':
+                 print_special (insn8, info);
+                 break;
+
+               case 'u':
+                 (*info->fprintf_func) (info->stream, "%d", insn0 >> 7);
+                 break;
+
+               case 'r':
+                 (*info->fprintf_func) (info->stream, "%d", (insn0 >> 4) & 7);
+                 break;
+
+               case 'd':
+                 (*info->fprintf_func) (info->stream, "%d", (insn0 >> 2) & 3);
+                 break;
+
+               case 'f':
+                 (*info->fprintf_func) (info->stream, "%d", insn0 & 3);
+                 break;
+
+               case 'F':
+                 (*info->fprintf_func) (info->stream, "%d", (insn16 >> 2) & 15);
+                 break;
+
+               case 'C':
+                 (*info->fprintf_func) (info->stream, "%d", insn16 & 3);
+                 break;
+
+               default:
+                 (*info->fprintf_func) (info->stream, "%c", *s);
+               }
+           }
+
+         /* Now we look for a const,consth pair of instructions,
+            in which case we try to print the symbolic address.  */
+         if (insn24 == 2)  /* consth */
+           {
+             int errcode;
+             char prev_insn[4];
+             unsigned char prev_insn0, prev_insn8, prev_insn16, prev_insn24;
+             
+             errcode = (*info->read_memory_func) (memaddr - 4,
+                                                  &prev_insn[0],
+                                                  4,
+                                                  info);
+             if (errcode == 0)
+               {
+                 /* If it is a delayed branch, we need to look at the
+                    instruction before the delayed brach to handle
+                    things like
+                    
+                    const _foo
+                    call _printf
+                    consth _foo
+                    */
+                 (*find_byte_func) (prev_insn, &prev_insn0, &prev_insn8,
+                                    &prev_insn16, &prev_insn24);
+                 if (is_delayed_branch (prev_insn24))
+                   {
+                     errcode = (*info->read_memory_func)
+                       (memaddr - 8, &prev_insn[0], 4, info);
+                     (*find_byte_func) (prev_insn, &prev_insn0, &prev_insn8,
+                                        &prev_insn16, &prev_insn24);
+                   }
+               }
+                 
+             /* If there was a problem reading memory, then assume
+                the previous instruction was not const.  */
+             if (errcode == 0)
+               {
+                 /* Is it const to the same register?  */
+                 if (prev_insn24 == 3
+                     && prev_insn8 == insn8)
+                   {
+                     (*info->fprintf_func) (info->stream, "\t; ");
+                     (*info->print_address_func)
+                       (((insn16 << 24) + (insn0 << 16)
+                         + (prev_insn16 << 8) + (prev_insn0)),
+                        info);
+                   }
+               }
+           }
+
+         return 4;
+       }
+    }
+  /* This used to be %8x for binutils.  */
+  (*info->fprintf_func)
+    (info->stream, ".word 0x%8x",
+     (insn24 << 24) + (insn16 << 16) + (insn8 << 8) + insn0);
+  return 4;
+}
+
+/* Disassemble an big-endian a29k instruction.  */
+int
+print_insn_big_a29k (memaddr, info)
+     bfd_vma memaddr;
+     struct disassemble_info *info;
+{
+  info->private_data = (PTR) find_bytes_big;
+  return print_insn (memaddr, info);
+}
+
+/* Disassemble a little-endian a29k instruction.  */
+int
+print_insn_little_a29k (memaddr, info)
+     bfd_vma memaddr;
+     struct disassemble_info *info;
+{
+  info->private_data = (PTR) find_bytes_little;
+  return print_insn (memaddr, info);
+}