home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / gdb-4.9 / gdb / i960-pinsn.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-12  |  4.5 KB  |  184 lines

  1. /* i80960 instruction disassembler for GDB.
  2.    Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
  3.  
  4. This file is part of GDB.
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "defs.h"
  21. #include "dis-asm.h"
  22.  
  23. /* Print the instruction at address MEMADDR in debugged memory,
  24.    on STREAM.  Returns length of the instruction, in bytes.  */
  25.  
  26. int
  27. print_insn (memaddr, stream)
  28.      CORE_ADDR memaddr;
  29.      FILE *stream;
  30. {
  31.   disassemble_info info;
  32.  
  33.   GDB_INIT_DISASSEMBLE_INFO(info, stream);
  34.  
  35.   return print_insn_i960 (memaddr, &info);
  36. }
  37.  
  38. /****************************************/
  39. /* MEM format                */
  40. /****************************************/
  41.  
  42. struct tabent {
  43.     char    *name;
  44.     char    numops;
  45. };
  46.  
  47. static int                /* returns instruction length: 4 or 8 */
  48. mem( memaddr, word1, word2, noprint )
  49.     unsigned long memaddr;
  50.     unsigned long word1, word2;
  51.     int noprint;        /* If TRUE, return instruction length, but
  52.                    don't output any text.  */
  53. {
  54.     int i, j;
  55.     int len;
  56.     int mode;
  57.     int offset;
  58.     const char *reg1, *reg2, *reg3;
  59.  
  60.     /* This lookup table is too sparse to make it worth typing in, but not
  61.      * so large as to make a sparse array necessary.  We allocate the
  62.      * table at runtime, initialize all entries to empty, and copy the
  63.      * real ones in from an initialization table.
  64.      *
  65.      * NOTE: In this table, the meaning of 'numops' is:
  66.      *     1: single operand
  67.      *     2: 2 operands, load instruction
  68.      *    -2: 2 operands, store instruction
  69.      */
  70.     static struct tabent *mem_tab = NULL;
  71. /* Opcodes of 0x8X, 9X, aX, bX, and cX must be in the table.  */
  72. #define MEM_MIN    0x80
  73. #define MEM_MAX    0xcf
  74. #define MEM_SIZ    ((MEM_MAX-MEM_MIN+1) * sizeof(struct tabent))
  75.  
  76.     static struct { int opcode; char *name; char numops; } mem_init[] = {
  77.         0x80,    "ldob",     2,
  78.         0x82,    "stob",    -2,
  79.         0x84,    "bx",     1,
  80.         0x85,    "balx",     2,
  81.         0x86,    "callx", 1,
  82.         0x88,    "ldos",     2,
  83.         0x8a,    "stos",    -2,
  84.         0x8c,    "lda",     2,
  85.         0x90,    "ld",     2,
  86.         0x92,    "st",    -2,
  87.         0x98,    "ldl",     2,
  88.         0x9a,    "stl",    -2,
  89.         0xa0,    "ldt",     2,
  90.         0xa2,    "stt",    -2,
  91.         0xb0,    "ldq",     2,
  92.         0xb2,    "stq",    -2,
  93.         0xc0,    "ldib",     2,
  94.         0xc2,    "stib",    -2,
  95.         0xc8,    "ldis",     2,
  96.         0xca,    "stis",    -2,
  97.         0,    NULL,    0
  98.     };
  99.  
  100.     if ( mem_tab == NULL ){
  101.         mem_tab = (struct tabent *) xmalloc( MEM_SIZ );
  102.         bzero( mem_tab, MEM_SIZ );
  103.         for ( i = 0; mem_init[i].opcode != 0; i++ ){
  104.             j = mem_init[i].opcode - MEM_MIN;
  105.             mem_tab[j].name = mem_init[i].name;
  106.             mem_tab[j].numops = mem_init[i].numops;
  107.         }
  108.     }
  109.  
  110.     i = ((word1 >> 24) & 0xff) - MEM_MIN;
  111.     mode = (word1 >> 10) & 0xf;
  112.  
  113.     if ( (mem_tab[i].name != NULL)        /* Valid instruction */
  114.     &&   ((mode == 5) || (mode >=12)) ){    /* With 32-bit displacement */
  115.         len = 8;
  116.     } else {
  117.         len = 4;
  118.     }
  119.  
  120.     if ( noprint ){
  121.         return len;
  122.     }
  123.     abort ();
  124. }
  125.  
  126. /* Read the i960 instruction at 'memaddr' and return the address of 
  127.    the next instruction after that, or 0 if 'memaddr' is not the
  128.    address of a valid instruction.  The first word of the instruction
  129.    is stored at 'pword1', and the second word, if any, is stored at
  130.    'pword2'.  */
  131.  
  132. CORE_ADDR
  133. next_insn (memaddr, pword1, pword2)
  134.      unsigned long *pword1, *pword2;
  135.      CORE_ADDR memaddr;
  136. {
  137.   int len;
  138.   unsigned long buf[2];
  139.  
  140.   /* Read the two (potential) words of the instruction at once,
  141.      to eliminate the overhead of two calls to read_memory ().
  142.      TODO: read more instructions at once and cache them.  */
  143.  
  144.   read_memory (memaddr, buf, sizeof (buf));
  145.   *pword1 = buf[0];
  146.   SWAP_TARGET_AND_HOST (pword1, sizeof (long));
  147.   *pword2 = buf[1];
  148.   SWAP_TARGET_AND_HOST (pword2, sizeof (long));
  149.  
  150.   /* Divide instruction set into classes based on high 4 bits of opcode*/
  151.  
  152.   switch ((*pword1 >> 28) & 0xf)
  153.     {
  154.     case 0x0:
  155.     case 0x1:    /* ctrl */
  156.  
  157.     case 0x2:
  158.     case 0x3:    /* cobr */
  159.  
  160.     case 0x5:
  161.     case 0x6:
  162.     case 0x7:    /* reg */
  163.       len = 4;
  164.       break;
  165.  
  166.     case 0x8:
  167.     case 0x9:
  168.     case 0xa:
  169.     case 0xb:
  170.     case 0xc:
  171.       len = mem (memaddr, *pword1, *pword2, 1);
  172.       break;
  173.  
  174.     default:    /* invalid instruction */
  175.       len = 0;
  176.       break;
  177.     }
  178.  
  179.   if (len)
  180.     return memaddr + len;
  181.   else
  182.     return 0;
  183. }
  184.