1 /* Single instruction disassembler for the Visium. 2 3 Copyright (C) 2002-2016 Free Software Foundation, Inc. 4 5 This file is part of the GNU opcodes library. 6 7 This library is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3, or (at your option) 10 any later version. 11 12 It is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15 License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 20 MA 02110-1301, USA. */ 21 22 #include "sysdep.h" 23 #include "dis-asm.h" 24 #include "opcode/visium.h" 25 26 #include <string.h> 27 #include <stdlib.h> 28 #include <stdio.h> 29 #include <ctype.h> 30 #include <setjmp.h> 31 32 /* Maximum length of an instruction. */ 33 #define MAXLEN 4 34 35 struct private 36 { 37 /* Points to first byte not fetched. */ 38 bfd_byte *max_fetched; 39 bfd_byte the_buffer[MAXLEN]; 40 bfd_vma insn_start; 41 jmp_buf bailout; 42 }; 43 44 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive) 45 to ADDR (exclusive) are valid. Returns 1 for success, longjmps 46 on error. */ 47 #define FETCH_DATA(info, addr) \ 48 ((addr) <= ((struct private *)(info->private_data))->max_fetched \ 49 ? 1 : fetch_data ((info), (addr))) 50 51 static int fetch_data (struct disassemble_info *info, bfd_byte * addr); 52 53 static int 54 fetch_data (struct disassemble_info *info, bfd_byte *addr) 55 { 56 int status; 57 struct private *priv = (struct private *) info->private_data; 58 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer); 59 60 status = (*info->read_memory_func) (start, 61 priv->max_fetched, 62 addr - priv->max_fetched, info); 63 if (status != 0) 64 { 65 (*info->memory_error_func) (status, start, info); 66 longjmp (priv->bailout, 1); 67 } 68 else 69 priv->max_fetched = addr; 70 return 1; 71 } 72 73 static char *size_names[] = { "?", "b", "w", "?", "l", "?", "?", "?" }; 74 75 static char *cc_names[] = 76 { 77 "fa", "eq", "cs", "os", "ns", "ne", "cc", "oc", 78 "nc", "ge", "gt", "hi", "le", "ls", "lt", "tr" 79 }; 80 81 /* Disassemble non-storage relative instructions. */ 82 83 static int 84 disassem_class0 (disassemble_info *info, unsigned int ins) 85 { 86 int opcode = (ins >> 21) & 0x000f; 87 88 if (ins & CLASS0_UNUSED_MASK) 89 goto illegal_opcode; 90 91 switch (opcode) 92 { 93 case 0: 94 /* BRR instruction. */ 95 { 96 unsigned cbf = (ins >> 27) & 0x000f; 97 int displacement = ((int) (ins << 16)) >> 16; 98 99 if (ins == 0) 100 (*info->fprintf_func) (info->stream, "nop"); 101 else 102 (*info->fprintf_func) (info->stream, "brr %s,%+d", 103 cc_names[cbf], displacement); 104 } 105 break; 106 case 1: 107 /* Illegal opcode. */ 108 goto illegal_opcode; 109 break; 110 case 2: 111 /* Illegal opcode. */ 112 goto illegal_opcode; 113 break; 114 case 3: 115 /* Illegal opcode. */ 116 goto illegal_opcode; 117 break; 118 case 4: 119 /* Illegal opcode. */ 120 goto illegal_opcode; 121 break; 122 case 5: 123 /* Illegal opcode. */ 124 goto illegal_opcode; 125 break; 126 case 6: 127 /* Illegal opcode. */ 128 goto illegal_opcode; 129 break; 130 case 7: 131 /* Illegal opcode. */ 132 goto illegal_opcode; 133 break; 134 case 8: 135 /* Illegal opcode. */ 136 goto illegal_opcode; 137 break; 138 case 9: 139 /* Illegal opcode. */ 140 goto illegal_opcode; 141 break; 142 case 10: 143 /* Illegal opcode. */ 144 goto illegal_opcode; 145 break; 146 case 11: 147 /* Illegal opcode. */ 148 goto illegal_opcode; 149 break; 150 case 12: 151 /* Illegal opcode. */ 152 goto illegal_opcode; 153 break; 154 case 13: 155 /* Illegal opcode. */ 156 goto illegal_opcode; 157 break; 158 case 14: 159 /* Illegal opcode. */ 160 goto illegal_opcode; 161 break; 162 case 15: 163 /* Illegal opcode. */ 164 goto illegal_opcode; 165 break; 166 } 167 return 0; 168 169 illegal_opcode: 170 return -1; 171 } 172 173 /* Disassemble non-storage register class instructions. */ 174 175 static int 176 disassem_class1 (disassemble_info *info, unsigned int ins) 177 { 178 int opcode = (ins >> 21) & 0xf; 179 int source_a = (ins >> 16) & 0x1f; 180 int source_b = (ins >> 4) & 0x1f; 181 int indx = (ins >> 10) & 0x1f; 182 183 int size = ins & 0x7; 184 185 if (ins & CLASS1_UNUSED_MASK) 186 goto illegal_opcode; 187 188 switch (opcode) 189 { 190 case 0: 191 /* Stop. */ 192 (*info->fprintf_func) (info->stream, "stop"); 193 break; 194 case 1: 195 /* BMI - Block Move Indirect. */ 196 if (ins != BMI) 197 goto illegal_opcode; 198 199 (*info->fprintf_func) (info->stream, "bmi r1,r2,r3"); 200 break; 201 case 2: 202 /* Illegal opcode. */ 203 goto illegal_opcode; 204 break; 205 case 3: 206 /* BMD - Block Move Direct. */ 207 if (ins != BMD) 208 goto illegal_opcode; 209 210 (*info->fprintf_func) (info->stream, "bmd r1,r2,r3"); 211 break; 212 case 4: 213 /* DSI - Disable Interrupts. */ 214 if (ins != DSI) 215 goto illegal_opcode; 216 217 (*info->fprintf_func) (info->stream, "dsi"); 218 break; 219 220 case 5: 221 /* ENI - Enable Interrupts. */ 222 if (ins != ENI) 223 goto illegal_opcode; 224 225 (*info->fprintf_func) (info->stream, "eni"); 226 break; 227 228 case 6: 229 /* Illegal opcode (was EUT). */ 230 goto illegal_opcode; 231 break; 232 case 7: 233 /* RFI - Return from Interrupt. */ 234 if (ins != RFI) 235 goto illegal_opcode; 236 237 (*info->fprintf_func) (info->stream, "rfi"); 238 break; 239 case 8: 240 /* Illegal opcode. */ 241 goto illegal_opcode; 242 break; 243 case 9: 244 /* Illegal opcode. */ 245 goto illegal_opcode; 246 break; 247 case 10: 248 /* Illegal opcode. */ 249 goto illegal_opcode; 250 break; 251 case 11: 252 /* Illegal opcode. */ 253 goto illegal_opcode; 254 break; 255 case 12: 256 /* Illegal opcode. */ 257 goto illegal_opcode; 258 break; 259 case 13: 260 goto illegal_opcode; 261 break; 262 case 14: 263 goto illegal_opcode; 264 break; 265 case 15: 266 if (ins & EAM_SELECT_MASK) 267 { 268 /* Extension arithmetic module write */ 269 int fp_ins = (ins >> 27) & 0xf; 270 271 if (size != 4) 272 goto illegal_opcode; 273 274 if (ins & FP_SELECT_MASK) 275 { 276 /* Which floating point instructions don't need a fsrcB 277 register. */ 278 const int no_fsrcb[16] = { 1, 0, 0, 0, 0, 1, 1, 1, 279 1, 1, 0, 0, 1, 0, 0, 0 280 }; 281 if (no_fsrcb[fp_ins] && source_b) 282 goto illegal_opcode; 283 284 /* Check that none of the floating register register numbers 285 is higher than 15. (If this is fload, then srcA is a 286 general register. */ 287 if (ins & ((1 << 14) | (1 << 8)) || (fp_ins && ins & (1 << 20))) 288 goto illegal_opcode; 289 290 switch (fp_ins) 291 { 292 case 0: 293 (*info->fprintf_func) (info->stream, "fload f%d,r%d", 294 indx, source_a); 295 break; 296 case 1: 297 (*info->fprintf_func) (info->stream, "fadd f%d,f%d,f%d", 298 indx, source_a, source_b); 299 break; 300 case 2: 301 (*info->fprintf_func) (info->stream, "fsub f%d,f%d,f%d", 302 indx, source_a, source_b); 303 break; 304 case 3: 305 (*info->fprintf_func) (info->stream, "fmult f%d,f%d,f%d", 306 indx, source_a, source_b); 307 break; 308 case 4: 309 (*info->fprintf_func) (info->stream, "fdiv f%d,f%d,f%d", 310 indx, source_a, source_b); 311 break; 312 case 5: 313 (*info->fprintf_func) (info->stream, "fsqrt f%d,f%d", 314 indx, source_a); 315 break; 316 case 6: 317 (*info->fprintf_func) (info->stream, "fneg f%d,f%d", 318 indx, source_a); 319 break; 320 case 7: 321 (*info->fprintf_func) (info->stream, "fabs f%d,f%d", 322 indx, source_a); 323 break; 324 case 8: 325 (*info->fprintf_func) (info->stream, "ftoi f%d,f%d", 326 indx, source_a); 327 break; 328 case 9: 329 (*info->fprintf_func) (info->stream, "itof f%d,f%d", 330 indx, source_a); 331 break; 332 case 12: 333 (*info->fprintf_func) (info->stream, "fmove f%d,f%d", 334 indx, source_a); 335 break; 336 default: 337 (*info->fprintf_func) (info->stream, 338 "fpinst %d,f%d,f%d,f%d", fp_ins, 339 indx, source_a, source_b); 340 break; 341 } 342 } 343 else 344 { 345 /* Which EAM operations do not need a srcB register. */ 346 const int no_srcb[32] = 347 { 0, 0, 1, 1, 0, 1, 1, 1, 348 0, 1, 1, 1, 0, 0, 0, 0, 349 0, 0, 0, 0, 0, 0, 0, 0, 350 0, 0, 0, 0, 0, 0, 0, 0 351 }; 352 353 if (no_srcb[indx] && source_b) 354 goto illegal_opcode; 355 356 if (fp_ins) 357 goto illegal_opcode; 358 359 switch (indx) 360 { 361 case 0: 362 (*info->fprintf_func) (info->stream, "mults r%d,r%d", 363 source_a, source_b); 364 break; 365 case 1: 366 (*info->fprintf_func) (info->stream, "multu r%d,r%d", 367 source_a, source_b); 368 break; 369 case 2: 370 (*info->fprintf_func) (info->stream, "divs r%d", 371 source_a); 372 break; 373 case 3: 374 (*info->fprintf_func) (info->stream, "divu r%d", 375 source_a); 376 break; 377 case 4: 378 (*info->fprintf_func) (info->stream, "writemd r%d,r%d", 379 source_a, source_b); 380 break; 381 case 5: 382 (*info->fprintf_func) (info->stream, "writemdc r%d", 383 source_a); 384 break; 385 case 6: 386 (*info->fprintf_func) (info->stream, "divds r%d", 387 source_a); 388 break; 389 case 7: 390 (*info->fprintf_func) (info->stream, "divdu r%d", 391 source_a); 392 break; 393 case 9: 394 (*info->fprintf_func) (info->stream, "asrd r%d", 395 source_a); 396 break; 397 case 10: 398 (*info->fprintf_func) (info->stream, "lsrd r%d", 399 source_a); 400 break; 401 case 11: 402 (*info->fprintf_func) (info->stream, "asld r%d", 403 source_a); 404 break; 405 default: 406 (*info->fprintf_func) (info->stream, 407 "eamwrite %d,r%d,r%d", indx, 408 source_a, source_b); 409 break; 410 } 411 } 412 } 413 else 414 { 415 /* WRITE - write to memory. */ 416 (*info->fprintf_func) (info->stream, "write.%s %d(r%d),r%d", 417 size_names[size], indx, source_a, source_b); 418 } 419 break; 420 } 421 422 return 0; 423 424 illegal_opcode: 425 return -1; 426 } 427 428 /* Disassemble storage immediate class instructions. */ 429 430 static int 431 disassem_class2 (disassemble_info *info, unsigned int ins) 432 { 433 int opcode = (ins >> 21) & 0xf; 434 int source_a = (ins >> 16) & 0x1f; 435 unsigned immediate = ins & 0x0000ffff; 436 437 if (ins & CC_MASK) 438 goto illegal_opcode; 439 440 switch (opcode) 441 { 442 case 0: 443 /* ADDI instruction. */ 444 (*info->fprintf_func) (info->stream, "addi r%d,%d", source_a, 445 immediate); 446 break; 447 case 1: 448 /* Illegal opcode. */ 449 goto illegal_opcode; 450 break; 451 case 2: 452 /* SUBI instruction. */ 453 (*info->fprintf_func) (info->stream, "subi r%d,%d", source_a, 454 immediate); 455 break; 456 case 3: 457 /* Illegal opcode. */ 458 goto illegal_opcode; 459 break; 460 case 4: 461 /* MOVIL instruction. */ 462 (*info->fprintf_func) (info->stream, "movil r%d,0x%04X", source_a, 463 immediate); 464 break; 465 case 5: 466 /* MOVIU instruction. */ 467 (*info->fprintf_func) (info->stream, "moviu r%d,0x%04X", source_a, 468 immediate); 469 break; 470 case 6: 471 /* MOVIQ instruction. */ 472 (*info->fprintf_func) (info->stream, "moviq r%d,%u", source_a, 473 immediate); 474 break; 475 case 7: 476 /* Illegal opcode. */ 477 goto illegal_opcode; 478 break; 479 case 8: 480 /* WRTL instruction. */ 481 if (source_a != 0) 482 goto illegal_opcode; 483 484 (*info->fprintf_func) (info->stream, "wrtl 0x%04X", immediate); 485 break; 486 case 9: 487 /* WRTU instruction. */ 488 if (source_a != 0) 489 goto illegal_opcode; 490 491 (*info->fprintf_func) (info->stream, "wrtu 0x%04X", immediate); 492 break; 493 case 10: 494 /* Illegal opcode. */ 495 goto illegal_opcode; 496 break; 497 case 11: 498 /* Illegal opcode. */ 499 goto illegal_opcode; 500 break; 501 case 12: 502 /* Illegal opcode. */ 503 goto illegal_opcode; 504 break; 505 case 13: 506 /* Illegal opcode. */ 507 goto illegal_opcode; 508 break; 509 case 14: 510 /* Illegal opcode. */ 511 goto illegal_opcode; 512 break; 513 case 15: 514 /* Illegal opcode. */ 515 goto illegal_opcode; 516 break; 517 } 518 519 return 0; 520 521 illegal_opcode: 522 return -1; 523 } 524 525 /* Disassemble storage register class instructions. */ 526 527 static int 528 disassem_class3 (disassemble_info *info, unsigned int ins) 529 { 530 int opcode = (ins >> 21) & 0xf; 531 int source_b = (ins >> 4) & 0x1f; 532 int source_a = (ins >> 16) & 0x1f; 533 int size = ins & 0x7; 534 int dest = (ins >> 10) & 0x1f; 535 536 /* Those instructions that don't have a srcB register. */ 537 const int no_srcb[16] = 538 { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0 }; 539 540 /* These are instructions which can take an immediate srcB value. */ 541 const int srcb_immed[16] = 542 { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1 }; 543 544 /* User opcodes should not provide a non-zero srcB register 545 when none is required. Only a BRA or floating point 546 instruction should have a non-zero condition code field. 547 Only a WRITE or EAMWRITE (opcode 15) should select an EAM 548 or floating point operation. Note that FP_SELECT_MASK is 549 the same bit (bit 3) as the interrupt bit which 550 distinguishes SYS1 from BRA and SYS2 from RFLAG. */ 551 if ((no_srcb[opcode] && source_b) 552 || (!srcb_immed[opcode] && ins & CLASS3_SOURCEB_IMMED) 553 || (opcode != 12 && opcode != 15 && ins & CC_MASK) 554 || (opcode != 15 && ins & (EAM_SELECT_MASK | FP_SELECT_MASK))) 555 goto illegal_opcode; 556 557 558 switch (opcode) 559 { 560 case 0: 561 /* ADD instruction. */ 562 (*info->fprintf_func) (info->stream, "add.%s r%d,r%d,r%d", 563 size_names[size], dest, source_a, source_b); 564 break; 565 case 1: 566 /* ADC instruction. */ 567 (*info->fprintf_func) (info->stream, "adc.%s r%d,r%d,r%d", 568 size_names[size], dest, source_a, source_b); 569 break; 570 case 2: 571 /* SUB instruction. */ 572 if (dest == 0) 573 (*info->fprintf_func) (info->stream, "cmp.%s r%d,r%d", 574 size_names[size], source_a, source_b); 575 else 576 (*info->fprintf_func) (info->stream, "sub.%s r%d,r%d,r%d", 577 size_names[size], dest, source_a, source_b); 578 break; 579 case 3: 580 /* SUBC instruction. */ 581 if (dest == 0) 582 (*info->fprintf_func) (info->stream, "cmpc.%s r%d,r%d", 583 size_names[size], source_a, source_b); 584 else 585 (*info->fprintf_func) (info->stream, "subc.%s r%d,r%d,r%d", 586 size_names[size], dest, source_a, source_b); 587 break; 588 case 4: 589 /* EXTW instruction. */ 590 if (size == 1) 591 goto illegal_opcode; 592 593 (*info->fprintf_func) (info->stream, "extw.%s r%d,r%d", 594 size_names[size], dest, source_a); 595 break; 596 case 5: 597 /* ASR instruction. */ 598 if (ins & CLASS3_SOURCEB_IMMED) 599 (*info->fprintf_func) (info->stream, "asr.%s r%d,r%d,%d", 600 size_names[size], dest, source_a, source_b); 601 else 602 (*info->fprintf_func) (info->stream, "asr.%s r%d,r%d,r%d", 603 size_names[size], dest, source_a, source_b); 604 break; 605 case 6: 606 /* LSR instruction. */ 607 if (ins & CLASS3_SOURCEB_IMMED) 608 (*info->fprintf_func) (info->stream, "lsr.%s r%d,r%d,%d", 609 size_names[size], dest, source_a, source_b); 610 else 611 (*info->fprintf_func) (info->stream, "lsr.%s r%d,r%d,r%d", 612 size_names[size], dest, source_a, source_b); 613 break; 614 case 7: 615 /* ASL instruction. */ 616 if (ins & CLASS3_SOURCEB_IMMED) 617 (*info->fprintf_func) (info->stream, "asl.%s r%d,r%d,%d", 618 size_names[size], dest, source_a, source_b); 619 else 620 (*info->fprintf_func) (info->stream, "asl.%s r%d,r%d,r%d", 621 size_names[size], dest, source_a, source_b); 622 break; 623 case 8: 624 /* XOR instruction. */ 625 (*info->fprintf_func) (info->stream, "xor.%s r%d,r%d,r%d", 626 size_names[size], dest, source_a, source_b); 627 break; 628 case 9: 629 /* OR instruction. */ 630 if (source_b == 0) 631 (*info->fprintf_func) (info->stream, "move.%s r%d,r%d", 632 size_names[size], dest, source_a); 633 else 634 (*info->fprintf_func) (info->stream, "or.%s r%d,r%d,r%d", 635 size_names[size], dest, source_a, source_b); 636 break; 637 case 10: 638 /* AND instruction. */ 639 (*info->fprintf_func) (info->stream, "and.%s r%d,r%d,r%d", 640 size_names[size], dest, source_a, source_b); 641 break; 642 case 11: 643 /* NOT instruction. */ 644 (*info->fprintf_func) (info->stream, "not.%s r%d,r%d", 645 size_names[size], dest, source_a); 646 break; 647 case 12: 648 /* BRA instruction. */ 649 { 650 unsigned cbf = (ins >> 27) & 0x000f; 651 652 if (size != 4) 653 goto illegal_opcode; 654 655 (*info->fprintf_func) (info->stream, "bra %s,r%d,r%d", 656 cc_names[cbf], source_a, dest); 657 } 658 break; 659 case 13: 660 /* RFLAG instruction. */ 661 if (source_a || size != 4) 662 goto illegal_opcode; 663 664 (*info->fprintf_func) (info->stream, "rflag r%d", dest); 665 break; 666 case 14: 667 /* EXTB instruction. */ 668 (*info->fprintf_func) (info->stream, "extb.%s r%d,r%d", 669 size_names[size], dest, source_a); 670 break; 671 case 15: 672 if (!(ins & CLASS3_SOURCEB_IMMED)) 673 goto illegal_opcode; 674 675 if (ins & EAM_SELECT_MASK) 676 { 677 /* Extension arithmetic module read. */ 678 int fp_ins = (ins >> 27) & 0xf; 679 680 if (size != 4) 681 goto illegal_opcode; 682 683 if (ins & FP_SELECT_MASK) 684 { 685 /* Check fsrcA <= 15 and fsrcB <= 15. */ 686 if (ins & ((1 << 20) | (1 << 8))) 687 goto illegal_opcode; 688 689 switch (fp_ins) 690 { 691 case 0: 692 if (source_b) 693 goto illegal_opcode; 694 695 (*info->fprintf_func) (info->stream, "fstore r%d,f%d", 696 dest, source_a); 697 break; 698 case 10: 699 (*info->fprintf_func) (info->stream, "fcmp r%d,f%d,f%d", 700 dest, source_a, source_b); 701 break; 702 case 11: 703 (*info->fprintf_func) (info->stream, "fcmpe r%d,f%d,f%d", 704 dest, source_a, source_b); 705 break; 706 default: 707 (*info->fprintf_func) (info->stream, 708 "fpuread %d,r%d,f%d,f%d", fp_ins, 709 dest, source_a, source_b); 710 break; 711 } 712 } 713 else 714 { 715 if (fp_ins || source_a) 716 goto illegal_opcode; 717 718 switch (source_b) 719 { 720 case 0: 721 (*info->fprintf_func) (info->stream, "readmda r%d", dest); 722 break; 723 case 1: 724 (*info->fprintf_func) (info->stream, "readmdb r%d", dest); 725 break; 726 case 2: 727 (*info->fprintf_func) (info->stream, "readmdc r%d", dest); 728 break; 729 default: 730 (*info->fprintf_func) (info->stream, "eamread r%d,%d", 731 dest, source_b); 732 break; 733 } 734 } 735 } 736 else 737 { 738 if (ins & FP_SELECT_MASK) 739 goto illegal_opcode; 740 741 /* READ instruction. */ 742 (*info->fprintf_func) (info->stream, "read.%s r%d,%d(r%d)", 743 size_names[size], dest, source_b, source_a); 744 } 745 break; 746 } 747 748 return 0; 749 750 illegal_opcode: 751 return -1; 752 753 } 754 755 /* Print the visium instruction at address addr in debugged memory, 756 on info->stream. Return length of the instruction, in bytes. */ 757 758 int 759 print_insn_visium (bfd_vma addr, disassemble_info *info) 760 { 761 unsigned ins; 762 unsigned p1, p2; 763 int ans; 764 int i; 765 766 /* Stuff copied from m68k-dis.c. */ 767 struct private priv; 768 bfd_byte *buffer = priv.the_buffer; 769 info->private_data = (PTR) & priv; 770 priv.max_fetched = priv.the_buffer; 771 priv.insn_start = addr; 772 if (setjmp (priv.bailout) != 0) 773 { 774 /* Error return. */ 775 return -1; 776 } 777 778 /* We do return this info. */ 779 info->insn_info_valid = 1; 780 781 /* Assume non branch insn. */ 782 info->insn_type = dis_nonbranch; 783 784 /* Assume no delay. */ 785 info->branch_delay_insns = 0; 786 787 /* Assume no target known. */ 788 info->target = 0; 789 790 /* Get 32-bit instruction word. */ 791 FETCH_DATA (info, buffer + 4); 792 ins = buffer[0] << 24; 793 ins |= buffer[1] << 16; 794 ins |= buffer[2] << 8; 795 ins |= buffer[3]; 796 797 ans = 0; 798 799 p1 = buffer[0] ^ buffer[1] ^ buffer[2] ^ buffer[3]; 800 p2 = 0; 801 for (i = 0; i < 8; i++) 802 { 803 p2 += p1 & 1; 804 p1 >>= 1; 805 } 806 807 /* Decode the instruction. */ 808 if (p2 & 1) 809 ans = -1; 810 else 811 { 812 switch ((ins >> 25) & 0x3) 813 { 814 case 0: 815 ans = disassem_class0 (info, ins); 816 break; 817 case 1: 818 ans = disassem_class1 (info, ins); 819 break; 820 case 2: 821 ans = disassem_class2 (info, ins); 822 break; 823 case 3: 824 ans = disassem_class3 (info, ins); 825 break; 826 } 827 } 828 829 if (ans != 0) 830 (*info->fprintf_func) (info->stream, "err"); 831 832 /* Return number of bytes consumed (always 4 for the Visium). */ 833 return 4; 834 } 835