1 /* Print National Semiconductor 32000 instructions for GDB, the GNU debugger.
2 Copyright 1986, 1988, 1991, 1992 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. */
22 #include "ns32k-opcode.h"
25 /* 32000 instructions are never longer than this. */
28 /* Number of elements in the opcode table. */
29 #define NOPCODES (sizeof notstrs / sizeof notstrs[0])
31 #define NEXT_IS_ADDR '|'
34 * extract "count" bits starting "offset" bits
39 bit_extract (buffer
, offset
, count
)
48 buffer
+= offset
>> 3;
54 if ((*buffer
& (1 << offset
)))
67 fbit_extract (buffer
, offset
, count
)
74 foo
.ival
= bit_extract (buffer
, offset
, 32);
79 dbit_extract (buffer
, offset
, count
)
82 struct {int low
, high
; } ival
;
86 foo
.ival
.low
= bit_extract (buffer
, offset
, 32);
87 foo
.ival
.high
= bit_extract (buffer
, offset
+32, 32);
91 sign_extend (value
, bits
)
93 value
= value
& ((1 << bits
) - 1);
94 return (value
& (1 << (bits
-1))
95 ? value
| (~((1 << bits
) - 1))
99 flip_bytes (ptr
, count
)
108 ptr
[0] = ptr
[count
-1];
115 /* Given a character C, does it represent a general addressing mode? */
117 ((c) == 'F' || (c) == 'L' || (c) == 'B' \
118 || (c) == 'W' || (c) == 'D' || (c) == 'A')
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
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)
134 /* Print the 32000 instruction at address MEMADDR in debugged memory,
135 on STREAM. Returns length of the instruction, in bytes. */
138 print_insn (memaddr
, stream
)
142 unsigned char buffer
[MAXLEN
];
144 register unsigned char *p
;
146 unsigned short first_word
;
148 int ioffset
; /* bits into instruction */
149 int aoffset
; /* bits into arguments */
150 char arg_bufs
[MAX_ARGS
+1][ARG_LEN
];
154 read_memory (memaddr
, buffer
, MAXLEN
);
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
)
162 /* Handle undefined instructions. */
165 fprintf (stream
, "0%o", buffer
[0]);
169 fprintf (stream
, "%s", notstrs
[i
].name
);
171 ioffset
= notstrs
[i
].detail
.ibits
;
172 aoffset
= notstrs
[i
].detail
.ibits
;
173 d
= notstrs
[i
].detail
.args
;
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
];
183 /* 0 for operand A, 1 for operand B, greater for other args. */
186 fputc ('\t', stream
);
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. */
196 int addr_mode
= bit_extract (buffer
, ioffset
- 5, 5);
198 if (Adrmod_is_index (addr_mode
))
201 index_offset
[0] = aoffset
;
204 if (d
[2] && Is_gen(d
[3]))
206 int addr_mode
= bit_extract (buffer
, ioffset
- 10, 5);
208 if (Adrmod_is_index (addr_mode
))
211 index_offset
[1] = aoffset
;
219 if (argnum
> maxarg
&& argnum
< MAX_ARGS
)
221 ioffset
= print_insn_arg (*d
, ioffset
, &aoffset
, buffer
,
222 memaddr
, arg_bufs
[argnum
],
223 index_offset
[whicharg
]);
227 for (argnum
= 0; argnum
<= maxarg
; argnum
++)
231 for (ch
= arg_bufs
[argnum
]; *ch
;)
233 if (*ch
== NEXT_IS_ADDR
)
237 print_address (addr
, stream
);
238 while (*ch
&& *ch
!= NEXT_IS_ADDR
)
244 putc (*ch
++, stream
);
247 fprintf (stream
, ", ");
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). */
263 print_insn_arg (d
, ioffset
, aoffsetp
, buffer
, addr
, result
, index_offset
)
265 int ioffset
, *aoffsetp
;
286 addr_mode
= bit_extract (buffer
, ioffset
-5, 5);
290 case 0x0: case 0x1: case 0x2: case 0x3:
291 case 0x4: case 0x5: case 0x6: case 0x7:
296 sprintf (result
, "f%d", addr_mode
);
299 sprintf (result
, "r%d", addr_mode
);
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);
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");
316 sprintf (result
, "reserved");
322 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
323 Ivalue
= sign_extend (Ivalue
, 8);
325 sprintf (result
, "$%d", Ivalue
);
328 Ivalue
= bit_extract (buffer
, *aoffsetp
, 16);
329 flip_bytes (&Ivalue
, 2);
331 Ivalue
= sign_extend (Ivalue
, 16);
332 sprintf (result
, "$%d", Ivalue
);
335 Ivalue
= bit_extract (buffer
, *aoffsetp
, 32);
336 flip_bytes (&Ivalue
, 4);
338 sprintf (result
, "$%d", Ivalue
);
341 Ivalue
= bit_extract (buffer
, *aoffsetp
, 32);
342 flip_bytes (&Ivalue
, 4);
344 sprintf (result
, "$|%d|", Ivalue
);
347 Fvalue
= fbit_extract (buffer
, *aoffsetp
, 32);
348 flip_bytes (&Fvalue
, 4);
350 sprintf (result
, "$%g", Fvalue
);
353 Lvalue
= dbit_extract (buffer
, *aoffsetp
, 64);
354 flip_bytes (&Lvalue
, 8);
356 sprintf (result
, "$%g", Lvalue
);
361 disp1
= get_displacement (buffer
, aoffsetp
);
362 sprintf (result
, "@|%d|", disp1
);
365 disp1
= get_displacement (buffer
, aoffsetp
);
366 disp2
= get_displacement (buffer
, aoffsetp
);
367 sprintf (result
, "EXT(%d) + %d", disp1
, disp2
);
370 sprintf (result
, "tos");
373 disp1
= get_displacement (buffer
, aoffsetp
);
374 sprintf (result
, "%d(fp)", disp1
);
377 disp1
= get_displacement (buffer
, aoffsetp
);
378 sprintf (result
, "%d(sp)", disp1
);
381 disp1
= get_displacement (buffer
, aoffsetp
);
382 sprintf (result
, "%d(sb)", disp1
);
385 disp1
= get_displacement (buffer
, aoffsetp
);
386 sprintf (result
, "|%d|", addr
+ disp1
);
392 index
= bit_extract (buffer
, index_offset
- 8, 3);
393 print_insn_arg (d
, index_offset
, aoffsetp
, buffer
, addr
,
396 static char *ind
[] = {"b", "w", "d", "q"};
399 off
= result
+ strlen (result
);
400 sprintf (off
, "[r%d:%s]", index
,
407 Ivalue
= bit_extract (buffer
, ioffset
-4, 4);
408 Ivalue
= sign_extend (Ivalue
, 4);
409 sprintf (result
, "%d", Ivalue
);
413 Ivalue
= bit_extract (buffer
, ioffset
-3, 3);
414 sprintf (result
, "r%d", Ivalue
&7);
418 sprintf (result
, "%d", get_displacement (buffer
, aoffsetp
));
421 sprintf (result
, "%c%d%c", NEXT_IS_ADDR
,
422 addr
+ get_displacement (buffer
, aoffsetp
),
426 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
428 sprintf (result
, "0x%x", Ivalue
);
434 get_displacement (buffer
, aoffsetp
)
440 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
441 switch (Ivalue
& 0xc0)
445 Ivalue
= sign_extend (Ivalue
, 7);
449 Ivalue
= bit_extract (buffer
, *aoffsetp
, 16);
450 flip_bytes (&Ivalue
, 2);
451 Ivalue
= sign_extend (Ivalue
, 14);
455 Ivalue
= bit_extract (buffer
, *aoffsetp
, 32);
456 flip_bytes (&Ivalue
, 4);
457 Ivalue
= sign_extend (Ivalue
, 30);
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. */
468 ns32k_localcount (enter_pc
)
471 unsigned char localtype
;
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));
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));
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.
497 ns32k_get_enter_addr (pc
)
500 CORE_ADDR enter_addr
;
503 if (ABOUT_TO_RETURN (pc
))
504 return 1; /* after exit */
506 enter_addr
= get_pc_function_start (pc
);
508 if (pc
== enter_addr
)
509 return 1; /* before enter */
511 op
= read_memory_integer (enter_addr
, 1);
514 return 0; /* function has no enter/exit */
516 return enter_addr
; /* pc is between enter and exit */
This page took 0.040683 seconds and 4 git commands to generate.