1 /* Single instruction disassembler for the Visium.
2 
3    Copyright (C) 2002-2021 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 "disassemble.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
fetch_data(struct disassemble_info * info,bfd_byte * addr)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
disassem_class0(disassemble_info * info,unsigned int ins)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 = ((ins & 0xffff) ^ 0x8000) - 0x8000;
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
disassem_class1(disassemble_info * info,unsigned int ins)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    %d,r%d", indx, source_a);
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
disassem_class2(disassemble_info * info,unsigned int ins)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
disassem_class3(disassemble_info * info,unsigned int ins)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
print_insn_visium(bfd_vma addr,disassemble_info * info)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 = (unsigned) 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