Get overlay testsuite to work on m32r when image is being built with a
[external/binutils.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 \f
37 /* Print the GOULD instruction at address MEMADDR in debugged memory,
38    on STREAM.  Returns length of the instruction, in bytes.  */
39
40 int
41 gould_print_insn (memaddr, stream)
42      CORE_ADDR memaddr;
43      FILE *stream;
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  */
194 findarg(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  */
223 CORE_ADDR
224 findframe(thisframe)
225     struct frame_info *thisframe;
226 {
227     register CORE_ADDR pointer;
228     CORE_ADDR framechain();
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  */
261 CORE_ADDR
262 framechain(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 }