1 /* Print National Semiconductor 32000 instructions.
2 Copyright (C) 1986-2015 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. */
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 buffer += offset >> 3;
274 FETCH_DATA (dis_info, buffer + 1);
275 if ((*buffer & (1 << offset)))
287 /* Like bit extract but the buffer is valid and doen't need to be fetched. */
290 bit_extract_simple (bfd_byte *buffer, int offset, int count)
295 buffer += offset >> 3;
301 if ((*buffer & (1 << offset)))
314 bit_copy (bfd_byte *buffer, int offset, int count, char *to)
316 for (; count > 8; count -= 8, to++, offset += 8)
317 *to = bit_extract (buffer, offset, 8);
318 *to = bit_extract (buffer, offset, count);
322 sign_extend (int value, int bits)
324 value = value & ((1 << bits) - 1);
325 return (value & (1 << (bits - 1))
326 ? value | (~((1 << bits) - 1))
331 flip_bytes (char *ptr, int count)
338 ptr[0] = ptr[count - 1];
339 ptr[count - 1] = tmp;
345 /* Given a character C, does it represent a general addressing mode? */
347 ((c) == 'F' || (c) == 'L' || (c) == 'B' \
348 || (c) == 'W' || (c) == 'D' || (c) == 'A' || (c) == 'I' || (c) == 'Z')
350 /* Adressing modes. */
351 #define Adrmod_index_byte 0x1c
352 #define Adrmod_index_word 0x1d
353 #define Adrmod_index_doubleword 0x1e
354 #define Adrmod_index_quadword 0x1f
356 /* Is MODE an indexed addressing mode? */
357 #define Adrmod_is_index(mode) \
358 ( mode == Adrmod_index_byte \
359 || mode == Adrmod_index_word \
360 || mode == Adrmod_index_doubleword \
361 || mode == Adrmod_index_quadword)
365 get_displacement (bfd_byte *buffer, int *aoffsetp)
370 Ivalue = bit_extract (buffer, *aoffsetp, 8);
371 switch (Ivalue & 0xc0)
375 Ivalue = sign_extend (Ivalue, 7);
379 Ivalue2 = bit_extract (buffer, *aoffsetp, 16);
380 flip_bytes ((char *) & Ivalue2, 2);
381 Ivalue = sign_extend (Ivalue2, 14);
385 Ivalue = bit_extract (buffer, *aoffsetp, 32);
386 flip_bytes ((char *) & Ivalue, 4);
387 Ivalue = sign_extend (Ivalue, 30);
394 #if 1 /* A version that should work on ns32k f's&d's on any machine. */
396 invalid_float (bfd_byte *p, int len)
401 val = (bit_extract_simple (p, 23, 8)/*exponent*/ == 0xff
402 || (bit_extract_simple (p, 23, 8)/*exponent*/ == 0
403 && bit_extract_simple (p, 0, 23)/*mantisa*/ != 0));
405 val = (bit_extract_simple (p, 52, 11)/*exponent*/ == 0x7ff
406 || (bit_extract_simple (p, 52, 11)/*exponent*/ == 0
407 && (bit_extract_simple (p, 0, 32)/*low mantisa*/ != 0
408 || bit_extract_simple (p, 32, 20)/*high mantisa*/ != 0)));
414 /* Assumes the bytes have been swapped to local order. */
419 struct { unsigned m:23, e:8, :1;} sf;
420 struct { unsigned lm; unsigned m:20, e:11, :1;} sd;
424 invalid_float (float_type_u *p, int len)
428 if (len == sizeof (float))
429 val = (p->sf.e == 0xff
430 || (p->sf.e == 0 && p->sf.m != 0));
431 else if (len == sizeof (double))
432 val = (p->sd.e == 0x7ff
433 || (p->sd.e == 0 && (p->sd.m != 0 || p->sd.lm != 0)));
440 /* Print an instruction operand of category given by d. IOFFSET is
441 the bit position below which small (<1 byte) parts of the operand can
442 be found (usually in the basic instruction, but for indexed
443 addressing it can be in the index byte). AOFFSETP is a pointer to the
444 bit position of the addressing extension. BUFFER contains the
445 instruction. ADDR is where BUFFER was read from. Put the disassembled
446 version of the operand in RESULT. INDEX_OFFSET is the bit position
447 of the index byte (it contains garbage if this operand is not a
448 general operand using scaled indexed addressing mode). */
451 print_insn_arg (int d,
473 /* A "gen" operand but 5 bits from the end of instruction. */
483 addr_mode = bit_extract (buffer, ioffset - 5, 5);
487 case 0x0: case 0x1: case 0x2: case 0x3:
488 case 0x4: case 0x5: case 0x6: case 0x7:
489 /* Register mode R0 -- R7. */
495 sprintf (result, "f%d", addr_mode);
498 sprintf (result, "r%d", addr_mode);
501 case 0x8: case 0x9: case 0xa: case 0xb:
502 case 0xc: case 0xd: case 0xe: case 0xf:
503 /* Register relative disp(R0 -- R7). */
504 disp1 = get_displacement (buffer, aoffsetp);
505 sprintf (result, "%d(r%d)", disp1, addr_mode & 7);
510 /* Memory relative disp2(disp1(FP, SP, SB)). */
511 disp1 = get_displacement (buffer, aoffsetp);
512 disp2 = get_displacement (buffer, aoffsetp);
513 sprintf (result, "%d(%d(%s))", disp2, disp1,
514 addr_mode == 0x10 ? "fp" : addr_mode == 0x11 ? "sp" : "sb");
518 sprintf (result, "reserved");
527 /* I and Z are output operands and can`t be immediate
528 A is an address and we can`t have the address of
529 an immediate either. We don't know how much to increase
530 aoffsetp by since whatever generated this is broken
532 sprintf (result, _("$<undefined>"));
535 Ivalue = bit_extract (buffer, *aoffsetp, 8);
536 Ivalue = sign_extend (Ivalue, 8);
538 sprintf (result, "$%d", Ivalue);
541 Ivalue = bit_extract (buffer, *aoffsetp, 16);
542 flip_bytes ((char *) & Ivalue, 2);
544 Ivalue = sign_extend (Ivalue, 16);
545 sprintf (result, "$%d", Ivalue);
548 Ivalue = bit_extract (buffer, *aoffsetp, 32);
549 flip_bytes ((char *) & Ivalue, 4);
551 sprintf (result, "$%d", Ivalue);
554 bit_copy (buffer, *aoffsetp, 32, (char *) &value.f);
555 flip_bytes ((char *) &value.f, 4);
557 if (INVALID_FLOAT (&value.f, 4))
558 sprintf (result, "<<invalid float 0x%.8x>>", value.i[0]);
559 else /* Assume host has ieee float. */
560 sprintf (result, "$%g", value.f);
563 bit_copy (buffer, *aoffsetp, 64, (char *) &value.d);
564 flip_bytes ((char *) &value.d, 8);
566 if (INVALID_FLOAT (&value.d, 8))
567 sprintf (result, "<<invalid double 0x%.8x%.8x>>",
568 value.i[1], value.i[0]);
569 else /* Assume host has ieee float. */
570 sprintf (result, "$%g", value.d);
575 /* Absolute @disp. */
576 disp1 = get_displacement (buffer, aoffsetp);
577 sprintf (result, "@|%d|", disp1);
580 /* External EXT(disp1) + disp2 (Mod table stuff). */
581 disp1 = get_displacement (buffer, aoffsetp);
582 disp2 = get_displacement (buffer, aoffsetp);
583 sprintf (result, "EXT(%d) + %d", disp1, disp2);
586 /* Top of stack tos. */
587 sprintf (result, "tos");
590 /* Memory space disp(FP). */
591 disp1 = get_displacement (buffer, aoffsetp);
592 sprintf (result, "%d(fp)", disp1);
595 /* Memory space disp(SP). */
596 disp1 = get_displacement (buffer, aoffsetp);
597 sprintf (result, "%d(sp)", disp1);
600 /* Memory space disp(SB). */
601 disp1 = get_displacement (buffer, aoffsetp);
602 sprintf (result, "%d(sb)", disp1);
605 /* Memory space disp(PC). */
606 disp1 = get_displacement (buffer, aoffsetp);
607 *result++ = NEXT_IS_ADDR;
608 sprintf_vma (result, addr + disp1);
609 result += strlen (result);
610 *result++ = NEXT_IS_ADDR;
619 static const char *ind = "bwdq";
622 /* Scaled index basemode[R0 -- R7:B,W,D,Q]. */
623 bit_index = bit_extract (buffer, index_offset - 8, 3);
624 print_insn_arg (d, index_offset, aoffsetp, buffer, addr,
626 off = result + strlen (result);
627 sprintf (off, "[r%d:%c]", bit_index, ind[addr_mode & 3]);
634 Ivalue = bit_extract (buffer, ioffset-4, 4);
635 Ivalue = sign_extend (Ivalue, 4);
636 sprintf (result, "%d", Ivalue);
640 Ivalue = bit_extract (buffer, ioffset-3, 3);
641 sprintf (result, "r%d", Ivalue&7);
645 sprintf (result, "%d", get_displacement (buffer, aoffsetp));
648 Ivalue = get_displacement (buffer, aoffsetp);
649 /* Warning!! HACK ALERT!
650 Operand type 'b' is only used by the cmp{b,w,d} and
651 movm{b,w,d} instructions; we need to know whether
652 it's a `b' or `w' or `d' instruction; and for both
653 cmpm and movm it's stored at the same place so we
654 just grab two bits of the opcode and look at it... */
655 size = bit_extract(buffer, ioffset-6, 2);
656 if (size == 0) /* 00 => b. */
658 else if (size == 1) /* 01 => w. */
661 size = 4; /* 11 => d. */
663 sprintf (result, "%d", (Ivalue / size) + 1);
666 *result++ = NEXT_IS_ADDR;
667 sprintf_vma (result, addr + get_displacement (buffer, aoffsetp));
668 result += strlen (result);
669 *result++ = NEXT_IS_ADDR;
673 Ivalue = bit_extract (buffer, *aoffsetp, 8);
675 sprintf (result, "0x%x", Ivalue);
678 Ivalue = bit_extract (buffer, *aoffsetp, 8);
679 optlist (Ivalue, opt_u, result);
683 Ivalue = bit_extract (buffer, *aoffsetp, 8);
684 optlist (Ivalue, opt_U, result);
688 Ivalue = bit_extract (buffer, ioffset - 9, 9);
689 optlist (Ivalue, opt_O, result);
693 Ivalue = bit_extract (buffer, ioffset - 4, 4);
694 optlist (Ivalue, opt_C, result);
698 Ivalue = bit_extract (buffer, ioffset - 8, 8);
699 optlist (Ivalue, opt_S, result);
703 Ivalue = bit_extract (buffer, ioffset - 4, 4);
704 list_search (Ivalue, 0 ? list_M032 : list_M532, result);
708 Ivalue = bit_extract (buffer, ioffset - 4, 4);
709 list_search (Ivalue, 0 ? list_P032 : list_P532, result);
713 Ivalue = bit_extract (buffer, *aoffsetp, 3);
714 sprintf (result, "%d", Ivalue);
718 Ivalue = bit_extract(buffer, *aoffsetp, 5);
719 sprintf (result, "%d", Ivalue + 1);
727 /* Print the 32000 instruction at address MEMADDR in debugged memory,
728 on STREAM. Returns length of the instruction, in bytes. */
731 print_insn_ns32k (bfd_vma memaddr, disassemble_info *info)
735 unsigned short first_word;
736 int ioffset; /* Bits into instruction. */
737 int aoffset; /* Bits into arguments. */
738 char arg_bufs[MAX_ARGS+1][ARG_LEN];
742 bfd_byte *buffer = priv.the_buffer;
745 info->private_data = & priv;
746 priv.max_fetched = priv.the_buffer;
747 priv.insn_start = memaddr;
748 if (OPCODES_SIGSETJMP (priv.bailout) != 0)
752 /* Look for 8bit opcodes first. Other wise, fetching two bytes could take
753 us over the end of accessible data unnecessarilly. */
754 FETCH_DATA (info, buffer + 1);
755 for (i = 0; i < NOPCODES; i++)
756 if (ns32k_opcodes[i].opcode_id_size <= 8
758 & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
759 == ns32k_opcodes[i].opcode_seed))
763 /* Maybe it is 9 to 16 bits big. */
764 FETCH_DATA (info, buffer + 2);
765 first_word = read_memory_integer(buffer, 2);
767 for (i = 0; i < NOPCODES; i++)
769 & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
770 == ns32k_opcodes[i].opcode_seed)
773 /* Handle undefined instructions. */
776 (*dis_info->fprintf_func)(dis_info->stream, "0%o", buffer[0]);
781 (*dis_info->fprintf_func)(dis_info->stream, "%s", ns32k_opcodes[i].name);
783 ioffset = ns32k_opcodes[i].opcode_size;
784 aoffset = ns32k_opcodes[i].opcode_size;
785 d = ns32k_opcodes[i].operands;
789 /* Offset in bits of the first thing beyond each index byte.
790 Element 0 is for operand A and element 1 is for operand B.
791 The rest are irrelevant, but we put them here so we don't
792 index outside the array. */
793 int index_offset[MAX_ARGS];
795 /* 0 for operand A, 1 for operand B, greater for other args. */
798 (*dis_info->fprintf_func)(dis_info->stream, "\t");
802 /* First we have to find and keep track of the index bytes,
803 if we are using scaled indexed addressing mode, since the index
804 bytes occur right after the basic instruction, not as part
805 of the addressing extension. */
808 int addr_mode = bit_extract (buffer, ioffset - 5, 5);
810 if (Adrmod_is_index (addr_mode))
813 index_offset[0] = aoffset;
817 if (d[2] && Is_gen(d[3]))
819 int addr_mode = bit_extract (buffer, ioffset - 10, 5);
821 if (Adrmod_is_index (addr_mode))
824 index_offset[1] = aoffset;
832 if (argnum > maxarg && argnum < MAX_ARGS)
834 ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
835 memaddr, arg_bufs[argnum],
836 index_offset[whicharg]);
840 for (argnum = 0; argnum <= maxarg; argnum++)
845 for (ch = arg_bufs[argnum]; *ch;)
847 if (*ch == NEXT_IS_ADDR)
850 addr = bfd_scan_vma (ch, NULL, 16);
851 (*dis_info->print_address_func) (addr, dis_info);
852 while (*ch && *ch != NEXT_IS_ADDR)
858 (*dis_info->fprintf_func)(dis_info->stream, "%c", *ch++);
861 (*dis_info->fprintf_func)(dis_info->stream, ", ");