]> Git Repo - binutils.git/blob - gdb/i960-pinsn.c
* target.h: Put remote_debug declaration back here. Add baud_rate.
[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
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                 memset( mem_tab, '\0', 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   char buf[8];
139
140   /* Read the two (potential) words of the instruction at once,
141      to eliminate the overhead of two calls to read_memory ().
142      FIXME: Loses if the first one is readable but the second is not
143      (e.g. last word of the segment).  */
144
145   read_memory (memaddr, buf, 8);
146   *pword1 = extract_unsigned_integer (buf, 4);
147   *pword2 = extract_unsigned_integer (buf + 4, 4);
148
149   /* Divide instruction set into classes based on high 4 bits of opcode*/
150
151   switch ((*pword1 >> 28) & 0xf)
152     {
153     case 0x0:
154     case 0x1:   /* ctrl */
155
156     case 0x2:
157     case 0x3:   /* cobr */
158
159     case 0x5:
160     case 0x6:
161     case 0x7:   /* reg */
162       len = 4;
163       break;
164
165     case 0x8:
166     case 0x9:
167     case 0xa:
168     case 0xb:
169     case 0xc:
170       len = mem (memaddr, *pword1, *pword2, 1);
171       break;
172
173     default:    /* invalid instruction */
174       len = 0;
175       break;
176     }
177
178   if (len)
179     return memaddr + len;
180   else
181     return 0;
182 }
This page took 0.034197 seconds and 4 git commands to generate.