Automatic date update in version.in
[binutils-gdb.git] / opcodes / ns32k-dis.c
blobce330ae50a8d5299455001030b8ef411396f5116
1 /* Print National Semiconductor 32000 instructions.
2 Copyright (C) 1986-2024 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)
9 any later version.
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. */
21 #include "sysdep.h"
22 #include "bfd.h"
23 #include "disassemble.h"
24 #if !defined(const) && !defined(__STDC__)
25 #define const
26 #endif
27 #include "opcode/ns32k.h"
28 #include "opintl.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)
35 static long
36 read_memory_integer (unsigned char * addr, int nr)
38 long val;
39 int i;
41 for (val = 0, i = nr - 1; i >= 0; i--)
43 val = (val << 8);
44 val |= (0xff & *(addr + i));
46 return val;
49 /* 32000 instructions are never longer than this. */
50 #define MAXLEN 62
52 #include <setjmp.h>
54 struct private
56 /* Points to first byte not fetched. */
57 bfd_byte *max_fetched;
58 bfd_byte the_buffer[MAXLEN];
59 bfd_vma insn_start;
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
66 on error. */
67 #define FETCH_DATA(info, addr) \
68 ((addr) <= ((struct private *)(info->private_data))->max_fetched \
69 ? 1 : fetch_data ((info), (addr)))
71 static int
72 fetch_data (struct disassemble_info *info, bfd_byte *addr)
74 int status;
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,
79 priv->max_fetched,
80 addr - priv->max_fetched,
81 info);
82 if (status != 0)
84 (*info->memory_error_func) (status, start, info);
85 OPCODES_SIGLONGJMP (priv->bailout, 1);
87 else
88 priv->max_fetched = addr;
89 return 1;
92 /* Number of elements in the opcode table. */
93 #define NOPCODES (sizeof ns32k_opcodes / sizeof ns32k_opcodes[0])
95 #define NEXT_IS_ADDR '|'
98 struct ns32k_option
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 },
116 { 0 , 0x00, 0x00 }
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 },
129 { 0 , 0x00, 0x00 }
132 static const struct ns32k_option opt_O[]= /* Setcfg. */
134 { "c", 0x8, 0x8 },
135 { "m", 0x4, 0x4 },
136 { "f", 0x2, 0x2 },
137 { "i", 0x1, 0x1 },
138 { 0 , 0x0, 0x0 }
141 static const struct ns32k_option opt_C[]= /* Cinv. */
143 { "a", 0x4, 0x4 },
144 { "i", 0x2, 0x2 },
145 { "d", 0x1, 0x1 },
146 { 0 , 0x0, 0x0 }
149 static const struct ns32k_option opt_S[]= /* String inst. */
151 { "b", 0x1, 0x1 },
152 { "u", 0x6, 0x6 },
153 { "w", 0x2, 0x2 },
154 { 0 , 0x0, 0x0 }
157 static const struct ns32k_option list_P532[]= /* Lpr spr. */
159 { "us", 0x0, 0xf },
160 { "dcr", 0x1, 0xf },
161 { "bpc", 0x2, 0xf },
162 { "dsr", 0x3, 0xf },
163 { "car", 0x4, 0xf },
164 { "fp", 0x8, 0xf },
165 { "sp", 0x9, 0xf },
166 { "sb", 0xa, 0xf },
167 { "usp", 0xb, 0xf },
168 { "cfg", 0xc, 0xf },
169 { "psr", 0xd, 0xf },
170 { "intbase", 0xe, 0xf },
171 { "mod", 0xf, 0xf },
172 { 0 , 0x00, 0xf }
175 static const struct ns32k_option list_M532[]= /* Lmr smr. */
177 { "mcr", 0x9, 0xf },
178 { "msr", 0xa, 0xf },
179 { "tear", 0xb, 0xf },
180 { "ptb0", 0xc, 0xf },
181 { "ptb1", 0xd, 0xf },
182 { "ivar0", 0xe, 0xf },
183 { "ivar1", 0xf, 0xf },
184 { 0 , 0x0, 0xf }
187 static const struct ns32k_option list_P032[]= /* Lpr spr. */
189 { "upsr", 0x0, 0xf },
190 { "fp", 0x8, 0xf },
191 { "sp", 0x9, 0xf },
192 { "sb", 0xa, 0xf },
193 { "psr", 0xb, 0xf },
194 { "intbase", 0xe, 0xf },
195 { "mod", 0xf, 0xf },
196 { 0 , 0x0, 0xf }
199 static const struct ns32k_option list_M032[]= /* Lmr smr. */
201 { "bpr0", 0x0, 0xf },
202 { "bpr1", 0x1, 0xf },
203 { "pf0", 0x4, 0xf },
204 { "pf1", 0x5, 0xf },
205 { "sc", 0x8, 0xf },
206 { "msr", 0xa, 0xf },
207 { "bcnt", 0xb, 0xf },
208 { "ptb0", 0xc, 0xf },
209 { "ptb1", 0xd, 0xf },
210 { "eia", 0xf, 0xf },
211 { 0 , 0x0, 0xf }
215 /* Figure out which options are present. */
217 static void
218 optlist (int options, const struct ns32k_option * optionP, char * result)
220 if (options == 0)
222 sprintf (result, "[]");
223 return;
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, ",");
240 if (options != 0)
241 strcat (result, "undefined");
243 strcat (result, "]");
246 static void
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);
254 return;
257 sprintf (result, "undefined");
260 /* Extract "count" bits starting "offset" bits into buffer. */
262 static int
263 bit_extract (bfd_byte *buffer, int offset, int count)
265 unsigned int result;
266 unsigned int bit;
268 if (offset < 0 || count < 0)
269 return 0;
270 buffer += offset >> 3;
271 offset &= 7;
272 bit = 1;
273 result = 0;
274 while (count--)
276 FETCH_DATA (dis_info, buffer + 1);
277 if ((*buffer & (1 << offset)))
278 result |= bit;
279 if (++offset == 8)
281 offset = 0;
282 buffer++;
284 bit <<= 1;
286 return result;
289 /* Like bit extract but the buffer is valid and doen't need to be fetched. */
291 static int
292 bit_extract_simple (bfd_byte *buffer, int offset, int count)
294 unsigned int result;
295 unsigned int bit;
297 if (offset < 0 || count < 0)
298 return 0;
299 buffer += offset >> 3;
300 offset &= 7;
301 bit = 1;
302 result = 0;
303 while (count--)
305 if ((*buffer & (1 << offset)))
306 result |= bit;
307 if (++offset == 8)
309 offset = 0;
310 buffer++;
312 bit <<= 1;
314 return result;
317 static void
318 bit_copy (bfd_byte *buffer, int offset, int count, char *to)
320 if (offset < 0 || count < 0)
321 return;
322 for (; count > 8; count -= 8, to++, offset += 8)
323 *to = bit_extract (buffer, offset, 8);
324 *to = bit_extract (buffer, offset, count);
327 static int
328 sign_extend (unsigned int value, unsigned int bits)
330 unsigned int sign = 1u << (bits - 1);
331 return ((value & (sign + sign - 1)) ^ sign) - sign;
334 static void
335 flip_bytes (char *ptr, int count)
337 char tmp;
339 while (count > 0)
341 tmp = ptr[0];
342 ptr[0] = ptr[count - 1];
343 ptr[count - 1] = tmp;
344 ptr++;
345 count -= 2;
349 /* Given a character C, does it represent a general addressing mode? */
350 #define Is_gen(c) (strchr ("FLBWDAIZf", (c)) != NULL)
352 /* Adressing modes. */
353 #define Adrmod_index_byte 0x1c
354 #define Adrmod_index_word 0x1d
355 #define Adrmod_index_doubleword 0x1e
356 #define Adrmod_index_quadword 0x1f
358 /* Is MODE an indexed addressing mode? */
359 #define Adrmod_is_index(mode) \
360 ( mode == Adrmod_index_byte \
361 || mode == Adrmod_index_word \
362 || mode == Adrmod_index_doubleword \
363 || mode == Adrmod_index_quadword)
366 static int
367 get_displacement (bfd_byte *buffer, int *aoffsetp)
369 int Ivalue;
370 short Ivalue2;
372 Ivalue = bit_extract (buffer, *aoffsetp, 8);
373 switch (Ivalue & 0xc0)
375 case 0x00:
376 case 0x40:
377 Ivalue = sign_extend (Ivalue, 7);
378 *aoffsetp += 8;
379 break;
380 case 0x80:
381 Ivalue2 = bit_extract (buffer, *aoffsetp, 16);
382 flip_bytes ((char *) & Ivalue2, 2);
383 Ivalue = sign_extend (Ivalue2, 14);
384 *aoffsetp += 16;
385 break;
386 case 0xc0:
387 Ivalue = bit_extract (buffer, *aoffsetp, 32);
388 flip_bytes ((char *) & Ivalue, 4);
389 Ivalue = sign_extend (Ivalue, 30);
390 *aoffsetp += 32;
391 break;
393 return Ivalue;
396 #if 1 /* A version that should work on ns32k f's&d's on any machine. */
397 static int
398 invalid_float (bfd_byte *p, int len)
400 int val;
402 if (len == 4)
403 val = (bit_extract_simple (p, 23, 8)/*exponent*/ == 0xff
404 || (bit_extract_simple (p, 23, 8)/*exponent*/ == 0
405 && bit_extract_simple (p, 0, 23)/*mantisa*/ != 0));
406 else if (len == 8)
407 val = (bit_extract_simple (p, 52, 11)/*exponent*/ == 0x7ff
408 || (bit_extract_simple (p, 52, 11)/*exponent*/ == 0
409 && (bit_extract_simple (p, 0, 32)/*low mantisa*/ != 0
410 || bit_extract_simple (p, 32, 20)/*high mantisa*/ != 0)));
411 else
412 val = 1;
413 return (val);
415 #else
416 /* Assumes the bytes have been swapped to local order. */
417 typedef union
419 double d;
420 float f;
421 struct { unsigned m:23, e:8, :1;} sf;
422 struct { unsigned lm; unsigned m:20, e:11, :1;} sd;
423 } float_type_u;
425 static int
426 invalid_float (float_type_u *p, int len)
428 int val;
430 if (len == sizeof (float))
431 val = (p->sf.e == 0xff
432 || (p->sf.e == 0 && p->sf.m != 0));
433 else if (len == sizeof (double))
434 val = (p->sd.e == 0x7ff
435 || (p->sd.e == 0 && (p->sd.m != 0 || p->sd.lm != 0)));
436 else
437 val = 1;
438 return val;
440 #endif
442 /* Print an instruction operand of category given by d. IOFFSET is
443 the bit position below which small (<1 byte) parts of the operand can
444 be found (usually in the basic instruction, but for indexed
445 addressing it can be in the index byte). AOFFSETP is a pointer to the
446 bit position of the addressing extension. BUFFER contains the
447 instruction. ADDR is where BUFFER was read from. Put the disassembled
448 version of the operand in RESULT. INDEX_OFFSET is the bit position
449 of the index byte (it contains -1 if this operand is not a
450 general operand using scaled indexed addressing mode). */
452 static int
453 print_insn_arg (int d,
454 int ioffset,
455 int *aoffsetp,
456 bfd_byte *buffer,
457 bfd_vma addr,
458 char *result,
459 int index_offset)
461 union
463 float f;
464 double d;
465 int i[2];
466 } value;
467 int Ivalue;
468 int addr_mode;
469 int disp1, disp2;
470 int size;
472 switch (d)
474 case 'f':
475 /* A "gen" operand but 5 bits from the end of instruction. */
476 ioffset -= 5;
477 /* Fall through. */
478 case 'Z':
479 case 'F':
480 case 'L':
481 case 'I':
482 case 'B':
483 case 'W':
484 case 'D':
485 case 'A':
486 addr_mode = bit_extract (buffer, ioffset - 5, 5);
487 ioffset -= 5;
488 switch (addr_mode)
490 case 0x0: case 0x1: case 0x2: case 0x3:
491 case 0x4: case 0x5: case 0x6: case 0x7:
492 /* Register mode R0 -- R7. */
493 switch (d)
495 case 'F':
496 case 'L':
497 case 'Z':
498 sprintf (result, "f%d", addr_mode);
499 break;
500 default:
501 sprintf (result, "r%d", addr_mode);
503 break;
504 case 0x8: case 0x9: case 0xa: case 0xb:
505 case 0xc: case 0xd: case 0xe: case 0xf:
506 /* Register relative disp(R0 -- R7). */
507 disp1 = get_displacement (buffer, aoffsetp);
508 sprintf (result, "%d(r%d)", disp1, addr_mode & 7);
509 break;
510 case 0x10:
511 case 0x11:
512 case 0x12:
513 /* Memory relative disp2(disp1(FP, SP, SB)). */
514 disp1 = get_displacement (buffer, aoffsetp);
515 disp2 = get_displacement (buffer, aoffsetp);
516 sprintf (result, "%d(%d(%s))", disp2, disp1,
517 addr_mode == 0x10 ? "fp" : addr_mode == 0x11 ? "sp" : "sb");
518 break;
519 case 0x13:
520 /* Reserved. */
521 sprintf (result, "reserved");
522 break;
523 case 0x14:
524 /* Immediate. */
525 switch (d)
527 default:
528 /* I and Z are output operands and can`t be immediate
529 A is an address and we can`t have the address of
530 an immediate either. We don't know how much to increase
531 aoffsetp by since whatever generated this is broken
532 anyway! */
533 sprintf (result, _("$<undefined>"));
534 break;
535 case 'B':
536 Ivalue = bit_extract (buffer, *aoffsetp, 8);
537 Ivalue = sign_extend (Ivalue, 8);
538 *aoffsetp += 8;
539 sprintf (result, "$%d", Ivalue);
540 break;
541 case 'W':
542 Ivalue = bit_extract (buffer, *aoffsetp, 16);
543 flip_bytes ((char *) & Ivalue, 2);
544 *aoffsetp += 16;
545 Ivalue = sign_extend (Ivalue, 16);
546 sprintf (result, "$%d", Ivalue);
547 break;
548 case 'D':
549 Ivalue = bit_extract (buffer, *aoffsetp, 32);
550 flip_bytes ((char *) & Ivalue, 4);
551 *aoffsetp += 32;
552 sprintf (result, "$%d", Ivalue);
553 break;
554 case 'F':
555 bit_copy (buffer, *aoffsetp, 32, (char *) &value.f);
556 flip_bytes ((char *) &value.f, 4);
557 *aoffsetp += 32;
558 if (INVALID_FLOAT (&value.f, 4))
559 sprintf (result, "<<invalid float 0x%.8x>>", value.i[0]);
560 else /* Assume host has ieee float. */
561 sprintf (result, "$%g", value.f);
562 break;
563 case 'L':
564 bit_copy (buffer, *aoffsetp, 64, (char *) &value.d);
565 flip_bytes ((char *) &value.d, 8);
566 *aoffsetp += 64;
567 if (INVALID_FLOAT (&value.d, 8))
568 sprintf (result, "<<invalid double 0x%.8x%.8x>>",
569 value.i[1], value.i[0]);
570 else /* Assume host has ieee float. */
571 sprintf (result, "$%g", value.d);
572 break;
574 break;
575 case 0x15:
576 /* Absolute @disp. */
577 disp1 = get_displacement (buffer, aoffsetp);
578 sprintf (result, "@|%d|", disp1);
579 break;
580 case 0x16:
581 /* External EXT(disp1) + disp2 (Mod table stuff). */
582 disp1 = get_displacement (buffer, aoffsetp);
583 disp2 = get_displacement (buffer, aoffsetp);
584 sprintf (result, "EXT(%d) + %d", disp1, disp2);
585 break;
586 case 0x17:
587 /* Top of stack tos. */
588 sprintf (result, "tos");
589 break;
590 case 0x18:
591 /* Memory space disp(FP). */
592 disp1 = get_displacement (buffer, aoffsetp);
593 sprintf (result, "%d(fp)", disp1);
594 break;
595 case 0x19:
596 /* Memory space disp(SP). */
597 disp1 = get_displacement (buffer, aoffsetp);
598 sprintf (result, "%d(sp)", disp1);
599 break;
600 case 0x1a:
601 /* Memory space disp(SB). */
602 disp1 = get_displacement (buffer, aoffsetp);
603 sprintf (result, "%d(sb)", disp1);
604 break;
605 case 0x1b:
606 /* Memory space disp(PC). */
607 disp1 = get_displacement (buffer, aoffsetp);
608 *result++ = NEXT_IS_ADDR;
609 sprintf (result, "%" PRIx64, (uint64_t) (addr + disp1));
610 result += strlen (result);
611 *result++ = NEXT_IS_ADDR;
612 *result = '\0';
613 break;
614 case 0x1c:
615 case 0x1d:
616 case 0x1e:
617 case 0x1f:
619 int bit_index;
620 static const char *ind = "bwdq";
621 char *off;
623 /* Scaled index basemode[R0 -- R7:B,W,D,Q]. */
624 bit_index = bit_extract (buffer, index_offset - 8, 3);
625 print_insn_arg (d, index_offset, aoffsetp, buffer, addr,
626 result, 0);
627 off = result + strlen (result);
628 sprintf (off, "[r%d:%c]", bit_index, ind[addr_mode & 3]);
630 break;
632 break;
633 case 'H':
634 case 'q':
635 Ivalue = bit_extract (buffer, ioffset-4, 4);
636 Ivalue = sign_extend (Ivalue, 4);
637 sprintf (result, "%d", Ivalue);
638 ioffset -= 4;
639 break;
640 case 'r':
641 Ivalue = bit_extract (buffer, ioffset-3, 3);
642 sprintf (result, "r%d", Ivalue&7);
643 ioffset -= 3;
644 break;
645 case 'd':
646 sprintf (result, "%d", get_displacement (buffer, aoffsetp));
647 break;
648 case 'b':
649 Ivalue = get_displacement (buffer, aoffsetp);
650 /* Warning!! HACK ALERT!
651 Operand type 'b' is only used by the cmp{b,w,d} and
652 movm{b,w,d} instructions; we need to know whether
653 it's a `b' or `w' or `d' instruction; and for both
654 cmpm and movm it's stored at the same place so we
655 just grab two bits of the opcode and look at it... */
656 size = bit_extract(buffer, ioffset-6, 2);
657 if (size == 0) /* 00 => b. */
658 size = 1;
659 else if (size == 1) /* 01 => w. */
660 size = 2;
661 else
662 size = 4; /* 11 => d. */
664 sprintf (result, "%d", (Ivalue / size) + 1);
665 break;
666 case 'p':
667 *result++ = NEXT_IS_ADDR;
668 sprintf (result, "%" PRIx64,
669 (uint64_t) (addr + get_displacement (buffer, aoffsetp)));
670 result += strlen (result);
671 *result++ = NEXT_IS_ADDR;
672 *result = '\0';
673 break;
674 case 'i':
675 Ivalue = bit_extract (buffer, *aoffsetp, 8);
676 *aoffsetp += 8;
677 sprintf (result, "0x%x", Ivalue);
678 break;
679 case 'u':
680 Ivalue = bit_extract (buffer, *aoffsetp, 8);
681 optlist (Ivalue, opt_u, result);
682 *aoffsetp += 8;
683 break;
684 case 'U':
685 Ivalue = bit_extract (buffer, *aoffsetp, 8);
686 optlist (Ivalue, opt_U, result);
687 *aoffsetp += 8;
688 break;
689 case 'O':
690 Ivalue = bit_extract (buffer, ioffset - 9, 9);
691 optlist (Ivalue, opt_O, result);
692 ioffset -= 9;
693 break;
694 case 'C':
695 Ivalue = bit_extract (buffer, ioffset - 4, 4);
696 optlist (Ivalue, opt_C, result);
697 ioffset -= 4;
698 break;
699 case 'S':
700 Ivalue = bit_extract (buffer, ioffset - 8, 8);
701 optlist (Ivalue, opt_S, result);
702 ioffset -= 8;
703 break;
704 case 'M':
705 Ivalue = bit_extract (buffer, ioffset - 4, 4);
706 list_search (Ivalue, 0 ? list_M032 : list_M532, result);
707 ioffset -= 4;
708 break;
709 case 'P':
710 Ivalue = bit_extract (buffer, ioffset - 4, 4);
711 list_search (Ivalue, 0 ? list_P032 : list_P532, result);
712 ioffset -= 4;
713 break;
714 case 'g':
715 Ivalue = bit_extract (buffer, *aoffsetp, 3);
716 sprintf (result, "%d", Ivalue);
717 *aoffsetp += 3;
718 break;
719 case 'G':
720 Ivalue = bit_extract(buffer, *aoffsetp, 5);
721 sprintf (result, "%d", Ivalue + 1);
722 *aoffsetp += 5;
723 break;
725 return ioffset;
729 /* Print the 32000 instruction at address MEMADDR in debugged memory,
730 on STREAM. Returns length of the instruction, in bytes. */
733 print_insn_ns32k (bfd_vma memaddr, disassemble_info *info)
735 unsigned int i;
736 const char *d;
737 unsigned short first_word;
738 int ioffset; /* Bits into instruction. */
739 int aoffset; /* Bits into arguments. */
740 char arg_bufs[MAX_ARGS+1][ARG_LEN];
741 int argnum;
742 int maxarg;
743 struct private priv;
744 bfd_byte *buffer = priv.the_buffer;
745 dis_info = info;
747 info->private_data = & priv;
748 priv.max_fetched = priv.the_buffer;
749 priv.insn_start = memaddr;
750 if (OPCODES_SIGSETJMP (priv.bailout) != 0)
751 /* Error return. */
752 return -1;
754 /* Look for 8bit opcodes first. Other wise, fetching two bytes could take
755 us over the end of accessible data unnecessarilly. */
756 FETCH_DATA (info, buffer + 1);
757 for (i = 0; i < NOPCODES; i++)
758 if (ns32k_opcodes[i].opcode_id_size <= 8
759 && ((buffer[0]
760 & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
761 == ns32k_opcodes[i].opcode_seed))
762 break;
763 if (i == NOPCODES)
765 /* Maybe it is 9 to 16 bits big. */
766 FETCH_DATA (info, buffer + 2);
767 first_word = read_memory_integer(buffer, 2);
769 for (i = 0; i < NOPCODES; i++)
770 if ((first_word
771 & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
772 == ns32k_opcodes[i].opcode_seed)
773 break;
775 /* Handle undefined instructions. */
776 if (i == NOPCODES)
778 (*dis_info->fprintf_func)(dis_info->stream, "0%o", buffer[0]);
779 return 1;
783 (*dis_info->fprintf_func)(dis_info->stream, "%s", ns32k_opcodes[i].name);
785 ioffset = ns32k_opcodes[i].opcode_size;
786 aoffset = ns32k_opcodes[i].opcode_size;
787 d = ns32k_opcodes[i].operands;
789 if (*d)
791 /* Offset in bits of the first thing beyond each index byte.
792 Element 0 is for operand A and element 1 is for operand B. */
793 int index_offset[2];
795 /* 0 for operand A, 1 for operand B, greater for other args. */
796 int whicharg = 0;
798 (*dis_info->fprintf_func)(dis_info->stream, "\t");
800 maxarg = 0;
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. */
806 index_offset[0] = -1;
807 index_offset[1] = -1;
808 if (Is_gen (d[1]))
810 int bitoff = d[1] == 'f' ? 10 : 5;
811 int addr_mode = bit_extract (buffer, ioffset - bitoff, 5);
813 if (Adrmod_is_index (addr_mode))
815 aoffset += 8;
816 index_offset[0] = aoffset;
820 if (d[2] && Is_gen (d[3]))
822 int addr_mode = bit_extract (buffer, ioffset - 10, 5);
824 if (Adrmod_is_index (addr_mode))
826 aoffset += 8;
827 index_offset[1] = aoffset;
831 while (*d)
833 argnum = *d - '1';
834 if (argnum >= MAX_ARGS)
835 abort ();
836 d++;
837 if (argnum > maxarg)
838 maxarg = argnum;
839 ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
840 memaddr, arg_bufs[argnum],
841 whicharg > 1 ? -1 : index_offset[whicharg]);
842 d++;
843 whicharg++;
846 for (argnum = 0; argnum <= maxarg; argnum++)
848 bfd_vma addr;
849 char *ch;
851 for (ch = arg_bufs[argnum]; *ch;)
853 if (*ch == NEXT_IS_ADDR)
855 ++ch;
856 addr = bfd_scan_vma (ch, NULL, 16);
857 (*dis_info->print_address_func) (addr, dis_info);
858 while (*ch && *ch != NEXT_IS_ADDR)
859 ++ch;
860 if (*ch)
861 ++ch;
863 else
864 (*dis_info->fprintf_func)(dis_info->stream, "%c", *ch++);
866 if (argnum < maxarg)
867 (*dis_info->fprintf_func)(dis_info->stream, ", ");
870 return aoffset / 8;