]> Git Repo - binutils.git/blob - gdb/i960-pinsn.c
* mt-a29k, mt-ebmon29k, mt-os68k, mt-ose68000, mt-ose68k,
[binutils.git] / gdb / i960-pinsn.c
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 static int                              /* returns instruction length: 4 or 8 */
42 mem( memaddr, word1, word2, noprint )
43     unsigned long memaddr;
44     unsigned long word1, word2;
45     int noprint;                /* If TRUE, return instruction length, but
46                                    don't output any text.  */
47 {
48         int i, j;
49         int len;
50         int mode;
51         int offset;
52         const char *reg1, *reg2, *reg3;
53
54         /* This lookup table is too sparse to make it worth typing in, but not
55          * so large as to make a sparse array necessary.  We allocate the
56          * table at runtime, initialize all entries to empty, and copy the
57          * real ones in from an initialization table.
58          *
59          * NOTE: In this table, the meaning of 'numops' is:
60          *       1: single operand
61          *       2: 2 operands, load instruction
62          *      -2: 2 operands, store instruction
63          */
64         static struct tabent *mem_tab = NULL;
65 /* Opcodes of 0x8X, 9X, aX, bX, and cX must be in the table.  */
66 #define MEM_MIN 0x80
67 #define MEM_MAX 0xcf
68 #define MEM_SIZ ((MEM_MAX-MEM_MIN+1) * sizeof(struct tabent))
69
70         static struct { int opcode; char *name; char numops; } mem_init[] = {
71                 0x80,   "ldob",  2,
72                 0x82,   "stob", -2,
73                 0x84,   "bx",    1,
74                 0x85,   "balx",  2,
75                 0x86,   "callx", 1,
76                 0x88,   "ldos",  2,
77                 0x8a,   "stos", -2,
78                 0x8c,   "lda",   2,
79                 0x90,   "ld",    2,
80                 0x92,   "st",   -2,
81                 0x98,   "ldl",   2,
82                 0x9a,   "stl",  -2,
83                 0xa0,   "ldt",   2,
84                 0xa2,   "stt",  -2,
85                 0xb0,   "ldq",   2,
86                 0xb2,   "stq",  -2,
87                 0xc0,   "ldib",  2,
88                 0xc2,   "stib", -2,
89                 0xc8,   "ldis",  2,
90                 0xca,   "stis", -2,
91                 0,      NULL,   0
92         };
93
94         if ( mem_tab == NULL ){
95                 mem_tab = (struct tabent *) xmalloc( MEM_SIZ );
96                 bzero( mem_tab, MEM_SIZ );
97                 for ( i = 0; mem_init[i].opcode != 0; i++ ){
98                         j = mem_init[i].opcode - MEM_MIN;
99                         mem_tab[j].name = mem_init[i].name;
100                         mem_tab[j].numops = mem_init[i].numops;
101                 }
102         }
103
104         i = ((word1 >> 24) & 0xff) - MEM_MIN;
105         mode = (word1 >> 10) & 0xf;
106
107         if ( (mem_tab[i].name != NULL)          /* Valid instruction */
108         &&   ((mode == 5) || (mode >=12)) ){    /* With 32-bit displacement */
109                 len = 8;
110         } else {
111                 len = 4;
112         }
113
114         if ( noprint ){
115                 return len;
116         }
117         abort ();
118 }
119
120 /* Read the i960 instruction at 'memaddr' and return the address of 
121    the next instruction after that, or 0 if 'memaddr' is not the
122    address of a valid instruction.  The first word of the instruction
123    is stored at 'pword1', and the second word, if any, is stored at
124    'pword2'.  */
125
126 CORE_ADDR
127 next_insn (memaddr, pword1, pword2)
128      unsigned long *pword1, *pword2;
129      CORE_ADDR memaddr;
130 {
131   int len;
132   unsigned long buf[2];
133
134   /* Read the two (potential) words of the instruction at once,
135      to eliminate the overhead of two calls to read_memory ().
136      TODO: read more instructions at once and cache them.  */
137
138   read_memory (memaddr, buf, sizeof (buf));
139   *pword1 = buf[0];
140   SWAP_TARGET_AND_HOST (pword1, sizeof (long));
141   *pword2 = buf[1];
142   SWAP_TARGET_AND_HOST (pword2, sizeof (long));
143
144   /* Divide instruction set into classes based on high 4 bits of opcode*/
145
146   switch ((*pword1 >> 28) & 0xf)
147     {
148     case 0x0:
149     case 0x1:   /* ctrl */
150
151     case 0x2:
152     case 0x3:   /* cobr */
153
154     case 0x5:
155     case 0x6:
156     case 0x7:   /* reg */
157       len = 4;
158       break;
159
160     case 0x8:
161     case 0x9:
162     case 0xa:
163     case 0xb:
164     case 0xc:
165       len = mem (memaddr, *pword1, *pword2, 1);
166       break;
167
168     default:    /* invalid instruction */
169       len = 0;
170       break;
171     }
172
173   if (len)
174     return memaddr + len;
175   else
176     return 0;
177 }
This page took 0.036941 seconds and 4 git commands to generate.