1 /* Print National Semiconductor 32000 instructions.
2 Copyright 1986, 1988, 1991, 1992, 1994, 1998, 2001, 2002
3 Free Software Foundation, Inc.
5 This file is part of opcodes library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
25 #if !defined(const) && !defined(__STDC__)
28 #include "opcode/ns32k.h"
31 static disassemble_info
*dis_info
;
34 * Hacks to get it to compile <= READ THESE AS FIXES NEEDED
36 #define INVALID_FLOAT(val, size) invalid_float((char *)val, size)
38 static int print_insn_arg
39 PARAMS ((int, int, int *, char *, bfd_vma
, char *, int));
40 static int get_displacement
PARAMS ((char *, int *));
41 static int invalid_float
PARAMS ((char *, int));
42 static long int read_memory_integer
PARAMS ((unsigned char *, int));
43 static int fetch_data
PARAMS ((struct disassemble_info
*, bfd_byte
*));
45 static void optlist
PARAMS ((int, const struct ns32k_option
*, char *));
46 static void list_search
PARAMS ((int, const struct ns32k_option
*, char *));
47 static int bit_extract
PARAMS ((bfd_byte
*, int, int));
48 static int bit_extract_simple
PARAMS ((bfd_byte
*, int, int));
49 static void bit_copy
PARAMS ((char *, int, int, char *));
50 static int sign_extend
PARAMS ((int, int));
51 static void flip_bytes
PARAMS ((char *, int));
53 static long read_memory_integer(addr
, nr
)
59 for (val
= 0, i
= nr
- 1; i
>= 0; i
--) {
61 val
|= (0xff & *(addr
+ i
));
66 /* 32000 instructions are never longer than this. */
74 /* Points to first byte not fetched. */
75 bfd_byte
*max_fetched
;
76 bfd_byte the_buffer
[MAXLEN
];
82 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
83 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
85 #define FETCH_DATA(info, addr) \
86 ((addr) <= ((struct private *)(info->private_data))->max_fetched \
87 ? 1 : fetch_data ((info), (addr)))
90 fetch_data (info
, addr
)
91 struct disassemble_info
*info
;
95 struct private *priv
= (struct private *)info
->private_data
;
96 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
98 status
= (*info
->read_memory_func
) (start
,
100 addr
- priv
->max_fetched
,
104 (*info
->memory_error_func
) (status
, start
, info
);
105 longjmp (priv
->bailout
, 1);
108 priv
->max_fetched
= addr
;
111 /* Number of elements in the opcode table. */
112 #define NOPCODES (sizeof ns32k_opcodes / sizeof ns32k_opcodes[0])
114 #define NEXT_IS_ADDR '|'
117 struct ns32k_option
{
118 char *pattern
; /* the option itself */
119 unsigned long value
; /* binary value of the option */
120 unsigned long match
; /* these bits must match */
124 static const struct ns32k_option opt_u
[]= /* restore, exit */
126 { "r0", 0x80, 0x80 },
127 { "r1", 0x40, 0x40 },
128 { "r2", 0x20, 0x20 },
129 { "r3", 0x10, 0x10 },
130 { "r4", 0x08, 0x08 },
131 { "r5", 0x04, 0x04 },
132 { "r6", 0x02, 0x02 },
133 { "r7", 0x01, 0x01 },
137 static const struct ns32k_option opt_U
[]= /* save, enter */
139 { "r0", 0x01, 0x01 },
140 { "r1", 0x02, 0x02 },
141 { "r2", 0x04, 0x04 },
142 { "r3", 0x08, 0x08 },
143 { "r4", 0x10, 0x10 },
144 { "r5", 0x20, 0x20 },
145 { "r6", 0x40, 0x40 },
146 { "r7", 0x80, 0x80 },
150 static const struct ns32k_option opt_O
[]= /* setcfg */
159 static const struct ns32k_option opt_C
[]= /* cinv */
167 static const struct ns32k_option opt_S
[]= /* string inst */
175 static const struct ns32k_option list_P532
[]= /* lpr spr */
188 { "intbase", 0xe, 0xf },
193 static const struct ns32k_option list_M532
[]= /* lmr smr */
197 { "tear", 0xb, 0xf },
198 { "ptb0", 0xc, 0xf },
199 { "ptb1", 0xd, 0xf },
200 { "ivar0", 0xe, 0xf },
201 { "ivar1", 0xf, 0xf },
205 static const struct ns32k_option list_P032
[]= /* lpr spr */
207 { "upsr", 0x0, 0xf },
212 { "intbase", 0xe, 0xf },
217 static const struct ns32k_option list_M032
[]= /* lmr smr */
219 { "bpr0", 0x0, 0xf },
220 { "bpr1", 0x1, 0xf },
225 { "bcnt", 0xb, 0xf },
226 { "ptb0", 0xc, 0xf },
227 { "ptb1", 0xd, 0xf },
234 * figure out which options are present
237 optlist(options
, optionP
, result
)
239 const struct ns32k_option
*optionP
;
243 sprintf(result
, "[]");
246 sprintf(result
, "[");
248 for (; (options
!= 0) && optionP
->pattern
; optionP
++) {
249 if ((options
& optionP
->match
) == optionP
->value
) {
250 /* we found a match, update result and options */
251 strcat(result
, optionP
->pattern
);
252 options
&= ~optionP
->value
;
253 if (options
!= 0) /* more options to come */
258 strcat(result
, "undefined");
264 list_search (reg_value
, optionP
, result
)
266 const struct ns32k_option
*optionP
;
269 for (; optionP
->pattern
; optionP
++) {
270 if ((reg_value
& optionP
->match
) == optionP
->value
) {
271 sprintf(result
, "%s", optionP
->pattern
);
275 sprintf(result
, "undefined");
279 * extract "count" bits starting "offset" bits
284 bit_extract (buffer
, offset
, count
)
292 buffer
+= offset
>> 3;
298 FETCH_DATA(dis_info
, buffer
+ 1);
299 if ((*buffer
& (1 << offset
)))
311 /* Like bit extract but the buffer is valid and doen't need to be
315 bit_extract_simple (buffer
, offset
, count
)
323 buffer
+= offset
>> 3;
329 if ((*buffer
& (1 << offset
)))
342 bit_copy (buffer
, offset
, count
, to
)
348 for(; count
> 8; count
-= 8, to
++, offset
+= 8)
349 *to
= bit_extract (buffer
, offset
, 8);
350 *to
= bit_extract (buffer
, offset
, count
);
355 sign_extend (value
, bits
)
358 value
= value
& ((1 << bits
) - 1);
359 return (value
& (1 << (bits
-1))
360 ? value
| (~((1 << bits
) - 1))
365 flip_bytes (ptr
, count
)
374 ptr
[0] = ptr
[count
-1];
381 /* Given a character C, does it represent a general addressing mode? */
383 ((c) == 'F' || (c) == 'L' || (c) == 'B' \
384 || (c) == 'W' || (c) == 'D' || (c) == 'A' || (c) == 'I' || (c) == 'Z')
386 /* Adressing modes. */
387 #define Adrmod_index_byte 0x1c
388 #define Adrmod_index_word 0x1d
389 #define Adrmod_index_doubleword 0x1e
390 #define Adrmod_index_quadword 0x1f
392 /* Is MODE an indexed addressing mode? */
393 #define Adrmod_is_index(mode) \
394 (mode == Adrmod_index_byte \
395 || mode == Adrmod_index_word \
396 || mode == Adrmod_index_doubleword \
397 || mode == Adrmod_index_quadword)
400 /* Print the 32000 instruction at address MEMADDR in debugged memory,
401 on STREAM. Returns length of the instruction, in bytes. */
404 print_insn_ns32k (memaddr
, info
)
406 disassemble_info
*info
;
408 register unsigned int i
;
410 unsigned short first_word
;
411 int ioffset
; /* bits into instruction */
412 int aoffset
; /* bits into arguments */
413 char arg_bufs
[MAX_ARGS
+1][ARG_LEN
];
417 bfd_byte
*buffer
= priv
.the_buffer
;
420 info
->private_data
= (PTR
) &priv
;
421 priv
.max_fetched
= priv
.the_buffer
;
422 priv
.insn_start
= memaddr
;
423 if (setjmp (priv
.bailout
) != 0)
427 /* Look for 8bit opcodes first. Other wise, fetching two bytes could take
428 * us over the end of accessible data unnecessarilly
430 FETCH_DATA(info
, buffer
+ 1);
431 for (i
= 0; i
< NOPCODES
; i
++)
432 if (ns32k_opcodes
[i
].opcode_id_size
<= 8
434 & (((unsigned long) 1 << ns32k_opcodes
[i
].opcode_id_size
) - 1))
435 == ns32k_opcodes
[i
].opcode_seed
))
438 /* Maybe it is 9 to 16 bits big */
439 FETCH_DATA(info
, buffer
+ 2);
440 first_word
= read_memory_integer(buffer
, 2);
442 for (i
= 0; i
< NOPCODES
; i
++)
444 & (((unsigned long) 1 << ns32k_opcodes
[i
].opcode_id_size
) - 1))
445 == ns32k_opcodes
[i
].opcode_seed
)
448 /* Handle undefined instructions. */
451 (*dis_info
->fprintf_func
)(dis_info
->stream
, "0%o", buffer
[0]);
456 (*dis_info
->fprintf_func
)(dis_info
->stream
, "%s", ns32k_opcodes
[i
].name
);
458 ioffset
= ns32k_opcodes
[i
].opcode_size
;
459 aoffset
= ns32k_opcodes
[i
].opcode_size
;
460 d
= ns32k_opcodes
[i
].operands
;
464 /* Offset in bits of the first thing beyond each index byte.
465 Element 0 is for operand A and element 1 is for operand B.
466 The rest are irrelevant, but we put them here so we don't
467 index outside the array. */
468 int index_offset
[MAX_ARGS
];
470 /* 0 for operand A, 1 for operand B, greater for other args. */
473 (*dis_info
->fprintf_func
)(dis_info
->stream
, "\t");
477 /* First we have to find and keep track of the index bytes,
478 if we are using scaled indexed addressing mode, since the index
479 bytes occur right after the basic instruction, not as part
480 of the addressing extension. */
483 int addr_mode
= bit_extract (buffer
, ioffset
- 5, 5);
485 if (Adrmod_is_index (addr_mode
))
488 index_offset
[0] = aoffset
;
491 if (d
[2] && Is_gen(d
[3]))
493 int addr_mode
= bit_extract (buffer
, ioffset
- 10, 5);
495 if (Adrmod_is_index (addr_mode
))
498 index_offset
[1] = aoffset
;
506 if (argnum
> maxarg
&& argnum
< MAX_ARGS
)
508 ioffset
= print_insn_arg (*d
, ioffset
, &aoffset
, buffer
,
509 memaddr
, arg_bufs
[argnum
],
510 index_offset
[whicharg
]);
514 for (argnum
= 0; argnum
<= maxarg
; argnum
++)
518 for (ch
= arg_bufs
[argnum
]; *ch
;)
520 if (*ch
== NEXT_IS_ADDR
)
523 addr
= bfd_scan_vma (ch
, NULL
, 16);
524 (*dis_info
->print_address_func
) (addr
, dis_info
);
525 while (*ch
&& *ch
!= NEXT_IS_ADDR
)
531 (*dis_info
->fprintf_func
)(dis_info
->stream
, "%c", *ch
++);
534 (*dis_info
->fprintf_func
)(dis_info
->stream
, ", ");
540 /* Print an instruction operand of category given by d. IOFFSET is
541 the bit position below which small (<1 byte) parts of the operand can
542 be found (usually in the basic instruction, but for indexed
543 addressing it can be in the index byte). AOFFSETP is a pointer to the
544 bit position of the addressing extension. BUFFER contains the
545 instruction. ADDR is where BUFFER was read from. Put the disassembled
546 version of the operand in RESULT. INDEX_OFFSET is the bit position
547 of the index byte (it contains garbage if this operand is not a
548 general operand using scaled indexed addressing mode). */
551 print_insn_arg (d
, ioffset
, aoffsetp
, buffer
, addr
, result
, index_offset
)
553 int ioffset
, *aoffsetp
;
573 /* a "gen" operand but 5 bits from the end of instruction */
583 addr_mode
= bit_extract (buffer
, ioffset
-5, 5);
587 case 0x0: case 0x1: case 0x2: case 0x3:
588 case 0x4: case 0x5: case 0x6: case 0x7:
589 /* register mode R0 -- R7 */
595 sprintf (result
, "f%d", addr_mode
);
598 sprintf (result
, "r%d", addr_mode
);
601 case 0x8: case 0x9: case 0xa: case 0xb:
602 case 0xc: case 0xd: case 0xe: case 0xf:
603 /* Register relative disp(R0 -- R7) */
604 disp1
= get_displacement (buffer
, aoffsetp
);
605 sprintf (result
, "%d(r%d)", disp1
, addr_mode
& 7);
610 /* Memory relative disp2(disp1(FP, SP, SB)) */
611 disp1
= get_displacement (buffer
, aoffsetp
);
612 disp2
= get_displacement (buffer
, aoffsetp
);
613 sprintf (result
, "%d(%d(%s))", disp2
, disp1
,
614 addr_mode
==0x10?"fp":addr_mode
==0x11?"sp":"sb");
618 sprintf (result
, "reserved");
624 case 'I': case 'Z': case 'A':
625 /* I and Z are output operands and can`t be immediate
626 * A is an address and we can`t have the address of
627 * an immediate either. We don't know how much to increase
628 * aoffsetp by since whatever generated this is broken
631 sprintf (result
, _("$<undefined>"));
634 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
635 Ivalue
= sign_extend (Ivalue
, 8);
637 sprintf (result
, "$%d", Ivalue
);
640 Ivalue
= bit_extract (buffer
, *aoffsetp
, 16);
641 flip_bytes ((char *) & Ivalue
, 2);
643 Ivalue
= sign_extend (Ivalue
, 16);
644 sprintf (result
, "$%d", Ivalue
);
647 Ivalue
= bit_extract (buffer
, *aoffsetp
, 32);
648 flip_bytes ((char *) & Ivalue
, 4);
650 sprintf (result
, "$%d", Ivalue
);
653 bit_copy (buffer
, *aoffsetp
, 32, (char *) &value
.f
);
654 flip_bytes ((char *) &value
.f
, 4);
656 if (INVALID_FLOAT (&value
.f
, 4))
657 sprintf (result
, "<<invalid float 0x%.8x>>", value
.i
[0]);
658 else /* assume host has ieee float */
659 sprintf (result
, "$%g", value
.f
);
662 bit_copy (buffer
, *aoffsetp
, 64, (char *) &value
.d
);
663 flip_bytes ((char *) &value
.d
, 8);
665 if (INVALID_FLOAT (&value
.d
, 8))
666 sprintf (result
, "<<invalid double 0x%.8x%.8x>>",
667 value
.i
[1], value
.i
[0]);
668 else /* assume host has ieee float */
669 sprintf (result
, "$%g", value
.d
);
675 disp1
= get_displacement (buffer
, aoffsetp
);
676 sprintf (result
, "@|%d|", disp1
);
679 /* External EXT(disp1) + disp2 (Mod table stuff) */
680 disp1
= get_displacement (buffer
, aoffsetp
);
681 disp2
= get_displacement (buffer
, aoffsetp
);
682 sprintf (result
, "EXT(%d) + %d", disp1
, disp2
);
685 /* Top of stack tos */
686 sprintf (result
, "tos");
689 /* Memory space disp(FP) */
690 disp1
= get_displacement (buffer
, aoffsetp
);
691 sprintf (result
, "%d(fp)", disp1
);
694 /* Memory space disp(SP) */
695 disp1
= get_displacement (buffer
, aoffsetp
);
696 sprintf (result
, "%d(sp)", disp1
);
699 /* Memory space disp(SB) */
700 disp1
= get_displacement (buffer
, aoffsetp
);
701 sprintf (result
, "%d(sb)", disp1
);
704 /* Memory space disp(PC) */
705 disp1
= get_displacement (buffer
, aoffsetp
);
706 *result
++ = NEXT_IS_ADDR
;
707 sprintf_vma (result
, addr
+ disp1
);
708 result
+= strlen (result
);
709 *result
++ = NEXT_IS_ADDR
;
716 /* Scaled index basemode[R0 -- R7:B,W,D,Q] */
717 index
= bit_extract (buffer
, index_offset
- 8, 3);
718 print_insn_arg (d
, index_offset
, aoffsetp
, buffer
, addr
,
721 static const char *ind
= "bwdq";
724 off
= result
+ strlen (result
);
725 sprintf (off
, "[r%d:%c]", index
,
733 Ivalue
= bit_extract (buffer
, ioffset
-4, 4);
734 Ivalue
= sign_extend (Ivalue
, 4);
735 sprintf (result
, "%d", Ivalue
);
739 Ivalue
= bit_extract (buffer
, ioffset
-3, 3);
740 sprintf (result
, "r%d", Ivalue
&7);
744 sprintf (result
, "%d", get_displacement (buffer
, aoffsetp
));
747 Ivalue
= get_displacement (buffer
, aoffsetp
);
749 * Warning!! HACK ALERT!
750 * Operand type 'b' is only used by the cmp{b,w,d} and
751 * movm{b,w,d} instructions; we need to know whether
752 * it's a `b' or `w' or `d' instruction; and for both
753 * cmpm and movm it's stored at the same place so we
754 * just grab two bits of the opcode and look at it...
757 size
= bit_extract(buffer
, ioffset
-6, 2);
758 if (size
== 0) /* 00 => b */
760 else if (size
== 1) /* 01 => w */
763 size
= 4; /* 11 => d */
765 sprintf (result
, "%d", (Ivalue
/ size
) + 1);
768 *result
++ = NEXT_IS_ADDR
;
769 sprintf_vma (result
, addr
+ get_displacement (buffer
, aoffsetp
));
770 result
+= strlen (result
);
771 *result
++ = NEXT_IS_ADDR
;
775 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
777 sprintf (result
, "0x%x", Ivalue
);
780 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
781 optlist(Ivalue
, opt_u
, result
);
785 Ivalue
= bit_extract(buffer
, *aoffsetp
, 8);
786 optlist(Ivalue
, opt_U
, result
);
790 Ivalue
= bit_extract(buffer
, ioffset
-9, 9);
791 optlist(Ivalue
, opt_O
, result
);
795 Ivalue
= bit_extract(buffer
, ioffset
-4, 4);
796 optlist(Ivalue
, opt_C
, result
);
800 Ivalue
= bit_extract(buffer
, ioffset
- 8, 8);
801 optlist(Ivalue
, opt_S
, result
);
805 Ivalue
= bit_extract(buffer
, ioffset
-4, 4);
806 list_search(Ivalue
, 0 ? list_M032
: list_M532
, result
);
810 Ivalue
= bit_extract(buffer
, ioffset
-4, 4);
811 list_search(Ivalue
, 0 ? list_P032
: list_P532
, result
);
815 Ivalue
= bit_extract(buffer
, *aoffsetp
, 3);
816 sprintf(result
, "%d", Ivalue
);
820 Ivalue
= bit_extract(buffer
, *aoffsetp
, 5);
821 sprintf(result
, "%d", Ivalue
+ 1);
829 get_displacement (buffer
, aoffsetp
)
836 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
837 switch (Ivalue
& 0xc0)
841 Ivalue
= sign_extend (Ivalue
, 7);
845 Ivalue2
= bit_extract (buffer
, *aoffsetp
, 16);
846 flip_bytes ((char *) & Ivalue2
, 2);
847 Ivalue
= sign_extend (Ivalue2
, 14);
851 Ivalue
= bit_extract (buffer
, *aoffsetp
, 32);
852 flip_bytes ((char *) & Ivalue
, 4);
853 Ivalue
= sign_extend (Ivalue
, 30);
861 #if 1 /* a version that should work on ns32k f's&d's on any machine */
863 invalid_float (p
, len
)
870 val
= (bit_extract_simple(p
, 23, 8)/*exponent*/ == 0xff
871 || (bit_extract_simple(p
, 23, 8)/*exponent*/ == 0 &&
872 bit_extract_simple(p
, 0, 23)/*mantisa*/ != 0));
874 val
= (bit_extract_simple(p
, 52, 11)/*exponent*/ == 0x7ff
875 || (bit_extract_simple(p
, 52, 11)/*exponent*/ == 0
876 && (bit_extract_simple(p
, 0, 32)/*low mantisa*/ != 0
877 || bit_extract_simple(p
, 32, 20)/*high mantisa*/ != 0)));
884 /* assumes the bytes have been swapped to local order */
885 typedef union { double d
;
887 struct { unsigned m
:23, e
:8, :1;} sf
;
888 struct { unsigned lm
; unsigned m
:20, e
:11, :1;} sd
;
892 invalid_float (p
, len
)
893 register float_type_u
*p
;
897 if ( len
== sizeof (float) )
898 val
= (p
->sf
.e
== 0xff
899 || (p
->sf
.e
== 0 && p
->sf
.m
!= 0));
900 else if ( len
== sizeof (double) )
901 val
= (p
->sd
.e
== 0x7ff
902 || (p
->sd
.e
== 0 && (p
->sd
.m
!= 0 || p
->sd
.lm
!= 0)));