* A few more improvements to gx jit prototype.
[deliverable/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
b6960094
AC
36int
37gould_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
98760eab
AC
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). */
46int
47gould_use_struct_convention (gcc_p, type)
48 int gcc_p;
49 struct type *type;
50{
51 return (TYPE_LENGTH(type) > 8);
52}
53
54
dd3b648e
RP
55\f
56/* Print the GOULD instruction at address MEMADDR in debugged memory,
57 on STREAM. Returns length of the instruction, in bytes. */
58
59int
18b46e7c
SS
60gould_print_insn (memaddr, stream)
61 CORE_ADDR memaddr;
62 FILE *stream;
dd3b648e
RP
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 */
213findarg(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 */
1dfc8dfb 242CORE_ADDR
dd3b648e 243findframe(thisframe)
1dfc8dfb 244 struct frame_info *thisframe;
dd3b648e 245{
1dfc8dfb
SS
246 register CORE_ADDR pointer;
247 CORE_ADDR framechain();
dd3b648e
RP
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 */
1dfc8dfb 280CORE_ADDR
dd3b648e
RP
281framechain(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.323462 seconds and 4 git commands to generate.