import gdb-19990504 snapshot
[deliverable/binutils-gdb.git] / gdb / tahoe-tdep.c
1 /* Print instructions for Tahoe target machines, for GDB.
2 Copyright 1986, 1989, 1991, 1992 Free Software Foundation, Inc.
3 Contributed by the State University of New York at Buffalo, by the
4 Distributed Computer Systems Lab, Department of Computer Science, 1991.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
22 #include "defs.h"
23 #include "symtab.h"
24 #include "opcode/tahoe.h"
25
26 /* Tahoe instructions are never longer than this. */
27 #define MAXLEN 62
28
29 /* Number of elements in the opcode table. */
30 #define NOPCODES (sizeof votstrs / sizeof votstrs[0])
31
32 static unsigned char *print_insn_arg ();
33
34 /* Advance PC across any function entry prologue instructions
35 to reach some "real" code. */
36
37 CORE_ADDR
38 tahoe_skip_prologue (pc)
39 CORE_ADDR pc;
40 {
41 register int op = (unsigned char) read_memory_integer (pc, 1);
42 if (op == 0x11)
43 pc += 2; /* skip brb */
44 if (op == 0x13)
45 pc += 3; /* skip brw */
46 if (op == 0x2c
47 && ((unsigned char) read_memory_integer (pc+2, 1)) == 0x5e)
48 pc += 3; /* skip subl2 */
49 if (op == 0xe9
50 && ((unsigned char) read_memory_integer (pc+1, 1)) == 0xae
51 && ((unsigned char) read_memory_integer(pc+3, 1)) == 0x5e)
52 pc += 4; /* skip movab */
53 if (op == 0xe9
54 && ((unsigned char) read_memory_integer (pc+1, 1)) == 0xce
55 && ((unsigned char) read_memory_integer(pc+4, 1)) == 0x5e)
56 pc += 5; /* skip movab */
57 if (op == 0xe9
58 && ((unsigned char) read_memory_integer (pc+1, 1)) == 0xee
59 && ((unsigned char) read_memory_integer(pc+6, 1)) == 0x5e)
60 pc += 7; /* skip movab */
61 return pc;
62 }
63
64
65 /* Print the Tahoe instruction at address MEMADDR in debugged memory,
66 on STREAM. Returns length of the instruction, in bytes. */
67
68 int
69 tahoe_print_insn (memaddr, stream)
70 CORE_ADDR memaddr;
71 GDB_FILE *stream;
72 {
73 unsigned char buffer[MAXLEN];
74 register int i;
75 register unsigned char *p;
76 register char *d;
77
78 read_memory (memaddr, buffer, MAXLEN);
79
80 for (i = 0; i < NOPCODES; i++)
81 if (votstrs[i].detail.code == buffer[0]
82 || votstrs[i].detail.code == *(unsigned short *)buffer)
83 break;
84
85 /* Handle undefined instructions. */
86 if (i == NOPCODES)
87 {
88 fprintf_unfiltered (stream, "0%o", buffer[0]);
89 return 1;
90 }
91
92 fprintf_unfiltered (stream, "%s", votstrs[i].name);
93
94 /* Point at first byte of argument data,
95 and at descriptor for first argument. */
96 p = buffer + 1 + (votstrs[i].detail.code >= 0x100);
97 d = votstrs[i].detail.args;
98
99 if (*d)
100 fputc_unfiltered ('\t', stream);
101
102 while (*d)
103 {
104 p = print_insn_arg (d, p, memaddr + (p - buffer), stream);
105 d += 2;
106 if (*d)
107 fprintf_unfiltered (stream, ",");
108 }
109 return p - buffer;
110 }
111 /*******************************************************************/
112 static unsigned char *
113 print_insn_arg (d, p, addr, stream)
114 char *d;
115 register char *p;
116 CORE_ADDR addr;
117 GDB_FILE *stream;
118 {
119 int temp1 = 0;
120 register int regnum = *p & 0xf;
121 float floatlitbuf;
122
123 if (*d == 'b')
124 {
125 if (d[1] == 'b')
126 fprintf_unfiltered (stream, "0x%x", addr + *p++ + 1);
127 else
128 {
129
130 temp1 = *p;
131 temp1 <<= 8;
132 temp1 |= *(p + 1);
133 fprintf_unfiltered (stream, "0x%x", addr + temp1 + 2);
134 p += 2;
135 }
136 }
137 else
138 switch ((*p++ >> 4) & 0xf)
139 {
140 case 0:
141 case 1:
142 case 2:
143 case 3: /* Literal (short immediate byte) mode */
144 if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
145 {
146 *(int *)&floatlitbuf = 0x4000 + ((p[-1] & 0x3f) << 4);
147 fprintf_unfiltered (stream, "$%f", floatlitbuf);
148 }
149 else
150 fprintf_unfiltered (stream, "$%d", p[-1] & 0x3f);
151 break;
152
153 case 4: /* Indexed */
154 p = (char *) print_insn_arg (d, p, addr + 1, stream);
155 fprintf_unfiltered (stream, "[%s]", REGISTER_NAME (regnum));
156 break;
157
158 case 5: /* Register */
159 fprintf_unfiltered (stream, REGISTER_NAME (regnum));
160 break;
161
162 case 7: /* Autodecrement */
163 fputc_unfiltered ('-', stream);
164 case 6: /* Register deferred */
165 fprintf_unfiltered (stream, "(%s)", REGISTER_NAME (regnum));
166 break;
167
168 case 9: /* Absolute Address & Autoincrement deferred */
169 fputc_unfiltered ('*', stream);
170 if (regnum == PC_REGNUM)
171 {
172 temp1 = *p;
173 temp1 <<= 8;
174 temp1 |= *(p +1);
175
176 fputc_unfiltered ('$', stream);
177 print_address (temp1, stream);
178 p += 4;
179 break;
180 }
181 case 8: /*Immediate & Autoincrement SP */
182 if (regnum == 8) /*88 is Immediate Byte Mode*/
183 fprintf_unfiltered (stream, "$%d", *p++);
184
185 else if (regnum == 9) /*89 is Immediate Word Mode*/
186 {
187 temp1 = *p;
188 temp1 <<= 8;
189 temp1 |= *(p +1);
190 fprintf_unfiltered (stream, "$%d", temp1);
191 p += 2;
192 }
193
194 else if (regnum == PC_REGNUM) /*8F is Immediate Long Mode*/
195 {
196 temp1 = *p;
197 temp1 <<=8;
198 temp1 |= *(p +1);
199 temp1 <<=8;
200 temp1 |= *(p +2);
201 temp1 <<= 8;
202 temp1 |= *(p +3);
203 fprintf_unfiltered (stream, "$%d", temp1);
204 p += 4;
205 }
206
207 else /*8E is Autoincrement SP Mode*/
208 fprintf_unfiltered (stream, "(%s)+", REGISTER_NAME (regnum));
209 break;
210
211 case 11: /* Register + Byte Displacement Deferred Mode*/
212 fputc_unfiltered ('*', stream);
213 case 10: /* Register + Byte Displacement Mode*/
214 if (regnum == PC_REGNUM)
215 print_address (addr + *p + 2, stream);
216 else
217 fprintf_unfiltered (stream, "%d(%s)", *p, REGISTER_NAME (regnum));
218 p += 1;
219 break;
220
221 case 13: /* Register + Word Displacement Deferred Mode*/
222 fputc_unfiltered ('*', stream);
223 case 12: /* Register + Word Displacement Mode*/
224 temp1 = *p;
225 temp1 <<= 8;
226 temp1 |= *(p +1);
227 if (regnum == PC_REGNUM)
228 print_address (addr + temp1 + 3, stream);
229 else
230 fprintf_unfiltered (stream, "%d(%s)", temp1, REGISTER_NAME (regnum));
231 p += 2;
232 break;
233
234 case 15: /* Register + Long Displacement Deferred Mode*/
235 fputc_unfiltered ('*', stream);
236 case 14: /* Register + Long Displacement Mode*/
237 temp1 = *p;
238 temp1 <<= 8;
239 temp1 |= *(p +1);
240 temp1 <<= 8;
241 temp1 |= *(p +2);
242 temp1 <<= 8;
243 temp1 |= *(p +3);
244 if (regnum == PC_REGNUM)
245 print_address (addr + temp1 + 5, stream);
246 else
247 fprintf_unfiltered (stream, "%d(%s)", temp1, REGISTER_NAME (regnum));
248 p += 4;
249 }
250
251 return (unsigned char *) p;
252 }
253
254
255
256
257
258
259
260
261
262
263
264
265
This page took 0.06825 seconds and 4 git commands to generate.