* symfile.c (reread_symbols): When re-reading symbols, do all the
[binutils-gdb.git] / gdb / m88k-pinsn.c
index bede269b0af9a539429895673e8c974966614538..336dd388817a38a389cb8ee458f2b1ca05e8b202 100644 (file)
-/* This file has been modified by Data General Corporation, November 1989. */
+/* Print instructions for the Motorola 88000, for GDB and GNU Binutils.
+   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1993
+   Free Software Foundation, Inc.
 
-#include <stdio.h>
-#include "m88k-opcode.h"
-#include "defs.h"
-#include "symtab.h"
+This file is part of GDB and the GNU Binutils.
+
+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.
 
-void sprint_address ();
+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.
 
-/* Changed hashtab to hashtable to avoid naming conflict
-   with libdc.o (used for tdesc) for m88k.
-*/
+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.  */
 
-INSTAB  *hashtable[HASHVAL] = {0};
+#include "defs.h"
+#include "dis-asm.h"
 
-/*
-*              Disassemble an M88000 Instruction
-*
-*
-*       This module decodes the first instruction in inbuf.  It uses the pc
-*      to display pc-relative displacements.  It writes the disassembled
-*      instruction in outbuf.
-*
-*                      Revision History
-*
-*       Revision 1.0    11/08/85        Creation date by Motorola
-*                      05/11/89        R. Trawick adapted to GDB interface.
-*/
-#define MAXLEN 20
+/* Print the m88k instruction at address MEMADDR in debugged memory,
+   on STREAM.  Returns length of the instruction, in bytes, which
+   is always 4.  */
 
+int
 print_insn (memaddr, stream)
      CORE_ADDR memaddr;
      FILE *stream;
 {
-  unsigned char buffer[MAXLEN];
-  /* should be expanded if disassembler prints symbol names */
-  char outbuf[100];
-  int n;
-
-  /* Instruction addresses may have low two bits set. Clear them.      */
-  memaddr&= 0xfffffffc;
-  read_memory (memaddr, buffer, MAXLEN);
-
-  n = m88kdis ((int)memaddr, buffer, outbuf);
-
-  fputs (outbuf, stream);
-
-  return (n);
-}
-
-/*
- * disassemble the first instruction in 'inbuf'.
- * 'pc' should be the address of this instruction, it will
- *   be used to print the target address if this is a relative jump or call
- * 'outbuf' gets filled in with the disassembled instruction.  It should
- *   be long enough to hold the longest disassembled instruction.
- *   100 bytes is certainly enough, unless symbol printing is added later
- * The function returns the length of this instruction in bytes.
- */
-
-int m88kdis( pc, inbuf, outbuf )
-
-    int                pc;
-    int                *inbuf;
-    char       *outbuf;
-
-{   static             ihashtab_initialized = 0;
-    int                        instruction;
-    unsigned int       opcode;
-    INSTAB             *entry_ptr;
-    int                        opmask;
-    int                        class;
-
-    instruction= *inbuf;
-
-    if (!ihashtab_initialized) {
-       init_disasm();
-    }
-
-    /* create a the appropriate mask to isolate the opcode */
-    opmask= DEFMASK;
-    class= instruction & DEFMASK;
-    if ((class >= SFU0) && (class <= SFU7)) {
-       if (instruction < SFU1) {
-           opmask= CTRLMASK;
-       } else {
-           opmask= SFUMASK;
-       }
-    } else if (class == RRR) {
-       opmask= RRRMASK;
-    } else if (class == RRI10) {
-       opmask= RRI10MASK;
-    }
-
-    /* isolate the opcode */
-    opcode= instruction & opmask;
-
-    /* search the hash table with the isolated opcode */
-    for (entry_ptr= hashtable[ opcode % HASHVAL ];
-        (entry_ptr != NULL) && (entry_ptr->opcode != opcode);
-        entry_ptr= entry_ptr->next) {
-    }
-
-    if (entry_ptr == NULL) {
-       sprintf( outbuf, "word\t%08x", instruction );
-    } else {
-       sprintf( outbuf, "%s\t", entry_ptr->mnemonic );
-       sprintop( &outbuf[strlen(outbuf)], &(entry_ptr->op1), instruction, pc, 1 );
-       sprintop( &outbuf[strlen(outbuf)], &(entry_ptr->op2), instruction, pc, 0 );
-       sprintop( &outbuf[strlen(outbuf)], &(entry_ptr->op3), instruction, pc, 0 );
-    }
-
-
-    return 4;
-}
-\f
-
-/*
-*                      Decode an Operand of an Instruction
-*
-*                      Functional Description
-*
-*       This module formats and writes an operand of an instruction to buf
-*       based on the operand specification.  When the first flag is set this
-*       is the first operand of an instruction.  Undefined operand types
-*       cause a <dis error> message.
-*
-*                      Parameters
-*      char    *buf            buffer where the operand may be printed
-*       OPSPEC  *opptr          Pointer to an operand specification
-*       UINT    inst            Instruction from which operand is extracted
-*      UINT    pc              PC of instruction; used for pc-relative disp.
-*       int     first           Flag which if nonzero indicates the first
-*                               operand of an instruction
-*
-*                      Output
-*
-*       The operand specified is extracted from the instruction and is
-*       written to buf in the format specified. The operand is preceded
-*       by a comma if it is not the first operand of an instruction and it
-*       is not a register indirect form.  Registers are preceded by 'r' and
-*       hex values by '0x'.
-*
-*                      Revision History
-*
-*       Revision 1.0    11/08/85        Creation date
-*/
-
-sprintop( buf, opptr, inst, pc, first )
-
-   char   *buf;
-   OPSPEC *opptr;
-   UINT   inst;
-   int   pc;
-   int    first;
-
-{  int   extracted_field;
-   char          *cond_mask_sym;
-   char          cond_mask_sym_buf[6];
-
-   if (opptr->width == 0)
-      return;
-
-   switch(opptr->type) {
-      case CRREG:
-                      if (!first)
-                          *buf++= ',';
-                      sprintf( buf, "cr%d", UEXT(inst,opptr->offset,opptr->width));
-                      break;
-
-      case FCRREG:
-                      if (!first)
-                          *buf++= ',';
-                      sprintf( buf, "fcr%d", UEXT(inst,opptr->offset,opptr->width));
-                      break;
-
-      case REGSC:
-                      sprintf( buf, "[r%d]", UEXT(inst,opptr->offset,opptr->width));
-                      break;
-
-      case REG:
-                      if (!first)
-                          *buf++= ',';
-                      sprintf( buf, "r%d", UEXT(inst,opptr->offset,opptr->width));
-                      break;
-
-      case HEX:
-                       if (!first)
-                          *buf++= ',';
-                       extracted_field= UEXT(inst, opptr->offset, opptr->width);
-                       if (extracted_field == 0) {
-                           sprintf( buf, "0" );
-                       } else {
-                           sprintf( buf, "0x%02x", extracted_field );
-                       }
-                       break;
-
-      case CONDMASK:
-                       if (!first)
-                          *buf++= ',';
-                       extracted_field= UEXT(inst, opptr->offset, opptr->width);
-                       switch (extracted_field & 0x0f) {
-                         case 0x1:     cond_mask_sym= "gt0";
-                                       break;
-                         case 0x2:     cond_mask_sym= "eq0";
-                                       break;
-                         case 0x3:     cond_mask_sym= "ge0";
-                                       break;
-                         case 0xc:     cond_mask_sym= "lt0";
-                                       break;
-                         case 0xd:     cond_mask_sym= "ne0";
-                                       break;
-                         case 0xe:     cond_mask_sym= "le0";
-                                       break;
-                         default:      cond_mask_sym= cond_mask_sym_buf;
-                                       sprintf( cond_mask_sym_buf,
-                                                "%x",
-                                                extracted_field );
-                                       break;
-                       }
-                       strcpy( buf, cond_mask_sym );
-                       break;
-                       
-      case PCREL:
-                       if (!first)
-                          *buf++= ',';
-                       sprint_address( pc + 4*(SEXT(inst,opptr->offset,opptr->width)),
-                                       buf );
-                       break;
-
-      case CONT:
-                      sprintf( buf,
-                               "%d,r%d",
-                               UEXT(inst,opptr->offset,5),
-                               UEXT(inst,(opptr->offset)+5,5) );
-                      break;
-
-      case BF:
-                      if (!first)
-                          *buf++= ',';
-                      sprintf( buf,
-                               "%d<%d>",
-                               UEXT(inst,(opptr->offset)+5,5),
-                               UEXT(inst,opptr->offset,5));
-                      break;
-
-      default:
-                      sprintf( buf, "<dis error: %08x>", inst );
-    }
-
-}
-
-/*
-*                 Initialize the Disassembler Instruction Table
-*
-*       Initialize the hash table and instruction table for the disassembler.
-*       This should be called once before the first call to disasm().
-*
-*                      Parameters
-*
-*                      Output
-*
-*       If the debug option is selected, certain statistics about the hashing
-*       distribution are written to stdout.
-*
-*                      Revision History
-*
-*       Revision 1.0    11/08/85        Creation date
-*/
-
-init_disasm()
-{
-   int i,size;
-
-   for (i=0 ; i < HASHVAL ; i++)
-      hashtable[i] = NULL;
-
-   for (i=0, size =  sizeof(instructions) / sizeof(INSTAB) ; i < size ;
-       install(&instructions[i++]));
-
-}
-
-/*
-*       Insert an instruction into the disassembler table by hashing the
-*       opcode and inserting it into the linked list for that hash value.
-*
-*                      Parameters
-*
-*       INSTAB *instptr         Pointer to the entry in the instruction table
-*                               to be installed
-*
-*       Revision 1.0    11/08/85        Creation date
-*                      05/11/89        R. TRAWICK ADAPTED FROM MOTOROLA
-*/
-
-install(instptr)
-   INSTAB *instptr;
-{
-   UINT i;
-
-   i = (instptr->opcode) % HASHVAL;
-   instptr->next = hashtable[i];
-   hashtable[i] = instptr;
-}
-\f
-
-/* adapted from print_address in printcmd by R. Trawick 5/15/89.  The two should
-   be combined.
- */
-
-void sprint_address (addr, buffer)
-
-     CORE_ADDR  addr;
-     char      *buffer;
-
-{
-       register int    i;
-       struct symbol   *fs;
-       char            *name;
-       int             name_location;
-
-       sprintf ( buffer, "0x%x", addr);
-
-       fs = find_pc_function (addr);
-
-       if (!fs) {
-           i = find_pc_misc_function (addr);
-
-           if (i < 0) return;  /* If nothing comes through, don't
-                                  print anything symbolic */
+  disassemble_info info;
 
-           name = misc_function_vector[i].name;
-           name_location = misc_function_vector[i].address;
-       } else {
-           name = fs->name;
-           name_location = BLOCK_START (SYMBOL_BLOCK_VALUE (fs));
-       }
+  GDB_INIT_DISASSEMBLE_INFO (info, stream);
 
-       if (addr - name_location)
-           sprintf (buffer, " <%s+%d>", name, addr - name_location);
-       else
-           sprintf (buffer, " <%s>", name);
+  /* print_insn_m88k is in opcodes/m88k-dis.c.  */
+  return print_insn_m88k ((bfd_vma) memaddr, &info);
 }