Coverage Report

Created: 2023-08-28 06:30

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