Coverage Report

Created: 2026-10-02 09:53

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.78k
#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
87.2k
{
38
87.2k
  long val;
39
87.2k
  int i;
40
41
261k
  for (val = 0, i = nr - 1; i >= 0; i--)
42
174k
    {
43
174k
      val =  (val << 8);
44
174k
      val |= (0xff & *(addr + i));
45
174k
    }
46
87.2k
  return val;
47
87.2k
}
48
49
/* 32000 instructions are never longer than this.  */
50
#define MAXLEN 62
51
52
#include <setjmp.h>
53
54
struct private
55
{
56
  /* Points to first byte not fetched.  */
57
  bfd_byte *max_fetched;
58
  bfd_byte the_buffer[MAXLEN];
59
  bfd_vma insn_start;
60
  OPCODES_SIGJMP_BUF bailout;
61
};
62
63
64
/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
65
   to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
66
   on error.  */
67
#define FETCH_DATA(info, addr) \
68
6.99M
  ((addr) <= ((struct private *)(info->private_data))->max_fetched \
69
6.99M
   ? 1 : fetch_data ((info), (addr)))
70
71
static int
72
fetch_data (struct disassemble_info *info, bfd_byte *addr)
73
884k
{
74
884k
  int status;
75
884k
  struct private *priv = (struct private *) info->private_data;
76
884k
  bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
77
78
884k
  status = (*info->read_memory_func) (start,
79
884k
              priv->max_fetched,
80
884k
              addr - priv->max_fetched,
81
884k
              info);
82
884k
  if (status != 0)
83
509
    {
84
509
      (*info->memory_error_func) (status, start, info);
85
509
      OPCODES_SIGLONGJMP (priv->bailout, 1);
86
509
    }
87
884k
  else
88
884k
    priv->max_fetched = addr;
89
884k
  return 1;
90
884k
}
91
92
/* Number of elements in the opcode table.  */
93
73.9M
#define NOPCODES (sizeof ns32k_opcodes / sizeof ns32k_opcodes[0])
94
95
2.28M
#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.1k
{
220
12.1k
  if (options == 0)
221
920
    {
222
920
      sprintf (result, "[]");
223
920
      return;
224
920
    }
225
226
11.1k
  sprintf (result, "[");
227
228
79.6k
  for (; (options != 0) && optionP->pattern; optionP++)
229
68.4k
    {
230
68.4k
      if ((options & optionP->match) == optionP->value)
231
31.4k
  {
232
    /* We found a match, update result and options.  */
233
31.4k
    strcat (result, optionP->pattern);
234
31.4k
    options &= ~optionP->value;
235
31.4k
    if (options != 0)  /* More options to come.  */
236
21.8k
      strcat (result, ",");
237
31.4k
  }
238
68.4k
    }
239
240
11.1k
  if (options != 0)
241
1.64k
    strcat (result, "undefined");
242
243
11.1k
  strcat (result, "]");
244
11.1k
}
245
246
static void
247
list_search (int reg_value, const struct ns32k_option *optionP, char *result)
248
11.4k
{
249
86.8k
  for (; optionP->pattern; optionP++)
250
84.3k
    {
251
84.3k
      if ((reg_value & optionP->match) == optionP->value)
252
8.94k
  {
253
8.94k
    sprintf (result, "%s", optionP->pattern);
254
8.94k
    return;
255
8.94k
  }
256
84.3k
    }
257
2.51k
  sprintf (result, "undefined");
258
2.51k
}
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.07M
{
265
1.07M
  unsigned int result;
266
1.07M
  unsigned int bit;
267
268
1.07M
  if (offset < 0 || count < 0)
269
23.5k
    return 0;
270
1.04M
  buffer += offset >> 3;
271
1.04M
  offset &= 7;
272
1.04M
  bit = 1;
273
1.04M
  result = 0;
274
7.67M
  while (count--)
275
6.62M
    {
276
6.62M
      FETCH_DATA (dis_info, buffer + 1);
277
6.62M
      if ((*buffer & (1 << offset)))
278
2.37M
  result |= bit;
279
6.62M
      if (++offset == 8)
280
1.10M
  {
281
1.10M
    offset = 0;
282
1.10M
    buffer++;
283
1.10M
  }
284
6.62M
      bit <<= 1;
285
6.62M
    }
286
1.04M
  return result;
287
1.07M
}
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.7k
{
294
27.7k
  unsigned int result;
295
27.7k
  unsigned int bit;
296
297
27.7k
  if (offset < 0 || count < 0)
298
0
    return 0;
299
27.7k
  buffer += offset >> 3;
300
27.7k
  offset &= 7;
301
27.7k
  bit = 1;
302
27.7k
  result = 0;
303
444k
  while (count--)
304
416k
    {
305
416k
      if ((*buffer & (1 << offset)))
306
60.4k
  result |= bit;
307
416k
      if (++offset == 8)
308
45.2k
  {
309
45.2k
    offset = 0;
310
45.2k
    buffer++;
311
45.2k
  }
312
416k
      bit <<= 1;
313
416k
    }
314
27.7k
  return result;
315
27.7k
}
316
317
static void
318
bit_copy (bfd_byte *buffer, int offset, int count, char *to)
319
9.78k
{
320
9.78k
  if (offset < 0 || count < 0)
321
0
    return;
322
59.8k
  for (; count > 8; count -= 8, to++, offset += 8)
323
50.0k
    *to = bit_extract (buffer, offset, 8);
324
9.78k
  *to = bit_extract (buffer, offset, count);
325
9.78k
}
326
327
static int
328
sign_extend (unsigned int value, unsigned int bits)
329
144k
{
330
144k
  unsigned int sign = 1u << (bits - 1);
331
144k
  return ((value & (sign + sign - 1)) ^ sign) - sign;
332
144k
}
333
334
static void
335
flip_bytes (char *ptr, int count)
336
56.4k
{
337
56.4k
  char tmp;
338
339
156k
  while (count > 0)
340
99.6k
    {
341
99.6k
      tmp = ptr[0];
342
99.6k
      ptr[0] = ptr[count - 1];
343
99.6k
      ptr[count - 1] = tmp;
344
99.6k
      ptr++;
345
99.6k
      count -= 2;
346
99.6k
    }
347
56.4k
}
348

349
/* Given a character C, does it represent a general addressing mode?  */
350
398k
#define Is_gen(c) (strchr ("FLBWDAIZf", (c)) != NULL)
351
352
/* Adressing modes.  */
353
699k
#define Adrmod_index_byte        0x1c
354
690k
#define Adrmod_index_word        0x1d
355
682k
#define Adrmod_index_doubleword  0x1e
356
675k
#define Adrmod_index_quadword    0x1f
357
358
/* Is MODE an indexed addressing mode?  */
359
#define Adrmod_is_index(mode) \
360
349k
  (   mode == Adrmod_index_byte \
361
349k
   || mode == Adrmod_index_word \
362
349k
   || mode == Adrmod_index_doubleword \
363
349k
   || mode == Adrmod_index_quadword)
364
365

366
static int
367
get_displacement (bfd_byte *buffer, int *aoffsetp)
368
129k
{
369
129k
  int Ivalue;
370
129k
  short Ivalue2;
371
372
129k
  Ivalue = bit_extract (buffer, *aoffsetp, 8);
373
129k
  switch (Ivalue & 0xc0)
374
129k
    {
375
50.0k
    case 0x00:
376
85.7k
    case 0x40:
377
85.7k
      Ivalue = sign_extend (Ivalue, 7);
378
85.7k
      *aoffsetp += 8;
379
85.7k
      break;
380
22.5k
    case 0x80:
381
22.5k
      Ivalue2 = bit_extract (buffer, *aoffsetp, 16);
382
22.5k
      flip_bytes ((char *) & Ivalue2, 2);
383
22.5k
      Ivalue = sign_extend (Ivalue2, 14);
384
22.5k
      *aoffsetp += 16;
385
22.5k
      break;
386
21.3k
    case 0xc0:
387
21.3k
      Ivalue = bit_extract (buffer, *aoffsetp, 32);
388
21.3k
      flip_bytes ((char *) & Ivalue, 4);
389
21.3k
      Ivalue = sign_extend (Ivalue, 30);
390
21.3k
      *aoffsetp += 32;
391
21.3k
      break;
392
129k
    }
393
129k
  return Ivalue;
394
129k
}
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.72k
{
400
9.72k
  int val;
401
402
9.72k
  if (len == 4)
403
4.54k
    val = (bit_extract_simple (p, 23, 8)/*exponent*/ == 0xff
404
4.14k
     || (bit_extract_simple (p, 23, 8)/*exponent*/ == 0
405
2.26k
         && bit_extract_simple (p, 0, 23)/*mantisa*/ != 0));
406
5.17k
  else if (len == 8)
407
5.17k
    val = (bit_extract_simple (p, 52, 11)/*exponent*/ == 0x7ff
408
5.08k
     || (bit_extract_simple (p, 52, 11)/*exponent*/ == 0
409
4.35k
         && (bit_extract_simple (p, 0, 32)/*low mantisa*/ != 0
410
2.15k
       || bit_extract_simple (p, 32, 20)/*high mantisa*/ != 0)));
411
0
  else
412
0
    val = 1;
413
9.72k
  return (val);
414
9.72k
}
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
451k
{
461
451k
  union
462
451k
  {
463
451k
    float f;
464
451k
    double d;
465
451k
    int i[2];
466
451k
  } value;
467
451k
  int Ivalue;
468
451k
  int addr_mode;
469
451k
  int disp1, disp2;
470
451k
  int size;
471
472
451k
  switch (d)
473
451k
    {
474
119
    case 'f':
475
      /* A "gen" operand but 5 bits from the end of instruction.  */
476
119
      ioffset -= 5;
477
      /* Fall through.  */
478
1.55k
    case 'Z':
479
8.63k
    case 'F':
480
15.5k
    case 'L':
481
179k
    case 'I':
482
300k
    case 'B':
483
341k
    case 'W':
484
380k
    case 'D':
485
396k
    case 'A':
486
396k
      addr_mode = bit_extract (buffer, ioffset - 5, 5);
487
396k
      ioffset -= 5;
488
396k
      switch (addr_mode)
489
396k
  {
490
184k
  case 0x0: case 0x1: case 0x2: case 0x3:
491
221k
  case 0x4: case 0x5: case 0x6: case 0x7:
492
    /* Register mode R0 -- R7.  */
493
221k
    switch (d)
494
221k
      {
495
969
      case 'F':
496
2.47k
      case 'L':
497
3.61k
      case 'Z':
498
3.61k
        sprintf (result, "f%d", addr_mode);
499
3.61k
        break;
500
218k
      default:
501
218k
        sprintf (result, "r%d", addr_mode);
502
221k
      }
503
221k
    break;
504
221k
  case 0x8: case 0x9: case 0xa: case 0xb:
505
51.3k
  case 0xc: case 0xd: case 0xe: case 0xf:
506
    /* Register relative disp(R0 -- R7).  */
507
51.3k
    disp1 = get_displacement (buffer, aoffsetp);
508
51.3k
    sprintf (result, "%d(r%d)", disp1, addr_mode & 7);
509
51.3k
    break;
510
8.17k
  case 0x10:
511
12.3k
  case 0x11:
512
15.2k
  case 0x12:
513
    /* Memory relative disp2(disp1(FP, SP, SB)).  */
514
15.2k
    disp1 = get_displacement (buffer, aoffsetp);
515
15.2k
    disp2 = get_displacement (buffer, aoffsetp);
516
15.2k
    sprintf (result, "%d(%d(%s))", disp2, disp1,
517
15.2k
       addr_mode == 0x10 ? "fp" : addr_mode == 0x11 ? "sp" : "sb");
518
15.2k
    break;
519
5.00k
  case 0x13:
520
    /* Reserved.  */
521
5.00k
    sprintf (result, "reserved");
522
5.00k
    break;
523
21.8k
  case 0x14:
524
    /* Immediate.  */
525
21.8k
    switch (d)
526
21.8k
      {
527
7.40k
      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.40k
        sprintf (result, _("$<undefined>"));
534
7.40k
        break;
535
1.73k
      case 'B':
536
1.73k
        Ivalue = bit_extract (buffer, *aoffsetp, 8);
537
1.73k
        Ivalue = sign_extend (Ivalue, 8);
538
1.73k
        *aoffsetp += 8;
539
1.73k
        sprintf (result, "$%d", Ivalue);
540
1.73k
        break;
541
1.18k
      case 'W':
542
1.18k
        Ivalue = bit_extract (buffer, *aoffsetp, 16);
543
1.18k
        flip_bytes ((char *) & Ivalue, 2);
544
1.18k
        *aoffsetp += 16;
545
1.18k
        Ivalue = sign_extend (Ivalue, 16);
546
1.18k
        sprintf (result, "$%d", Ivalue);
547
1.18k
        break;
548
1.74k
      case 'D':
549
1.74k
        Ivalue = bit_extract (buffer, *aoffsetp, 32);
550
1.74k
        flip_bytes ((char *) & Ivalue, 4);
551
1.74k
        *aoffsetp += 32;
552
1.74k
        sprintf (result, "$%d", Ivalue);
553
1.74k
        break;
554
4.55k
      case 'F':
555
4.55k
        bit_copy (buffer, *aoffsetp, 32, (char *) &value.f);
556
4.55k
        flip_bytes ((char *) &value.f, 4);
557
4.55k
        *aoffsetp += 32;
558
4.55k
        if (INVALID_FLOAT (&value.f, 4))
559
2.16k
    sprintf (result, "<<invalid float 0x%.8x>>", value.i[0]);
560
2.39k
        else /* Assume host has ieee float.  */
561
2.39k
    sprintf (result, "$%g", value.f);
562
4.55k
        break;
563
5.22k
      case 'L':
564
5.22k
        bit_copy (buffer, *aoffsetp, 64, (char *) &value.d);
565
5.22k
        flip_bytes ((char *) &value.d, 8);
566
5.22k
        *aoffsetp += 64;
567
5.22k
        if (INVALID_FLOAT (&value.d, 8))
568
3.08k
    sprintf (result, "<<invalid double 0x%.8x%.8x>>",
569
3.08k
       value.i[1], value.i[0]);
570
2.13k
        else /* Assume host has ieee float.  */
571
2.13k
    sprintf (result, "$%g", value.d);
572
5.22k
        break;
573
21.8k
      }
574
21.7k
    break;
575
21.7k
  case 0x15:
576
    /* Absolute @disp.  */
577
3.77k
    disp1 = get_displacement (buffer, aoffsetp);
578
3.77k
    sprintf (result, "@|%d|", disp1);
579
3.77k
    break;
580
3.27k
  case 0x16:
581
    /* External EXT(disp1) + disp2 (Mod table stuff).  */
582
3.27k
    disp1 = get_displacement (buffer, aoffsetp);
583
3.27k
    disp2 = get_displacement (buffer, aoffsetp);
584
3.27k
    sprintf (result, "EXT(%d) + %d", disp1, disp2);
585
3.27k
    break;
586
6.66k
  case 0x17:
587
    /* Top of stack tos.  */
588
6.66k
    sprintf (result, "tos");
589
6.66k
    break;
590
9.06k
  case 0x18:
591
    /* Memory space disp(FP).  */
592
9.06k
    disp1 = get_displacement (buffer, aoffsetp);
593
9.06k
    sprintf (result, "%d(fp)", disp1);
594
9.06k
    break;
595
5.56k
  case 0x19:
596
    /* Memory space disp(SP).  */
597
5.56k
    disp1 = get_displacement (buffer, aoffsetp);
598
5.56k
    sprintf (result, "%d(sp)", disp1);
599
5.56k
    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.86k
  case 0x1b:
606
    /* Memory space disp(PC).  */
607
2.86k
    disp1 = get_displacement (buffer, aoffsetp);
608
2.86k
    *result++ = NEXT_IS_ADDR;
609
2.86k
    sprintf (result, "%" PRIx64, (uint64_t) (addr + disp1));
610
2.86k
    result += strlen (result);
611
2.86k
    *result++ = NEXT_IS_ADDR;
612
2.86k
    *result = '\0';
613
2.86k
    break;
614
10.7k
  case 0x1c:
615
20.8k
  case 0x1d:
616
31.2k
  case 0x1e:
617
46.7k
  case 0x1f:
618
46.7k
    {
619
46.7k
      int bit_index;
620
46.7k
      static const char *ind = "bwdq";
621
46.7k
      char *off;
622
623
      /* Scaled index basemode[R0 -- R7:B,W,D,Q].  */
624
46.7k
      bit_index = bit_extract (buffer, index_offset - 8, 3);
625
46.7k
      print_insn_arg (d, index_offset, aoffsetp, buffer, addr,
626
46.7k
          result, 0);
627
46.7k
      off = result + strlen (result);
628
46.7k
      sprintf (off, "[r%d:%c]", bit_index, ind[addr_mode & 3]);
629
46.7k
    }
630
46.7k
    break;
631
396k
  }
632
396k
      break;
633
396k
    case 'H':
634
11.9k
    case 'q':
635
11.9k
      Ivalue = bit_extract (buffer, ioffset-4, 4);
636
11.9k
      Ivalue = sign_extend (Ivalue, 4);
637
11.9k
      sprintf (result, "%d", Ivalue);
638
11.9k
      ioffset -= 4;
639
11.9k
      break;
640
1.53k
    case 'r':
641
1.53k
      Ivalue = bit_extract (buffer, ioffset-3, 3);
642
1.53k
      sprintf (result, "r%d", Ivalue&7);
643
1.53k
      ioffset -= 3;
644
1.53k
      break;
645
3.79k
    case 'd':
646
3.79k
      sprintf (result, "%d", get_displacement (buffer, aoffsetp));
647
3.79k
      break;
648
1.10k
    case 'b':
649
1.10k
      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.10k
      size = bit_extract(buffer, ioffset-6, 2);
657
1.10k
      if (size == 0)    /* 00 => b.  */
658
342
  size = 1;
659
759
      else if (size == 1)  /* 01 => w.  */
660
495
  size = 2;
661
264
      else
662
264
  size = 4;   /* 11 => d.  */
663
664
1.10k
      sprintf (result, "%d", (Ivalue / size) + 1);
665
1.10k
      break;
666
12.0k
    case 'p':
667
12.0k
      *result++ = NEXT_IS_ADDR;
668
12.0k
      sprintf (result, "%" PRIx64,
669
12.0k
         (uint64_t) (addr + get_displacement (buffer, aoffsetp)));
670
12.0k
      result += strlen (result);
671
12.0k
      *result++ = NEXT_IS_ADDR;
672
12.0k
      *result = '\0';
673
12.0k
      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.64k
    case 'u':
680
5.64k
      Ivalue = bit_extract (buffer, *aoffsetp, 8);
681
5.64k
      optlist (Ivalue, opt_u, result);
682
5.64k
      *aoffsetp += 8;
683
5.64k
      break;
684
3.37k
    case 'U':
685
3.37k
      Ivalue = bit_extract (buffer, *aoffsetp, 8);
686
3.37k
      optlist (Ivalue, opt_U, result);
687
3.37k
      *aoffsetp += 8;
688
3.37k
      break;
689
1.60k
    case 'O':
690
1.60k
      Ivalue = bit_extract (buffer, ioffset - 9, 9);
691
1.60k
      optlist (Ivalue, opt_O, result);
692
1.60k
      ioffset -= 9;
693
1.60k
      break;
694
545
    case 'C':
695
545
      Ivalue = bit_extract (buffer, ioffset - 4, 4);
696
545
      optlist (Ivalue, opt_C, result);
697
545
      ioffset -= 4;
698
545
      break;
699
963
    case 'S':
700
963
      Ivalue = bit_extract (buffer, ioffset - 8, 8);
701
963
      optlist (Ivalue, opt_S, result);
702
963
      ioffset -= 8;
703
963
      break;
704
1.08k
    case 'M':
705
1.08k
      Ivalue = bit_extract (buffer, ioffset - 4, 4);
706
1.08k
      list_search (Ivalue, 0 ? list_M032 : list_M532, result);
707
1.08k
      ioffset -= 4;
708
1.08k
      break;
709
10.3k
    case 'P':
710
10.3k
      Ivalue = bit_extract (buffer, ioffset - 4, 4);
711
10.3k
      list_search (Ivalue, 0 ? list_P032 : list_P532, result);
712
10.3k
      ioffset -= 4;
713
10.3k
      break;
714
577
    case 'g':
715
577
      Ivalue = bit_extract (buffer, *aoffsetp, 3);
716
577
      sprintf (result, "%d", Ivalue);
717
577
      *aoffsetp += 3;
718
577
      break;
719
578
    case 'G':
720
578
      Ivalue = bit_extract(buffer, *aoffsetp, 5);
721
578
      sprintf (result, "%d", Ivalue + 1);
722
578
      *aoffsetp += 5;
723
578
      break;
724
451k
    }
725
451k
  return ioffset;
726
451k
}
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
285k
{
735
285k
  unsigned int i;
736
285k
  const char *d;
737
285k
  unsigned short first_word;
738
285k
  int ioffset;    /* Bits into instruction.  */
739
285k
  int aoffset;    /* Bits into arguments.  */
740
285k
  char arg_bufs[MAX_ARGS+1][ARG_LEN];
741
285k
  int argnum;
742
285k
  int maxarg;
743
285k
  struct private priv;
744
285k
  bfd_byte *buffer = priv.the_buffer;
745
285k
  dis_info = info;
746
747
285k
  info->private_data = & priv;
748
285k
  priv.max_fetched = priv.the_buffer;
749
285k
  priv.insn_start = memaddr;
750
285k
  if (OPCODES_SIGSETJMP (priv.bailout) != 0)
751
    /* Error return.  */
752
509
    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
285k
  FETCH_DATA (info, buffer + 1);
757
47.6M
  for (i = 0; i < NOPCODES; i++)
758
47.6M
    if (ns32k_opcodes[i].opcode_id_size <= 8
759
13.6M
  && ((buffer[0]
760
13.6M
       & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
761
13.6M
      == ns32k_opcodes[i].opcode_seed))
762
198k
      break;
763
285k
  if (i == NOPCODES)
764
87.2k
    {
765
      /* Maybe it is 9 to 16 bits big.  */
766
87.2k
      FETCH_DATA (info, buffer + 2);
767
87.2k
      first_word = read_memory_integer(buffer, 2);
768
769
25.8M
      for (i = 0; i < NOPCODES; i++)
770
25.8M
  if ((first_word
771
25.8M
       & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
772
25.8M
      == ns32k_opcodes[i].opcode_seed)
773
20.5k
    break;
774
775
      /* Handle undefined instructions.  */
776
87.2k
      if (i == NOPCODES)
777
66.6k
  {
778
66.6k
    (*dis_info->fprintf_func)(dis_info->stream, "0%o", buffer[0]);
779
66.6k
    return 1;
780
66.6k
  }
781
87.2k
    }
782
783
218k
  (*dis_info->fprintf_func)(dis_info->stream, "%s", ns32k_opcodes[i].name);
784
785
218k
  ioffset = ns32k_opcodes[i].opcode_size;
786
218k
  aoffset = ns32k_opcodes[i].opcode_size;
787
218k
  d = ns32k_opcodes[i].operands;
788
789
218k
  if (*d)
790
213k
    {
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
213k
      int index_offset[2];
794
795
      /* 0 for operand A, 1 for operand B, greater for other args.  */
796
213k
      int whicharg = 0;
797
798
213k
      (*dis_info->fprintf_func)(dis_info->stream, "\t");
799
800
213k
      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
213k
      index_offset[0] = -1;
807
213k
      index_offset[1] = -1;
808
213k
      if (Is_gen (d[1]))
809
189k
  {
810
189k
    int bitoff = d[1] == 'f' ? 10 : 5;
811
189k
    int addr_mode = bit_extract (buffer, ioffset - bitoff, 5);
812
813
189k
    if (Adrmod_is_index (addr_mode))
814
19.1k
      {
815
19.1k
        aoffset += 8;
816
19.1k
        index_offset[0] = aoffset;
817
19.1k
      }
818
189k
  }
819
820
213k
      if (d[2] && Is_gen (d[3]))
821
160k
  {
822
160k
    int addr_mode = bit_extract (buffer, ioffset - 10, 5);
823
824
160k
    if (Adrmod_is_index (addr_mode))
825
15.8k
      {
826
15.8k
        aoffset += 8;
827
15.8k
        index_offset[1] = aoffset;
828
15.8k
      }
829
160k
  }
830
831
617k
      while (*d)
832
404k
  {
833
404k
    argnum = *d - '1';
834
404k
    if (argnum >= MAX_ARGS)
835
0
      abort ();
836
404k
    d++;
837
404k
    if (argnum > maxarg)
838
191k
      maxarg = argnum;
839
404k
    ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
840
404k
            memaddr, arg_bufs[argnum],
841
404k
            whicharg > 1 ? -1 : index_offset[whicharg]);
842
404k
    d++;
843
404k
    whicharg++;
844
404k
  }
845
846
617k
      for (argnum = 0; argnum <= maxarg; argnum++)
847
404k
  {
848
404k
    bfd_vma addr;
849
404k
    char *ch;
850
851
2.51M
    for (ch = arg_bufs[argnum]; *ch;)
852
2.11M
      {
853
2.11M
        if (*ch == NEXT_IS_ADDR)
854
18.6k
    {
855
18.6k
      ++ch;
856
18.6k
      addr = bfd_scan_vma (ch, NULL, 16);
857
18.6k
      (*dis_info->print_address_func) (addr, dis_info);
858
139k
      while (*ch && *ch != NEXT_IS_ADDR)
859
121k
        ++ch;
860
18.6k
      if (*ch)
861
18.6k
        ++ch;
862
18.6k
    }
863
2.09M
        else
864
2.09M
    (*dis_info->fprintf_func)(dis_info->stream, "%c", *ch++);
865
2.11M
      }
866
404k
    if (argnum < maxarg)
867
191k
      (*dis_info->fprintf_func)(dis_info->stream, ", ");
868
404k
  }
869
213k
    }
870
218k
  return aoffset / 8;
871
218k
}