i960 cgen simulator support.
[platform/upstream/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 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 }