Coverage Report

Created: 2026-03-10 08:46

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