1 /* Print 32000 instructions for GDB, the GNU debugger.
2 Copyright (C) 1986,1988 Free Software Foundation, Inc.
4 GDB is distributed in the hope that it will be useful, but WITHOUT ANY
5 WARRANTY. No author or distributor accepts responsibility to anyone
6 for the consequences of using it or for whether it serves any
7 particular purpose or works at all, unless he says so in writing.
8 Refer to the GDB General Public License for full details.
10 Everyone is granted permission to copy, modify and redistribute GDB,
11 but only under the conditions described in the GDB General Public
12 License. A copy of this license is supposed to have been given to you
13 along with GDB so you can know your rights and responsibilities. It
14 should be in a file named COPYING. Among other things, the copyright
15 notice and this notice must be preserved on all copies.
17 In other words, go ahead and share GDB, but don't try to stop
18 anyone else from sharing it farther. Help stamp out software hoarding!
26 #include "ns32k-opcode.h"
29 /* 32000 instructions are never longer than this. */
32 /* Number of elements in the opcode table. */
33 #define NOPCODES (sizeof notstrs / sizeof notstrs[0])
35 extern char *reg_names
[];
37 #define NEXT_IS_ADDR '|'
40 * extract "count" bits starting "offset" bits
45 bit_extract (buffer
, offset
, count
)
54 buffer
+= offset
>> 3;
60 if ((*buffer
& (1 << offset
)))
73 fbit_extract (buffer
, offset
, count
)
80 foo
.ival
= bit_extract (buffer
, offset
, 32);
85 dbit_extract (buffer
, offset
, count
)
88 struct {int low
, high
; } ival
;
92 foo
.ival
.low
= bit_extract (buffer
, offset
, 32);
93 foo
.ival
.high
= bit_extract (buffer
, offset
+32, 32);
97 sign_extend (value
, bits
)
99 value
= value
& ((1 << bits
) - 1);
100 return (value
& (1 << (bits
-1))
101 ? value
| (~((1 << bits
) - 1))
105 flip_bytes (ptr
, count
)
114 ptr
[0] = ptr
[count
-1];
121 /* Given a character C, does it represent a general addressing mode? */
123 ((c) == 'F' || (c) == 'L' || (c) == 'B' \
124 || (c) == 'W' || (c) == 'D' || (c) == 'A')
126 /* Adressing modes. */
127 #define Adrmod_index_byte 0x1c
128 #define Adrmod_index_word 0x1d
129 #define Adrmod_index_doubleword 0x1e
130 #define Adrmod_index_quadword 0x1f
132 /* Is MODE an indexed addressing mode? */
133 #define Adrmod_is_index(mode) \
134 (mode == Adrmod_index_byte \
135 || mode == Adrmod_index_word \
136 || mode == Adrmod_index_doubleword \
137 || mode == Adrmod_index_quadword)
140 /* Print the 32000 instruction at address MEMADDR in debugged memory,
141 on STREAM. Returns length of the instruction, in bytes. */
144 print_insn (memaddr
, stream
)
148 unsigned char buffer
[MAXLEN
];
150 register unsigned char *p
;
152 unsigned short first_word
;
154 int ioffset
; /* bits into instruction */
155 int aoffset
; /* bits into arguments */
156 char arg_bufs
[MAX_ARGS
+1][ARG_LEN
];
160 read_memory (memaddr
, buffer
, MAXLEN
);
162 first_word
= *(unsigned short *) buffer
;
163 for (i
= 0; i
< NOPCODES
; i
++)
164 if ((first_word
& ((1 << notstrs
[i
].detail
.obits
) - 1))
165 == notstrs
[i
].detail
.code
)
168 /* Handle undefined instructions. */
171 fprintf (stream
, "0%o", buffer
[0]);
175 fprintf (stream
, "%s", notstrs
[i
].name
);
177 ioffset
= notstrs
[i
].detail
.ibits
;
178 aoffset
= notstrs
[i
].detail
.ibits
;
179 d
= notstrs
[i
].detail
.args
;
183 /* Offset in bits of the first thing beyond each index byte.
184 Element 0 is for operand A and element 1 is for operand B.
185 The rest are irrelevant, but we put them here so we don't
186 index outside the array. */
187 int index_offset
[MAX_ARGS
];
189 /* 0 for operand A, 1 for operand B, greater for other args. */
192 fputc ('\t', stream
);
196 /* First we have to find and keep track of the index bytes,
197 if we are using scaled indexed addressing mode, since the index
198 bytes occur right after the basic instruction, not as part
199 of the addressing extension. */
202 int addr_mode
= bit_extract (buffer
, ioffset
- 5, 5);
204 if (Adrmod_is_index (addr_mode
))
207 index_offset
[0] = aoffset
;
210 if (d
[2] && Is_gen(d
[3]))
212 int addr_mode
= bit_extract (buffer
, ioffset
- 10, 5);
214 if (Adrmod_is_index (addr_mode
))
217 index_offset
[1] = aoffset
;
225 if (argnum
> maxarg
&& argnum
< MAX_ARGS
)
227 ioffset
= print_insn_arg (*d
, ioffset
, &aoffset
, buffer
,
228 memaddr
, arg_bufs
[argnum
],
229 index_offset
[whicharg
]);
233 for (argnum
= 0; argnum
<= maxarg
; argnum
++)
237 for (ch
= arg_bufs
[argnum
]; *ch
;)
239 if (*ch
== NEXT_IS_ADDR
)
243 print_address (addr
, stream
);
244 while (*ch
&& *ch
!= NEXT_IS_ADDR
)
250 putc (*ch
++, stream
);
253 fprintf (stream
, ", ");
259 /* Print an instruction operand of category given by d. IOFFSET is
260 the bit position below which small (<1 byte) parts of the operand can
261 be found (usually in the basic instruction, but for indexed
262 addressing it can be in the index byte). AOFFSETP is a pointer to the
263 bit position of the addressing extension. BUFFER contains the
264 instruction. ADDR is where BUFFER was read from. Put the disassembled
265 version of the operand in RESULT. INDEX_OFFSET is the bit position
266 of the index byte (it contains garbage if this operand is not a
267 general operand using scaled indexed addressing mode). */
269 print_insn_arg (d
, ioffset
, aoffsetp
, buffer
, addr
, result
, index_offset
)
271 int ioffset
, *aoffsetp
;
292 addr_mode
= bit_extract (buffer
, ioffset
-5, 5);
296 case 0x0: case 0x1: case 0x2: case 0x3:
297 case 0x4: case 0x5: case 0x6: case 0x7:
302 sprintf (result
, "f%d", addr_mode
);
305 sprintf (result
, "r%d", addr_mode
);
308 case 0x8: case 0x9: case 0xa: case 0xb:
309 case 0xc: case 0xd: case 0xe: case 0xf:
310 disp1
= get_displacement (buffer
, aoffsetp
);
311 sprintf (result
, "%d(r%d)", disp1
, addr_mode
& 7);
316 disp1
= get_displacement (buffer
, aoffsetp
);
317 disp2
= get_displacement (buffer
, aoffsetp
);
318 sprintf (result
, "%d(%d(%s))", disp2
, disp1
,
319 addr_mode
==0x10?"fp":addr_mode
==0x11?"sp":"sb");
322 sprintf (result
, "reserved");
328 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
329 Ivalue
= sign_extend (Ivalue
, 8);
331 sprintf (result
, "$%d", Ivalue
);
334 Ivalue
= bit_extract (buffer
, *aoffsetp
, 16);
335 flip_bytes (&Ivalue
, 2);
337 Ivalue
= sign_extend (Ivalue
, 16);
338 sprintf (result
, "$%d", Ivalue
);
341 Ivalue
= bit_extract (buffer
, *aoffsetp
, 32);
342 flip_bytes (&Ivalue
, 4);
344 sprintf (result
, "$%d", Ivalue
);
347 Ivalue
= bit_extract (buffer
, *aoffsetp
, 32);
348 flip_bytes (&Ivalue
, 4);
350 sprintf (result
, "$|%d|", Ivalue
);
353 Fvalue
= fbit_extract (buffer
, *aoffsetp
, 32);
354 flip_bytes (&Fvalue
, 4);
356 sprintf (result
, "$%g", Fvalue
);
359 Lvalue
= dbit_extract (buffer
, *aoffsetp
, 64);
360 flip_bytes (&Lvalue
, 8);
362 sprintf (result
, "$%g", Lvalue
);
367 disp1
= get_displacement (buffer
, aoffsetp
);
368 sprintf (result
, "@|%d|", disp1
);
371 disp1
= get_displacement (buffer
, aoffsetp
);
372 disp2
= get_displacement (buffer
, aoffsetp
);
373 sprintf (result
, "EXT(%d) + %d", disp1
, disp2
);
376 sprintf (result
, "tos");
379 disp1
= get_displacement (buffer
, aoffsetp
);
380 sprintf (result
, "%d(fp)", disp1
);
383 disp1
= get_displacement (buffer
, aoffsetp
);
384 sprintf (result
, "%d(sp)", disp1
);
387 disp1
= get_displacement (buffer
, aoffsetp
);
388 sprintf (result
, "%d(sb)", disp1
);
391 disp1
= get_displacement (buffer
, aoffsetp
);
392 sprintf (result
, "|%d|", addr
+ disp1
);
398 index
= bit_extract (buffer
, index_offset
- 8, 3);
399 print_insn_arg (d
, index_offset
, aoffsetp
, buffer
, addr
,
402 static char *ind
[] = {"b", "w", "d", "q"};
405 off
= result
+ strlen (result
);
406 sprintf (off
, "[r%d:%s]", index
,
413 Ivalue
= bit_extract (buffer
, ioffset
-4, 4);
414 Ivalue
= sign_extend (Ivalue
, 4);
415 sprintf (result
, "%d", Ivalue
);
419 Ivalue
= bit_extract (buffer
, ioffset
-3, 3);
420 sprintf (result
, "r%d", Ivalue
&7);
424 sprintf (result
, "%d", get_displacement (buffer
, aoffsetp
));
427 sprintf (result
, "%c%d%c", NEXT_IS_ADDR
,
428 addr
+ get_displacement (buffer
, aoffsetp
),
432 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
434 sprintf (result
, "0x%x", Ivalue
);
440 get_displacement (buffer
, aoffsetp
)
446 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
447 switch (Ivalue
& 0xc0)
451 Ivalue
= sign_extend (Ivalue
, 7);
455 Ivalue
= bit_extract (buffer
, *aoffsetp
, 16);
456 flip_bytes (&Ivalue
, 2);
457 Ivalue
= sign_extend (Ivalue
, 14);
461 Ivalue
= bit_extract (buffer
, *aoffsetp
, 32);
462 flip_bytes (&Ivalue
, 4);
463 Ivalue
= sign_extend (Ivalue
, 30);
470 /* Return the number of locals in the current frame given a pc
471 pointing to the enter instruction. This is used in the macro
472 FRAME_FIND_SAVED_REGS. */
474 ns32k_localcount (enter_pc
)
477 unsigned char localtype
;
480 localtype
= read_memory_integer (enter_pc
+2, 1);
481 if ((localtype
& 0x80) == 0)
482 localcount
= localtype
;
483 else if ((localtype
& 0xc0) == 0x80)
484 localcount
= (((localtype
& 0x3f) << 8)
485 | (read_memory_integer (enter_pc
+3, 1) & 0xff));
487 localcount
= (((localtype
& 0x3f) << 24)
488 | ((read_memory_integer (enter_pc
+3, 1) & 0xff) << 16)
489 | ((read_memory_integer (enter_pc
+4, 1) & 0xff) << 8 )
490 | (read_memory_integer (enter_pc
+5, 1) & 0xff));
495 * Get the address of the enter opcode for the function
496 * containing PC, if there is an enter for the function,
497 * and if the pc is between the enter and exit.
498 * Returns positive address if pc is between enter/exit,
499 * 1 if pc before enter or after exit, 0 otherwise.
503 ns32k_get_enter_addr (pc
)
506 CORE_ADDR enter_addr
;
509 if (ABOUT_TO_RETURN (pc
))
510 return 1; /* after exit */
512 enter_addr
= get_pc_function_start (pc
);
514 if (pc
== enter_addr
)
515 return 1; /* before enter */
517 op
= read_memory_integer (enter_addr
, 1);
520 return 0; /* function has no enter/exit */
522 return enter_addr
; /* pc is between enter and exit */
This page took 0.046503 seconds and 4 git commands to generate.