]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/tahoe-tdep.c
import gdb-1999-07-07 post reformat
[thirdparty/binutils-gdb.git] / gdb / tahoe-tdep.c
CommitLineData
c906108c
SS
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
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
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.
c906108c 12
c5aa993b
JM
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.
c906108c 17
c5aa993b
JM
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,
21 Boston, MA 02111-1307, USA. */
c906108c
SS
22
23#include "defs.h"
24#include "symtab.h"
25#include "opcode/tahoe.h"
26
27/* Tahoe instructions are never longer than this. */
28#define MAXLEN 62
29
30/* Number of elements in the opcode table. */
31#define NOPCODES (sizeof votstrs / sizeof votstrs[0])
32
33static unsigned char *print_insn_arg ();
34
b83266a0
SS
35/* Advance PC across any function entry prologue instructions
36 to reach some "real" code. */
37
38CORE_ADDR
39tahoe_skip_prologue (pc)
40 CORE_ADDR pc;
41{
42 register int op = (unsigned char) read_memory_integer (pc, 1);
43 if (op == 0x11)
c5aa993b 44 pc += 2; /* skip brb */
b83266a0 45 if (op == 0x13)
c5aa993b 46 pc += 3; /* skip brw */
b83266a0 47 if (op == 0x2c
c5aa993b
JM
48 && ((unsigned char) read_memory_integer (pc + 2, 1)) == 0x5e)
49 pc += 3; /* skip subl2 */
b83266a0 50 if (op == 0xe9
c5aa993b
JM
51 && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xae
52 && ((unsigned char) read_memory_integer (pc + 3, 1)) == 0x5e)
53 pc += 4; /* skip movab */
b83266a0 54 if (op == 0xe9
c5aa993b
JM
55 && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xce
56 && ((unsigned char) read_memory_integer (pc + 4, 1)) == 0x5e)
57 pc += 5; /* skip movab */
b83266a0 58 if (op == 0xe9
c5aa993b
JM
59 && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xee
60 && ((unsigned char) read_memory_integer (pc + 6, 1)) == 0x5e)
61 pc += 7; /* skip movab */
b83266a0
SS
62 return pc;
63}
64
392a587b
JM
65/* Return number of args passed to a frame.
66 Can return -1, meaning no way to tell. */
67
68int
69tahoe_frame_num_args (fi)
70 struct frame_info *fi;
71{
c5aa993b 72 return (((0xffff & read_memory_integer (((fi)->frame - 4), 4)) - 4) >> 2);
392a587b 73}
b83266a0 74
c906108c
SS
75/* Print the Tahoe instruction at address MEMADDR in debugged memory,
76 on STREAM. Returns length of the instruction, in bytes. */
77
78int
79tahoe_print_insn (memaddr, stream)
80 CORE_ADDR memaddr;
81 GDB_FILE *stream;
82{
83 unsigned char buffer[MAXLEN];
84 register int i;
85 register unsigned char *p;
86 register char *d;
87
88 read_memory (memaddr, buffer, MAXLEN);
89
90 for (i = 0; i < NOPCODES; i++)
91 if (votstrs[i].detail.code == buffer[0]
c5aa993b 92 || votstrs[i].detail.code == *(unsigned short *) buffer)
c906108c
SS
93 break;
94
95 /* Handle undefined instructions. */
96 if (i == NOPCODES)
97 {
98 fprintf_unfiltered (stream, "0%o", buffer[0]);
99 return 1;
100 }
101
102 fprintf_unfiltered (stream, "%s", votstrs[i].name);
103
104 /* Point at first byte of argument data,
105 and at descriptor for first argument. */
106 p = buffer + 1 + (votstrs[i].detail.code >= 0x100);
107 d = votstrs[i].detail.args;
108
109 if (*d)
110 fputc_unfiltered ('\t', stream);
111
112 while (*d)
113 {
114 p = print_insn_arg (d, p, memaddr + (p - buffer), stream);
115 d += 2;
116 if (*d)
117 fprintf_unfiltered (stream, ",");
118 }
119 return p - buffer;
120}
121/*******************************************************************/
122static unsigned char *
123print_insn_arg (d, p, addr, stream)
124 char *d;
125 register char *p;
126 CORE_ADDR addr;
127 GDB_FILE *stream;
128{
129 int temp1 = 0;
130 register int regnum = *p & 0xf;
131 float floatlitbuf;
132
133 if (*d == 'b')
134 {
135 if (d[1] == 'b')
136 fprintf_unfiltered (stream, "0x%x", addr + *p++ + 1);
137 else
138 {
139
140 temp1 = *p;
141 temp1 <<= 8;
142 temp1 |= *(p + 1);
143 fprintf_unfiltered (stream, "0x%x", addr + temp1 + 2);
144 p += 2;
145 }
146 }
147 else
148 switch ((*p++ >> 4) & 0xf)
149 {
150 case 0:
151 case 1:
152 case 2:
153 case 3: /* Literal (short immediate byte) mode */
154 if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
155 {
c5aa993b 156 *(int *) &floatlitbuf = 0x4000 + ((p[-1] & 0x3f) << 4);
c906108c
SS
157 fprintf_unfiltered (stream, "$%f", floatlitbuf);
158 }
159 else
160 fprintf_unfiltered (stream, "$%d", p[-1] & 0x3f);
161 break;
162
163 case 4: /* Indexed */
164 p = (char *) print_insn_arg (d, p, addr + 1, stream);
165 fprintf_unfiltered (stream, "[%s]", REGISTER_NAME (regnum));
166 break;
167
168 case 5: /* Register */
169 fprintf_unfiltered (stream, REGISTER_NAME (regnum));
170 break;
171
172 case 7: /* Autodecrement */
173 fputc_unfiltered ('-', stream);
174 case 6: /* Register deferred */
175 fprintf_unfiltered (stream, "(%s)", REGISTER_NAME (regnum));
176 break;
177
c5aa993b 178 case 9: /* Absolute Address & Autoincrement deferred */
c906108c
SS
179 fputc_unfiltered ('*', stream);
180 if (regnum == PC_REGNUM)
181 {
182 temp1 = *p;
183 temp1 <<= 8;
c5aa993b 184 temp1 |= *(p + 1);
c906108c
SS
185
186 fputc_unfiltered ('$', stream);
187 print_address (temp1, stream);
188 p += 4;
189 break;
190 }
191 case 8: /*Immediate & Autoincrement SP */
c5aa993b 192 if (regnum == 8) /*88 is Immediate Byte Mode */
c906108c
SS
193 fprintf_unfiltered (stream, "$%d", *p++);
194
c5aa993b 195 else if (regnum == 9) /*89 is Immediate Word Mode */
c906108c
SS
196 {
197 temp1 = *p;
c5aa993b
JM
198 temp1 <<= 8;
199 temp1 |= *(p + 1);
c906108c
SS
200 fprintf_unfiltered (stream, "$%d", temp1);
201 p += 2;
c5aa993b 202 }
c906108c 203
c5aa993b 204 else if (regnum == PC_REGNUM) /*8F is Immediate Long Mode */
c906108c
SS
205 {
206 temp1 = *p;
c906108c 207 temp1 <<= 8;
c5aa993b
JM
208 temp1 |= *(p + 1);
209 temp1 <<= 8;
210 temp1 |= *(p + 2);
211 temp1 <<= 8;
212 temp1 |= *(p + 3);
c906108c
SS
213 fprintf_unfiltered (stream, "$%d", temp1);
214 p += 4;
215 }
216
c5aa993b
JM
217 else /*8E is Autoincrement SP Mode */
218 fprintf_unfiltered (stream, "(%s)+", REGISTER_NAME (regnum));
c906108c
SS
219 break;
220
c5aa993b 221 case 11: /* Register + Byte Displacement Deferred Mode */
c906108c 222 fputc_unfiltered ('*', stream);
c5aa993b 223 case 10: /* Register + Byte Displacement Mode */
c906108c
SS
224 if (regnum == PC_REGNUM)
225 print_address (addr + *p + 2, stream);
226 else
227 fprintf_unfiltered (stream, "%d(%s)", *p, REGISTER_NAME (regnum));
228 p += 1;
229 break;
230
c5aa993b 231 case 13: /* Register + Word Displacement Deferred Mode */
c906108c 232 fputc_unfiltered ('*', stream);
c5aa993b 233 case 12: /* Register + Word Displacement Mode */
c906108c
SS
234 temp1 = *p;
235 temp1 <<= 8;
c5aa993b 236 temp1 |= *(p + 1);
c906108c
SS
237 if (regnum == PC_REGNUM)
238 print_address (addr + temp1 + 3, stream);
239 else
240 fprintf_unfiltered (stream, "%d(%s)", temp1, REGISTER_NAME (regnum));
241 p += 2;
242 break;
243
c5aa993b 244 case 15: /* Register + Long Displacement Deferred Mode */
c906108c 245 fputc_unfiltered ('*', stream);
c5aa993b 246 case 14: /* Register + Long Displacement Mode */
c906108c
SS
247 temp1 = *p;
248 temp1 <<= 8;
c5aa993b 249 temp1 |= *(p + 1);
c906108c 250 temp1 <<= 8;
c5aa993b 251 temp1 |= *(p + 2);
c906108c 252 temp1 <<= 8;
c5aa993b 253 temp1 |= *(p + 3);
c906108c
SS
254 if (regnum == PC_REGNUM)
255 print_address (addr + temp1 + 5, stream);
256 else
257 fprintf_unfiltered (stream, "%d(%s)", temp1, REGISTER_NAME (regnum));
258 p += 4;
259 }
260
261 return (unsigned char *) p;
262}