1 /* Print National Semiconductor 32000 instructions.
2 Copyright (C) 1986-2019 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 (int value
, int bits
)
330 value
= value
& ((1 << bits
) - 1);
331 return (value
& (1 << (bits
- 1))
332 ? value
| (~((1 << bits
) - 1))
337 flip_bytes (char *ptr
, int count
)
344 ptr
[0] = ptr
[count
- 1];
345 ptr
[count
- 1] = tmp
;
351 /* Given a character C, does it represent a general addressing mode? */
353 ((c) == 'F' || (c) == 'L' || (c) == 'B' \
354 || (c) == 'W' || (c) == 'D' || (c) == 'A' || (c) == 'I' || (c) == 'Z')
356 /* Adressing modes. */
357 #define Adrmod_index_byte 0x1c
358 #define Adrmod_index_word 0x1d
359 #define Adrmod_index_doubleword 0x1e
360 #define Adrmod_index_quadword 0x1f
362 /* Is MODE an indexed addressing mode? */
363 #define Adrmod_is_index(mode) \
364 ( mode == Adrmod_index_byte \
365 || mode == Adrmod_index_word \
366 || mode == Adrmod_index_doubleword \
367 || mode == Adrmod_index_quadword)
371 get_displacement (bfd_byte
*buffer
, int *aoffsetp
)
376 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
377 switch (Ivalue
& 0xc0)
381 Ivalue
= sign_extend (Ivalue
, 7);
385 Ivalue2
= bit_extract (buffer
, *aoffsetp
, 16);
386 flip_bytes ((char *) & Ivalue2
, 2);
387 Ivalue
= sign_extend (Ivalue2
, 14);
391 Ivalue
= bit_extract (buffer
, *aoffsetp
, 32);
392 flip_bytes ((char *) & Ivalue
, 4);
393 Ivalue
= sign_extend (Ivalue
, 30);
400 #if 1 /* A version that should work on ns32k f's&d's on any machine. */
402 invalid_float (bfd_byte
*p
, int len
)
407 val
= (bit_extract_simple (p
, 23, 8)/*exponent*/ == 0xff
408 || (bit_extract_simple (p
, 23, 8)/*exponent*/ == 0
409 && bit_extract_simple (p
, 0, 23)/*mantisa*/ != 0));
411 val
= (bit_extract_simple (p
, 52, 11)/*exponent*/ == 0x7ff
412 || (bit_extract_simple (p
, 52, 11)/*exponent*/ == 0
413 && (bit_extract_simple (p
, 0, 32)/*low mantisa*/ != 0
414 || bit_extract_simple (p
, 32, 20)/*high mantisa*/ != 0)));
420 /* Assumes the bytes have been swapped to local order. */
425 struct { unsigned m
:23, e
:8, :1;} sf
;
426 struct { unsigned lm
; unsigned m
:20, e
:11, :1;} sd
;
430 invalid_float (float_type_u
*p
, int len
)
434 if (len
== sizeof (float))
435 val
= (p
->sf
.e
== 0xff
436 || (p
->sf
.e
== 0 && p
->sf
.m
!= 0));
437 else if (len
== sizeof (double))
438 val
= (p
->sd
.e
== 0x7ff
439 || (p
->sd
.e
== 0 && (p
->sd
.m
!= 0 || p
->sd
.lm
!= 0)));
446 /* Print an instruction operand of category given by d. IOFFSET is
447 the bit position below which small (<1 byte) parts of the operand can
448 be found (usually in the basic instruction, but for indexed
449 addressing it can be in the index byte). AOFFSETP is a pointer to the
450 bit position of the addressing extension. BUFFER contains the
451 instruction. ADDR is where BUFFER was read from. Put the disassembled
452 version of the operand in RESULT. INDEX_OFFSET is the bit position
453 of the index byte (it contains garbage if this operand is not a
454 general operand using scaled indexed addressing mode). */
457 print_insn_arg (int d
,
479 /* A "gen" operand but 5 bits from the end of instruction. */
490 addr_mode
= bit_extract (buffer
, ioffset
- 5, 5);
494 case 0x0: case 0x1: case 0x2: case 0x3:
495 case 0x4: case 0x5: case 0x6: case 0x7:
496 /* Register mode R0 -- R7. */
502 sprintf (result
, "f%d", addr_mode
);
505 sprintf (result
, "r%d", addr_mode
);
508 case 0x8: case 0x9: case 0xa: case 0xb:
509 case 0xc: case 0xd: case 0xe: case 0xf:
510 /* Register relative disp(R0 -- R7). */
511 disp1
= get_displacement (buffer
, aoffsetp
);
512 sprintf (result
, "%d(r%d)", disp1
, addr_mode
& 7);
517 /* Memory relative disp2(disp1(FP, SP, SB)). */
518 disp1
= get_displacement (buffer
, aoffsetp
);
519 disp2
= get_displacement (buffer
, aoffsetp
);
520 sprintf (result
, "%d(%d(%s))", disp2
, disp1
,
521 addr_mode
== 0x10 ? "fp" : addr_mode
== 0x11 ? "sp" : "sb");
525 sprintf (result
, "reserved");
534 /* I and Z are output operands and can`t be immediate
535 A is an address and we can`t have the address of
536 an immediate either. We don't know how much to increase
537 aoffsetp by since whatever generated this is broken
539 sprintf (result
, _("$<undefined>"));
542 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
543 Ivalue
= sign_extend (Ivalue
, 8);
545 sprintf (result
, "$%d", Ivalue
);
548 Ivalue
= bit_extract (buffer
, *aoffsetp
, 16);
549 flip_bytes ((char *) & Ivalue
, 2);
551 Ivalue
= sign_extend (Ivalue
, 16);
552 sprintf (result
, "$%d", Ivalue
);
555 Ivalue
= bit_extract (buffer
, *aoffsetp
, 32);
556 flip_bytes ((char *) & Ivalue
, 4);
558 sprintf (result
, "$%d", Ivalue
);
561 bit_copy (buffer
, *aoffsetp
, 32, (char *) &value
.f
);
562 flip_bytes ((char *) &value
.f
, 4);
564 if (INVALID_FLOAT (&value
.f
, 4))
565 sprintf (result
, "<<invalid float 0x%.8x>>", value
.i
[0]);
566 else /* Assume host has ieee float. */
567 sprintf (result
, "$%g", value
.f
);
570 bit_copy (buffer
, *aoffsetp
, 64, (char *) &value
.d
);
571 flip_bytes ((char *) &value
.d
, 8);
573 if (INVALID_FLOAT (&value
.d
, 8))
574 sprintf (result
, "<<invalid double 0x%.8x%.8x>>",
575 value
.i
[1], value
.i
[0]);
576 else /* Assume host has ieee float. */
577 sprintf (result
, "$%g", value
.d
);
582 /* Absolute @disp. */
583 disp1
= get_displacement (buffer
, aoffsetp
);
584 sprintf (result
, "@|%d|", disp1
);
587 /* External EXT(disp1) + disp2 (Mod table stuff). */
588 disp1
= get_displacement (buffer
, aoffsetp
);
589 disp2
= get_displacement (buffer
, aoffsetp
);
590 sprintf (result
, "EXT(%d) + %d", disp1
, disp2
);
593 /* Top of stack tos. */
594 sprintf (result
, "tos");
597 /* Memory space disp(FP). */
598 disp1
= get_displacement (buffer
, aoffsetp
);
599 sprintf (result
, "%d(fp)", disp1
);
602 /* Memory space disp(SP). */
603 disp1
= get_displacement (buffer
, aoffsetp
);
604 sprintf (result
, "%d(sp)", disp1
);
607 /* Memory space disp(SB). */
608 disp1
= get_displacement (buffer
, aoffsetp
);
609 sprintf (result
, "%d(sb)", disp1
);
612 /* Memory space disp(PC). */
613 disp1
= get_displacement (buffer
, aoffsetp
);
614 *result
++ = NEXT_IS_ADDR
;
615 sprintf_vma (result
, addr
+ disp1
);
616 result
+= strlen (result
);
617 *result
++ = NEXT_IS_ADDR
;
626 static const char *ind
= "bwdq";
629 /* Scaled index basemode[R0 -- R7:B,W,D,Q]. */
630 bit_index
= bit_extract (buffer
, index_offset
- 8, 3);
631 print_insn_arg (d
, index_offset
, aoffsetp
, buffer
, addr
,
633 off
= result
+ strlen (result
);
634 sprintf (off
, "[r%d:%c]", bit_index
, ind
[addr_mode
& 3]);
641 Ivalue
= bit_extract (buffer
, ioffset
-4, 4);
642 Ivalue
= sign_extend (Ivalue
, 4);
643 sprintf (result
, "%d", Ivalue
);
647 Ivalue
= bit_extract (buffer
, ioffset
-3, 3);
648 sprintf (result
, "r%d", Ivalue
&7);
652 sprintf (result
, "%d", get_displacement (buffer
, aoffsetp
));
655 Ivalue
= get_displacement (buffer
, aoffsetp
);
656 /* Warning!! HACK ALERT!
657 Operand type 'b' is only used by the cmp{b,w,d} and
658 movm{b,w,d} instructions; we need to know whether
659 it's a `b' or `w' or `d' instruction; and for both
660 cmpm and movm it's stored at the same place so we
661 just grab two bits of the opcode and look at it... */
662 size
= bit_extract(buffer
, ioffset
-6, 2);
663 if (size
== 0) /* 00 => b. */
665 else if (size
== 1) /* 01 => w. */
668 size
= 4; /* 11 => d. */
670 sprintf (result
, "%d", (Ivalue
/ size
) + 1);
673 *result
++ = NEXT_IS_ADDR
;
674 sprintf_vma (result
, addr
+ get_displacement (buffer
, aoffsetp
));
675 result
+= strlen (result
);
676 *result
++ = NEXT_IS_ADDR
;
680 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
682 sprintf (result
, "0x%x", Ivalue
);
685 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
686 optlist (Ivalue
, opt_u
, result
);
690 Ivalue
= bit_extract (buffer
, *aoffsetp
, 8);
691 optlist (Ivalue
, opt_U
, result
);
695 Ivalue
= bit_extract (buffer
, ioffset
- 9, 9);
696 optlist (Ivalue
, opt_O
, result
);
700 Ivalue
= bit_extract (buffer
, ioffset
- 4, 4);
701 optlist (Ivalue
, opt_C
, result
);
705 Ivalue
= bit_extract (buffer
, ioffset
- 8, 8);
706 optlist (Ivalue
, opt_S
, result
);
710 Ivalue
= bit_extract (buffer
, ioffset
- 4, 4);
711 list_search (Ivalue
, 0 ? list_M032
: list_M532
, result
);
715 Ivalue
= bit_extract (buffer
, ioffset
- 4, 4);
716 list_search (Ivalue
, 0 ? list_P032
: list_P532
, result
);
720 Ivalue
= bit_extract (buffer
, *aoffsetp
, 3);
721 sprintf (result
, "%d", Ivalue
);
725 Ivalue
= bit_extract(buffer
, *aoffsetp
, 5);
726 sprintf (result
, "%d", Ivalue
+ 1);
734 /* Print the 32000 instruction at address MEMADDR in debugged memory,
735 on STREAM. Returns length of the instruction, in bytes. */
738 print_insn_ns32k (bfd_vma memaddr
, disassemble_info
*info
)
742 unsigned short first_word
;
743 int ioffset
; /* Bits into instruction. */
744 int aoffset
; /* Bits into arguments. */
745 char arg_bufs
[MAX_ARGS
+1][ARG_LEN
];
749 bfd_byte
*buffer
= priv
.the_buffer
;
752 info
->private_data
= & priv
;
753 priv
.max_fetched
= priv
.the_buffer
;
754 priv
.insn_start
= memaddr
;
755 if (OPCODES_SIGSETJMP (priv
.bailout
) != 0)
759 /* Look for 8bit opcodes first. Other wise, fetching two bytes could take
760 us over the end of accessible data unnecessarilly. */
761 FETCH_DATA (info
, buffer
+ 1);
762 for (i
= 0; i
< NOPCODES
; i
++)
763 if (ns32k_opcodes
[i
].opcode_id_size
<= 8
765 & (((unsigned long) 1 << ns32k_opcodes
[i
].opcode_id_size
) - 1))
766 == ns32k_opcodes
[i
].opcode_seed
))
770 /* Maybe it is 9 to 16 bits big. */
771 FETCH_DATA (info
, buffer
+ 2);
772 first_word
= read_memory_integer(buffer
, 2);
774 for (i
= 0; i
< NOPCODES
; i
++)
776 & (((unsigned long) 1 << ns32k_opcodes
[i
].opcode_id_size
) - 1))
777 == ns32k_opcodes
[i
].opcode_seed
)
780 /* Handle undefined instructions. */
783 (*dis_info
->fprintf_func
)(dis_info
->stream
, "0%o", buffer
[0]);
788 (*dis_info
->fprintf_func
)(dis_info
->stream
, "%s", ns32k_opcodes
[i
].name
);
790 ioffset
= ns32k_opcodes
[i
].opcode_size
;
791 aoffset
= ns32k_opcodes
[i
].opcode_size
;
792 d
= ns32k_opcodes
[i
].operands
;
796 /* Offset in bits of the first thing beyond each index byte.
797 Element 0 is for operand A and element 1 is for operand B.
798 The rest are irrelevant, but we put them here so we don't
799 index outside the array. */
800 int index_offset
[MAX_ARGS
];
802 /* 0 for operand A, 1 for operand B, greater for other args. */
805 (*dis_info
->fprintf_func
)(dis_info
->stream
, "\t");
809 /* First we have to find and keep track of the index bytes,
810 if we are using scaled indexed addressing mode, since the index
811 bytes occur right after the basic instruction, not as part
812 of the addressing extension. */
815 int addr_mode
= bit_extract (buffer
, ioffset
- 5, 5);
817 if (Adrmod_is_index (addr_mode
))
820 index_offset
[0] = aoffset
;
824 if (d
[2] && Is_gen(d
[3]))
826 int addr_mode
= bit_extract (buffer
, ioffset
- 10, 5);
828 if (Adrmod_is_index (addr_mode
))
831 index_offset
[1] = aoffset
;
839 if (argnum
> maxarg
&& argnum
< MAX_ARGS
)
841 ioffset
= print_insn_arg (*d
, ioffset
, &aoffset
, buffer
,
842 memaddr
, arg_bufs
[argnum
],
843 index_offset
[whicharg
]);
849 for (argnum
= 0; argnum
<= maxarg
; argnum
++)
854 for (ch
= arg_bufs
[argnum
]; *ch
;)
856 if (*ch
== NEXT_IS_ADDR
)
859 addr
= bfd_scan_vma (ch
, NULL
, 16);
860 (*dis_info
->print_address_func
) (addr
, dis_info
);
861 while (*ch
&& *ch
!= NEXT_IS_ADDR
)
867 (*dis_info
->fprintf_func
)(dis_info
->stream
, "%c", *ch
++);
870 (*dis_info
->fprintf_func
)(dis_info
->stream
, ", ");