Coverage Report

Created: 2025-07-08 11:15

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