Coverage Report

Created: 2026-05-11 07:54

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