1999-01-19 Fernando Nasser <fnasser@totem.to.cygnus.com>
[deliverable/binutils-gdb.git] / gdb / gould-tdep.c
1 /* GOULD RISC target-dependent code for GDB, the GNU debugger.
2 Copyright 1986, 1987, 1989, 1991 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20 #include "defs.h"
21 #include "symtab.h"
22 #include "frame.h"
23 #include "gdbcore.h"
24 #if defined GOULD_PN
25 #include "opcode/pn.h"
26 #else
27 #include "opcode/np1.h"
28 #endif
29
30 /* GOULD RISC instructions are never longer than this many bytes. */
31 #define MAXLEN 4
32
33 /* Number of elements in the opcode table. */
34 #define NOPCODES (sizeof gld_opcodes / sizeof gld_opcodes[0])
35
36 int
37 gould_frame_chain_valid (chain, fi)
38 CORE_ADDR chain;
39 struct frame_info *fi; /* not used here */
40 {
41 return (chain != 0 && chain != (thisframe)->frame);
42 }
43
44 /* Both gcc and cc return small structs in registers (i.e. in GDB
45 terminology, small structs don't use the struct return convention). */
46 int
47 gould_use_struct_convention (gcc_p, type)
48 int gcc_p;
49 struct type *type;
50 {
51 return (TYPE_LENGTH(type) > 8);
52 }
53
54
55 \f
56 /* Print the GOULD instruction at address MEMADDR in debugged memory,
57 on STREAM. Returns length of the instruction, in bytes. */
58
59 int
60 gould_print_insn (memaddr, stream)
61 CORE_ADDR memaddr;
62 FILE *stream;
63 {
64 unsigned char buffer[MAXLEN];
65 register int i;
66 register char *d;
67 register int bestmask;
68 unsigned best;
69 int temp, index, bestlen;
70
71 read_memory (memaddr, buffer, MAXLEN);
72
73 bestmask = 0;
74 index = -1;
75 best = 0xffffffff;
76 for (i = 0; i < NOPCODES; i++)
77 {
78 register unsigned int opcode = gld_opcodes[i].opcode;
79 register unsigned int mask = gld_opcodes[i].mask;
80 register unsigned int len = gld_opcodes[i].length;
81 register unsigned int test;
82
83 /* Get possible opcode bytes into integer */
84 test = buffer[0] << 24;
85 test |= buffer[1] << 16;
86 test |= buffer[2] << 8;
87 test |= buffer[3];
88
89 /* Mask with opcode and see if match */
90 if ((opcode & mask) == (test & mask))
91 {
92 /* See if second or third match */
93 if (index >= 0)
94 {
95 /* Take new one if it looks good */
96 if (bestlen == MAXLEN && len == MAXLEN)
97 {
98 /* See if lower bits matched */
99 if (((bestmask & 3) == 0) &&
100 ((mask & 3) != 0))
101 {
102 bestmask = mask;
103 bestlen = len;
104 best = test;
105 index = i;
106 }
107 }
108 }
109 else
110 {
111 /* First match, save it */
112 bestmask = mask;
113 bestlen = len;
114 best = test;
115 index = i;
116 }
117 }
118 }
119
120 /* Handle undefined instructions. */
121 if (index < 0)
122 {
123 fprintf (stream, "undefined 0%o",(buffer[0]<<8)+buffer[1]);
124 return 2;
125 }
126
127 /* Print instruction name */
128 fprintf (stream, "%-12s", gld_opcodes[index].name);
129
130 /* Adjust if short instruction */
131 if (gld_opcodes[index].length < 4)
132 {
133 best >>= 16;
134 i = 0;
135 }
136 else
137 {
138 i = 16;
139 }
140
141 /* Dump out instruction arguments */
142 for (d = gld_opcodes[index].args; *d; ++d)
143 {
144 switch (*d)
145 {
146 case 'f':
147 fprintf (stream, "%d", (best >> (7 + i)) & 7);
148 break;
149 case 'r':
150 fprintf (stream, "r%d", (best >> (7 + i)) & 7);
151 break;
152 case 'R':
153 fprintf (stream, "r%d", (best >> (4 + i)) & 7);
154 break;
155 case 'b':
156 fprintf (stream, "b%d", (best >> (7 + i)) & 7);
157 break;
158 case 'B':
159 fprintf (stream, "b%d", (best >> (4 + i)) & 7);
160 break;
161 case 'v':
162 fprintf (stream, "b%d", (best >> (7 + i)) & 7);
163 break;
164 case 'V':
165 fprintf (stream, "b%d", (best >> (4 + i)) & 7);
166 break;
167 case 'X':
168 temp = (best >> 20) & 7;
169 if (temp)
170 fprintf (stream, "r%d", temp);
171 else
172 putc ('0', stream);
173 break;
174 case 'A':
175 temp = (best >> 16) & 7;
176 if (temp)
177 fprintf (stream, "(b%d)", temp);
178 break;
179 case 'S':
180 fprintf (stream, "#%d", best & 0x1f);
181 break;
182 case 'I':
183 fprintf (stream, "#%x", best & 0xffff);
184 break;
185 case 'O':
186 fprintf (stream, "%x", best & 0xffff);
187 break;
188 case 'h':
189 fprintf (stream, "%d", best & 0xfffe);
190 break;
191 case 'd':
192 fprintf (stream, "%d", best & 0xfffc);
193 break;
194 case 'T':
195 fprintf (stream, "%d", (best >> 8) & 0xff);
196 break;
197 case 'N':
198 fprintf (stream, "%d", best & 0xff);
199 break;
200 default:
201 putc (*d, stream);
202 break;
203 }
204 }
205
206 /* Return length of instruction */
207 return (gld_opcodes[index].length);
208 }
209
210 /*
211 * Find the number of arguments to a function.
212 */
213 findarg(frame)
214 struct frame_info *frame;
215 {
216 register struct symbol *func;
217 register unsigned pc;
218
219 #ifdef notdef
220 /* find starting address of frame function */
221 pc = get_pc_function_start (frame->pc);
222
223 /* find function symbol info */
224 func = find_pc_function (pc);
225
226 /* call blockframe code to look for match */
227 if (func != NULL)
228 return (func->value.block->nsyms / sizeof(int));
229 #endif
230
231 return (-1);
232 }
233
234 /*
235 * In the case of the NPL, the frame's norminal address is Br2 and the
236 * previous routines frame is up the stack X bytes. Finding out what
237 * 'X' is can be tricky.
238 *
239 * 1.) stored in the code function header xA(Br1).
240 * 2.) must be careful of recurssion.
241 */
242 CORE_ADDR
243 findframe(thisframe)
244 struct frame_info *thisframe;
245 {
246 register CORE_ADDR pointer;
247 CORE_ADDR framechain();
248 #if 0
249 struct frame_info *frame;
250
251 /* Setup toplevel frame structure */
252 frame->pc = read_pc();
253 frame->next_frame = 0;
254 frame->frame = read_register (SP_REGNUM); /* Br2 */
255
256 /* Search for this frame (start at current Br2) */
257 do
258 {
259 pointer = framechain(frame);
260 frame->next_frame = frame->frame;
261 frame->frame = pointer;
262 frame->pc = FRAME_SAVED_PC(frame);
263 }
264 while (frame->next_frame != thisframe);
265 #endif
266
267 pointer = framechain (thisframe);
268
269 /* stop gap for now, end at __base3 */
270 if (thisframe->pc == 0)
271 return 0;
272
273 return pointer;
274 }
275
276 /*
277 * Gdb front-end and internal framechain routine.
278 * Go back up stack one level. Tricky...
279 */
280 CORE_ADDR
281 framechain(frame)
282 register struct frame_info *frame;
283 {
284 register CORE_ADDR func, prevsp;
285 register unsigned value;
286
287 /* Get real function start address from internal frame address */
288 func = get_pc_function_start(frame->pc);
289
290 /* If no stack given, read register Br1 "(sp)" */
291 if (!frame->frame)
292 prevsp = read_register (SP_REGNUM);
293 else
294 prevsp = frame->frame;
295
296 /* Check function header, case #2 */
297 value = read_memory_integer (func, 4);
298 if (value)
299 {
300 /* 32bit call push value stored in function header */
301 prevsp += value;
302 }
303 else
304 {
305 /* read half-word from suabr at start of function */
306 prevsp += read_memory_integer (func + 10, 2);
307 }
308
309 return (prevsp);
310 }
This page took 0.035343 seconds and 4 git commands to generate.