1 /* Print National Semiconductor 32000 instructions. 2 Copyright (C) 1986-2014 Free Software Foundation, Inc. 3 4 This file is part of the GNU opcodes library. 5 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. 10 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. 15 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. */ 20 21 #include "sysdep.h" 22 #include "bfd.h" 23 #include "dis-asm.h" 24 #if !defined(const) && !defined(__STDC__) 25 #define const 26 #endif 27 #include "opcode/ns32k.h" 28 #include "opintl.h" 29 30 static disassemble_info *dis_info; 31 32 /* Hacks to get it to compile <= READ THESE AS FIXES NEEDED. */ 33 #define INVALID_FLOAT(val, size) invalid_float ((bfd_byte *) val, size) 34 35 static long 36 read_memory_integer (unsigned char * addr, int nr) 37 { 38 long val; 39 int i; 40 41 for (val = 0, i = nr - 1; i >= 0; i--) 42 { 43 val = (val << 8); 44 val |= (0xff & *(addr + i)); 45 } 46 return val; 47 } 48 49 /* 32000 instructions are never longer than this. */ 50 #define MAXLEN 62 51 52 #include <setjmp.h> 53 54 struct private 55 { 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; 61 }; 62 63 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))) 70 71 static int 72 fetch_data (struct disassemble_info *info, bfd_byte *addr) 73 { 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); 77 78 status = (*info->read_memory_func) (start, 79 priv->max_fetched, 80 addr - priv->max_fetched, 81 info); 82 if (status != 0) 83 { 84 (*info->memory_error_func) (status, start, info); 85 OPCODES_SIGLONGJMP (priv->bailout, 1); 86 } 87 else 88 priv->max_fetched = addr; 89 return 1; 90 } 91 92 /* Number of elements in the opcode table. */ 93 #define NOPCODES (sizeof ns32k_opcodes / sizeof ns32k_opcodes[0]) 94 95 #define NEXT_IS_ADDR '|' 96 97 98 struct ns32k_option 100 { 101 char *pattern; /* The option itself. */ 102 unsigned long value; /* Binary value of the option. */ 103 unsigned long match; /* These bits must match. */ 104 }; 105 106 107 static const struct ns32k_option opt_u[]= /* Restore, exit. */ 109 { 110 { "r0", 0x80, 0x80 }, 111 { "r1", 0x40, 0x40 }, 112 { "r2", 0x20, 0x20 }, 113 { "r3", 0x10, 0x10 }, 114 { "r4", 0x08, 0x08 }, 115 { "r5", 0x04, 0x04 }, 116 { "r6", 0x02, 0x02 }, 117 { "r7", 0x01, 0x01 }, 118 { 0 , 0x00, 0x00 } 119 }; 120 121 static const struct ns32k_option opt_U[]= /* Save, enter. */ 122 { 123 { "r0", 0x01, 0x01 }, 124 { "r1", 0x02, 0x02 }, 125 { "r2", 0x04, 0x04 }, 126 { "r3", 0x08, 0x08 }, 127 { "r4", 0x10, 0x10 }, 128 { "r5", 0x20, 0x20 }, 129 { "r6", 0x40, 0x40 }, 130 { "r7", 0x80, 0x80 }, 131 { 0 , 0x00, 0x00 } 132 }; 133 134 static const struct ns32k_option opt_O[]= /* Setcfg. */ 135 { 136 { "c", 0x8, 0x8 }, 137 { "m", 0x4, 0x4 }, 138 { "f", 0x2, 0x2 }, 139 { "i", 0x1, 0x1 }, 140 { 0 , 0x0, 0x0 } 141 }; 142 143 static const struct ns32k_option opt_C[]= /* Cinv. */ 144 { 145 { "a", 0x4, 0x4 }, 146 { "i", 0x2, 0x2 }, 147 { "d", 0x1, 0x1 }, 148 { 0 , 0x0, 0x0 } 149 }; 150 151 static const struct ns32k_option opt_S[]= /* String inst. */ 152 { 153 { "b", 0x1, 0x1 }, 154 { "u", 0x6, 0x6 }, 155 { "w", 0x2, 0x2 }, 156 { 0 , 0x0, 0x0 } 157 }; 158 159 static const struct ns32k_option list_P532[]= /* Lpr spr. */ 160 { 161 { "us", 0x0, 0xf }, 162 { "dcr", 0x1, 0xf }, 163 { "bpc", 0x2, 0xf }, 164 { "dsr", 0x3, 0xf }, 165 { "car", 0x4, 0xf }, 166 { "fp", 0x8, 0xf }, 167 { "sp", 0x9, 0xf }, 168 { "sb", 0xa, 0xf }, 169 { "usp", 0xb, 0xf }, 170 { "cfg", 0xc, 0xf }, 171 { "psr", 0xd, 0xf }, 172 { "intbase", 0xe, 0xf }, 173 { "mod", 0xf, 0xf }, 174 { 0 , 0x00, 0xf } 175 }; 176 177 static const struct ns32k_option list_M532[]= /* Lmr smr. */ 178 { 179 { "mcr", 0x9, 0xf }, 180 { "msr", 0xa, 0xf }, 181 { "tear", 0xb, 0xf }, 182 { "ptb0", 0xc, 0xf }, 183 { "ptb1", 0xd, 0xf }, 184 { "ivar0", 0xe, 0xf }, 185 { "ivar1", 0xf, 0xf }, 186 { 0 , 0x0, 0xf } 187 }; 188 189 static const struct ns32k_option list_P032[]= /* Lpr spr. */ 190 { 191 { "upsr", 0x0, 0xf }, 192 { "fp", 0x8, 0xf }, 193 { "sp", 0x9, 0xf }, 194 { "sb", 0xa, 0xf }, 195 { "psr", 0xb, 0xf }, 196 { "intbase", 0xe, 0xf }, 197 { "mod", 0xf, 0xf }, 198 { 0 , 0x0, 0xf } 199 }; 200 201 static const struct ns32k_option list_M032[]= /* Lmr smr. */ 202 { 203 { "bpr0", 0x0, 0xf }, 204 { "bpr1", 0x1, 0xf }, 205 { "pf0", 0x4, 0xf }, 206 { "pf1", 0x5, 0xf }, 207 { "sc", 0x8, 0xf }, 208 { "msr", 0xa, 0xf }, 209 { "bcnt", 0xb, 0xf }, 210 { "ptb0", 0xc, 0xf }, 211 { "ptb1", 0xd, 0xf }, 212 { "eia", 0xf, 0xf }, 213 { 0 , 0x0, 0xf } 214 }; 215 216 217 /* Figure out which options are present. */ 218 219 static void 220 optlist (int options, const struct ns32k_option * optionP, char * result) 221 { 222 if (options == 0) 223 { 224 sprintf (result, "[]"); 225 return; 226 } 227 228 sprintf (result, "["); 229 230 for (; (options != 0) && optionP->pattern; optionP++) 231 { 232 if ((options & optionP->match) == optionP->value) 233 { 234 /* We found a match, update result and options. */ 235 strcat (result, optionP->pattern); 236 options &= ~optionP->value; 237 if (options != 0) /* More options to come. */ 238 strcat (result, ","); 239 } 240 } 241 242 if (options != 0) 243 strcat (result, "undefined"); 244 245 strcat (result, "]"); 246 } 247 248 static void 249 list_search (int reg_value, const struct ns32k_option *optionP, char *result) 250 { 251 for (; optionP->pattern; optionP++) 252 { 253 if ((reg_value & optionP->match) == optionP->value) 254 { 255 sprintf (result, "%s", optionP->pattern); 256 return; 257 } 258 } 259 sprintf (result, "undefined"); 260 } 261 262 /* Extract "count" bits starting "offset" bits into buffer. */ 264 265 static int 266 bit_extract (bfd_byte *buffer, int offset, int count) 267 { 268 int result; 269 int bit; 270 271 buffer += offset >> 3; 272 offset &= 7; 273 bit = 1; 274 result = 0; 275 while (count--) 276 { 277 FETCH_DATA (dis_info, buffer + 1); 278 if ((*buffer & (1 << offset))) 279 result |= bit; 280 if (++offset == 8) 281 { 282 offset = 0; 283 buffer++; 284 } 285 bit <<= 1; 286 } 287 return result; 288 } 289 290 /* Like bit extract but the buffer is valid and doen't need to be fetched. */ 291 292 static int 293 bit_extract_simple (bfd_byte *buffer, int offset, int count) 294 { 295 int result; 296 int bit; 297 298 buffer += offset >> 3; 299 offset &= 7; 300 bit = 1; 301 result = 0; 302 while (count--) 303 { 304 if ((*buffer & (1 << offset))) 305 result |= bit; 306 if (++offset == 8) 307 { 308 offset = 0; 309 buffer++; 310 } 311 bit <<= 1; 312 } 313 return result; 314 } 315 316 static void 317 bit_copy (bfd_byte *buffer, int offset, int count, char *to) 318 { 319 for (; count > 8; count -= 8, to++, offset += 8) 320 *to = bit_extract (buffer, offset, 8); 321 *to = bit_extract (buffer, offset, count); 322 } 323 324 static int 325 sign_extend (int value, int bits) 326 { 327 value = value & ((1 << bits) - 1); 328 return (value & (1 << (bits - 1)) 329 ? value | (~((1 << bits) - 1)) 330 : value); 331 } 332 333 static void 334 flip_bytes (char *ptr, int count) 335 { 336 char tmp; 337 338 while (count > 0) 339 { 340 tmp = ptr[0]; 341 ptr[0] = ptr[count - 1]; 342 ptr[count - 1] = tmp; 343 ptr++; 344 count -= 2; 345 } 346 } 347 348 /* Given a character C, does it represent a general addressing mode? */ 350 #define Is_gen(c) \ 351 ((c) == 'F' || (c) == 'L' || (c) == 'B' \ 352 || (c) == 'W' || (c) == 'D' || (c) == 'A' || (c) == 'I' || (c) == 'Z') 353 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 359 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) 366 367 368 static int 370 get_displacement (bfd_byte *buffer, int *aoffsetp) 371 { 372 int Ivalue; 373 short Ivalue2; 374 375 Ivalue = bit_extract (buffer, *aoffsetp, 8); 376 switch (Ivalue & 0xc0) 377 { 378 case 0x00: 379 case 0x40: 380 Ivalue = sign_extend (Ivalue, 7); 381 *aoffsetp += 8; 382 break; 383 case 0x80: 384 Ivalue2 = bit_extract (buffer, *aoffsetp, 16); 385 flip_bytes ((char *) & Ivalue2, 2); 386 Ivalue = sign_extend (Ivalue2, 14); 387 *aoffsetp += 16; 388 break; 389 case 0xc0: 390 Ivalue = bit_extract (buffer, *aoffsetp, 32); 391 flip_bytes ((char *) & Ivalue, 4); 392 Ivalue = sign_extend (Ivalue, 30); 393 *aoffsetp += 32; 394 break; 395 } 396 return Ivalue; 397 } 398 399 #if 1 /* A version that should work on ns32k f's&d's on any machine. */ 400 static int 401 invalid_float (bfd_byte *p, int len) 402 { 403 int val; 404 405 if (len == 4) 406 val = (bit_extract_simple (p, 23, 8)/*exponent*/ == 0xff 407 || (bit_extract_simple (p, 23, 8)/*exponent*/ == 0 408 && bit_extract_simple (p, 0, 23)/*mantisa*/ != 0)); 409 else if (len == 8) 410 val = (bit_extract_simple (p, 52, 11)/*exponent*/ == 0x7ff 411 || (bit_extract_simple (p, 52, 11)/*exponent*/ == 0 412 && (bit_extract_simple (p, 0, 32)/*low mantisa*/ != 0 413 || bit_extract_simple (p, 32, 20)/*high mantisa*/ != 0))); 414 else 415 val = 1; 416 return (val); 417 } 418 #else 419 /* Assumes the bytes have been swapped to local order. */ 420 typedef union 421 { 422 double d; 423 float f; 424 struct { unsigned m:23, e:8, :1;} sf; 425 struct { unsigned lm; unsigned m:20, e:11, :1;} sd; 426 } float_type_u; 427 428 static int 429 invalid_float (float_type_u *p, int len) 430 { 431 int val; 432 433 if (len == sizeof (float)) 434 val = (p->sf.e == 0xff 435 || (p->sf.e == 0 && p->sf.m != 0)); 436 else if (len == sizeof (double)) 437 val = (p->sd.e == 0x7ff 438 || (p->sd.e == 0 && (p->sd.m != 0 || p->sd.lm != 0))); 439 else 440 val = 1; 441 return val; 442 } 443 #endif 444 445 /* Print an instruction operand of category given by d. IOFFSET is 446 the bit position below which small (<1 byte) parts of the operand can 447 be found (usually in the basic instruction, but for indexed 448 addressing it can be in the index byte). AOFFSETP is a pointer to the 449 bit position of the addressing extension. BUFFER contains the 450 instruction. ADDR is where BUFFER was read from. Put the disassembled 451 version of the operand in RESULT. INDEX_OFFSET is the bit position 452 of the index byte (it contains garbage if this operand is not a 453 general operand using scaled indexed addressing mode). */ 454 455 static int 456 print_insn_arg (int d, 457 int ioffset, 458 int *aoffsetp, 459 bfd_byte *buffer, 460 bfd_vma addr, 461 char *result, 462 int index_offset) 463 { 464 union 465 { 466 float f; 467 double d; 468 int i[2]; 469 } value; 470 int Ivalue; 471 int addr_mode; 472 int disp1, disp2; 473 int size; 474 475 switch (d) 476 { 477 case 'f': 478 /* A "gen" operand but 5 bits from the end of instruction. */ 479 ioffset -= 5; 480 case 'Z': 481 case 'F': 482 case 'L': 483 case 'I': 484 case 'B': 485 case 'W': 486 case 'D': 487 case 'A': 488 addr_mode = bit_extract (buffer, ioffset - 5, 5); 489 ioffset -= 5; 490 switch (addr_mode) 491 { 492 case 0x0: case 0x1: case 0x2: case 0x3: 493 case 0x4: case 0x5: case 0x6: case 0x7: 494 /* Register mode R0 -- R7. */ 495 switch (d) 496 { 497 case 'F': 498 case 'L': 499 case 'Z': 500 sprintf (result, "f%d", addr_mode); 501 break; 502 default: 503 sprintf (result, "r%d", addr_mode); 504 } 505 break; 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); 511 break; 512 case 0x10: 513 case 0x11: 514 case 0x12: 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"); 520 break; 521 case 0x13: 522 /* Reserved. */ 523 sprintf (result, "reserved"); 524 break; 525 case 0x14: 526 /* Immediate. */ 527 switch (d) 528 { 529 case 'I': 530 case 'Z': 531 case 'A': 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 536 anyway! */ 537 sprintf (result, _("$<undefined>")); 538 break; 539 case 'B': 540 Ivalue = bit_extract (buffer, *aoffsetp, 8); 541 Ivalue = sign_extend (Ivalue, 8); 542 *aoffsetp += 8; 543 sprintf (result, "$%d", Ivalue); 544 break; 545 case 'W': 546 Ivalue = bit_extract (buffer, *aoffsetp, 16); 547 flip_bytes ((char *) & Ivalue, 2); 548 *aoffsetp += 16; 549 Ivalue = sign_extend (Ivalue, 16); 550 sprintf (result, "$%d", Ivalue); 551 break; 552 case 'D': 553 Ivalue = bit_extract (buffer, *aoffsetp, 32); 554 flip_bytes ((char *) & Ivalue, 4); 555 *aoffsetp += 32; 556 sprintf (result, "$%d", Ivalue); 557 break; 558 case 'F': 559 bit_copy (buffer, *aoffsetp, 32, (char *) &value.f); 560 flip_bytes ((char *) &value.f, 4); 561 *aoffsetp += 32; 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); 566 break; 567 case 'L': 568 bit_copy (buffer, *aoffsetp, 64, (char *) &value.d); 569 flip_bytes ((char *) &value.d, 8); 570 *aoffsetp += 64; 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); 576 break; 577 } 578 break; 579 case 0x15: 580 /* Absolute @disp. */ 581 disp1 = get_displacement (buffer, aoffsetp); 582 sprintf (result, "@|%d|", disp1); 583 break; 584 case 0x16: 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); 589 break; 590 case 0x17: 591 /* Top of stack tos. */ 592 sprintf (result, "tos"); 593 break; 594 case 0x18: 595 /* Memory space disp(FP). */ 596 disp1 = get_displacement (buffer, aoffsetp); 597 sprintf (result, "%d(fp)", disp1); 598 break; 599 case 0x19: 600 /* Memory space disp(SP). */ 601 disp1 = get_displacement (buffer, aoffsetp); 602 sprintf (result, "%d(sp)", disp1); 603 break; 604 case 0x1a: 605 /* Memory space disp(SB). */ 606 disp1 = get_displacement (buffer, aoffsetp); 607 sprintf (result, "%d(sb)", disp1); 608 break; 609 case 0x1b: 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; 616 *result = '\0'; 617 break; 618 case 0x1c: 619 case 0x1d: 620 case 0x1e: 621 case 0x1f: 622 { 623 int bit_index; 624 static const char *ind = "bwdq"; 625 char *off; 626 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, 630 result, 0); 631 off = result + strlen (result); 632 sprintf (off, "[r%d:%c]", bit_index, ind[addr_mode & 3]); 633 } 634 break; 635 } 636 break; 637 case 'H': 638 case 'q': 639 Ivalue = bit_extract (buffer, ioffset-4, 4); 640 Ivalue = sign_extend (Ivalue, 4); 641 sprintf (result, "%d", Ivalue); 642 ioffset -= 4; 643 break; 644 case 'r': 645 Ivalue = bit_extract (buffer, ioffset-3, 3); 646 sprintf (result, "r%d", Ivalue&7); 647 ioffset -= 3; 648 break; 649 case 'd': 650 sprintf (result, "%d", get_displacement (buffer, aoffsetp)); 651 break; 652 case 'b': 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. */ 662 size = 1; 663 else if (size == 1) /* 01 => w. */ 664 size = 2; 665 else 666 size = 4; /* 11 => d. */ 667 668 sprintf (result, "%d", (Ivalue / size) + 1); 669 break; 670 case 'p': 671 *result++ = NEXT_IS_ADDR; 672 sprintf_vma (result, addr + get_displacement (buffer, aoffsetp)); 673 result += strlen (result); 674 *result++ = NEXT_IS_ADDR; 675 *result = '\0'; 676 break; 677 case 'i': 678 Ivalue = bit_extract (buffer, *aoffsetp, 8); 679 *aoffsetp += 8; 680 sprintf (result, "0x%x", Ivalue); 681 break; 682 case 'u': 683 Ivalue = bit_extract (buffer, *aoffsetp, 8); 684 optlist (Ivalue, opt_u, result); 685 *aoffsetp += 8; 686 break; 687 case 'U': 688 Ivalue = bit_extract (buffer, *aoffsetp, 8); 689 optlist (Ivalue, opt_U, result); 690 *aoffsetp += 8; 691 break; 692 case 'O': 693 Ivalue = bit_extract (buffer, ioffset - 9, 9); 694 optlist (Ivalue, opt_O, result); 695 ioffset -= 9; 696 break; 697 case 'C': 698 Ivalue = bit_extract (buffer, ioffset - 4, 4); 699 optlist (Ivalue, opt_C, result); 700 ioffset -= 4; 701 break; 702 case 'S': 703 Ivalue = bit_extract (buffer, ioffset - 8, 8); 704 optlist (Ivalue, opt_S, result); 705 ioffset -= 8; 706 break; 707 case 'M': 708 Ivalue = bit_extract (buffer, ioffset - 4, 4); 709 list_search (Ivalue, 0 ? list_M032 : list_M532, result); 710 ioffset -= 4; 711 break; 712 case 'P': 713 Ivalue = bit_extract (buffer, ioffset - 4, 4); 714 list_search (Ivalue, 0 ? list_P032 : list_P532, result); 715 ioffset -= 4; 716 break; 717 case 'g': 718 Ivalue = bit_extract (buffer, *aoffsetp, 3); 719 sprintf (result, "%d", Ivalue); 720 *aoffsetp += 3; 721 break; 722 case 'G': 723 Ivalue = bit_extract(buffer, *aoffsetp, 5); 724 sprintf (result, "%d", Ivalue + 1); 725 *aoffsetp += 5; 726 break; 727 } 728 return ioffset; 729 } 730 731 732 /* Print the 32000 instruction at address MEMADDR in debugged memory, 734 on STREAM. Returns length of the instruction, in bytes. */ 735 736 int 737 print_insn_ns32k (bfd_vma memaddr, disassemble_info *info) 738 { 739 unsigned int i; 740 const char *d; 741 unsigned short first_word; 742 int ioffset; /* Bits into instruction. */ 743 int aoffset; /* Bits into arguments. */ 744 char arg_bufs[MAX_ARGS+1][ARG_LEN]; 745 int argnum; 746 int maxarg; 747 struct private priv; 748 bfd_byte *buffer = priv.the_buffer; 749 dis_info = info; 750 751 info->private_data = & priv; 752 priv.max_fetched = priv.the_buffer; 753 priv.insn_start = memaddr; 754 if (OPCODES_SIGSETJMP (priv.bailout) != 0) 755 /* Error return. */ 756 return -1; 757 758 /* Look for 8bit opcodes first. Other wise, fetching two bytes could take 759 us over the end of accessible data unnecessarilly. */ 760 FETCH_DATA (info, buffer + 1); 761 for (i = 0; i < NOPCODES; i++) 762 if (ns32k_opcodes[i].opcode_id_size <= 8 763 && ((buffer[0] 764 & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1)) 765 == ns32k_opcodes[i].opcode_seed)) 766 break; 767 if (i == NOPCODES) 768 { 769 /* Maybe it is 9 to 16 bits big. */ 770 FETCH_DATA (info, buffer + 2); 771 first_word = read_memory_integer(buffer, 2); 772 773 for (i = 0; i < NOPCODES; i++) 774 if ((first_word 775 & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1)) 776 == ns32k_opcodes[i].opcode_seed) 777 break; 778 779 /* Handle undefined instructions. */ 780 if (i == NOPCODES) 781 { 782 (*dis_info->fprintf_func)(dis_info->stream, "0%o", buffer[0]); 783 return 1; 784 } 785 } 786 787 (*dis_info->fprintf_func)(dis_info->stream, "%s", ns32k_opcodes[i].name); 788 789 ioffset = ns32k_opcodes[i].opcode_size; 790 aoffset = ns32k_opcodes[i].opcode_size; 791 d = ns32k_opcodes[i].operands; 792 793 if (*d) 794 { 795 /* Offset in bits of the first thing beyond each index byte. 796 Element 0 is for operand A and element 1 is for operand B. 797 The rest are irrelevant, but we put them here so we don't 798 index outside the array. */ 799 int index_offset[MAX_ARGS]; 800 801 /* 0 for operand A, 1 for operand B, greater for other args. */ 802 int whicharg = 0; 803 804 (*dis_info->fprintf_func)(dis_info->stream, "\t"); 805 806 maxarg = 0; 807 808 /* First we have to find and keep track of the index bytes, 809 if we are using scaled indexed addressing mode, since the index 810 bytes occur right after the basic instruction, not as part 811 of the addressing extension. */ 812 if (Is_gen(d[1])) 813 { 814 int addr_mode = bit_extract (buffer, ioffset - 5, 5); 815 816 if (Adrmod_is_index (addr_mode)) 817 { 818 aoffset += 8; 819 index_offset[0] = aoffset; 820 } 821 } 822 823 if (d[2] && Is_gen(d[3])) 824 { 825 int addr_mode = bit_extract (buffer, ioffset - 10, 5); 826 827 if (Adrmod_is_index (addr_mode)) 828 { 829 aoffset += 8; 830 index_offset[1] = aoffset; 831 } 832 } 833 834 while (*d) 835 { 836 argnum = *d - '1'; 837 d++; 838 if (argnum > maxarg && argnum < MAX_ARGS) 839 maxarg = argnum; 840 ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer, 841 memaddr, arg_bufs[argnum], 842 index_offset[whicharg]); 843 d++; 844 whicharg++; 845 } 846 for (argnum = 0; argnum <= maxarg; argnum++) 847 { 848 bfd_vma addr; 849 char *ch; 850 851 for (ch = arg_bufs[argnum]; *ch;) 852 { 853 if (*ch == NEXT_IS_ADDR) 854 { 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; 862 } 863 else 864 (*dis_info->fprintf_func)(dis_info->stream, "%c", *ch++); 865 } 866 if (argnum < maxarg) 867 (*dis_info->fprintf_func)(dis_info->stream, ", "); 868 } 869 } 870 return aoffset / 8; 871 } 872