Coverage Report

Created: 2026-09-14 08:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/binutils-gdb/opcodes/visium-dis.c
Line
Count
Source
1
/* Single instruction disassembler for the Visium.
2
3
   Copyright (C) 2002-2026 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
902k
  ((addr) <= ((struct private *)(info->private_data))->max_fetched \
49
902k
   ? 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
902k
{
56
902k
  int status;
57
902k
  struct private *priv = (struct private *) info->private_data;
58
902k
  bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
59
60
902k
  status = (*info->read_memory_func) (start,
61
902k
              priv->max_fetched,
62
902k
              addr - priv->max_fetched, info);
63
902k
  if (status != 0)
64
464
    {
65
464
      (*info->memory_error_func) (status, start, info);
66
464
      longjmp (priv->bailout, 1);
67
464
    }
68
902k
  else
69
902k
    priv->max_fetched = addr;
70
902k
  return 1;
71
902k
}
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
232k
{
86
232k
  int opcode = (ins >> 21) & 0x000f;
87
88
232k
  if (ins & CLASS0_UNUSED_MASK)
89
119k
    goto illegal_opcode;
90
91
113k
  switch (opcode)
92
113k
    {
93
91.2k
    case 0:
94
      /* BRR instruction.  */
95
91.2k
      {
96
91.2k
  unsigned cbf = (ins >> 27) & 0x000f;
97
91.2k
  int displacement = ((ins & 0xffff) ^ 0x8000) - 0x8000;
98
99
91.2k
  if (ins == 0)
100
50.0k
    (*info->fprintf_func) (info->stream, "nop");
101
41.1k
  else
102
41.1k
    (*info->fprintf_func) (info->stream, "brr     %s,%+d",
103
41.1k
         cc_names[cbf], displacement);
104
91.2k
      }
105
91.2k
      break;
106
3.12k
    case 1:
107
      /* Illegal opcode.  */
108
3.12k
      goto illegal_opcode;
109
0
      break;
110
1.13k
    case 2:
111
      /* Illegal opcode.  */
112
1.13k
      goto illegal_opcode;
113
0
      break;
114
6.11k
    case 3:
115
      /* Illegal opcode.  */
116
6.11k
      goto illegal_opcode;
117
0
      break;
118
1.28k
    case 4:
119
      /* Illegal opcode.  */
120
1.28k
      goto illegal_opcode;
121
0
      break;
122
1.18k
    case 5:
123
      /* Illegal opcode.  */
124
1.18k
      goto illegal_opcode;
125
0
      break;
126
2.64k
    case 6:
127
      /* Illegal opcode.  */
128
2.64k
      goto illegal_opcode;
129
0
      break;
130
393
    case 7:
131
      /* Illegal opcode.  */
132
393
      goto illegal_opcode;
133
0
      break;
134
5.23k
    case 8:
135
      /* Illegal opcode.  */
136
5.23k
      goto illegal_opcode;
137
0
      break;
138
229
    case 9:
139
      /* Illegal opcode.  */
140
229
      goto illegal_opcode;
141
0
      break;
142
65
    case 10:
143
      /* Illegal opcode.  */
144
65
      goto illegal_opcode;
145
0
      break;
146
225
    case 11:
147
      /* Illegal opcode.  */
148
225
      goto illegal_opcode;
149
0
      break;
150
251
    case 12:
151
      /* Illegal opcode.  */
152
251
      goto illegal_opcode;
153
0
      break;
154
54
    case 13:
155
      /* Illegal opcode.  */
156
54
      goto illegal_opcode;
157
0
      break;
158
132
    case 14:
159
      /* Illegal opcode.  */
160
132
      goto illegal_opcode;
161
0
      break;
162
94
    case 15:
163
      /* Illegal opcode.  */
164
94
      goto illegal_opcode;
165
0
      break;
166
113k
    }
167
91.2k
  return 0;
168
169
141k
 illegal_opcode:
170
141k
  return -1;
171
113k
}
172
173
/* Disassemble non-storage register class instructions.   */
174
175
static int
176
disassem_class1 (disassemble_info *info, unsigned int ins)
177
87.7k
{
178
87.7k
  int opcode = (ins >> 21) & 0xf;
179
87.7k
  int source_a = (ins >> 16) & 0x1f;
180
87.7k
  int source_b = (ins >> 4) & 0x1f;
181
87.7k
  int indx = (ins >> 10) & 0x1f;
182
183
87.7k
  int size = ins & 0x7;
184
185
87.7k
  if (ins & CLASS1_UNUSED_MASK)
186
45.3k
    goto illegal_opcode;
187
188
42.3k
  switch (opcode)
189
42.3k
    {
190
6.99k
    case 0:
191
      /* Stop.  */
192
6.99k
      (*info->fprintf_func) (info->stream, "stop    %d,r%d", indx, source_a);
193
6.99k
      break;
194
1.66k
    case 1:
195
      /* BMI - Block Move Indirect.  */
196
1.66k
      if (ins != BMI)
197
1.56k
  goto illegal_opcode;
198
199
98
      (*info->fprintf_func) (info->stream, "bmi     r1,r2,r3");
200
98
      break;
201
1.43k
    case 2:
202
      /* Illegal opcode.  */
203
1.43k
      goto illegal_opcode;
204
0
      break;
205
3.08k
    case 3:
206
      /* BMD - Block Move Direct.  */
207
3.08k
      if (ins != BMD)
208
3.05k
  goto illegal_opcode;
209
210
35
      (*info->fprintf_func) (info->stream, "bmd     r1,r2,r3");
211
35
      break;
212
1.60k
    case 4:
213
      /* DSI - Disable Interrupts.  */
214
1.60k
      if (ins != DSI)
215
1.58k
  goto illegal_opcode;
216
217
21
      (*info->fprintf_func) (info->stream, "dsi");
218
21
      break;
219
220
1.43k
    case 5:
221
      /* ENI - Enable Interrupts.  */
222
1.43k
      if (ins != ENI)
223
1.37k
  goto illegal_opcode;
224
225
62
      (*info->fprintf_func) (info->stream, "eni");
226
62
      break;
227
228
1.33k
    case 6:
229
      /* Illegal opcode (was EUT).  */
230
1.33k
      goto illegal_opcode;
231
0
      break;
232
1.77k
    case 7:
233
      /* RFI - Return from Interrupt.  */
234
1.77k
      if (ins != RFI)
235
1.73k
  goto illegal_opcode;
236
237
40
      (*info->fprintf_func) (info->stream, "rfi");
238
40
      break;
239
6.04k
    case 8:
240
      /* Illegal opcode.  */
241
6.04k
      goto illegal_opcode;
242
0
      break;
243
2.44k
    case 9:
244
      /* Illegal opcode.  */
245
2.44k
      goto illegal_opcode;
246
0
      break;
247
2.00k
    case 10:
248
      /* Illegal opcode.  */
249
2.00k
      goto illegal_opcode;
250
0
      break;
251
3.42k
    case 11:
252
      /* Illegal opcode.  */
253
3.42k
      goto illegal_opcode;
254
0
      break;
255
1.86k
    case 12:
256
      /* Illegal opcode.  */
257
1.86k
      goto illegal_opcode;
258
0
      break;
259
1.38k
    case 13:
260
1.38k
      goto illegal_opcode;
261
0
      break;
262
1.28k
    case 14:
263
1.28k
      goto illegal_opcode;
264
0
      break;
265
4.54k
    case 15:
266
4.54k
      if (ins & EAM_SELECT_MASK)
267
3.02k
  {
268
    /* Extension arithmetic module write */
269
3.02k
    int fp_ins = (ins >> 27) & 0xf;
270
271
3.02k
    if (size != 4)
272
660
      goto illegal_opcode;
273
274
2.36k
    if (ins & FP_SELECT_MASK)
275
1.10k
      {
276
        /* Which floating point instructions don't need a fsrcB
277
           register.  */
278
1.10k
        const int no_fsrcb[16] = { 1, 0, 0, 0, 0, 1, 1, 1,
279
1.10k
    1, 1, 0, 0, 1, 0, 0, 0
280
1.10k
        };
281
1.10k
        if (no_fsrcb[fp_ins] && source_b)
282
45
    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
1.05k
        if (ins & ((1 << 14) | (1 << 8)) || (fp_ins && ins & (1 << 20)))
288
147
    goto illegal_opcode;
289
290
908
        switch (fp_ins)
291
908
    {
292
25
    case 0:
293
25
      (*info->fprintf_func) (info->stream, "fload   f%d,r%d",
294
25
           indx, source_a);
295
25
      break;
296
28
    case 1:
297
28
      (*info->fprintf_func) (info->stream, "fadd    f%d,f%d,f%d",
298
28
           indx, source_a, source_b);
299
28
      break;
300
39
    case 2:
301
39
      (*info->fprintf_func) (info->stream, "fsub    f%d,f%d,f%d",
302
39
           indx, source_a, source_b);
303
39
      break;
304
19
    case 3:
305
19
      (*info->fprintf_func) (info->stream, "fmult   f%d,f%d,f%d",
306
19
           indx, source_a, source_b);
307
19
      break;
308
39
    case 4:
309
39
      (*info->fprintf_func) (info->stream, "fdiv    f%d,f%d,f%d",
310
39
           indx, source_a, source_b);
311
39
      break;
312
229
    case 5:
313
229
      (*info->fprintf_func) (info->stream, "fsqrt   f%d,f%d",
314
229
           indx, source_a);
315
229
      break;
316
151
    case 6:
317
151
      (*info->fprintf_func) (info->stream, "fneg    f%d,f%d",
318
151
           indx, source_a);
319
151
      break;
320
98
    case 7:
321
98
      (*info->fprintf_func) (info->stream, "fabs    f%d,f%d",
322
98
           indx, source_a);
323
98
      break;
324
4
    case 8:
325
4
      (*info->fprintf_func) (info->stream, "ftoi    f%d,f%d",
326
4
           indx, source_a);
327
4
      break;
328
72
    case 9:
329
72
      (*info->fprintf_func) (info->stream, "itof    f%d,f%d",
330
72
           indx, source_a);
331
72
      break;
332
118
    case 12:
333
118
      (*info->fprintf_func) (info->stream, "fmove   f%d,f%d",
334
118
           indx, source_a);
335
118
      break;
336
86
    default:
337
86
      (*info->fprintf_func) (info->stream,
338
86
           "fpinst  %d,f%d,f%d,f%d", fp_ins,
339
86
           indx, source_a, source_b);
340
86
      break;
341
908
    }
342
908
      }
343
1.26k
    else
344
1.26k
      {
345
        /* Which EAM operations do not need a srcB register.  */
346
1.26k
        const int no_srcb[32] =
347
1.26k
        { 0, 0, 1, 1, 0, 1, 1, 1,
348
1.26k
    0, 1, 1, 1, 0, 0, 0, 0,
349
1.26k
    0, 0, 0, 0, 0, 0, 0, 0,
350
1.26k
    0, 0, 0, 0, 0, 0, 0, 0
351
1.26k
        };
352
353
1.26k
        if (no_srcb[indx] && source_b)
354
25
    goto illegal_opcode;
355
356
1.23k
        if (fp_ins)
357
141
    goto illegal_opcode;
358
359
1.09k
        switch (indx)
360
1.09k
    {
361
21
    case 0:
362
21
      (*info->fprintf_func) (info->stream, "mults   r%d,r%d",
363
21
           source_a, source_b);
364
21
      break;
365
90
    case 1:
366
90
      (*info->fprintf_func) (info->stream, "multu   r%d,r%d",
367
90
           source_a, source_b);
368
90
      break;
369
40
    case 2:
370
40
      (*info->fprintf_func) (info->stream, "divs    r%d",
371
40
           source_a);
372
40
      break;
373
0
    case 3:
374
0
      (*info->fprintf_func) (info->stream, "divu    r%d",
375
0
           source_a);
376
0
      break;
377
179
    case 4:
378
179
      (*info->fprintf_func) (info->stream, "writemd r%d,r%d",
379
179
           source_a, source_b);
380
179
      break;
381
80
    case 5:
382
80
      (*info->fprintf_func) (info->stream, "writemdc r%d",
383
80
           source_a);
384
80
      break;
385
0
    case 6:
386
0
      (*info->fprintf_func) (info->stream, "divds   r%d",
387
0
           source_a);
388
0
      break;
389
66
    case 7:
390
66
      (*info->fprintf_func) (info->stream, "divdu   r%d",
391
66
           source_a);
392
66
      break;
393
0
    case 9:
394
0
      (*info->fprintf_func) (info->stream, "asrd    r%d",
395
0
           source_a);
396
0
      break;
397
58
    case 10:
398
58
      (*info->fprintf_func) (info->stream, "lsrd    r%d",
399
58
           source_a);
400
58
      break;
401
45
    case 11:
402
45
      (*info->fprintf_func) (info->stream, "asld    r%d",
403
45
           source_a);
404
45
      break;
405
519
    default:
406
519
      (*info->fprintf_func) (info->stream,
407
519
           "eamwrite %d,r%d,r%d", indx,
408
519
           source_a, source_b);
409
519
      break;
410
1.09k
    }
411
1.09k
      }
412
2.36k
  }
413
1.52k
      else
414
1.52k
  {
415
    /* WRITE - write to memory.  */
416
1.52k
    (*info->fprintf_func) (info->stream, "write.%s %d(r%d),r%d",
417
1.52k
         size_names[size], indx, source_a, source_b);
418
1.52k
  }
419
3.53k
      break;
420
42.3k
    }
421
422
10.7k
  return 0;
423
424
76.9k
 illegal_opcode:
425
76.9k
  return -1;
426
42.3k
}
427
428
/* Disassemble storage immediate class instructions.   */
429
430
static int
431
disassem_class2 (disassemble_info *info, unsigned int ins)
432
92.0k
{
433
92.0k
  int opcode = (ins >> 21) & 0xf;
434
92.0k
  int source_a = (ins >> 16) & 0x1f;
435
92.0k
  unsigned immediate = ins & 0x0000ffff;
436
437
92.0k
  if (ins & CC_MASK)
438
77.0k
    goto illegal_opcode;
439
440
14.9k
  switch (opcode)
441
14.9k
    {
442
2.81k
    case 0:
443
      /* ADDI instruction.  */
444
2.81k
      (*info->fprintf_func) (info->stream, "addi    r%d,%d", source_a,
445
2.81k
           immediate);
446
2.81k
      break;
447
875
    case 1:
448
      /* Illegal opcode.  */
449
875
      goto illegal_opcode;
450
0
      break;
451
455
    case 2:
452
      /* SUBI instruction.  */
453
455
      (*info->fprintf_func) (info->stream, "subi    r%d,%d", source_a,
454
455
           immediate);
455
455
      break;
456
419
    case 3:
457
      /* Illegal opcode.  */
458
419
      goto illegal_opcode;
459
0
      break;
460
845
    case 4:
461
      /* MOVIL instruction.  */
462
845
      (*info->fprintf_func) (info->stream, "movil   r%d,0x%04X", source_a,
463
845
           immediate);
464
845
      break;
465
362
    case 5:
466
      /* MOVIU instruction.  */
467
362
      (*info->fprintf_func) (info->stream, "moviu   r%d,0x%04X", source_a,
468
362
           immediate);
469
362
      break;
470
417
    case 6:
471
      /* MOVIQ instruction.  */
472
417
      (*info->fprintf_func) (info->stream, "moviq   r%d,%u", source_a,
473
417
           immediate);
474
417
      break;
475
908
    case 7:
476
      /* Illegal opcode.  */
477
908
      goto illegal_opcode;
478
0
      break;
479
3.15k
    case 8:
480
      /* WRTL instruction.  */
481
3.15k
      if (source_a != 0)
482
1.85k
  goto illegal_opcode;
483
484
1.30k
      (*info->fprintf_func) (info->stream, "wrtl    0x%04X", immediate);
485
1.30k
      break;
486
763
    case 9:
487
      /* WRTU instruction.  */
488
763
      if (source_a != 0)
489
642
  goto illegal_opcode;
490
491
121
      (*info->fprintf_func) (info->stream, "wrtu    0x%04X", immediate);
492
121
      break;
493
535
    case 10:
494
      /* Illegal opcode.  */
495
535
      goto illegal_opcode;
496
0
      break;
497
272
    case 11:
498
      /* Illegal opcode.  */
499
272
      goto illegal_opcode;
500
0
      break;
501
1.48k
    case 12:
502
      /* Illegal opcode.  */
503
1.48k
      goto illegal_opcode;
504
0
      break;
505
496
    case 13:
506
      /* Illegal opcode.  */
507
496
      goto illegal_opcode;
508
0
      break;
509
623
    case 14:
510
      /* Illegal opcode.  */
511
623
      goto illegal_opcode;
512
0
      break;
513
533
    case 15:
514
      /* Illegal opcode.  */
515
533
      goto illegal_opcode;
516
0
      break;
517
14.9k
    }
518
519
6.31k
  return 0;
520
521
85.7k
 illegal_opcode:
522
85.7k
  return -1;
523
14.9k
}
524
525
/* Disassemble storage register class instructions.  */
526
527
static int
528
disassem_class3 (disassemble_info *info, unsigned int ins)
529
148k
{
530
148k
  int opcode = (ins >> 21) & 0xf;
531
148k
  int source_b = (ins >> 4) & 0x1f;
532
148k
  int source_a = (ins >> 16) & 0x1f;
533
148k
  int size = ins & 0x7;
534
148k
  int dest = (ins >> 10) & 0x1f;
535
536
  /* Those instructions that don't have a srcB register.  */
537
148k
  const int no_srcb[16] =
538
148k
  { 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
148k
  const int srcb_immed[16] =
542
148k
  { 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
148k
  if ((no_srcb[opcode] && source_b)
552
128k
      || (!srcb_immed[opcode] && ins & CLASS3_SOURCEB_IMMED)
553
98.6k
      || (opcode != 12 && opcode != 15 && ins & CC_MASK)
554
64.8k
      || (opcode != 15 && ins & (EAM_SELECT_MASK | FP_SELECT_MASK)))
555
86.4k
    goto illegal_opcode;
556
557
558
62.0k
  switch (opcode)
559
62.0k
    {
560
850
    case 0:
561
      /* ADD instruction.  */
562
850
      (*info->fprintf_func) (info->stream, "add.%s   r%d,r%d,r%d",
563
850
           size_names[size], dest, source_a, source_b);
564
850
      break;
565
168
    case 1:
566
      /* ADC instruction.  */
567
168
      (*info->fprintf_func) (info->stream, "adc.%s   r%d,r%d,r%d",
568
168
           size_names[size], dest, source_a, source_b);
569
168
      break;
570
203
    case 2:
571
      /* SUB instruction.  */
572
203
      if (dest == 0)
573
61
  (*info->fprintf_func) (info->stream, "cmp.%s   r%d,r%d",
574
61
             size_names[size], source_a, source_b);
575
142
      else
576
142
  (*info->fprintf_func) (info->stream, "sub.%s   r%d,r%d,r%d",
577
142
             size_names[size], dest, source_a, source_b);
578
203
      break;
579
714
    case 3:
580
      /* SUBC instruction.  */
581
714
      if (dest == 0)
582
275
  (*info->fprintf_func) (info->stream, "cmpc.%s  r%d,r%d",
583
275
             size_names[size], source_a, source_b);
584
439
      else
585
439
  (*info->fprintf_func) (info->stream, "subc.%s  r%d,r%d,r%d",
586
439
             size_names[size], dest, source_a, source_b);
587
714
      break;
588
201
    case 4:
589
      /* EXTW instruction.  */
590
201
      if (size == 1)
591
33
  goto illegal_opcode;
592
593
168
      (*info->fprintf_func) (info->stream, "extw.%s  r%d,r%d",
594
168
           size_names[size], dest, source_a);
595
168
      break;
596
360
    case 5:
597
      /* ASR instruction.  */
598
360
      if (ins & CLASS3_SOURCEB_IMMED)
599
157
  (*info->fprintf_func) (info->stream, "asr.%s   r%d,r%d,%d",
600
157
             size_names[size], dest, source_a, source_b);
601
203
      else
602
203
  (*info->fprintf_func) (info->stream, "asr.%s   r%d,r%d,r%d",
603
203
             size_names[size], dest, source_a, source_b);
604
360
      break;
605
378
    case 6:
606
      /* LSR instruction.  */
607
378
      if (ins & CLASS3_SOURCEB_IMMED)
608
274
  (*info->fprintf_func) (info->stream, "lsr.%s   r%d,r%d,%d",
609
274
             size_names[size], dest, source_a, source_b);
610
104
      else
611
104
  (*info->fprintf_func) (info->stream, "lsr.%s   r%d,r%d,r%d",
612
104
             size_names[size], dest, source_a, source_b);
613
378
      break;
614
294
    case 7:
615
      /* ASL instruction.  */
616
294
      if (ins & CLASS3_SOURCEB_IMMED)
617
112
  (*info->fprintf_func) (info->stream, "asl.%s   r%d,r%d,%d",
618
112
             size_names[size], dest, source_a, source_b);
619
182
      else
620
182
  (*info->fprintf_func) (info->stream, "asl.%s   r%d,r%d,r%d",
621
182
             size_names[size], dest, source_a, source_b);
622
294
      break;
623
524
    case 8:
624
      /* XOR instruction.  */
625
524
      (*info->fprintf_func) (info->stream, "xor.%s   r%d,r%d,r%d",
626
524
           size_names[size], dest, source_a, source_b);
627
524
      break;
628
270
    case 9:
629
      /* OR instruction.  */
630
270
      if (source_b == 0)
631
131
  (*info->fprintf_func) (info->stream, "move.%s  r%d,r%d",
632
131
             size_names[size], dest, source_a);
633
139
      else
634
139
  (*info->fprintf_func) (info->stream, "or.%s    r%d,r%d,r%d",
635
139
             size_names[size], dest, source_a, source_b);
636
270
      break;
637
285
    case 10:
638
      /* AND instruction.  */
639
285
      (*info->fprintf_func) (info->stream, "and.%s   r%d,r%d,r%d",
640
285
           size_names[size], dest, source_a, source_b);
641
285
      break;
642
204
    case 11:
643
      /* NOT instruction.  */
644
204
      (*info->fprintf_func) (info->stream, "not.%s   r%d,r%d",
645
204
           size_names[size], dest, source_a);
646
204
      break;
647
573
    case 12:
648
      /* BRA instruction.  */
649
573
      {
650
573
  unsigned cbf = (ins >> 27) & 0x000f;
651
652
573
  if (size != 4)
653
282
    goto illegal_opcode;
654
655
291
  (*info->fprintf_func) (info->stream, "bra     %s,r%d,r%d",
656
291
             cc_names[cbf], source_a, dest);
657
291
      }
658
0
      break;
659
440
    case 13:
660
      /* RFLAG instruction.  */
661
440
      if (source_a || size != 4)
662
167
  goto illegal_opcode;
663
664
273
      (*info->fprintf_func) (info->stream, "rflag   r%d", dest);
665
273
      break;
666
104
    case 14:
667
      /* EXTB instruction.  */
668
104
      (*info->fprintf_func) (info->stream, "extb.%s  r%d,r%d",
669
104
           size_names[size], dest, source_a);
670
104
      break;
671
56.4k
    case 15:
672
56.4k
      if (!(ins & CLASS3_SOURCEB_IMMED))
673
5.03k
  goto illegal_opcode;
674
675
51.4k
      if (ins & EAM_SELECT_MASK)
676
49.4k
  {
677
    /* Extension arithmetic module read.  */
678
49.4k
    int fp_ins = (ins >> 27) & 0xf;
679
680
49.4k
    if (size != 4)
681
48.6k
      goto illegal_opcode;
682
683
787
    if (ins & FP_SELECT_MASK)
684
391
      {
685
        /* Check fsrcA <= 15 and fsrcB <= 15.  */
686
391
        if (ins & ((1 << 20) | (1 << 8)))
687
265
    goto illegal_opcode;
688
689
126
        switch (fp_ins)
690
126
    {
691
14
    case 0:
692
14
      if (source_b)
693
14
        goto illegal_opcode;
694
695
0
      (*info->fprintf_func) (info->stream, "fstore  r%d,f%d",
696
0
           dest, source_a);
697
0
      break;
698
46
    case 10:
699
46
      (*info->fprintf_func) (info->stream, "fcmp    r%d,f%d,f%d",
700
46
           dest, source_a, source_b);
701
46
      break;
702
15
    case 11:
703
15
      (*info->fprintf_func) (info->stream, "fcmpe   r%d,f%d,f%d",
704
15
           dest, source_a, source_b);
705
15
      break;
706
51
    default:
707
51
      (*info->fprintf_func) (info->stream,
708
51
           "fpuread %d,r%d,f%d,f%d", fp_ins,
709
51
           dest, source_a, source_b);
710
51
      break;
711
126
    }
712
126
      }
713
396
    else
714
396
      {
715
396
        if (fp_ins || source_a)
716
396
    goto illegal_opcode;
717
718
0
        switch (source_b)
719
0
    {
720
0
    case 0:
721
0
      (*info->fprintf_func) (info->stream, "readmda r%d", dest);
722
0
      break;
723
0
    case 1:
724
0
      (*info->fprintf_func) (info->stream, "readmdb r%d", dest);
725
0
      break;
726
0
    case 2:
727
0
      (*info->fprintf_func) (info->stream, "readmdc r%d", dest);
728
0
      break;
729
0
    default:
730
0
      (*info->fprintf_func) (info->stream, "eamread r%d,%d",
731
0
           dest, source_b);
732
0
      break;
733
0
    }
734
0
      }
735
787
  }
736
1.98k
      else
737
1.98k
  {
738
1.98k
    if (ins & FP_SELECT_MASK)
739
687
      goto illegal_opcode;
740
741
    /* READ instruction.  */
742
1.30k
    (*info->fprintf_func) (info->stream, "read.%s  r%d,%d(r%d)",
743
1.30k
         size_names[size], dest, source_b, source_a);
744
1.30k
  }
745
1.41k
      break;
746
62.0k
    }
747
748
6.49k
  return 0;
749
750
142k
 illegal_opcode:
751
142k
  return -1;
752
753
62.0k
}
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
902k
{
761
902k
  unsigned ins;
762
902k
  unsigned p1, p2;
763
902k
  int ans;
764
902k
  int i;
765
766
  /* Stuff copied from m68k-dis.c.  */
767
902k
  struct private priv;
768
902k
  bfd_byte *buffer = priv.the_buffer;
769
902k
  info->private_data = &priv;
770
902k
  priv.max_fetched = priv.the_buffer;
771
902k
  priv.insn_start = addr;
772
902k
  if (setjmp (priv.bailout) != 0)
773
464
    {
774
      /* Error return.  */
775
464
      return -1;
776
464
    }
777
778
  /* We do return this info.  */
779
902k
  info->insn_info_valid = 1;
780
781
  /* Assume non branch insn.  */
782
902k
  info->insn_type = dis_nonbranch;
783
784
  /* Assume no delay.  */
785
902k
  info->branch_delay_insns = 0;
786
787
  /* Assume no target known.  */
788
902k
  info->target = 0;
789
790
  /* Get 32-bit instruction word.  */
791
902k
  FETCH_DATA (info, buffer + 4);
792
902k
  ins = (unsigned) buffer[0] << 24;
793
902k
  ins |= buffer[1] << 16;
794
902k
  ins |= buffer[2] << 8;
795
902k
  ins |= buffer[3];
796
797
902k
  ans = 0;
798
799
902k
  p1 = buffer[0] ^ buffer[1] ^ buffer[2] ^ buffer[3];
800
902k
  p2 = 0;
801
8.11M
  for (i = 0; i < 8; i++)
802
7.21M
    {
803
7.21M
      p2 += p1 & 1;
804
7.21M
      p1 >>= 1;
805
7.21M
    }
806
807
  /* Decode the instruction.  */
808
902k
  if (p2 & 1)
809
340k
    ans = -1;
810
561k
  else
811
561k
    {
812
561k
      switch ((ins >> 25) & 0x3)
813
561k
  {
814
232k
  case 0:
815
232k
    ans = disassem_class0 (info, ins);
816
232k
    break;
817
87.7k
  case 1:
818
87.7k
    ans = disassem_class1 (info, ins);
819
87.7k
    break;
820
92.0k
  case 2:
821
92.0k
    ans = disassem_class2 (info, ins);
822
92.0k
    break;
823
148k
  case 3:
824
148k
    ans = disassem_class3 (info, ins);
825
148k
    break;
826
561k
  }
827
561k
    }
828
829
902k
  if (ans != 0)
830
787k
    (*info->fprintf_func) (info->stream, "err");
831
832
  /* Return number of bytes consumed (always 4 for the Visium).  */
833
902k
  return 4;
834
902k
}