1 /* Print 32000 instructions for GDB, the GNU debugger.
2 Copyright (C) 1986,1988 Free Software Foundation, Inc.
4 This file is part of GDB.
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.
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.
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. */
25 #include "ns32k-opcode.h"
28 /* 32000 instructions are never longer than this. */
31 /* Number of elements in the opcode table. */
32 #define NOPCODES (sizeof notstrs / sizeof notstrs[0])
34 extern char *reg_names
[];
36 #define NEXT_IS_ADDR '|'
39 * extract "count" bits starting "offset" bits
44 bit_extract (buffer
, offset
, count
)
53 buffer
+= offset
>> 3;
59 if ((*buffer
& (1 << offset
)))
72 fbit_extract (buffer
, offset
, count
)
79 foo
.ival
= bit_extract (buffer
, offset
, 32);
84 dbit_extract (buffer
, offset
, count
)
87 struct {int low
, high
; } ival
;
91 foo
.ival
.low
= bit_extract (buffer
, offset
, 32);
92 foo
.ival
.high
= bit_extract (buffer
, offset
+32, 32);
96 sign_extend (value
, bits
)
98 value
= value
& ((1 << bits
) - 1);
99 return (value
& (1 << (bits
-1))
100 ? value
| (~((1 << bits
) - 1))
104 flip_bytes (ptr
, count
)
113 ptr
[0] = ptr
[count
-1];
120 /* Given a character C, does it represent a general addressing mode? */
122 ((c) == 'F' || (c) == 'L' || (c) == 'B' \
123 || (c) == 'W' || (c) == 'D' || (c) == 'A')
125 /* Adressing modes. */
126 #define Adrmod_index_byte 0x1c
127 #define Adrmod_index_word 0x1d
128 #define Adrmod_index_doubleword 0x1e
129 #define Adrmod_index_quadword 0x1f
131 /* Is MODE an indexed addressing mode? */
132 #define Adrmod_is_index(mode) \
133 (mode == Adrmod_index_byte \
134 || mode == Adrmod_index_word \
135 || mode == Adrmod_index_doubleword \
136 || mode == Adrmod_index_quadword)
139 /* Print the 32000 instruction at address MEMADDR in debugged memory,
140 on STREAM. Returns length of the instruction, in bytes. */
143 print_insn (memaddr
, stream
)
147 unsigned char buffer
[MAXLEN
];
149 register unsigned char *p
;
151 unsigned short first_word
;
153 int ioffset
; /* bits into instruction */
154 int aoffset
; /* bits into arguments */
155 char arg_bufs
[MAX_ARGS
+1][ARG_LEN
];
159 read_memory (memaddr
, buffer
, MAXLEN
);
161 first_word
= *(unsigned short *) buffer
;
162 for (i
= 0; i
< NOPCODES
; i
++)
163 if ((first_word
& ((1 << notstrs
[i
].detail
.obits
) - 1))
164 == notstrs
[i
].detail
.code
)
167 /* Handle undefined instructions. */
170 fprintf (stream
, "0%o", buffer
[0]);
174 fprintf (stream
, "%s", notstrs
[i
].name
);
176 ioffset
= notstrs
[i
].detail
.ibits
;
177 aoffset
= notstrs
[i
].detail
.ibits
;
178 d
= notstrs
[i
].detail
.args
;
182 /* Offset in bits of the first thing beyond each index byte.
183 Element 0 is for operand A and element 1 is for operand B.
184 The rest are irrelevant, but we put them here so we don't
185 index outside the array. */
186 int index_offset
[MAX_ARGS
];
188 /* 0 for operand A, 1 for operand B, greater for other args. */
191 fputc ('\t', stream
);
195 /* First we have to find and keep track of the index bytes,
196 if we are using scaled indexed addressing mode, since the index
197 bytes occur right after the basic instruction, not as part
198 of the addressing extension. */
201 int addr_mode
= bit_extract (buffer
, ioffset
- 5, 5);
203 if (Adrmod_is_index (addr_mode
))
206 index_offset
[0] = aoffset
;
209 if (d
[2] && Is_gen(d
[3]))
211 int addr_mode
= bit_extract (buffer
, ioffset
- 10, 5);
213 if (Adrmod_is_index (addr_mode
))
216 index_offset
[1] = aoffset
;
224 if (argnum
> maxarg
&& argnum
< MAX_ARGS
)
226 ioffset
= print_insn_arg (*d
, ioffset
, &aoffset
, buffer
,
227 memaddr
, arg_bufs
[argnum
],
228 index_offset
[whicharg
]);
232 for (argnum
= 0; argnum
<= maxarg
; argnum
++)
236 for (ch
= arg_bufs
[argnum
]; *ch
;)
238 if (*ch
== NEXT_IS_ADDR
)
242 print_address (addr
, stream
);
243 while (*ch
&& *ch
!= NEXT_IS_ADDR
)
249 putc (*ch
++, stream
);
252 fprintf (stream
, ", ");
258 /* Print an instruction operand of category given by d. IOFFSET is
259 the bit position below which small (<1 byte) parts of the operand can
260 be found (usually in the basic instruction, but for indexed
261 addressing it can be in the index byte). AOFFSETP is a pointer to the
262 bit position of the addressing extension. BUFFER contains the
263 instruction. ADDR is where BUFFER was read from. Put the disassembled
264 version of the operand in RESULT. INDEX_OFFSET is the bit position
265 of the index byte (it contains garbage if this operand is not a
266 general operand using scaled indexed addressing mode). */
268 print_insn_arg (d
, ioffset
, aoffsetp
, buffer
, addr
, result
, index_offset
)
270 int ioffset
, *aoffsetp
;
291 addr_mode
= bit_extract (buffer
, ioffset
-5, 5);
295 case 0x0: case 0x1: case 0x2: case 0x3:
296 case 0x4: case 0x5: case 0x6: case 0x7:
301 sprintf (result
, "f%d", addr_mode
);
304 sprintf (result
, "r%d", addr_mode
);
307 case 0x8: case 0x9: case 0xa: case 0xb:
308 case 0xc: case 0xd: case 0xe: case 0xf:
309 disp1
= get_displacement (buffer
, aoffsetp
);
310 sprintf (result
, "%d(r%d)", disp1
, addr_mode
& 7);
315 disp1
= get_displacement (buffer
, aoffsetp
);
316 disp2
= get_displacement (buffer
, aoffsetp
);
317 sprintf (result
, "%d(%d(%s))", disp2
, disp1
,
318 addr_mode
==0x10?"fp":addr_mode
==0x11?"sp":"sb");
321 sprintf (result
, "reserved");
327 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
328 Ivalue
= sign_extend (Ivalue
, 8);
330 sprintf (result
, "$%d", Ivalue
);
333 Ivalue
= bit_extract (buffer
, *aoffsetp
, 16);
334 flip_bytes (&Ivalue
, 2);
336 Ivalue
= sign_extend (Ivalue
, 16);
337 sprintf (result
, "$%d", Ivalue
);
340 Ivalue
= bit_extract (buffer
, *aoffsetp
, 32);
341 flip_bytes (&Ivalue
, 4);
343 sprintf (result
, "$%d", Ivalue
);
346 Ivalue
= bit_extract (buffer
, *aoffsetp
, 32);
347 flip_bytes (&Ivalue
, 4);
349 sprintf (result
, "$|%d|", Ivalue
);
352 Fvalue
= fbit_extract (buffer
, *aoffsetp
, 32);
353 flip_bytes (&Fvalue
, 4);
355 sprintf (result
, "$%g", Fvalue
);
358 Lvalue
= dbit_extract (buffer
, *aoffsetp
, 64);
359 flip_bytes (&Lvalue
, 8);
361 sprintf (result
, "$%g", Lvalue
);
366 disp1
= get_displacement (buffer
, aoffsetp
);
367 sprintf (result
, "@|%d|", disp1
);
370 disp1
= get_displacement (buffer
, aoffsetp
);
371 disp2
= get_displacement (buffer
, aoffsetp
);
372 sprintf (result
, "EXT(%d) + %d", disp1
, disp2
);
375 sprintf (result
, "tos");
378 disp1
= get_displacement (buffer
, aoffsetp
);
379 sprintf (result
, "%d(fp)", disp1
);
382 disp1
= get_displacement (buffer
, aoffsetp
);
383 sprintf (result
, "%d(sp)", disp1
);
386 disp1
= get_displacement (buffer
, aoffsetp
);
387 sprintf (result
, "%d(sb)", disp1
);
390 disp1
= get_displacement (buffer
, aoffsetp
);
391 sprintf (result
, "|%d|", addr
+ disp1
);
397 index
= bit_extract (buffer
, index_offset
- 8, 3);
398 print_insn_arg (d
, index_offset
, aoffsetp
, buffer
, addr
,
401 static char *ind
[] = {"b", "w", "d", "q"};
404 off
= result
+ strlen (result
);
405 sprintf (off
, "[r%d:%s]", index
,
412 Ivalue
= bit_extract (buffer
, ioffset
-4, 4);
413 Ivalue
= sign_extend (Ivalue
, 4);
414 sprintf (result
, "%d", Ivalue
);
418 Ivalue
= bit_extract (buffer
, ioffset
-3, 3);
419 sprintf (result
, "r%d", Ivalue
&7);
423 sprintf (result
, "%d", get_displacement (buffer
, aoffsetp
));
426 sprintf (result
, "%c%d%c", NEXT_IS_ADDR
,
427 addr
+ get_displacement (buffer
, aoffsetp
),
431 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
433 sprintf (result
, "0x%x", Ivalue
);
439 get_displacement (buffer
, aoffsetp
)
445 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
446 switch (Ivalue
& 0xc0)
450 Ivalue
= sign_extend (Ivalue
, 7);
454 Ivalue
= bit_extract (buffer
, *aoffsetp
, 16);
455 flip_bytes (&Ivalue
, 2);
456 Ivalue
= sign_extend (Ivalue
, 14);
460 Ivalue
= bit_extract (buffer
, *aoffsetp
, 32);
461 flip_bytes (&Ivalue
, 4);
462 Ivalue
= sign_extend (Ivalue
, 30);
469 /* Return the number of locals in the current frame given a pc
470 pointing to the enter instruction. This is used in the macro
471 FRAME_FIND_SAVED_REGS. */
473 ns32k_localcount (enter_pc
)
476 unsigned char localtype
;
479 localtype
= read_memory_integer (enter_pc
+2, 1);
480 if ((localtype
& 0x80) == 0)
481 localcount
= localtype
;
482 else if ((localtype
& 0xc0) == 0x80)
483 localcount
= (((localtype
& 0x3f) << 8)
484 | (read_memory_integer (enter_pc
+3, 1) & 0xff));
486 localcount
= (((localtype
& 0x3f) << 24)
487 | ((read_memory_integer (enter_pc
+3, 1) & 0xff) << 16)
488 | ((read_memory_integer (enter_pc
+4, 1) & 0xff) << 8 )
489 | (read_memory_integer (enter_pc
+5, 1) & 0xff));
494 * Get the address of the enter opcode for the function
495 * containing PC, if there is an enter for the function,
496 * and if the pc is between the enter and exit.
497 * Returns positive address if pc is between enter/exit,
498 * 1 if pc before enter or after exit, 0 otherwise.
502 ns32k_get_enter_addr (pc
)
505 CORE_ADDR enter_addr
;
508 if (ABOUT_TO_RETURN (pc
))
509 return 1; /* after exit */
511 enter_addr
= get_pc_function_start (pc
);
513 if (pc
== enter_addr
)
514 return 1; /* before enter */
516 op
= read_memory_integer (enter_addr
, 1);
519 return 0; /* function has no enter/exit */
521 return enter_addr
; /* pc is between enter and exit */
This page took 0.039486 seconds and 4 git commands to generate.