Coverage Report

Created: 2023-06-29 07:13

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