Coverage Report

Created: 2026-04-04 08:16

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