Coverage Report

Created: 2026-07-25 10:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/binutils-gdb/opcodes/ns32k-dis.c
Line
Count
Source
1
/* Print National Semiconductor 32000 instructions.
2
   Copyright (C) 1986-2026 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
9.56k
#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
96.5k
{
38
96.5k
  long val;
39
96.5k
  int i;
40
41
289k
  for (val = 0, i = nr - 1; i >= 0; i--)
42
193k
    {
43
193k
      val =  (val << 8);
44
193k
      val |= (0xff & *(addr + i));
45
193k
    }
46
96.5k
  return val;
47
96.5k
}
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
7.44M
  ((addr) <= ((struct private *)(info->private_data))->max_fetched \
69
7.44M
   ? 1 : fetch_data ((info), (addr)))
70
71
static int
72
fetch_data (struct disassemble_info *info, bfd_byte *addr)
73
948k
{
74
948k
  int status;
75
948k
  struct private *priv = (struct private *) info->private_data;
76
948k
  bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
77
78
948k
  status = (*info->read_memory_func) (start,
79
948k
              priv->max_fetched,
80
948k
              addr - priv->max_fetched,
81
948k
              info);
82
948k
  if (status != 0)
83
463
    {
84
463
      (*info->memory_error_func) (status, start, info);
85
463
      OPCODES_SIGLONGJMP (priv->bailout, 1);
86
463
    }
87
947k
  else
88
947k
    priv->max_fetched = addr;
89
947k
  return 1;
90
948k
}
91
92
/* Number of elements in the opcode table.  */
93
81.2M
#define NOPCODES (sizeof ns32k_opcodes / sizeof ns32k_opcodes[0])
94
95
2.41M
#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
11.9k
{
220
11.9k
  if (options == 0)
221
1.24k
    {
222
1.24k
      sprintf (result, "[]");
223
1.24k
      return;
224
1.24k
    }
225
226
10.7k
  sprintf (result, "[");
227
228
78.6k
  for (; (options != 0) && optionP->pattern; optionP++)
229
67.8k
    {
230
67.8k
      if ((options & optionP->match) == optionP->value)
231
31.9k
  {
232
    /* We found a match, update result and options.  */
233
31.9k
    strcat (result, optionP->pattern);
234
31.9k
    options &= ~optionP->value;
235
31.9k
    if (options != 0)  /* More options to come.  */
236
22.3k
      strcat (result, ",");
237
31.9k
  }
238
67.8k
    }
239
240
10.7k
  if (options != 0)
241
1.22k
    strcat (result, "undefined");
242
243
10.7k
  strcat (result, "]");
244
10.7k
}
245
246
static void
247
list_search (int reg_value, const struct ns32k_option *optionP, char *result)
248
11.1k
{
249
84.0k
  for (; optionP->pattern; optionP++)
250
81.5k
    {
251
81.5k
      if ((reg_value & optionP->match) == optionP->value)
252
8.60k
  {
253
8.60k
    sprintf (result, "%s", optionP->pattern);
254
8.60k
    return;
255
8.60k
  }
256
81.5k
    }
257
2.51k
  sprintf (result, "undefined");
258
2.51k
}
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
1.13M
{
265
1.13M
  unsigned int result;
266
1.13M
  unsigned int bit;
267
268
1.13M
  if (offset < 0 || count < 0)
269
24.3k
    return 0;
270
1.11M
  buffer += offset >> 3;
271
1.11M
  offset &= 7;
272
1.11M
  bit = 1;
273
1.11M
  result = 0;
274
8.14M
  while (count--)
275
7.03M
    {
276
7.03M
      FETCH_DATA (dis_info, buffer + 1);
277
7.03M
      if ((*buffer & (1 << offset)))
278
2.54M
  result |= bit;
279
7.03M
      if (++offset == 8)
280
1.17M
  {
281
1.17M
    offset = 0;
282
1.17M
    buffer++;
283
1.17M
  }
284
7.03M
      bit <<= 1;
285
7.03M
    }
286
1.11M
  return result;
287
1.13M
}
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
26.4k
{
294
26.4k
  unsigned int result;
295
26.4k
  unsigned int bit;
296
297
26.4k
  if (offset < 0 || count < 0)
298
0
    return 0;
299
26.4k
  buffer += offset >> 3;
300
26.4k
  offset &= 7;
301
26.4k
  bit = 1;
302
26.4k
  result = 0;
303
418k
  while (count--)
304
391k
    {
305
391k
      if ((*buffer & (1 << offset)))
306
60.1k
  result |= bit;
307
391k
      if (++offset == 8)
308
42.3k
  {
309
42.3k
    offset = 0;
310
42.3k
    buffer++;
311
42.3k
  }
312
391k
      bit <<= 1;
313
391k
    }
314
26.4k
  return result;
315
26.4k
}
316
317
static void
318
bit_copy (bfd_byte *buffer, int offset, int count, char *to)
319
9.56k
{
320
9.56k
  if (offset < 0 || count < 0)
321
0
    return;
322
58.1k
  for (; count > 8; count -= 8, to++, offset += 8)
323
48.6k
    *to = bit_extract (buffer, offset, 8);
324
9.56k
  *to = bit_extract (buffer, offset, count);
325
9.56k
}
326
327
static int
328
sign_extend (unsigned int value, unsigned int bits)
329
157k
{
330
157k
  unsigned int sign = 1u << (bits - 1);
331
157k
  return ((value & (sign + sign - 1)) ^ sign) - sign;
332
157k
}
333
334
static void
335
flip_bytes (char *ptr, int count)
336
59.3k
{
337
59.3k
  char tmp;
338
339
163k
  while (count > 0)
340
103k
    {
341
103k
      tmp = ptr[0];
342
103k
      ptr[0] = ptr[count - 1];
343
103k
      ptr[count - 1] = tmp;
344
103k
      ptr++;
345
103k
      count -= 2;
346
103k
    }
347
59.3k
}
348

349
/* Given a character C, does it represent a general addressing mode?  */
350
424k
#define Is_gen(c) (strchr ("FLBWDAIZf", (c)) != NULL)
351
352
/* Adressing modes.  */
353
747k
#define Adrmod_index_byte        0x1c
354
736k
#define Adrmod_index_word        0x1d
355
729k
#define Adrmod_index_doubleword  0x1e
356
721k
#define Adrmod_index_quadword    0x1f
357
358
/* Is MODE an indexed addressing mode?  */
359
#define Adrmod_is_index(mode) \
360
373k
  (   mode == Adrmod_index_byte \
361
373k
   || mode == Adrmod_index_word \
362
373k
   || mode == Adrmod_index_doubleword \
363
373k
   || mode == Adrmod_index_quadword)
364
365

366
static int
367
get_displacement (bfd_byte *buffer, int *aoffsetp)
368
139k
{
369
139k
  int Ivalue;
370
139k
  short Ivalue2;
371
372
139k
  Ivalue = bit_extract (buffer, *aoffsetp, 8);
373
139k
  switch (Ivalue & 0xc0)
374
139k
    {
375
54.0k
    case 0x00:
376
92.7k
    case 0x40:
377
92.7k
      Ivalue = sign_extend (Ivalue, 7);
378
92.7k
      *aoffsetp += 8;
379
92.7k
      break;
380
23.1k
    case 0x80:
381
23.1k
      Ivalue2 = bit_extract (buffer, *aoffsetp, 16);
382
23.1k
      flip_bytes ((char *) & Ivalue2, 2);
383
23.1k
      Ivalue = sign_extend (Ivalue2, 14);
384
23.1k
      *aoffsetp += 16;
385
23.1k
      break;
386
23.5k
    case 0xc0:
387
23.5k
      Ivalue = bit_extract (buffer, *aoffsetp, 32);
388
23.5k
      flip_bytes ((char *) & Ivalue, 4);
389
23.5k
      Ivalue = sign_extend (Ivalue, 30);
390
23.5k
      *aoffsetp += 32;
391
23.5k
      break;
392
139k
    }
393
139k
  return Ivalue;
394
139k
}
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
9.51k
{
400
9.51k
  int val;
401
402
9.51k
  if (len == 4)
403
4.54k
    val = (bit_extract_simple (p, 23, 8)/*exponent*/ == 0xff
404
4.03k
     || (bit_extract_simple (p, 23, 8)/*exponent*/ == 0
405
2.38k
         && bit_extract_simple (p, 0, 23)/*mantisa*/ != 0));
406
4.96k
  else if (len == 8)
407
4.96k
    val = (bit_extract_simple (p, 52, 11)/*exponent*/ == 0x7ff
408
4.70k
     || (bit_extract_simple (p, 52, 11)/*exponent*/ == 0
409
3.88k
         && (bit_extract_simple (p, 0, 32)/*low mantisa*/ != 0
410
1.89k
       || bit_extract_simple (p, 32, 20)/*high mantisa*/ != 0)));
411
0
  else
412
0
    val = 1;
413
9.51k
  return (val);
414
9.51k
}
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
481k
{
461
481k
  union
462
481k
  {
463
481k
    float f;
464
481k
    double d;
465
481k
    int i[2];
466
481k
  } value;
467
481k
  int Ivalue;
468
481k
  int addr_mode;
469
481k
  int disp1, disp2;
470
481k
  int size;
471
472
481k
  switch (d)
473
481k
    {
474
130
    case 'f':
475
      /* A "gen" operand but 5 bits from the end of instruction.  */
476
130
      ioffset -= 5;
477
      /* Fall through.  */
478
1.52k
    case 'Z':
479
8.94k
    case 'F':
480
15.3k
    case 'L':
481
194k
    case 'I':
482
320k
    case 'B':
483
366k
    case 'W':
484
407k
    case 'D':
485
422k
    case 'A':
486
422k
      addr_mode = bit_extract (buffer, ioffset - 5, 5);
487
422k
      ioffset -= 5;
488
422k
      switch (addr_mode)
489
422k
  {
490
196k
  case 0x0: case 0x1: case 0x2: case 0x3:
491
237k
  case 0x4: case 0x5: case 0x6: case 0x7:
492
    /* Register mode R0 -- R7.  */
493
237k
    switch (d)
494
237k
      {
495
1.01k
      case 'F':
496
2.12k
      case 'L':
497
3.17k
      case 'Z':
498
3.17k
        sprintf (result, "f%d", addr_mode);
499
3.17k
        break;
500
233k
      default:
501
233k
        sprintf (result, "r%d", addr_mode);
502
237k
      }
503
237k
    break;
504
237k
  case 0x8: case 0x9: case 0xa: case 0xb:
505
56.3k
  case 0xc: case 0xd: case 0xe: case 0xf:
506
    /* Register relative disp(R0 -- R7).  */
507
56.3k
    disp1 = get_displacement (buffer, aoffsetp);
508
56.3k
    sprintf (result, "%d(r%d)", disp1, addr_mode & 7);
509
56.3k
    break;
510
9.06k
  case 0x10:
511
13.2k
  case 0x11:
512
16.3k
  case 0x12:
513
    /* Memory relative disp2(disp1(FP, SP, SB)).  */
514
16.3k
    disp1 = get_displacement (buffer, aoffsetp);
515
16.3k
    disp2 = get_displacement (buffer, aoffsetp);
516
16.3k
    sprintf (result, "%d(%d(%s))", disp2, disp1,
517
16.3k
       addr_mode == 0x10 ? "fp" : addr_mode == 0x11 ? "sp" : "sb");
518
16.3k
    break;
519
5.40k
  case 0x13:
520
    /* Reserved.  */
521
5.40k
    sprintf (result, "reserved");
522
5.40k
    break;
523
22.5k
  case 0x14:
524
    /* Immediate.  */
525
22.5k
    switch (d)
526
22.5k
      {
527
7.88k
      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
7.88k
        sprintf (result, _("$<undefined>"));
534
7.88k
        break;
535
1.85k
      case 'B':
536
1.85k
        Ivalue = bit_extract (buffer, *aoffsetp, 8);
537
1.85k
        Ivalue = sign_extend (Ivalue, 8);
538
1.85k
        *aoffsetp += 8;
539
1.85k
        sprintf (result, "$%d", Ivalue);
540
1.85k
        break;
541
1.57k
      case 'W':
542
1.57k
        Ivalue = bit_extract (buffer, *aoffsetp, 16);
543
1.57k
        flip_bytes ((char *) & Ivalue, 2);
544
1.57k
        *aoffsetp += 16;
545
1.57k
        Ivalue = sign_extend (Ivalue, 16);
546
1.57k
        sprintf (result, "$%d", Ivalue);
547
1.57k
        break;
548
1.68k
      case 'D':
549
1.68k
        Ivalue = bit_extract (buffer, *aoffsetp, 32);
550
1.68k
        flip_bytes ((char *) & Ivalue, 4);
551
1.68k
        *aoffsetp += 32;
552
1.68k
        sprintf (result, "$%d", Ivalue);
553
1.68k
        break;
554
4.54k
      case 'F':
555
4.54k
        bit_copy (buffer, *aoffsetp, 32, (char *) &value.f);
556
4.54k
        flip_bytes ((char *) &value.f, 4);
557
4.54k
        *aoffsetp += 32;
558
4.54k
        if (INVALID_FLOAT (&value.f, 4))
559
2.25k
    sprintf (result, "<<invalid float 0x%.8x>>", value.i[0]);
560
2.29k
        else /* Assume host has ieee float.  */
561
2.29k
    sprintf (result, "$%g", value.f);
562
4.54k
        break;
563
5.01k
      case 'L':
564
5.01k
        bit_copy (buffer, *aoffsetp, 64, (char *) &value.d);
565
5.01k
        flip_bytes ((char *) &value.d, 8);
566
5.01k
        *aoffsetp += 64;
567
5.01k
        if (INVALID_FLOAT (&value.d, 8))
568
2.97k
    sprintf (result, "<<invalid double 0x%.8x%.8x>>",
569
2.97k
       value.i[1], value.i[0]);
570
2.04k
        else /* Assume host has ieee float.  */
571
2.04k
    sprintf (result, "$%g", value.d);
572
5.01k
        break;
573
22.5k
      }
574
22.4k
    break;
575
22.4k
  case 0x15:
576
    /* Absolute @disp.  */
577
3.99k
    disp1 = get_displacement (buffer, aoffsetp);
578
3.99k
    sprintf (result, "@|%d|", disp1);
579
3.99k
    break;
580
3.47k
  case 0x16:
581
    /* External EXT(disp1) + disp2 (Mod table stuff).  */
582
3.47k
    disp1 = get_displacement (buffer, aoffsetp);
583
3.47k
    disp2 = get_displacement (buffer, aoffsetp);
584
3.47k
    sprintf (result, "EXT(%d) + %d", disp1, disp2);
585
3.47k
    break;
586
6.80k
  case 0x17:
587
    /* Top of stack tos.  */
588
6.80k
    sprintf (result, "tos");
589
6.80k
    break;
590
9.23k
  case 0x18:
591
    /* Memory space disp(FP).  */
592
9.23k
    disp1 = get_displacement (buffer, aoffsetp);
593
9.23k
    sprintf (result, "%d(fp)", disp1);
594
9.23k
    break;
595
5.73k
  case 0x19:
596
    /* Memory space disp(SP).  */
597
5.73k
    disp1 = get_displacement (buffer, aoffsetp);
598
5.73k
    sprintf (result, "%d(sp)", disp1);
599
5.73k
    break;
600
4.07k
  case 0x1a:
601
    /* Memory space disp(SB).  */
602
4.07k
    disp1 = get_displacement (buffer, aoffsetp);
603
4.07k
    sprintf (result, "%d(sb)", disp1);
604
4.07k
    break;
605
2.56k
  case 0x1b:
606
    /* Memory space disp(PC).  */
607
2.56k
    disp1 = get_displacement (buffer, aoffsetp);
608
2.56k
    *result++ = NEXT_IS_ADDR;
609
2.56k
    sprintf (result, "%" PRIx64, (uint64_t) (addr + disp1));
610
2.56k
    result += strlen (result);
611
2.56k
    *result++ = NEXT_IS_ADDR;
612
2.56k
    *result = '\0';
613
2.56k
    break;
614
12.8k
  case 0x1c:
615
22.3k
  case 0x1d:
616
32.3k
  case 0x1e:
617
49.2k
  case 0x1f:
618
49.2k
    {
619
49.2k
      int bit_index;
620
49.2k
      static const char *ind = "bwdq";
621
49.2k
      char *off;
622
623
      /* Scaled index basemode[R0 -- R7:B,W,D,Q].  */
624
49.2k
      bit_index = bit_extract (buffer, index_offset - 8, 3);
625
49.2k
      print_insn_arg (d, index_offset, aoffsetp, buffer, addr,
626
49.2k
          result, 0);
627
49.2k
      off = result + strlen (result);
628
49.2k
      sprintf (off, "[r%d:%c]", bit_index, ind[addr_mode & 3]);
629
49.2k
    }
630
49.2k
    break;
631
422k
  }
632
422k
      break;
633
422k
    case 'H':
634
14.2k
    case 'q':
635
14.2k
      Ivalue = bit_extract (buffer, ioffset-4, 4);
636
14.2k
      Ivalue = sign_extend (Ivalue, 4);
637
14.2k
      sprintf (result, "%d", Ivalue);
638
14.2k
      ioffset -= 4;
639
14.2k
      break;
640
1.83k
    case 'r':
641
1.83k
      Ivalue = bit_extract (buffer, ioffset-3, 3);
642
1.83k
      sprintf (result, "r%d", Ivalue&7);
643
1.83k
      ioffset -= 3;
644
1.83k
      break;
645
4.38k
    case 'd':
646
4.38k
      sprintf (result, "%d", get_displacement (buffer, aoffsetp));
647
4.38k
      break;
648
706
    case 'b':
649
706
      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
706
      size = bit_extract(buffer, ioffset-6, 2);
657
706
      if (size == 0)    /* 00 => b.  */
658
276
  size = 1;
659
430
      else if (size == 1)  /* 01 => w.  */
660
152
  size = 2;
661
278
      else
662
278
  size = 4;   /* 11 => d.  */
663
664
706
      sprintf (result, "%d", (Ivalue / size) + 1);
665
706
      break;
666
12.8k
    case 'p':
667
12.8k
      *result++ = NEXT_IS_ADDR;
668
12.8k
      sprintf (result, "%" PRIx64,
669
12.8k
         (uint64_t) (addr + get_displacement (buffer, aoffsetp)));
670
12.8k
      result += strlen (result);
671
12.8k
      *result++ = NEXT_IS_ADDR;
672
12.8k
      *result = '\0';
673
12.8k
      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
4.28k
    case 'u':
680
4.28k
      Ivalue = bit_extract (buffer, *aoffsetp, 8);
681
4.28k
      optlist (Ivalue, opt_u, result);
682
4.28k
      *aoffsetp += 8;
683
4.28k
      break;
684
4.78k
    case 'U':
685
4.78k
      Ivalue = bit_extract (buffer, *aoffsetp, 8);
686
4.78k
      optlist (Ivalue, opt_U, result);
687
4.78k
      *aoffsetp += 8;
688
4.78k
      break;
689
1.21k
    case 'O':
690
1.21k
      Ivalue = bit_extract (buffer, ioffset - 9, 9);
691
1.21k
      optlist (Ivalue, opt_O, result);
692
1.21k
      ioffset -= 9;
693
1.21k
      break;
694
636
    case 'C':
695
636
      Ivalue = bit_extract (buffer, ioffset - 4, 4);
696
636
      optlist (Ivalue, opt_C, result);
697
636
      ioffset -= 4;
698
636
      break;
699
1.08k
    case 'S':
700
1.08k
      Ivalue = bit_extract (buffer, ioffset - 8, 8);
701
1.08k
      optlist (Ivalue, opt_S, result);
702
1.08k
      ioffset -= 8;
703
1.08k
      break;
704
1.20k
    case 'M':
705
1.20k
      Ivalue = bit_extract (buffer, ioffset - 4, 4);
706
1.20k
      list_search (Ivalue, 0 ? list_M032 : list_M532, result);
707
1.20k
      ioffset -= 4;
708
1.20k
      break;
709
9.92k
    case 'P':
710
9.92k
      Ivalue = bit_extract (buffer, ioffset - 4, 4);
711
9.92k
      list_search (Ivalue, 0 ? list_P032 : list_P532, result);
712
9.92k
      ioffset -= 4;
713
9.92k
      break;
714
625
    case 'g':
715
625
      Ivalue = bit_extract (buffer, *aoffsetp, 3);
716
625
      sprintf (result, "%d", Ivalue);
717
625
      *aoffsetp += 3;
718
625
      break;
719
625
    case 'G':
720
625
      Ivalue = bit_extract(buffer, *aoffsetp, 5);
721
625
      sprintf (result, "%d", Ivalue + 1);
722
625
      *aoffsetp += 5;
723
625
      break;
724
481k
    }
725
481k
  return ioffset;
726
481k
}
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
309k
{
735
309k
  unsigned int i;
736
309k
  const char *d;
737
309k
  unsigned short first_word;
738
309k
  int ioffset;    /* Bits into instruction.  */
739
309k
  int aoffset;    /* Bits into arguments.  */
740
309k
  char arg_bufs[MAX_ARGS+1][ARG_LEN];
741
309k
  int argnum;
742
309k
  int maxarg;
743
309k
  struct private priv;
744
309k
  bfd_byte *buffer = priv.the_buffer;
745
309k
  dis_info = info;
746
747
309k
  info->private_data = & priv;
748
309k
  priv.max_fetched = priv.the_buffer;
749
309k
  priv.insn_start = memaddr;
750
309k
  if (OPCODES_SIGSETJMP (priv.bailout) != 0)
751
    /* Error return.  */
752
463
    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
309k
  FETCH_DATA (info, buffer + 1);
757
52.0M
  for (i = 0; i < NOPCODES; i++)
758
51.9M
    if (ns32k_opcodes[i].opcode_id_size <= 8
759
14.9M
  && ((buffer[0]
760
14.9M
       & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
761
14.9M
      == ns32k_opcodes[i].opcode_seed))
762
213k
      break;
763
309k
  if (i == NOPCODES)
764
96.5k
    {
765
      /* Maybe it is 9 to 16 bits big.  */
766
96.5k
      FETCH_DATA (info, buffer + 2);
767
96.5k
      first_word = read_memory_integer(buffer, 2);
768
769
28.7M
      for (i = 0; i < NOPCODES; i++)
770
28.6M
  if ((first_word
771
28.6M
       & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
772
28.6M
      == ns32k_opcodes[i].opcode_seed)
773
20.8k
    break;
774
775
      /* Handle undefined instructions.  */
776
96.5k
      if (i == NOPCODES)
777
75.7k
  {
778
75.7k
    (*dis_info->fprintf_func)(dis_info->stream, "0%o", buffer[0]);
779
75.7k
    return 1;
780
75.7k
  }
781
96.5k
    }
782
783
233k
  (*dis_info->fprintf_func)(dis_info->stream, "%s", ns32k_opcodes[i].name);
784
785
233k
  ioffset = ns32k_opcodes[i].opcode_size;
786
233k
  aoffset = ns32k_opcodes[i].opcode_size;
787
233k
  d = ns32k_opcodes[i].operands;
788
789
233k
  if (*d)
790
226k
    {
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
226k
      int index_offset[2];
794
795
      /* 0 for operand A, 1 for operand B, greater for other args.  */
796
226k
      int whicharg = 0;
797
798
226k
      (*dis_info->fprintf_func)(dis_info->stream, "\t");
799
800
226k
      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
226k
      index_offset[0] = -1;
807
226k
      index_offset[1] = -1;
808
226k
      if (Is_gen (d[1]))
809
202k
  {
810
202k
    int bitoff = d[1] == 'f' ? 10 : 5;
811
202k
    int addr_mode = bit_extract (buffer, ioffset - bitoff, 5);
812
813
202k
    if (Adrmod_is_index (addr_mode))
814
19.9k
      {
815
19.9k
        aoffset += 8;
816
19.9k
        index_offset[0] = aoffset;
817
19.9k
      }
818
202k
  }
819
820
226k
      if (d[2] && Is_gen (d[3]))
821
171k
  {
822
171k
    int addr_mode = bit_extract (buffer, ioffset - 10, 5);
823
824
171k
    if (Adrmod_is_index (addr_mode))
825
17.2k
      {
826
17.2k
        aoffset += 8;
827
17.2k
        index_offset[1] = aoffset;
828
17.2k
      }
829
171k
  }
830
831
658k
      while (*d)
832
432k
  {
833
432k
    argnum = *d - '1';
834
432k
    if (argnum >= MAX_ARGS)
835
0
      abort ();
836
432k
    d++;
837
432k
    if (argnum > maxarg)
838
204k
      maxarg = argnum;
839
432k
    ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
840
432k
            memaddr, arg_bufs[argnum],
841
432k
            whicharg > 1 ? -1 : index_offset[whicharg]);
842
432k
    d++;
843
432k
    whicharg++;
844
432k
  }
845
846
658k
      for (argnum = 0; argnum <= maxarg; argnum++)
847
431k
  {
848
431k
    bfd_vma addr;
849
431k
    char *ch;
850
851
2.67M
    for (ch = arg_bufs[argnum]; *ch;)
852
2.23M
      {
853
2.23M
        if (*ch == NEXT_IS_ADDR)
854
19.3k
    {
855
19.3k
      ++ch;
856
19.3k
      addr = bfd_scan_vma (ch, NULL, 16);
857
19.3k
      (*dis_info->print_address_func) (addr, dis_info);
858
143k
      while (*ch && *ch != NEXT_IS_ADDR)
859
124k
        ++ch;
860
19.3k
      if (*ch)
861
19.3k
        ++ch;
862
19.3k
    }
863
2.21M
        else
864
2.21M
    (*dis_info->fprintf_func)(dis_info->stream, "%c", *ch++);
865
2.23M
      }
866
431k
    if (argnum < maxarg)
867
205k
      (*dis_info->fprintf_func)(dis_info->stream, ", ");
868
431k
  }
869
226k
    }
870
233k
  return aoffset / 8;
871
233k
}