Coverage Report

Created: 2026-09-14 08:07

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