1 /* Print National Semiconductor 32000 instructions.
2 Copyright (C) 1986-2020 Free Software Foundation, Inc.
4 This file is part of the GNU opcodes library.
6 This library 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 3, or (at your option)
11 It is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 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., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
23 #include "disassemble.h"
24 #if !defined(const) && !defined(__STDC__)
27 #include "opcode/ns32k.h"
30 static disassemble_info
*dis_info
;
32 /* Hacks to get it to compile <= READ THESE AS FIXES NEEDED. */
33 #define INVALID_FLOAT(val, size) invalid_float ((bfd_byte *) val, size)
36 read_memory_integer (unsigned char * addr
, int nr
)
41 for (val
= 0, i
= nr
- 1; i
>= 0; i
--)
44 val
|= (0xff & *(addr
+ i
));
49 /* 32000 instructions are never longer than this. */
56 /* Points to first byte not fetched. */
57 bfd_byte
*max_fetched
;
58 bfd_byte the_buffer
[MAXLEN
];
60 OPCODES_SIGJMP_BUF bailout
;
64 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
65 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
67 #define FETCH_DATA(info, addr) \
68 ((addr) <= ((struct private *)(info->private_data))->max_fetched \
69 ? 1 : fetch_data ((info), (addr)))
72 fetch_data (struct disassemble_info
*info
, bfd_byte
*addr
)
75 struct private *priv
= (struct private *) info
->private_data
;
76 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
78 status
= (*info
->read_memory_func
) (start
,
80 addr
- priv
->max_fetched
,
84 (*info
->memory_error_func
) (status
, start
, info
);
85 OPCODES_SIGLONGJMP (priv
->bailout
, 1);
88 priv
->max_fetched
= addr
;
92 /* Number of elements in the opcode table. */
93 #define NOPCODES (sizeof ns32k_opcodes / sizeof ns32k_opcodes[0])
95 #define NEXT_IS_ADDR '|'
100 char *pattern
; /* The option itself. */
101 unsigned long value
; /* Binary value of the option. */
102 unsigned long match
; /* These bits must match. */
106 static const struct ns32k_option opt_u
[]= /* Restore, exit. */
108 { "r0", 0x80, 0x80 },
109 { "r1", 0x40, 0x40 },
110 { "r2", 0x20, 0x20 },
111 { "r3", 0x10, 0x10 },
112 { "r4", 0x08, 0x08 },
113 { "r5", 0x04, 0x04 },
114 { "r6", 0x02, 0x02 },
115 { "r7", 0x01, 0x01 },
119 static const struct ns32k_option opt_U
[]= /* Save, enter. */
121 { "r0", 0x01, 0x01 },
122 { "r1", 0x02, 0x02 },
123 { "r2", 0x04, 0x04 },
124 { "r3", 0x08, 0x08 },
125 { "r4", 0x10, 0x10 },
126 { "r5", 0x20, 0x20 },
127 { "r6", 0x40, 0x40 },
128 { "r7", 0x80, 0x80 },
132 static const struct ns32k_option opt_O
[]= /* Setcfg. */
141 static const struct ns32k_option opt_C
[]= /* Cinv. */
149 static const struct ns32k_option opt_S
[]= /* String inst. */
157 static const struct ns32k_option list_P532
[]= /* Lpr spr. */
170 { "intbase", 0xe, 0xf },
175 static const struct ns32k_option list_M532
[]= /* Lmr smr. */
179 { "tear", 0xb, 0xf },
180 { "ptb0", 0xc, 0xf },
181 { "ptb1", 0xd, 0xf },
182 { "ivar0", 0xe, 0xf },
183 { "ivar1", 0xf, 0xf },
187 static const struct ns32k_option list_P032
[]= /* Lpr spr. */
189 { "upsr", 0x0, 0xf },
194 { "intbase", 0xe, 0xf },
199 static const struct ns32k_option list_M032
[]= /* Lmr smr. */
201 { "bpr0", 0x0, 0xf },
202 { "bpr1", 0x1, 0xf },
207 { "bcnt", 0xb, 0xf },
208 { "ptb0", 0xc, 0xf },
209 { "ptb1", 0xd, 0xf },
215 /* Figure out which options are present. */
218 optlist (int options
, const struct ns32k_option
* optionP
, char * result
)
222 sprintf (result
, "[]");
226 sprintf (result
, "[");
228 for (; (options
!= 0) && optionP
->pattern
; optionP
++)
230 if ((options
& optionP
->match
) == optionP
->value
)
232 /* We found a match, update result and options. */
233 strcat (result
, optionP
->pattern
);
234 options
&= ~optionP
->value
;
235 if (options
!= 0) /* More options to come. */
236 strcat (result
, ",");
241 strcat (result
, "undefined");
243 strcat (result
, "]");
247 list_search (int reg_value
, const struct ns32k_option
*optionP
, char *result
)
249 for (; optionP
->pattern
; optionP
++)
251 if ((reg_value
& optionP
->match
) == optionP
->value
)
253 sprintf (result
, "%s", optionP
->pattern
);
257 sprintf (result
, "undefined");
260 /* Extract "count" bits starting "offset" bits into buffer. */
263 bit_extract (bfd_byte
*buffer
, int offset
, int count
)
268 if (offset
< 0 || count
< 0)
270 buffer
+= offset
>> 3;
276 FETCH_DATA (dis_info
, buffer
+ 1);
277 if ((*buffer
& (1 << offset
)))
289 /* Like bit extract but the buffer is valid and doen't need to be fetched. */
292 bit_extract_simple (bfd_byte
*buffer
, int offset
, int count
)
297 if (offset
< 0 || count
< 0)
299 buffer
+= offset
>> 3;
305 if ((*buffer
& (1 << offset
)))
318 bit_copy (bfd_byte
*buffer
, int offset
, int count
, char *to
)
320 if (offset
< 0 || count
< 0)
322 for (; count
> 8; count
-= 8, to
++, offset
+= 8)
323 *to
= bit_extract (buffer
, offset
, 8);
324 *to
= bit_extract (buffer
, offset
, count
);
328 sign_extend (unsigned int value
, unsigned int bits
)
330 unsigned int sign
= 1u << (bits
- 1);
331 return ((value
& (sign
+ sign
- 1)) ^ sign
) - sign
;
335 flip_bytes (char *ptr
, int count
)
342 ptr
[0] = ptr
[count
- 1];
343 ptr
[count
- 1] = tmp
;
349 /* Given a character C, does it represent a general addressing mode? */
351 ((c) == 'F' || (c) == 'L' || (c) == 'B' \
352 || (c) == 'W' || (c) == 'D' || (c) == 'A' || (c) == 'I' || (c) == 'Z')
354 /* Adressing modes. */
355 #define Adrmod_index_byte 0x1c
356 #define Adrmod_index_word 0x1d
357 #define Adrmod_index_doubleword 0x1e
358 #define Adrmod_index_quadword 0x1f
360 /* Is MODE an indexed addressing mode? */
361 #define Adrmod_is_index(mode) \
362 ( mode == Adrmod_index_byte \
363 || mode == Adrmod_index_word \
364 || mode == Adrmod_index_doubleword \
365 || mode == Adrmod_index_quadword)
369 get_displacement (bfd_byte
*buffer
, int *aoffsetp
)
374 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
375 switch (Ivalue
& 0xc0)
379 Ivalue
= sign_extend (Ivalue
, 7);
383 Ivalue2
= bit_extract (buffer
, *aoffsetp
, 16);
384 flip_bytes ((char *) & Ivalue2
, 2);
385 Ivalue
= sign_extend (Ivalue2
, 14);
389 Ivalue
= bit_extract (buffer
, *aoffsetp
, 32);
390 flip_bytes ((char *) & Ivalue
, 4);
391 Ivalue
= sign_extend (Ivalue
, 30);
398 #if 1 /* A version that should work on ns32k f's&d's on any machine. */
400 invalid_float (bfd_byte
*p
, int len
)
405 val
= (bit_extract_simple (p
, 23, 8)/*exponent*/ == 0xff
406 || (bit_extract_simple (p
, 23, 8)/*exponent*/ == 0
407 && bit_extract_simple (p
, 0, 23)/*mantisa*/ != 0));
409 val
= (bit_extract_simple (p
, 52, 11)/*exponent*/ == 0x7ff
410 || (bit_extract_simple (p
, 52, 11)/*exponent*/ == 0
411 && (bit_extract_simple (p
, 0, 32)/*low mantisa*/ != 0
412 || bit_extract_simple (p
, 32, 20)/*high mantisa*/ != 0)));
418 /* Assumes the bytes have been swapped to local order. */
423 struct { unsigned m
:23, e
:8, :1;} sf
;
424 struct { unsigned lm
; unsigned m
:20, e
:11, :1;} sd
;
428 invalid_float (float_type_u
*p
, int len
)
432 if (len
== sizeof (float))
433 val
= (p
->sf
.e
== 0xff
434 || (p
->sf
.e
== 0 && p
->sf
.m
!= 0));
435 else if (len
== sizeof (double))
436 val
= (p
->sd
.e
== 0x7ff
437 || (p
->sd
.e
== 0 && (p
->sd
.m
!= 0 || p
->sd
.lm
!= 0)));
444 /* Print an instruction operand of category given by d. IOFFSET is
445 the bit position below which small (<1 byte) parts of the operand can
446 be found (usually in the basic instruction, but for indexed
447 addressing it can be in the index byte). AOFFSETP is a pointer to the
448 bit position of the addressing extension. BUFFER contains the
449 instruction. ADDR is where BUFFER was read from. Put the disassembled
450 version of the operand in RESULT. INDEX_OFFSET is the bit position
451 of the index byte (it contains garbage if this operand is not a
452 general operand using scaled indexed addressing mode). */
455 print_insn_arg (int d
,
477 /* A "gen" operand but 5 bits from the end of instruction. */
488 addr_mode
= bit_extract (buffer
, ioffset
- 5, 5);
492 case 0x0: case 0x1: case 0x2: case 0x3:
493 case 0x4: case 0x5: case 0x6: case 0x7:
494 /* Register mode R0 -- R7. */
500 sprintf (result
, "f%d", addr_mode
);
503 sprintf (result
, "r%d", addr_mode
);
506 case 0x8: case 0x9: case 0xa: case 0xb:
507 case 0xc: case 0xd: case 0xe: case 0xf:
508 /* Register relative disp(R0 -- R7). */
509 disp1
= get_displacement (buffer
, aoffsetp
);
510 sprintf (result
, "%d(r%d)", disp1
, addr_mode
& 7);
515 /* Memory relative disp2(disp1(FP, SP, SB)). */
516 disp1
= get_displacement (buffer
, aoffsetp
);
517 disp2
= get_displacement (buffer
, aoffsetp
);
518 sprintf (result
, "%d(%d(%s))", disp2
, disp1
,
519 addr_mode
== 0x10 ? "fp" : addr_mode
== 0x11 ? "sp" : "sb");
523 sprintf (result
, "reserved");
532 /* I and Z are output operands and can`t be immediate
533 A is an address and we can`t have the address of
534 an immediate either. We don't know how much to increase
535 aoffsetp by since whatever generated this is broken
537 sprintf (result
, _("$<undefined>"));
540 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
541 Ivalue
= sign_extend (Ivalue
, 8);
543 sprintf (result
, "$%d", Ivalue
);
546 Ivalue
= bit_extract (buffer
, *aoffsetp
, 16);
547 flip_bytes ((char *) & Ivalue
, 2);
549 Ivalue
= sign_extend (Ivalue
, 16);
550 sprintf (result
, "$%d", Ivalue
);
553 Ivalue
= bit_extract (buffer
, *aoffsetp
, 32);
554 flip_bytes ((char *) & Ivalue
, 4);
556 sprintf (result
, "$%d", Ivalue
);
559 bit_copy (buffer
, *aoffsetp
, 32, (char *) &value
.f
);
560 flip_bytes ((char *) &value
.f
, 4);
562 if (INVALID_FLOAT (&value
.f
, 4))
563 sprintf (result
, "<<invalid float 0x%.8x>>", value
.i
[0]);
564 else /* Assume host has ieee float. */
565 sprintf (result
, "$%g", value
.f
);
568 bit_copy (buffer
, *aoffsetp
, 64, (char *) &value
.d
);
569 flip_bytes ((char *) &value
.d
, 8);
571 if (INVALID_FLOAT (&value
.d
, 8))
572 sprintf (result
, "<<invalid double 0x%.8x%.8x>>",
573 value
.i
[1], value
.i
[0]);
574 else /* Assume host has ieee float. */
575 sprintf (result
, "$%g", value
.d
);
580 /* Absolute @disp. */
581 disp1
= get_displacement (buffer
, aoffsetp
);
582 sprintf (result
, "@|%d|", disp1
);
585 /* External EXT(disp1) + disp2 (Mod table stuff). */
586 disp1
= get_displacement (buffer
, aoffsetp
);
587 disp2
= get_displacement (buffer
, aoffsetp
);
588 sprintf (result
, "EXT(%d) + %d", disp1
, disp2
);
591 /* Top of stack tos. */
592 sprintf (result
, "tos");
595 /* Memory space disp(FP). */
596 disp1
= get_displacement (buffer
, aoffsetp
);
597 sprintf (result
, "%d(fp)", disp1
);
600 /* Memory space disp(SP). */
601 disp1
= get_displacement (buffer
, aoffsetp
);
602 sprintf (result
, "%d(sp)", disp1
);
605 /* Memory space disp(SB). */
606 disp1
= get_displacement (buffer
, aoffsetp
);
607 sprintf (result
, "%d(sb)", disp1
);
610 /* Memory space disp(PC). */
611 disp1
= get_displacement (buffer
, aoffsetp
);
612 *result
++ = NEXT_IS_ADDR
;
613 sprintf_vma (result
, addr
+ disp1
);
614 result
+= strlen (result
);
615 *result
++ = NEXT_IS_ADDR
;
624 static const char *ind
= "bwdq";
627 /* Scaled index basemode[R0 -- R7:B,W,D,Q]. */
628 bit_index
= bit_extract (buffer
, index_offset
- 8, 3);
629 print_insn_arg (d
, index_offset
, aoffsetp
, buffer
, addr
,
631 off
= result
+ strlen (result
);
632 sprintf (off
, "[r%d:%c]", bit_index
, ind
[addr_mode
& 3]);
639 Ivalue
= bit_extract (buffer
, ioffset
-4, 4);
640 Ivalue
= sign_extend (Ivalue
, 4);
641 sprintf (result
, "%d", Ivalue
);
645 Ivalue
= bit_extract (buffer
, ioffset
-3, 3);
646 sprintf (result
, "r%d", Ivalue
&7);
650 sprintf (result
, "%d", get_displacement (buffer
, aoffsetp
));
653 Ivalue
= get_displacement (buffer
, aoffsetp
);
654 /* Warning!! HACK ALERT!
655 Operand type 'b' is only used by the cmp{b,w,d} and
656 movm{b,w,d} instructions; we need to know whether
657 it's a `b' or `w' or `d' instruction; and for both
658 cmpm and movm it's stored at the same place so we
659 just grab two bits of the opcode and look at it... */
660 size
= bit_extract(buffer
, ioffset
-6, 2);
661 if (size
== 0) /* 00 => b. */
663 else if (size
== 1) /* 01 => w. */
666 size
= 4; /* 11 => d. */
668 sprintf (result
, "%d", (Ivalue
/ size
) + 1);
671 *result
++ = NEXT_IS_ADDR
;
672 sprintf_vma (result
, addr
+ get_displacement (buffer
, aoffsetp
));
673 result
+= strlen (result
);
674 *result
++ = NEXT_IS_ADDR
;
678 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
680 sprintf (result
, "0x%x", Ivalue
);
683 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
684 optlist (Ivalue
, opt_u
, result
);
688 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
689 optlist (Ivalue
, opt_U
, result
);
693 Ivalue
= bit_extract (buffer
, ioffset
- 9, 9);
694 optlist (Ivalue
, opt_O
, result
);
698 Ivalue
= bit_extract (buffer
, ioffset
- 4, 4);
699 optlist (Ivalue
, opt_C
, result
);
703 Ivalue
= bit_extract (buffer
, ioffset
- 8, 8);
704 optlist (Ivalue
, opt_S
, result
);
708 Ivalue
= bit_extract (buffer
, ioffset
- 4, 4);
709 list_search (Ivalue
, 0 ? list_M032
: list_M532
, result
);
713 Ivalue
= bit_extract (buffer
, ioffset
- 4, 4);
714 list_search (Ivalue
, 0 ? list_P032
: list_P532
, result
);
718 Ivalue
= bit_extract (buffer
, *aoffsetp
, 3);
719 sprintf (result
, "%d", Ivalue
);
723 Ivalue
= bit_extract(buffer
, *aoffsetp
, 5);
724 sprintf (result
, "%d", Ivalue
+ 1);
732 /* Print the 32000 instruction at address MEMADDR in debugged memory,
733 on STREAM. Returns length of the instruction, in bytes. */
736 print_insn_ns32k (bfd_vma memaddr
, disassemble_info
*info
)
740 unsigned short first_word
;
741 int ioffset
; /* Bits into instruction. */
742 int aoffset
; /* Bits into arguments. */
743 char arg_bufs
[MAX_ARGS
+1][ARG_LEN
];
747 bfd_byte
*buffer
= priv
.the_buffer
;
750 info
->private_data
= & priv
;
751 priv
.max_fetched
= priv
.the_buffer
;
752 priv
.insn_start
= memaddr
;
753 if (OPCODES_SIGSETJMP (priv
.bailout
) != 0)
757 /* Look for 8bit opcodes first. Other wise, fetching two bytes could take
758 us over the end of accessible data unnecessarilly. */
759 FETCH_DATA (info
, buffer
+ 1);
760 for (i
= 0; i
< NOPCODES
; i
++)
761 if (ns32k_opcodes
[i
].opcode_id_size
<= 8
763 & (((unsigned long) 1 << ns32k_opcodes
[i
].opcode_id_size
) - 1))
764 == ns32k_opcodes
[i
].opcode_seed
))
768 /* Maybe it is 9 to 16 bits big. */
769 FETCH_DATA (info
, buffer
+ 2);
770 first_word
= read_memory_integer(buffer
, 2);
772 for (i
= 0; i
< NOPCODES
; i
++)
774 & (((unsigned long) 1 << ns32k_opcodes
[i
].opcode_id_size
) - 1))
775 == ns32k_opcodes
[i
].opcode_seed
)
778 /* Handle undefined instructions. */
781 (*dis_info
->fprintf_func
)(dis_info
->stream
, "0%o", buffer
[0]);
786 (*dis_info
->fprintf_func
)(dis_info
->stream
, "%s", ns32k_opcodes
[i
].name
);
788 ioffset
= ns32k_opcodes
[i
].opcode_size
;
789 aoffset
= ns32k_opcodes
[i
].opcode_size
;
790 d
= ns32k_opcodes
[i
].operands
;
794 /* Offset in bits of the first thing beyond each index byte.
795 Element 0 is for operand A and element 1 is for operand B.
796 The rest are irrelevant, but we put them here so we don't
797 index outside the array. */
798 int index_offset
[MAX_ARGS
];
800 /* 0 for operand A, 1 for operand B, greater for other args. */
803 (*dis_info
->fprintf_func
)(dis_info
->stream
, "\t");
807 /* First we have to find and keep track of the index bytes,
808 if we are using scaled indexed addressing mode, since the index
809 bytes occur right after the basic instruction, not as part
810 of the addressing extension. */
813 int addr_mode
= bit_extract (buffer
, ioffset
- 5, 5);
815 if (Adrmod_is_index (addr_mode
))
818 index_offset
[0] = aoffset
;
822 if (d
[2] && Is_gen(d
[3]))
824 int addr_mode
= bit_extract (buffer
, ioffset
- 10, 5);
826 if (Adrmod_is_index (addr_mode
))
829 index_offset
[1] = aoffset
;
837 if (argnum
> maxarg
&& argnum
< MAX_ARGS
)
839 ioffset
= print_insn_arg (*d
, ioffset
, &aoffset
, buffer
,
840 memaddr
, arg_bufs
[argnum
],
841 index_offset
[whicharg
]);
847 for (argnum
= 0; argnum
<= maxarg
; argnum
++)
852 for (ch
= arg_bufs
[argnum
]; *ch
;)
854 if (*ch
== NEXT_IS_ADDR
)
857 addr
= bfd_scan_vma (ch
, NULL
, 16);
858 (*dis_info
->print_address_func
) (addr
, dis_info
);
859 while (*ch
&& *ch
!= NEXT_IS_ADDR
)
865 (*dis_info
->fprintf_func
)(dis_info
->stream
, "%c", *ch
++);
868 (*dis_info
->fprintf_func
)(dis_info
->stream
, ", ");