1 /* Print National Semiconductor 32000 instructions for GDB, the GNU debugger.
2 Copyright 1986, 1988, 1991 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 extern char *reg_names
[];
33 #define NEXT_IS_ADDR '|'
36 * extract "count" bits starting "offset" bits
41 bit_extract (buffer
, offset
, count
)
50 buffer
+= offset
>> 3;
56 if ((*buffer
& (1 << offset
)))
69 fbit_extract (buffer
, offset
, count
)
76 foo
.ival
= bit_extract (buffer
, offset
, 32);
81 dbit_extract (buffer
, offset
, count
)
84 struct {int low
, high
; } ival
;
88 foo
.ival
.low
= bit_extract (buffer
, offset
, 32);
89 foo
.ival
.high
= bit_extract (buffer
, offset
+32, 32);
93 sign_extend (value
, bits
)
95 value
= value
& ((1 << bits
) - 1);
96 return (value
& (1 << (bits
-1))
97 ? value
| (~((1 << bits
) - 1))
101 flip_bytes (ptr
, count
)
110 ptr
[0] = ptr
[count
-1];
117 /* Given a character C, does it represent a general addressing mode? */
119 ((c) == 'F' || (c) == 'L' || (c) == 'B' \
120 || (c) == 'W' || (c) == 'D' || (c) == 'A')
122 /* Adressing modes. */
123 #define Adrmod_index_byte 0x1c
124 #define Adrmod_index_word 0x1d
125 #define Adrmod_index_doubleword 0x1e
126 #define Adrmod_index_quadword 0x1f
128 /* Is MODE an indexed addressing mode? */
129 #define Adrmod_is_index(mode) \
130 (mode == Adrmod_index_byte \
131 || mode == Adrmod_index_word \
132 || mode == Adrmod_index_doubleword \
133 || mode == Adrmod_index_quadword)
136 /* Print the 32000 instruction at address MEMADDR in debugged memory,
137 on STREAM. Returns length of the instruction, in bytes. */
140 print_insn (memaddr
, stream
)
144 unsigned char buffer
[MAXLEN
];
146 register unsigned char *p
;
148 unsigned short first_word
;
150 int ioffset
; /* bits into instruction */
151 int aoffset
; /* bits into arguments */
152 char arg_bufs
[MAX_ARGS
+1][ARG_LEN
];
156 read_memory (memaddr
, buffer
, MAXLEN
);
158 first_word
= *(unsigned short *) buffer
;
159 for (i
= 0; i
< NOPCODES
; i
++)
160 if ((first_word
& ((1 << notstrs
[i
].detail
.obits
) - 1))
161 == notstrs
[i
].detail
.code
)
164 /* Handle undefined instructions. */
167 fprintf (stream
, "0%o", buffer
[0]);
171 fprintf (stream
, "%s", notstrs
[i
].name
);
173 ioffset
= notstrs
[i
].detail
.ibits
;
174 aoffset
= notstrs
[i
].detail
.ibits
;
175 d
= notstrs
[i
].detail
.args
;
179 /* Offset in bits of the first thing beyond each index byte.
180 Element 0 is for operand A and element 1 is for operand B.
181 The rest are irrelevant, but we put them here so we don't
182 index outside the array. */
183 int index_offset
[MAX_ARGS
];
185 /* 0 for operand A, 1 for operand B, greater for other args. */
188 fputc ('\t', stream
);
192 /* First we have to find and keep track of the index bytes,
193 if we are using scaled indexed addressing mode, since the index
194 bytes occur right after the basic instruction, not as part
195 of the addressing extension. */
198 int addr_mode
= bit_extract (buffer
, ioffset
- 5, 5);
200 if (Adrmod_is_index (addr_mode
))
203 index_offset
[0] = aoffset
;
206 if (d
[2] && Is_gen(d
[3]))
208 int addr_mode
= bit_extract (buffer
, ioffset
- 10, 5);
210 if (Adrmod_is_index (addr_mode
))
213 index_offset
[1] = aoffset
;
221 if (argnum
> maxarg
&& argnum
< MAX_ARGS
)
223 ioffset
= print_insn_arg (*d
, ioffset
, &aoffset
, buffer
,
224 memaddr
, arg_bufs
[argnum
],
225 index_offset
[whicharg
]);
229 for (argnum
= 0; argnum
<= maxarg
; argnum
++)
233 for (ch
= arg_bufs
[argnum
]; *ch
;)
235 if (*ch
== NEXT_IS_ADDR
)
239 print_address (addr
, stream
);
240 while (*ch
&& *ch
!= NEXT_IS_ADDR
)
246 putc (*ch
++, stream
);
249 fprintf (stream
, ", ");
255 /* Print an instruction operand of category given by d. IOFFSET is
256 the bit position below which small (<1 byte) parts of the operand can
257 be found (usually in the basic instruction, but for indexed
258 addressing it can be in the index byte). AOFFSETP is a pointer to the
259 bit position of the addressing extension. BUFFER contains the
260 instruction. ADDR is where BUFFER was read from. Put the disassembled
261 version of the operand in RESULT. INDEX_OFFSET is the bit position
262 of the index byte (it contains garbage if this operand is not a
263 general operand using scaled indexed addressing mode). */
265 print_insn_arg (d
, ioffset
, aoffsetp
, buffer
, addr
, result
, index_offset
)
267 int ioffset
, *aoffsetp
;
288 addr_mode
= bit_extract (buffer
, ioffset
-5, 5);
292 case 0x0: case 0x1: case 0x2: case 0x3:
293 case 0x4: case 0x5: case 0x6: case 0x7:
298 sprintf (result
, "f%d", addr_mode
);
301 sprintf (result
, "r%d", addr_mode
);
304 case 0x8: case 0x9: case 0xa: case 0xb:
305 case 0xc: case 0xd: case 0xe: case 0xf:
306 disp1
= get_displacement (buffer
, aoffsetp
);
307 sprintf (result
, "%d(r%d)", disp1
, addr_mode
& 7);
312 disp1
= get_displacement (buffer
, aoffsetp
);
313 disp2
= get_displacement (buffer
, aoffsetp
);
314 sprintf (result
, "%d(%d(%s))", disp2
, disp1
,
315 addr_mode
==0x10?"fp":addr_mode
==0x11?"sp":"sb");
318 sprintf (result
, "reserved");
324 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
325 Ivalue
= sign_extend (Ivalue
, 8);
327 sprintf (result
, "$%d", Ivalue
);
330 Ivalue
= bit_extract (buffer
, *aoffsetp
, 16);
331 flip_bytes (&Ivalue
, 2);
333 Ivalue
= sign_extend (Ivalue
, 16);
334 sprintf (result
, "$%d", Ivalue
);
337 Ivalue
= bit_extract (buffer
, *aoffsetp
, 32);
338 flip_bytes (&Ivalue
, 4);
340 sprintf (result
, "$%d", Ivalue
);
343 Ivalue
= bit_extract (buffer
, *aoffsetp
, 32);
344 flip_bytes (&Ivalue
, 4);
346 sprintf (result
, "$|%d|", Ivalue
);
349 Fvalue
= fbit_extract (buffer
, *aoffsetp
, 32);
350 flip_bytes (&Fvalue
, 4);
352 sprintf (result
, "$%g", Fvalue
);
355 Lvalue
= dbit_extract (buffer
, *aoffsetp
, 64);
356 flip_bytes (&Lvalue
, 8);
358 sprintf (result
, "$%g", Lvalue
);
363 disp1
= get_displacement (buffer
, aoffsetp
);
364 sprintf (result
, "@|%d|", disp1
);
367 disp1
= get_displacement (buffer
, aoffsetp
);
368 disp2
= get_displacement (buffer
, aoffsetp
);
369 sprintf (result
, "EXT(%d) + %d", disp1
, disp2
);
372 sprintf (result
, "tos");
375 disp1
= get_displacement (buffer
, aoffsetp
);
376 sprintf (result
, "%d(fp)", disp1
);
379 disp1
= get_displacement (buffer
, aoffsetp
);
380 sprintf (result
, "%d(sp)", disp1
);
383 disp1
= get_displacement (buffer
, aoffsetp
);
384 sprintf (result
, "%d(sb)", disp1
);
387 disp1
= get_displacement (buffer
, aoffsetp
);
388 sprintf (result
, "|%d|", addr
+ disp1
);
394 index
= bit_extract (buffer
, index_offset
- 8, 3);
395 print_insn_arg (d
, index_offset
, aoffsetp
, buffer
, addr
,
398 static char *ind
[] = {"b", "w", "d", "q"};
401 off
= result
+ strlen (result
);
402 sprintf (off
, "[r%d:%s]", index
,
409 Ivalue
= bit_extract (buffer
, ioffset
-4, 4);
410 Ivalue
= sign_extend (Ivalue
, 4);
411 sprintf (result
, "%d", Ivalue
);
415 Ivalue
= bit_extract (buffer
, ioffset
-3, 3);
416 sprintf (result
, "r%d", Ivalue
&7);
420 sprintf (result
, "%d", get_displacement (buffer
, aoffsetp
));
423 sprintf (result
, "%c%d%c", NEXT_IS_ADDR
,
424 addr
+ get_displacement (buffer
, aoffsetp
),
428 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
430 sprintf (result
, "0x%x", Ivalue
);
436 get_displacement (buffer
, aoffsetp
)
442 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
443 switch (Ivalue
& 0xc0)
447 Ivalue
= sign_extend (Ivalue
, 7);
451 Ivalue
= bit_extract (buffer
, *aoffsetp
, 16);
452 flip_bytes (&Ivalue
, 2);
453 Ivalue
= sign_extend (Ivalue
, 14);
457 Ivalue
= bit_extract (buffer
, *aoffsetp
, 32);
458 flip_bytes (&Ivalue
, 4);
459 Ivalue
= sign_extend (Ivalue
, 30);
466 /* Return the number of locals in the current frame given a pc
467 pointing to the enter instruction. This is used in the macro
468 FRAME_FIND_SAVED_REGS. */
470 ns32k_localcount (enter_pc
)
473 unsigned char localtype
;
476 localtype
= read_memory_integer (enter_pc
+2, 1);
477 if ((localtype
& 0x80) == 0)
478 localcount
= localtype
;
479 else if ((localtype
& 0xc0) == 0x80)
480 localcount
= (((localtype
& 0x3f) << 8)
481 | (read_memory_integer (enter_pc
+3, 1) & 0xff));
483 localcount
= (((localtype
& 0x3f) << 24)
484 | ((read_memory_integer (enter_pc
+3, 1) & 0xff) << 16)
485 | ((read_memory_integer (enter_pc
+4, 1) & 0xff) << 8 )
486 | (read_memory_integer (enter_pc
+5, 1) & 0xff));
491 * Get the address of the enter opcode for the function
492 * containing PC, if there is an enter for the function,
493 * and if the pc is between the enter and exit.
494 * Returns positive address if pc is between enter/exit,
495 * 1 if pc before enter or after exit, 0 otherwise.
499 ns32k_get_enter_addr (pc
)
502 CORE_ADDR enter_addr
;
505 if (ABOUT_TO_RETURN (pc
))
506 return 1; /* after exit */
508 enter_addr
= get_pc_function_start (pc
);
510 if (pc
== enter_addr
)
511 return 1; /* before enter */
513 op
= read_memory_integer (enter_addr
, 1);
516 return 0; /* function has no enter/exit */
518 return enter_addr
; /* pc is between enter and exit */
This page took 0.047177 seconds and 4 git commands to generate.