Coverage Report

Created: 2026-07-12 09:22

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.73k
#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
80.9k
{
38
80.9k
  long val;
39
80.9k
  int i;
40
41
242k
  for (val = 0, i = nr - 1; i >= 0; i--)
42
161k
    {
43
161k
      val =  (val << 8);
44
161k
      val |= (0xff & *(addr + i));
45
161k
    }
46
80.9k
  return val;
47
80.9k
}
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
6.16M
  ((addr) <= ((struct private *)(info->private_data))->max_fetched \
69
6.16M
   ? 1 : fetch_data ((info), (addr)))
70
71
static int
72
fetch_data (struct disassemble_info *info, bfd_byte *addr)
73
783k
{
74
783k
  int status;
75
783k
  struct private *priv = (struct private *) info->private_data;
76
783k
  bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
77
78
783k
  status = (*info->read_memory_func) (start,
79
783k
              priv->max_fetched,
80
783k
              addr - priv->max_fetched,
81
783k
              info);
82
783k
  if (status != 0)
83
360
    {
84
360
      (*info->memory_error_func) (status, start, info);
85
360
      OPCODES_SIGLONGJMP (priv->bailout, 1);
86
360
    }
87
783k
  else
88
783k
    priv->max_fetched = addr;
89
783k
  return 1;
90
783k
}
91
92
/* Number of elements in the opcode table.  */
93
67.5M
#define NOPCODES (sizeof ns32k_opcodes / sizeof ns32k_opcodes[0])
94
95
1.95M
#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
9.27k
{
220
9.27k
  if (options == 0)
221
818
    {
222
818
      sprintf (result, "[]");
223
818
      return;
224
818
    }
225
226
8.46k
  sprintf (result, "[");
227
228
59.7k
  for (; (options != 0) && optionP->pattern; optionP++)
229
51.2k
    {
230
51.2k
      if ((options & optionP->match) == optionP->value)
231
24.1k
  {
232
    /* We found a match, update result and options.  */
233
24.1k
    strcat (result, optionP->pattern);
234
24.1k
    options &= ~optionP->value;
235
24.1k
    if (options != 0)  /* More options to come.  */
236
17.0k
      strcat (result, ",");
237
24.1k
  }
238
51.2k
    }
239
240
8.46k
  if (options != 0)
241
1.37k
    strcat (result, "undefined");
242
243
8.46k
  strcat (result, "]");
244
8.46k
}
245
246
static void
247
list_search (int reg_value, const struct ns32k_option *optionP, char *result)
248
8.39k
{
249
62.8k
  for (; optionP->pattern; optionP++)
250
61.2k
    {
251
61.2k
      if ((reg_value & optionP->match) == optionP->value)
252
6.80k
  {
253
6.80k
    sprintf (result, "%s", optionP->pattern);
254
6.80k
    return;
255
6.80k
  }
256
61.2k
    }
257
1.59k
  sprintf (result, "undefined");
258
1.59k
}
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
936k
{
265
936k
  unsigned int result;
266
936k
  unsigned int bit;
267
268
936k
  if (offset < 0 || count < 0)
269
19.5k
    return 0;
270
917k
  buffer += offset >> 3;
271
917k
  offset &= 7;
272
917k
  bit = 1;
273
917k
  result = 0;
274
6.74M
  while (count--)
275
5.82M
    {
276
5.82M
      FETCH_DATA (dis_info, buffer + 1);
277
5.82M
      if ((*buffer & (1 << offset)))
278
2.07M
  result |= bit;
279
5.82M
      if (++offset == 8)
280
970k
  {
281
970k
    offset = 0;
282
970k
    buffer++;
283
970k
  }
284
5.82M
      bit <<= 1;
285
5.82M
    }
286
917k
  return result;
287
936k
}
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.7k
{
294
26.7k
  unsigned int result;
295
26.7k
  unsigned int bit;
296
297
26.7k
  if (offset < 0 || count < 0)
298
0
    return 0;
299
26.7k
  buffer += offset >> 3;
300
26.7k
  offset &= 7;
301
26.7k
  bit = 1;
302
26.7k
  result = 0;
303
419k
  while (count--)
304
392k
    {
305
392k
      if ((*buffer & (1 << offset)))
306
60.8k
  result |= bit;
307
392k
      if (++offset == 8)
308
42.2k
  {
309
42.2k
    offset = 0;
310
42.2k
    buffer++;
311
42.2k
  }
312
392k
      bit <<= 1;
313
392k
    }
314
26.7k
  return result;
315
26.7k
}
316
317
static void
318
bit_copy (bfd_byte *buffer, int offset, int count, char *to)
319
9.73k
{
320
9.73k
  if (offset < 0 || count < 0)
321
0
    return;
322
57.9k
  for (; count > 8; count -= 8, to++, offset += 8)
323
48.1k
    *to = bit_extract (buffer, offset, 8);
324
9.73k
  *to = bit_extract (buffer, offset, count);
325
9.73k
}
326
327
static int
328
sign_extend (unsigned int value, unsigned int bits)
329
120k
{
330
120k
  unsigned int sign = 1u << (bits - 1);
331
120k
  return ((value & (sign + sign - 1)) ^ sign) - sign;
332
120k
}
333
334
static void
335
flip_bytes (char *ptr, int count)
336
51.3k
{
337
51.3k
  char tmp;
338
339
142k
  while (count > 0)
340
91.6k
    {
341
91.6k
      tmp = ptr[0];
342
91.6k
      ptr[0] = ptr[count - 1];
343
91.6k
      ptr[count - 1] = tmp;
344
91.6k
      ptr++;
345
91.6k
      count -= 2;
346
91.6k
    }
347
51.3k
}
348

349
/* Given a character C, does it represent a general addressing mode?  */
350
346k
#define Is_gen(c) (strchr ("FLBWDAIZf", (c)) != NULL)
351
352
/* Adressing modes.  */
353
618k
#define Adrmod_index_byte        0x1c
354
609k
#define Adrmod_index_word        0x1d
355
604k
#define Adrmod_index_doubleword  0x1e
356
598k
#define Adrmod_index_quadword    0x1f
357
358
/* Is MODE an indexed addressing mode?  */
359
#define Adrmod_is_index(mode) \
360
309k
  (   mode == Adrmod_index_byte \
361
309k
   || mode == Adrmod_index_word \
362
309k
   || mode == Adrmod_index_doubleword \
363
309k
   || mode == Adrmod_index_quadword)
364
365

366
static int
367
get_displacement (bfd_byte *buffer, int *aoffsetp)
368
107k
{
369
107k
  int Ivalue;
370
107k
  short Ivalue2;
371
372
107k
  Ivalue = bit_extract (buffer, *aoffsetp, 8);
373
107k
  switch (Ivalue & 0xc0)
374
107k
    {
375
40.3k
    case 0x00:
376
69.0k
    case 0x40:
377
69.0k
      Ivalue = sign_extend (Ivalue, 7);
378
69.0k
      *aoffsetp += 8;
379
69.0k
      break;
380
19.1k
    case 0x80:
381
19.1k
      Ivalue2 = bit_extract (buffer, *aoffsetp, 16);
382
19.1k
      flip_bytes ((char *) & Ivalue2, 2);
383
19.1k
      Ivalue = sign_extend (Ivalue2, 14);
384
19.1k
      *aoffsetp += 16;
385
19.1k
      break;
386
19.5k
    case 0xc0:
387
19.5k
      Ivalue = bit_extract (buffer, *aoffsetp, 32);
388
19.5k
      flip_bytes ((char *) & Ivalue, 4);
389
19.5k
      Ivalue = sign_extend (Ivalue, 30);
390
19.5k
      *aoffsetp += 32;
391
19.5k
      break;
392
107k
    }
393
107k
  return Ivalue;
394
107k
}
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.68k
{
400
9.68k
  int val;
401
402
9.68k
  if (len == 4)
403
4.94k
    val = (bit_extract_simple (p, 23, 8)/*exponent*/ == 0xff
404
4.36k
     || (bit_extract_simple (p, 23, 8)/*exponent*/ == 0
405
2.77k
         && bit_extract_simple (p, 0, 23)/*mantisa*/ != 0));
406
4.73k
  else if (len == 8)
407
4.73k
    val = (bit_extract_simple (p, 52, 11)/*exponent*/ == 0x7ff
408
4.55k
     || (bit_extract_simple (p, 52, 11)/*exponent*/ == 0
409
3.67k
         && (bit_extract_simple (p, 0, 32)/*low mantisa*/ != 0
410
1.71k
       || bit_extract_simple (p, 32, 20)/*high mantisa*/ != 0)));
411
0
  else
412
0
    val = 1;
413
9.68k
  return (val);
414
9.68k
}
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
391k
{
461
391k
  union
462
391k
  {
463
391k
    float f;
464
391k
    double d;
465
391k
    int i[2];
466
391k
  } value;
467
391k
  int Ivalue;
468
391k
  int addr_mode;
469
391k
  int disp1, disp2;
470
391k
  int size;
471
472
391k
  switch (d)
473
391k
    {
474
124
    case 'f':
475
      /* A "gen" operand but 5 bits from the end of instruction.  */
476
124
      ioffset -= 5;
477
      /* Fall through.  */
478
1.71k
    case 'Z':
479
9.67k
    case 'F':
480
15.5k
    case 'L':
481
160k
    case 'I':
482
267k
    case 'B':
483
303k
    case 'W':
484
336k
    case 'D':
485
348k
    case 'A':
486
348k
      addr_mode = bit_extract (buffer, ioffset - 5, 5);
487
348k
      ioffset -= 5;
488
348k
      switch (addr_mode)
489
348k
  {
490
165k
  case 0x0: case 0x1: case 0x2: case 0x3:
491
199k
  case 0x4: case 0x5: case 0x6: case 0x7:
492
    /* Register mode R0 -- R7.  */
493
199k
    switch (d)
494
199k
      {
495
1.08k
      case 'F':
496
2.05k
      case 'L':
497
3.30k
      case 'Z':
498
3.30k
        sprintf (result, "f%d", addr_mode);
499
3.30k
        break;
500
196k
      default:
501
196k
        sprintf (result, "r%d", addr_mode);
502
199k
      }
503
199k
    break;
504
199k
  case 0x8: case 0x9: case 0xa: case 0xb:
505
43.1k
  case 0xc: case 0xd: case 0xe: case 0xf:
506
    /* Register relative disp(R0 -- R7).  */
507
43.1k
    disp1 = get_displacement (buffer, aoffsetp);
508
43.1k
    sprintf (result, "%d(r%d)", disp1, addr_mode & 7);
509
43.1k
    break;
510
6.18k
  case 0x10:
511
9.28k
  case 0x11:
512
12.0k
  case 0x12:
513
    /* Memory relative disp2(disp1(FP, SP, SB)).  */
514
12.0k
    disp1 = get_displacement (buffer, aoffsetp);
515
12.0k
    disp2 = get_displacement (buffer, aoffsetp);
516
12.0k
    sprintf (result, "%d(%d(%s))", disp2, disp1,
517
12.0k
       addr_mode == 0x10 ? "fp" : addr_mode == 0x11 ? "sp" : "sb");
518
12.0k
    break;
519
4.09k
  case 0x13:
520
    /* Reserved.  */
521
4.09k
    sprintf (result, "reserved");
522
4.09k
    break;
523
19.6k
  case 0x14:
524
    /* Immediate.  */
525
19.6k
    switch (d)
526
19.6k
      {
527
5.43k
      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
5.43k
        sprintf (result, _("$<undefined>"));
534
5.43k
        break;
535
1.44k
      case 'B':
536
1.44k
        Ivalue = bit_extract (buffer, *aoffsetp, 8);
537
1.44k
        Ivalue = sign_extend (Ivalue, 8);
538
1.44k
        *aoffsetp += 8;
539
1.44k
        sprintf (result, "$%d", Ivalue);
540
1.44k
        break;
541
1.44k
      case 'W':
542
1.44k
        Ivalue = bit_extract (buffer, *aoffsetp, 16);
543
1.44k
        flip_bytes ((char *) & Ivalue, 2);
544
1.44k
        *aoffsetp += 16;
545
1.44k
        Ivalue = sign_extend (Ivalue, 16);
546
1.44k
        sprintf (result, "$%d", Ivalue);
547
1.44k
        break;
548
1.58k
      case 'D':
549
1.58k
        Ivalue = bit_extract (buffer, *aoffsetp, 32);
550
1.58k
        flip_bytes ((char *) & Ivalue, 4);
551
1.58k
        *aoffsetp += 32;
552
1.58k
        sprintf (result, "$%d", Ivalue);
553
1.58k
        break;
554
4.95k
      case 'F':
555
4.95k
        bit_copy (buffer, *aoffsetp, 32, (char *) &value.f);
556
4.95k
        flip_bytes ((char *) &value.f, 4);
557
4.95k
        *aoffsetp += 32;
558
4.95k
        if (INVALID_FLOAT (&value.f, 4))
559
2.61k
    sprintf (result, "<<invalid float 0x%.8x>>", value.i[0]);
560
2.33k
        else /* Assume host has ieee float.  */
561
2.33k
    sprintf (result, "$%g", value.f);
562
4.95k
        break;
563
4.78k
      case 'L':
564
4.78k
        bit_copy (buffer, *aoffsetp, 64, (char *) &value.d);
565
4.78k
        flip_bytes ((char *) &value.d, 8);
566
4.78k
        *aoffsetp += 64;
567
4.78k
        if (INVALID_FLOAT (&value.d, 8))
568
2.82k
    sprintf (result, "<<invalid double 0x%.8x%.8x>>",
569
2.82k
       value.i[1], value.i[0]);
570
1.95k
        else /* Assume host has ieee float.  */
571
1.95k
    sprintf (result, "$%g", value.d);
572
4.78k
        break;
573
19.6k
      }
574
19.5k
    break;
575
19.5k
  case 0x15:
576
    /* Absolute @disp.  */
577
3.20k
    disp1 = get_displacement (buffer, aoffsetp);
578
3.20k
    sprintf (result, "@|%d|", disp1);
579
3.20k
    break;
580
3.43k
  case 0x16:
581
    /* External EXT(disp1) + disp2 (Mod table stuff).  */
582
3.43k
    disp1 = get_displacement (buffer, aoffsetp);
583
3.43k
    disp2 = get_displacement (buffer, aoffsetp);
584
3.43k
    sprintf (result, "EXT(%d) + %d", disp1, disp2);
585
3.43k
    break;
586
5.90k
  case 0x17:
587
    /* Top of stack tos.  */
588
5.90k
    sprintf (result, "tos");
589
5.90k
    break;
590
8.27k
  case 0x18:
591
    /* Memory space disp(FP).  */
592
8.27k
    disp1 = get_displacement (buffer, aoffsetp);
593
8.27k
    sprintf (result, "%d(fp)", disp1);
594
8.27k
    break;
595
4.89k
  case 0x19:
596
    /* Memory space disp(SP).  */
597
4.89k
    disp1 = get_displacement (buffer, aoffsetp);
598
4.89k
    sprintf (result, "%d(sp)", disp1);
599
4.89k
    break;
600
3.06k
  case 0x1a:
601
    /* Memory space disp(SB).  */
602
3.06k
    disp1 = get_displacement (buffer, aoffsetp);
603
3.06k
    sprintf (result, "%d(sb)", disp1);
604
3.06k
    break;
605
2.09k
  case 0x1b:
606
    /* Memory space disp(PC).  */
607
2.09k
    disp1 = get_displacement (buffer, aoffsetp);
608
2.09k
    *result++ = NEXT_IS_ADDR;
609
2.09k
    sprintf (result, "%" PRIx64, (uint64_t) (addr + disp1));
610
2.09k
    result += strlen (result);
611
2.09k
    *result++ = NEXT_IS_ADDR;
612
2.09k
    *result = '\0';
613
2.09k
    break;
614
9.70k
  case 0x1c:
615
17.0k
  case 0x1d:
616
24.9k
  case 0x1e:
617
39.4k
  case 0x1f:
618
39.4k
    {
619
39.4k
      int bit_index;
620
39.4k
      static const char *ind = "bwdq";
621
39.4k
      char *off;
622
623
      /* Scaled index basemode[R0 -- R7:B,W,D,Q].  */
624
39.4k
      bit_index = bit_extract (buffer, index_offset - 8, 3);
625
39.4k
      print_insn_arg (d, index_offset, aoffsetp, buffer, addr,
626
39.4k
          result, 0);
627
39.4k
      off = result + strlen (result);
628
39.4k
      sprintf (off, "[r%d:%c]", bit_index, ind[addr_mode & 3]);
629
39.4k
    }
630
39.4k
    break;
631
348k
  }
632
348k
      break;
633
348k
    case 'H':
634
10.0k
    case 'q':
635
10.0k
      Ivalue = bit_extract (buffer, ioffset-4, 4);
636
10.0k
      Ivalue = sign_extend (Ivalue, 4);
637
10.0k
      sprintf (result, "%d", Ivalue);
638
10.0k
      ioffset -= 4;
639
10.0k
      break;
640
1.44k
    case 'r':
641
1.44k
      Ivalue = bit_extract (buffer, ioffset-3, 3);
642
1.44k
      sprintf (result, "r%d", Ivalue&7);
643
1.44k
      ioffset -= 3;
644
1.44k
      break;
645
3.35k
    case 'd':
646
3.35k
      sprintf (result, "%d", get_displacement (buffer, aoffsetp));
647
3.35k
      break;
648
502
    case 'b':
649
502
      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
502
      size = bit_extract(buffer, ioffset-6, 2);
657
502
      if (size == 0)    /* 00 => b.  */
658
201
  size = 1;
659
301
      else if (size == 1)  /* 01 => w.  */
660
141
  size = 2;
661
160
      else
662
160
  size = 4;   /* 11 => d.  */
663
664
502
      sprintf (result, "%d", (Ivalue / size) + 1);
665
502
      break;
666
8.49k
    case 'p':
667
8.49k
      *result++ = NEXT_IS_ADDR;
668
8.49k
      sprintf (result, "%" PRIx64,
669
8.49k
         (uint64_t) (addr + get_displacement (buffer, aoffsetp)));
670
8.49k
      result += strlen (result);
671
8.49k
      *result++ = NEXT_IS_ADDR;
672
8.49k
      *result = '\0';
673
8.49k
      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.24k
    case 'u':
680
4.24k
      Ivalue = bit_extract (buffer, *aoffsetp, 8);
681
4.24k
      optlist (Ivalue, opt_u, result);
682
4.24k
      *aoffsetp += 8;
683
4.24k
      break;
684
2.46k
    case 'U':
685
2.46k
      Ivalue = bit_extract (buffer, *aoffsetp, 8);
686
2.46k
      optlist (Ivalue, opt_U, result);
687
2.46k
      *aoffsetp += 8;
688
2.46k
      break;
689
1.23k
    case 'O':
690
1.23k
      Ivalue = bit_extract (buffer, ioffset - 9, 9);
691
1.23k
      optlist (Ivalue, opt_O, result);
692
1.23k
      ioffset -= 9;
693
1.23k
      break;
694
677
    case 'C':
695
677
      Ivalue = bit_extract (buffer, ioffset - 4, 4);
696
677
      optlist (Ivalue, opt_C, result);
697
677
      ioffset -= 4;
698
677
      break;
699
682
    case 'S':
700
682
      Ivalue = bit_extract (buffer, ioffset - 8, 8);
701
682
      optlist (Ivalue, opt_S, result);
702
682
      ioffset -= 8;
703
682
      break;
704
765
    case 'M':
705
765
      Ivalue = bit_extract (buffer, ioffset - 4, 4);
706
765
      list_search (Ivalue, 0 ? list_M032 : list_M532, result);
707
765
      ioffset -= 4;
708
765
      break;
709
7.63k
    case 'P':
710
7.63k
      Ivalue = bit_extract (buffer, ioffset - 4, 4);
711
7.63k
      list_search (Ivalue, 0 ? list_P032 : list_P532, result);
712
7.63k
      ioffset -= 4;
713
7.63k
      break;
714
579
    case 'g':
715
579
      Ivalue = bit_extract (buffer, *aoffsetp, 3);
716
579
      sprintf (result, "%d", Ivalue);
717
579
      *aoffsetp += 3;
718
579
      break;
719
579
    case 'G':
720
579
      Ivalue = bit_extract(buffer, *aoffsetp, 5);
721
579
      sprintf (result, "%d", Ivalue + 1);
722
579
      *aoffsetp += 5;
723
579
      break;
724
391k
    }
725
390k
  return ioffset;
726
391k
}
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
253k
{
735
253k
  unsigned int i;
736
253k
  const char *d;
737
253k
  unsigned short first_word;
738
253k
  int ioffset;    /* Bits into instruction.  */
739
253k
  int aoffset;    /* Bits into arguments.  */
740
253k
  char arg_bufs[MAX_ARGS+1][ARG_LEN];
741
253k
  int argnum;
742
253k
  int maxarg;
743
253k
  struct private priv;
744
253k
  bfd_byte *buffer = priv.the_buffer;
745
253k
  dis_info = info;
746
747
253k
  info->private_data = & priv;
748
253k
  priv.max_fetched = priv.the_buffer;
749
253k
  priv.insn_start = memaddr;
750
253k
  if (OPCODES_SIGSETJMP (priv.bailout) != 0)
751
    /* Error return.  */
752
360
    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
253k
  FETCH_DATA (info, buffer + 1);
757
43.0M
  for (i = 0; i < NOPCODES; i++)
758
42.9M
    if (ns32k_opcodes[i].opcode_id_size <= 8
759
12.3M
  && ((buffer[0]
760
12.3M
       & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
761
12.3M
      == ns32k_opcodes[i].opcode_seed))
762
172k
      break;
763
253k
  if (i == NOPCODES)
764
80.9k
    {
765
      /* Maybe it is 9 to 16 bits big.  */
766
80.9k
      FETCH_DATA (info, buffer + 2);
767
80.9k
      first_word = read_memory_integer(buffer, 2);
768
769
24.0M
      for (i = 0; i < NOPCODES; i++)
770
24.0M
  if ((first_word
771
24.0M
       & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
772
24.0M
      == ns32k_opcodes[i].opcode_seed)
773
18.6k
    break;
774
775
      /* Handle undefined instructions.  */
776
80.9k
      if (i == NOPCODES)
777
62.2k
  {
778
62.2k
    (*dis_info->fprintf_func)(dis_info->stream, "0%o", buffer[0]);
779
62.2k
    return 1;
780
62.2k
  }
781
80.9k
    }
782
783
190k
  (*dis_info->fprintf_func)(dis_info->stream, "%s", ns32k_opcodes[i].name);
784
785
190k
  ioffset = ns32k_opcodes[i].opcode_size;
786
190k
  aoffset = ns32k_opcodes[i].opcode_size;
787
190k
  d = ns32k_opcodes[i].operands;
788
789
190k
  if (*d)
790
183k
    {
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
183k
      int index_offset[2];
794
795
      /* 0 for operand A, 1 for operand B, greater for other args.  */
796
183k
      int whicharg = 0;
797
798
183k
      (*dis_info->fprintf_func)(dis_info->stream, "\t");
799
800
183k
      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
183k
      index_offset[0] = -1;
807
183k
      index_offset[1] = -1;
808
183k
      if (Is_gen (d[1]))
809
166k
  {
810
166k
    int bitoff = d[1] == 'f' ? 10 : 5;
811
166k
    int addr_mode = bit_extract (buffer, ioffset - bitoff, 5);
812
813
166k
    if (Adrmod_is_index (addr_mode))
814
16.6k
      {
815
16.6k
        aoffset += 8;
816
16.6k
        index_offset[0] = aoffset;
817
16.6k
      }
818
166k
  }
819
820
183k
      if (d[2] && Is_gen (d[3]))
821
142k
  {
822
142k
    int addr_mode = bit_extract (buffer, ioffset - 10, 5);
823
824
142k
    if (Adrmod_is_index (addr_mode))
825
13.0k
      {
826
13.0k
        aoffset += 8;
827
13.0k
        index_offset[1] = aoffset;
828
13.0k
      }
829
142k
  }
830
831
535k
      while (*d)
832
351k
  {
833
351k
    argnum = *d - '1';
834
351k
    if (argnum >= MAX_ARGS)
835
0
      abort ();
836
351k
    d++;
837
351k
    if (argnum > maxarg)
838
167k
      maxarg = argnum;
839
351k
    ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
840
351k
            memaddr, arg_bufs[argnum],
841
351k
            whicharg > 1 ? -1 : index_offset[whicharg]);
842
351k
    d++;
843
351k
    whicharg++;
844
351k
  }
845
846
535k
      for (argnum = 0; argnum <= maxarg; argnum++)
847
351k
  {
848
351k
    bfd_vma addr;
849
351k
    char *ch;
850
851
2.18M
    for (ch = arg_bufs[argnum]; *ch;)
852
1.83M
      {
853
1.83M
        if (*ch == NEXT_IS_ADDR)
854
13.7k
    {
855
13.7k
      ++ch;
856
13.7k
      addr = bfd_scan_vma (ch, NULL, 16);
857
13.7k
      (*dis_info->print_address_func) (addr, dis_info);
858
99.9k
      while (*ch && *ch != NEXT_IS_ADDR)
859
86.1k
        ++ch;
860
13.7k
      if (*ch)
861
13.7k
        ++ch;
862
13.7k
    }
863
1.82M
        else
864
1.82M
    (*dis_info->fprintf_func)(dis_info->stream, "%c", *ch++);
865
1.83M
      }
866
351k
    if (argnum < maxarg)
867
167k
      (*dis_info->fprintf_func)(dis_info->stream, ", ");
868
351k
  }
869
183k
    }
870
190k
  return aoffset / 8;
871
190k
}