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