Home | History | Annotate | Download | only in opcodes
      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