]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/gould-tdep.c
Update FSF address.
[thirdparty/binutils-gdb.git] / gdb / gould-tdep.c
CommitLineData
18b46e7c 1/* GOULD RISC target-dependent code for GDB, the GNU debugger.
7d9884b9 2 Copyright 1986, 1987, 1989, 1991 Free Software Foundation, Inc.
dd3b648e
RP
3
4This file is part of GDB.
5
99a7de40 6This program is free software; you can redistribute it and/or modify
dd3b648e 7it under the terms of the GNU General Public License as published by
99a7de40
JG
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
dd3b648e 10
99a7de40 11This program is distributed in the hope that it will be useful,
dd3b648e
RP
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
99a7de40 17along with this program; if not, write to the Free Software
6c9638b4 18Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
dd3b648e 19
dd3b648e 20#include "defs.h"
dd3b648e
RP
21#include "symtab.h"
22#include "frame.h"
7d9884b9 23#include "gdbcore.h"
dd3b648e 24#if defined GOULD_PN
aab77d5f 25#include "opcode/pn.h"
dd3b648e 26#else
aab77d5f 27#include "opcode/np1.h"
dd3b648e
RP
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\f
37/* Print the GOULD instruction at address MEMADDR in debugged memory,
38 on STREAM. Returns length of the instruction, in bytes. */
39
40int
18b46e7c
SS
41gould_print_insn (memaddr, stream)
42 CORE_ADDR memaddr;
43 FILE *stream;
dd3b648e
RP
44{
45 unsigned char buffer[MAXLEN];
46 register int i;
47 register char *d;
48 register int bestmask;
49 unsigned best;
50 int temp, index, bestlen;
51
52 read_memory (memaddr, buffer, MAXLEN);
53
54 bestmask = 0;
55 index = -1;
56 best = 0xffffffff;
57 for (i = 0; i < NOPCODES; i++)
58 {
59 register unsigned int opcode = gld_opcodes[i].opcode;
60 register unsigned int mask = gld_opcodes[i].mask;
61 register unsigned int len = gld_opcodes[i].length;
62 register unsigned int test;
63
64 /* Get possible opcode bytes into integer */
65 test = buffer[0] << 24;
66 test |= buffer[1] << 16;
67 test |= buffer[2] << 8;
68 test |= buffer[3];
69
70 /* Mask with opcode and see if match */
71 if ((opcode & mask) == (test & mask))
72 {
73 /* See if second or third match */
74 if (index >= 0)
75 {
76 /* Take new one if it looks good */
77 if (bestlen == MAXLEN && len == MAXLEN)
78 {
79 /* See if lower bits matched */
80 if (((bestmask & 3) == 0) &&
81 ((mask & 3) != 0))
82 {
83 bestmask = mask;
84 bestlen = len;
85 best = test;
86 index = i;
87 }
88 }
89 }
90 else
91 {
92 /* First match, save it */
93 bestmask = mask;
94 bestlen = len;
95 best = test;
96 index = i;
97 }
98 }
99 }
100
101 /* Handle undefined instructions. */
102 if (index < 0)
103 {
104 fprintf (stream, "undefined 0%o",(buffer[0]<<8)+buffer[1]);
105 return 2;
106 }
107
108 /* Print instruction name */
109 fprintf (stream, "%-12s", gld_opcodes[index].name);
110
111 /* Adjust if short instruction */
112 if (gld_opcodes[index].length < 4)
113 {
114 best >>= 16;
115 i = 0;
116 }
117 else
118 {
119 i = 16;
120 }
121
122 /* Dump out instruction arguments */
123 for (d = gld_opcodes[index].args; *d; ++d)
124 {
125 switch (*d)
126 {
127 case 'f':
128 fprintf (stream, "%d", (best >> (7 + i)) & 7);
129 break;
130 case 'r':
131 fprintf (stream, "r%d", (best >> (7 + i)) & 7);
132 break;
133 case 'R':
134 fprintf (stream, "r%d", (best >> (4 + i)) & 7);
135 break;
136 case 'b':
137 fprintf (stream, "b%d", (best >> (7 + i)) & 7);
138 break;
139 case 'B':
140 fprintf (stream, "b%d", (best >> (4 + i)) & 7);
141 break;
142 case 'v':
143 fprintf (stream, "b%d", (best >> (7 + i)) & 7);
144 break;
145 case 'V':
146 fprintf (stream, "b%d", (best >> (4 + i)) & 7);
147 break;
148 case 'X':
149 temp = (best >> 20) & 7;
150 if (temp)
151 fprintf (stream, "r%d", temp);
152 else
153 putc ('0', stream);
154 break;
155 case 'A':
156 temp = (best >> 16) & 7;
157 if (temp)
158 fprintf (stream, "(b%d)", temp);
159 break;
160 case 'S':
161 fprintf (stream, "#%d", best & 0x1f);
162 break;
163 case 'I':
164 fprintf (stream, "#%x", best & 0xffff);
165 break;
166 case 'O':
167 fprintf (stream, "%x", best & 0xffff);
168 break;
169 case 'h':
170 fprintf (stream, "%d", best & 0xfffe);
171 break;
172 case 'd':
173 fprintf (stream, "%d", best & 0xfffc);
174 break;
175 case 'T':
176 fprintf (stream, "%d", (best >> 8) & 0xff);
177 break;
178 case 'N':
179 fprintf (stream, "%d", best & 0xff);
180 break;
181 default:
182 putc (*d, stream);
183 break;
184 }
185 }
186
187 /* Return length of instruction */
188 return (gld_opcodes[index].length);
189}
190
191/*
192 * Find the number of arguments to a function.
193 */
194findarg(frame)
195 struct frame_info *frame;
196{
197 register struct symbol *func;
198 register unsigned pc;
199
200#ifdef notdef
201 /* find starting address of frame function */
202 pc = get_pc_function_start (frame->pc);
203
204 /* find function symbol info */
205 func = find_pc_function (pc);
206
207 /* call blockframe code to look for match */
208 if (func != NULL)
209 return (func->value.block->nsyms / sizeof(int));
210#endif
211
212 return (-1);
213}
214
215/*
216 * In the case of the NPL, the frame's norminal address is Br2 and the
217 * previous routines frame is up the stack X bytes. Finding out what
218 * 'X' is can be tricky.
219 *
220 * 1.) stored in the code function header xA(Br1).
221 * 2.) must be careful of recurssion.
222 */
1dfc8dfb 223CORE_ADDR
dd3b648e 224findframe(thisframe)
1dfc8dfb 225 struct frame_info *thisframe;
dd3b648e 226{
1dfc8dfb
SS
227 register CORE_ADDR pointer;
228 CORE_ADDR framechain();
dd3b648e
RP
229#if 0
230 struct frame_info *frame;
231
232 /* Setup toplevel frame structure */
233 frame->pc = read_pc();
234 frame->next_frame = 0;
235 frame->frame = read_register (SP_REGNUM); /* Br2 */
236
237 /* Search for this frame (start at current Br2) */
238 do
239 {
240 pointer = framechain(frame);
241 frame->next_frame = frame->frame;
242 frame->frame = pointer;
243 frame->pc = FRAME_SAVED_PC(frame);
244 }
245 while (frame->next_frame != thisframe);
246#endif
247
248 pointer = framechain (thisframe);
249
250 /* stop gap for now, end at __base3 */
251 if (thisframe->pc == 0)
252 return 0;
253
254 return pointer;
255}
256
257/*
258 * Gdb front-end and internal framechain routine.
259 * Go back up stack one level. Tricky...
260 */
1dfc8dfb 261CORE_ADDR
dd3b648e
RP
262framechain(frame)
263 register struct frame_info *frame;
264{
265 register CORE_ADDR func, prevsp;
266 register unsigned value;
267
268 /* Get real function start address from internal frame address */
269 func = get_pc_function_start(frame->pc);
270
271 /* If no stack given, read register Br1 "(sp)" */
272 if (!frame->frame)
273 prevsp = read_register (SP_REGNUM);
274 else
275 prevsp = frame->frame;
276
277 /* Check function header, case #2 */
278 value = read_memory_integer (func, 4);
279 if (value)
280 {
281 /* 32bit call push value stored in function header */
282 prevsp += value;
283 }
284 else
285 {
286 /* read half-word from suabr at start of function */
287 prevsp += read_memory_integer (func + 10, 2);
288 }
289
290 return (prevsp);
291}