* aout64.h (BMAGIC): Define.
[deliverable/binutils-gdb.git] / gdb / ns32k-pinsn.c
1 /* Print National Semiconductor 32000 instructions for GDB, the GNU debugger.
2 Copyright 1986, 1988, 1991, 1992 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 "defs.h"
21 #include "symtab.h"
22 #include "ns32k-opcode.h"
23 #include "gdbcore.h"
24
25 /* 32000 instructions are never longer than this. */
26 #define MAXLEN 62
27
28 /* Number of elements in the opcode table. */
29 #define NOPCODES (sizeof notstrs / sizeof notstrs[0])
30
31 #define NEXT_IS_ADDR '|'
32
33 /*
34 * extract "count" bits starting "offset" bits
35 * into buffer
36 */
37
38 int
39 bit_extract (buffer, offset, count)
40 char *buffer;
41 int offset;
42 int count;
43 {
44 int result;
45 int mask;
46 int bit;
47
48 buffer += offset >> 3;
49 offset &= 7;
50 bit = 1;
51 result = 0;
52 while (count--)
53 {
54 if ((*buffer & (1 << offset)))
55 result |= bit;
56 if (++offset == 8)
57 {
58 offset = 0;
59 buffer++;
60 }
61 bit <<= 1;
62 }
63 return result;
64 }
65
66 float
67 fbit_extract (buffer, offset, count)
68 {
69 union {
70 int ival;
71 float fval;
72 } foo;
73
74 foo.ival = bit_extract (buffer, offset, 32);
75 return foo.fval;
76 }
77
78 double
79 dbit_extract (buffer, offset, count)
80 {
81 union {
82 struct {int low, high; } ival;
83 double dval;
84 } foo;
85
86 foo.ival.low = bit_extract (buffer, offset, 32);
87 foo.ival.high = bit_extract (buffer, offset+32, 32);
88 return foo.dval;
89 }
90
91 sign_extend (value, bits)
92 {
93 value = value & ((1 << bits) - 1);
94 return (value & (1 << (bits-1))
95 ? value | (~((1 << bits) - 1))
96 : value);
97 }
98
99 flip_bytes (ptr, count)
100 char *ptr;
101 int count;
102 {
103 char tmp;
104
105 while (count > 0)
106 {
107 tmp = *ptr;
108 ptr[0] = ptr[count-1];
109 ptr[count-1] = tmp;
110 ptr++;
111 count -= 2;
112 }
113 }
114 \f
115 /* Given a character C, does it represent a general addressing mode? */
116 #define Is_gen(c) \
117 ((c) == 'F' || (c) == 'L' || (c) == 'B' \
118 || (c) == 'W' || (c) == 'D' || (c) == 'A')
119
120 /* Adressing modes. */
121 #define Adrmod_index_byte 0x1c
122 #define Adrmod_index_word 0x1d
123 #define Adrmod_index_doubleword 0x1e
124 #define Adrmod_index_quadword 0x1f
125
126 /* Is MODE an indexed addressing mode? */
127 #define Adrmod_is_index(mode) \
128 (mode == Adrmod_index_byte \
129 || mode == Adrmod_index_word \
130 || mode == Adrmod_index_doubleword \
131 || mode == Adrmod_index_quadword)
132
133 \f
134 /* Print the 32000 instruction at address MEMADDR in debugged memory,
135 on STREAM. Returns length of the instruction, in bytes. */
136
137 int
138 print_insn (memaddr, stream)
139 CORE_ADDR memaddr;
140 FILE *stream;
141 {
142 unsigned char buffer[MAXLEN];
143 register int i;
144 register unsigned char *p;
145 register char *d;
146 unsigned short first_word;
147 int gen, disp;
148 int ioffset; /* bits into instruction */
149 int aoffset; /* bits into arguments */
150 char arg_bufs[MAX_ARGS+1][ARG_LEN];
151 int argnum;
152 int maxarg;
153
154 read_memory (memaddr, buffer, MAXLEN);
155
156 first_word = *(unsigned short *) buffer;
157 for (i = 0; i < NOPCODES; i++)
158 if ((first_word & ((1 << notstrs[i].detail.obits) - 1))
159 == notstrs[i].detail.code)
160 break;
161
162 /* Handle undefined instructions. */
163 if (i == NOPCODES)
164 {
165 fprintf (stream, "0%o", buffer[0]);
166 return 1;
167 }
168
169 fprintf (stream, "%s", notstrs[i].name);
170
171 ioffset = notstrs[i].detail.ibits;
172 aoffset = notstrs[i].detail.ibits;
173 d = notstrs[i].detail.args;
174
175 if (*d)
176 {
177 /* Offset in bits of the first thing beyond each index byte.
178 Element 0 is for operand A and element 1 is for operand B.
179 The rest are irrelevant, but we put them here so we don't
180 index outside the array. */
181 int index_offset[MAX_ARGS];
182
183 /* 0 for operand A, 1 for operand B, greater for other args. */
184 int whicharg = 0;
185
186 fputc ('\t', stream);
187
188 maxarg = 0;
189
190 /* First we have to find and keep track of the index bytes,
191 if we are using scaled indexed addressing mode, since the index
192 bytes occur right after the basic instruction, not as part
193 of the addressing extension. */
194 if (Is_gen(d[1]))
195 {
196 int addr_mode = bit_extract (buffer, ioffset - 5, 5);
197
198 if (Adrmod_is_index (addr_mode))
199 {
200 aoffset += 8;
201 index_offset[0] = aoffset;
202 }
203 }
204 if (d[2] && Is_gen(d[3]))
205 {
206 int addr_mode = bit_extract (buffer, ioffset - 10, 5);
207
208 if (Adrmod_is_index (addr_mode))
209 {
210 aoffset += 8;
211 index_offset[1] = aoffset;
212 }
213 }
214
215 while (*d)
216 {
217 argnum = *d - '1';
218 d++;
219 if (argnum > maxarg && argnum < MAX_ARGS)
220 maxarg = argnum;
221 ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
222 memaddr, arg_bufs[argnum],
223 index_offset[whicharg]);
224 d++;
225 whicharg++;
226 }
227 for (argnum = 0; argnum <= maxarg; argnum++)
228 {
229 CORE_ADDR addr;
230 char *ch;
231 for (ch = arg_bufs[argnum]; *ch;)
232 {
233 if (*ch == NEXT_IS_ADDR)
234 {
235 ++ch;
236 addr = atoi (ch);
237 print_address (addr, stream);
238 while (*ch && *ch != NEXT_IS_ADDR)
239 ++ch;
240 if (*ch)
241 ++ch;
242 }
243 else
244 putc (*ch++, stream);
245 }
246 if (argnum < maxarg)
247 fprintf (stream, ", ");
248 }
249 }
250 return aoffset / 8;
251 }
252
253 /* Print an instruction operand of category given by d. IOFFSET is
254 the bit position below which small (<1 byte) parts of the operand can
255 be found (usually in the basic instruction, but for indexed
256 addressing it can be in the index byte). AOFFSETP is a pointer to the
257 bit position of the addressing extension. BUFFER contains the
258 instruction. ADDR is where BUFFER was read from. Put the disassembled
259 version of the operand in RESULT. INDEX_OFFSET is the bit position
260 of the index byte (it contains garbage if this operand is not a
261 general operand using scaled indexed addressing mode). */
262
263 print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset)
264 char d;
265 int ioffset, *aoffsetp;
266 char *buffer;
267 CORE_ADDR addr;
268 char *result;
269 int index_offset;
270 {
271 int addr_mode;
272 float Fvalue;
273 double Lvalue;
274 int Ivalue;
275 int disp1, disp2;
276 int index;
277
278 switch (d)
279 {
280 case 'F':
281 case 'L':
282 case 'B':
283 case 'W':
284 case 'D':
285 case 'A':
286 addr_mode = bit_extract (buffer, ioffset-5, 5);
287 ioffset -= 5;
288 switch (addr_mode)
289 {
290 case 0x0: case 0x1: case 0x2: case 0x3:
291 case 0x4: case 0x5: case 0x6: case 0x7:
292 switch (d)
293 {
294 case 'F':
295 case 'L':
296 sprintf (result, "f%d", addr_mode);
297 break;
298 default:
299 sprintf (result, "r%d", addr_mode);
300 }
301 break;
302 case 0x8: case 0x9: case 0xa: case 0xb:
303 case 0xc: case 0xd: case 0xe: case 0xf:
304 disp1 = get_displacement (buffer, aoffsetp);
305 sprintf (result, "%d(r%d)", disp1, addr_mode & 7);
306 break;
307 case 0x10:
308 case 0x11:
309 case 0x12:
310 disp1 = get_displacement (buffer, aoffsetp);
311 disp2 = get_displacement (buffer, aoffsetp);
312 sprintf (result, "%d(%d(%s))", disp2, disp1,
313 addr_mode==0x10?"fp":addr_mode==0x11?"sp":"sb");
314 break;
315 case 0x13:
316 sprintf (result, "reserved");
317 break;
318 case 0x14:
319 switch (d)
320 {
321 case 'B':
322 Ivalue = bit_extract (buffer, *aoffsetp, 8);
323 Ivalue = sign_extend (Ivalue, 8);
324 *aoffsetp += 8;
325 sprintf (result, "$%d", Ivalue);
326 break;
327 case 'W':
328 Ivalue = bit_extract (buffer, *aoffsetp, 16);
329 flip_bytes (&Ivalue, 2);
330 *aoffsetp += 16;
331 Ivalue = sign_extend (Ivalue, 16);
332 sprintf (result, "$%d", Ivalue);
333 break;
334 case 'D':
335 Ivalue = bit_extract (buffer, *aoffsetp, 32);
336 flip_bytes (&Ivalue, 4);
337 *aoffsetp += 32;
338 sprintf (result, "$%d", Ivalue);
339 break;
340 case 'A':
341 Ivalue = bit_extract (buffer, *aoffsetp, 32);
342 flip_bytes (&Ivalue, 4);
343 *aoffsetp += 32;
344 sprintf (result, "$|%d|", Ivalue);
345 break;
346 case 'F':
347 Fvalue = fbit_extract (buffer, *aoffsetp, 32);
348 flip_bytes (&Fvalue, 4);
349 *aoffsetp += 32;
350 sprintf (result, "$%g", Fvalue);
351 break;
352 case 'L':
353 Lvalue = dbit_extract (buffer, *aoffsetp, 64);
354 flip_bytes (&Lvalue, 8);
355 *aoffsetp += 64;
356 sprintf (result, "$%g", Lvalue);
357 break;
358 }
359 break;
360 case 0x15:
361 disp1 = get_displacement (buffer, aoffsetp);
362 sprintf (result, "@|%d|", disp1);
363 break;
364 case 0x16:
365 disp1 = get_displacement (buffer, aoffsetp);
366 disp2 = get_displacement (buffer, aoffsetp);
367 sprintf (result, "EXT(%d) + %d", disp1, disp2);
368 break;
369 case 0x17:
370 sprintf (result, "tos");
371 break;
372 case 0x18:
373 disp1 = get_displacement (buffer, aoffsetp);
374 sprintf (result, "%d(fp)", disp1);
375 break;
376 case 0x19:
377 disp1 = get_displacement (buffer, aoffsetp);
378 sprintf (result, "%d(sp)", disp1);
379 break;
380 case 0x1a:
381 disp1 = get_displacement (buffer, aoffsetp);
382 sprintf (result, "%d(sb)", disp1);
383 break;
384 case 0x1b:
385 disp1 = get_displacement (buffer, aoffsetp);
386 sprintf (result, "|%d|", addr + disp1);
387 break;
388 case 0x1c:
389 case 0x1d:
390 case 0x1e:
391 case 0x1f:
392 index = bit_extract (buffer, index_offset - 8, 3);
393 print_insn_arg (d, index_offset, aoffsetp, buffer, addr,
394 result, 0);
395 {
396 static char *ind[] = {"b", "w", "d", "q"};
397 char *off;
398
399 off = result + strlen (result);
400 sprintf (off, "[r%d:%s]", index,
401 ind[addr_mode & 3]);
402 }
403 break;
404 }
405 break;
406 case 'q':
407 Ivalue = bit_extract (buffer, ioffset-4, 4);
408 Ivalue = sign_extend (Ivalue, 4);
409 sprintf (result, "%d", Ivalue);
410 ioffset -= 4;
411 break;
412 case 'r':
413 Ivalue = bit_extract (buffer, ioffset-3, 3);
414 sprintf (result, "r%d", Ivalue&7);
415 ioffset -= 3;
416 break;
417 case 'd':
418 sprintf (result, "%d", get_displacement (buffer, aoffsetp));
419 break;
420 case 'p':
421 sprintf (result, "%c%d%c", NEXT_IS_ADDR,
422 addr + get_displacement (buffer, aoffsetp),
423 NEXT_IS_ADDR);
424 break;
425 case 'i':
426 Ivalue = bit_extract (buffer, *aoffsetp, 8);
427 *aoffsetp += 8;
428 sprintf (result, "0x%x", Ivalue);
429 break;
430 }
431 return ioffset;
432 }
433
434 get_displacement (buffer, aoffsetp)
435 char *buffer;
436 int *aoffsetp;
437 {
438 int Ivalue;
439
440 Ivalue = bit_extract (buffer, *aoffsetp, 8);
441 switch (Ivalue & 0xc0)
442 {
443 case 0x00:
444 case 0x40:
445 Ivalue = sign_extend (Ivalue, 7);
446 *aoffsetp += 8;
447 break;
448 case 0x80:
449 Ivalue = bit_extract (buffer, *aoffsetp, 16);
450 flip_bytes (&Ivalue, 2);
451 Ivalue = sign_extend (Ivalue, 14);
452 *aoffsetp += 16;
453 break;
454 case 0xc0:
455 Ivalue = bit_extract (buffer, *aoffsetp, 32);
456 flip_bytes (&Ivalue, 4);
457 Ivalue = sign_extend (Ivalue, 30);
458 *aoffsetp += 32;
459 break;
460 }
461 return Ivalue;
462 }
463 \f
464 /* Return the number of locals in the current frame given a pc
465 pointing to the enter instruction. This is used in the macro
466 FRAME_FIND_SAVED_REGS. */
467
468 ns32k_localcount (enter_pc)
469 CORE_ADDR enter_pc;
470 {
471 unsigned char localtype;
472 int localcount;
473
474 localtype = read_memory_integer (enter_pc+2, 1);
475 if ((localtype & 0x80) == 0)
476 localcount = localtype;
477 else if ((localtype & 0xc0) == 0x80)
478 localcount = (((localtype & 0x3f) << 8)
479 | (read_memory_integer (enter_pc+3, 1) & 0xff));
480 else
481 localcount = (((localtype & 0x3f) << 24)
482 | ((read_memory_integer (enter_pc+3, 1) & 0xff) << 16)
483 | ((read_memory_integer (enter_pc+4, 1) & 0xff) << 8 )
484 | (read_memory_integer (enter_pc+5, 1) & 0xff));
485 return localcount;
486 }
487
488 /*
489 * Get the address of the enter opcode for the function
490 * containing PC, if there is an enter for the function,
491 * and if the pc is between the enter and exit.
492 * Returns positive address if pc is between enter/exit,
493 * 1 if pc before enter or after exit, 0 otherwise.
494 */
495
496 CORE_ADDR
497 ns32k_get_enter_addr (pc)
498 CORE_ADDR pc;
499 {
500 CORE_ADDR enter_addr;
501 unsigned char op;
502
503 if (ABOUT_TO_RETURN (pc))
504 return 1; /* after exit */
505
506 enter_addr = get_pc_function_start (pc);
507
508 if (pc == enter_addr)
509 return 1; /* before enter */
510
511 op = read_memory_integer (enter_addr, 1);
512
513 if (op != 0x82)
514 return 0; /* function has no enter/exit */
515
516 return enter_addr; /* pc is between enter and exit */
517 }
This page took 0.060685 seconds and 4 git commands to generate.