Coverage Report

Created: 2024-05-21 06:29

/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-2024 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.02k
#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
75.2k
{
38
75.2k
  long val;
39
75.2k
  int i;
40
41
225k
  for (val = 0, i = nr - 1; i >= 0; i--)
42
150k
    {
43
150k
      val =  (val << 8);
44
150k
      val |= (0xff & *(addr + i));
45
150k
    }
46
75.2k
  return val;
47
75.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
5.06M
  ((addr) <= ((struct private *)(info->private_data))->max_fetched \
69
5.06M
   ? 1 : fetch_data ((info), (addr)))
70
71
static int
72
fetch_data (struct disassemble_info *info, bfd_byte *addr)
73
660k
{
74
660k
  int status;
75
660k
  struct private *priv = (struct private *) info->private_data;
76
660k
  bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
77
78
660k
  status = (*info->read_memory_func) (start,
79
660k
              priv->max_fetched,
80
660k
              addr - priv->max_fetched,
81
660k
              info);
82
660k
  if (status != 0)
83
357
    {
84
357
      (*info->memory_error_func) (status, start, info);
85
357
      OPCODES_SIGLONGJMP (priv->bailout, 1);
86
357
    }
87
660k
  else
88
660k
    priv->max_fetched = addr;
89
660k
  return 1;
90
660k
}
91
92
/* Number of elements in the opcode table.  */
93
61.9M
#define NOPCODES (sizeof ns32k_opcodes / sizeof ns32k_opcodes[0])
94
95
1.57M
#define NEXT_IS_ADDR  '|'
96
97

98
struct ns32k_option
99
{
100
  char *pattern;    /* The option itself.  */
101
  unsigned long value;    /* Binary value of the option.  */
102
  unsigned long match;    /* These bits must match.  */
103
};
104
105

106
static const struct ns32k_option opt_u[]= /* Restore, exit.  */
107
{
108
  { "r0", 0x80, 0x80  },
109
  { "r1", 0x40, 0x40  },
110
  { "r2", 0x20, 0x20  },
111
  { "r3", 0x10, 0x10  },
112
  { "r4", 0x08, 0x08  },
113
  { "r5", 0x04, 0x04  },
114
  { "r6", 0x02, 0x02  },
115
  { "r7", 0x01, 0x01  },
116
  {  0 ,  0x00, 0x00  }
117
};
118
119
static const struct ns32k_option opt_U[]= /* Save, enter.  */
120
{
121
  { "r0", 0x01, 0x01  },
122
  { "r1", 0x02, 0x02  },
123
  { "r2", 0x04, 0x04  },
124
  { "r3", 0x08, 0x08  },
125
  { "r4", 0x10, 0x10  },
126
  { "r5", 0x20, 0x20  },
127
  { "r6", 0x40, 0x40  },
128
  { "r7", 0x80, 0x80  },
129
  {  0 ,  0x00, 0x00  }
130
};
131
132
static const struct ns32k_option opt_O[]= /* Setcfg.  */
133
{
134
  { "c",  0x8,  0x8 },
135
  { "m",  0x4,  0x4 },
136
  { "f",  0x2,  0x2 },
137
  { "i",  0x1,  0x1 },
138
  {  0 ,  0x0,  0x0 }
139
};
140
141
static const struct ns32k_option opt_C[]= /* Cinv.  */
142
{
143
  { "a",  0x4,  0x4 },
144
  { "i",  0x2,  0x2 },
145
  { "d",  0x1,  0x1 },
146
  {  0 ,  0x0,  0x0 }
147
};
148
149
static const struct ns32k_option opt_S[]= /* String inst.  */
150
{
151
  { "b",  0x1,  0x1 },
152
  { "u",  0x6,  0x6 },
153
  { "w",  0x2,  0x2 },
154
  {  0 ,  0x0,  0x0 }
155
};
156
157
static const struct ns32k_option list_P532[]= /* Lpr spr.  */
158
{
159
  { "us", 0x0,  0xf },
160
  { "dcr",  0x1,  0xf },
161
  { "bpc",  0x2,  0xf },
162
  { "dsr",  0x3,  0xf },
163
  { "car",  0x4,  0xf },
164
  { "fp", 0x8,  0xf },
165
  { "sp", 0x9,  0xf },
166
  { "sb", 0xa,  0xf },
167
  { "usp",  0xb,  0xf },
168
  { "cfg",  0xc,  0xf },
169
  { "psr",  0xd,  0xf },
170
  { "intbase",  0xe,  0xf },
171
  { "mod",  0xf,  0xf },
172
  {  0 ,  0x00, 0xf }
173
};
174
175
static const struct ns32k_option list_M532[]= /* Lmr smr.  */
176
{
177
  { "mcr",  0x9,  0xf },
178
  { "msr",  0xa,  0xf },
179
  { "tear", 0xb,  0xf },
180
  { "ptb0", 0xc,  0xf },
181
  { "ptb1", 0xd,  0xf },
182
  { "ivar0",  0xe,  0xf },
183
  { "ivar1",  0xf,  0xf },
184
  {  0 ,  0x0,  0xf }
185
};
186
187
static const struct ns32k_option list_P032[]= /* Lpr spr.  */
188
{
189
  { "upsr", 0x0,  0xf },
190
  { "fp", 0x8,  0xf },
191
  { "sp", 0x9,  0xf },
192
  { "sb", 0xa,  0xf },
193
  { "psr",  0xb,  0xf },
194
  { "intbase",  0xe,  0xf },
195
  { "mod",  0xf,  0xf },
196
  {  0 ,  0x0,  0xf }
197
};
198
199
static const struct ns32k_option list_M032[]= /* Lmr smr.  */
200
{
201
  { "bpr0", 0x0,  0xf },
202
  { "bpr1", 0x1,  0xf },
203
  { "pf0",  0x4,  0xf },
204
  { "pf1",  0x5,  0xf },
205
  { "sc", 0x8,  0xf },
206
  { "msr",  0xa,  0xf },
207
  { "bcnt", 0xb,  0xf },
208
  { "ptb0", 0xc,  0xf },
209
  { "ptb1", 0xd,  0xf },
210
  { "eia",  0xf,  0xf },
211
  {  0 ,  0x0,  0xf }
212
};
213
214
215
/* Figure out which options are present.   */
216
217
static void
218
optlist (int options, const struct ns32k_option * optionP, char * result)
219
4.87k
{
220
4.87k
  if (options == 0)
221
178
    {
222
178
      sprintf (result, "[]");
223
178
      return;
224
178
    }
225
226
4.69k
  sprintf (result, "[");
227
228
36.6k
  for (; (options != 0) && optionP->pattern; optionP++)
229
31.9k
    {
230
31.9k
      if ((options & optionP->match) == optionP->value)
231
16.4k
  {
232
    /* We found a match, update result and options.  */
233
16.4k
    strcat (result, optionP->pattern);
234
16.4k
    options &= ~optionP->value;
235
16.4k
    if (options != 0)  /* More options to come.  */
236
11.9k
      strcat (result, ",");
237
16.4k
  }
238
31.9k
    }
239
240
4.69k
  if (options != 0)
241
201
    strcat (result, "undefined");
242
243
4.69k
  strcat (result, "]");
244
4.69k
}
245
246
static void
247
list_search (int reg_value, const struct ns32k_option *optionP, char *result)
248
4.10k
{
249
33.7k
  for (; optionP->pattern; optionP++)
250
33.3k
    {
251
33.3k
      if ((reg_value & optionP->match) == optionP->value)
252
3.72k
  {
253
3.72k
    sprintf (result, "%s", optionP->pattern);
254
3.72k
    return;
255
3.72k
  }
256
33.3k
    }
257
379
  sprintf (result, "undefined");
258
379
}
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
763k
{
265
763k
  unsigned int result;
266
763k
  unsigned int bit;
267
268
763k
  if (offset < 0 || count < 0)
269
17.2k
    return 0;
270
745k
  buffer += offset >> 3;
271
745k
  offset &= 7;
272
745k
  bit = 1;
273
745k
  result = 0;
274
5.52M
  while (count--)
275
4.77M
    {
276
4.77M
      FETCH_DATA (dis_info, buffer + 1);
277
4.77M
      if ((*buffer & (1 << offset)))
278
1.72M
  result |= bit;
279
4.77M
      if (++offset == 8)
280
788k
  {
281
788k
    offset = 0;
282
788k
    buffer++;
283
788k
  }
284
4.77M
      bit <<= 1;
285
4.77M
    }
286
745k
  return result;
287
763k
}
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
25.0k
{
294
25.0k
  unsigned int result;
295
25.0k
  unsigned int bit;
296
297
25.0k
  if (offset < 0 || count < 0)
298
0
    return 0;
299
25.0k
  buffer += offset >> 3;
300
25.0k
  offset &= 7;
301
25.0k
  bit = 1;
302
25.0k
  result = 0;
303
393k
  while (count--)
304
368k
    {
305
368k
      if ((*buffer & (1 << offset)))
306
55.3k
  result |= bit;
307
368k
      if (++offset == 8)
308
38.8k
  {
309
38.8k
    offset = 0;
310
38.8k
    buffer++;
311
38.8k
  }
312
368k
      bit <<= 1;
313
368k
    }
314
25.0k
  return result;
315
25.0k
}
316
317
static void
318
bit_copy (bfd_byte *buffer, int offset, int count, char *to)
319
9.02k
{
320
9.02k
  if (offset < 0 || count < 0)
321
0
    return;
322
56.3k
  for (; count > 8; count -= 8, to++, offset += 8)
323
47.2k
    *to = bit_extract (buffer, offset, 8);
324
9.02k
  *to = bit_extract (buffer, offset, count);
325
9.02k
}
326
327
static int
328
sign_extend (unsigned int value, unsigned int bits)
329
96.1k
{
330
96.1k
  unsigned int sign = 1u << (bits - 1);
331
96.1k
  return ((value & (sign + sign - 1)) ^ sign) - sign;
332
96.1k
}
333
334
static void
335
flip_bytes (char *ptr, int count)
336
43.1k
{
337
43.1k
  char tmp;
338
339
123k
  while (count > 0)
340
80.4k
    {
341
80.4k
      tmp = ptr[0];
342
80.4k
      ptr[0] = ptr[count - 1];
343
80.4k
      ptr[count - 1] = tmp;
344
80.4k
      ptr++;
345
80.4k
      count -= 2;
346
80.4k
    }
347
43.1k
}
348

349
/* Given a character C, does it represent a general addressing mode?  */
350
270k
#define Is_gen(c) (strchr ("FLBWDAIZf", (c)) != NULL)
351
352
/* Adressing modes.  */
353
497k
#define Adrmod_index_byte        0x1c
354
490k
#define Adrmod_index_word        0x1d
355
486k
#define Adrmod_index_doubleword  0x1e
356
481k
#define Adrmod_index_quadword    0x1f
357
358
/* Is MODE an indexed addressing mode?  */
359
#define Adrmod_is_index(mode) \
360
248k
  (   mode == Adrmod_index_byte \
361
248k
   || mode == Adrmod_index_word \
362
248k
   || mode == Adrmod_index_doubleword \
363
248k
   || mode == Adrmod_index_quadword)
364
365

366
static int
367
get_displacement (bfd_byte *buffer, int *aoffsetp)
368
86.4k
{
369
86.4k
  int Ivalue;
370
86.4k
  short Ivalue2;
371
372
86.4k
  Ivalue = bit_extract (buffer, *aoffsetp, 8);
373
86.4k
  switch (Ivalue & 0xc0)
374
86.4k
    {
375
30.2k
    case 0x00:
376
53.6k
    case 0x40:
377
53.6k
      Ivalue = sign_extend (Ivalue, 7);
378
53.6k
      *aoffsetp += 8;
379
53.6k
      break;
380
15.3k
    case 0x80:
381
15.3k
      Ivalue2 = bit_extract (buffer, *aoffsetp, 16);
382
15.3k
      flip_bytes ((char *) & Ivalue2, 2);
383
15.3k
      Ivalue = sign_extend (Ivalue2, 14);
384
15.3k
      *aoffsetp += 16;
385
15.3k
      break;
386
17.3k
    case 0xc0:
387
17.3k
      Ivalue = bit_extract (buffer, *aoffsetp, 32);
388
17.3k
      flip_bytes ((char *) & Ivalue, 4);
389
17.3k
      Ivalue = sign_extend (Ivalue, 30);
390
17.3k
      *aoffsetp += 32;
391
17.3k
      break;
392
86.4k
    }
393
86.2k
  return Ivalue;
394
86.4k
}
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.01k
{
400
9.01k
  int val;
401
402
9.01k
  if (len == 4)
403
3.95k
    val = (bit_extract_simple (p, 23, 8)/*exponent*/ == 0xff
404
3.95k
     || (bit_extract_simple (p, 23, 8)/*exponent*/ == 0
405
3.30k
         && bit_extract_simple (p, 0, 23)/*mantisa*/ != 0));
406
5.05k
  else if (len == 8)
407
5.05k
    val = (bit_extract_simple (p, 52, 11)/*exponent*/ == 0x7ff
408
5.05k
     || (bit_extract_simple (p, 52, 11)/*exponent*/ == 0
409
4.93k
         && (bit_extract_simple (p, 0, 32)/*low mantisa*/ != 0
410
3.05k
       || bit_extract_simple (p, 32, 20)/*high mantisa*/ != 0)));
411
0
  else
412
0
    val = 1;
413
9.01k
  return (val);
414
9.01k
}
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
309k
{
461
309k
  union
462
309k
  {
463
309k
    float f;
464
309k
    double d;
465
309k
    int i[2];
466
309k
  } value;
467
309k
  int Ivalue;
468
309k
  int addr_mode;
469
309k
  int disp1, disp2;
470
309k
  int size;
471
472
309k
  switch (d)
473
309k
    {
474
13
    case 'f':
475
      /* A "gen" operand but 5 bits from the end of instruction.  */
476
13
      ioffset -= 5;
477
      /* Fall through.  */
478
592
    case 'Z':
479
6.15k
    case 'F':
480
11.5k
    case 'L':
481
130k
    case 'I':
482
215k
    case 'B':
483
244k
    case 'W':
484
274k
    case 'D':
485
283k
    case 'A':
486
283k
      addr_mode = bit_extract (buffer, ioffset - 5, 5);
487
283k
      ioffset -= 5;
488
283k
      switch (addr_mode)
489
283k
  {
490
134k
  case 0x0: case 0x1: case 0x2: case 0x3:
491
159k
  case 0x4: case 0x5: case 0x6: case 0x7:
492
    /* Register mode R0 -- R7.  */
493
159k
    switch (d)
494
159k
      {
495
491
      case 'F':
496
601
      case 'L':
497
839
      case 'Z':
498
839
        sprintf (result, "f%d", addr_mode);
499
839
        break;
500
158k
      default:
501
158k
        sprintf (result, "r%d", addr_mode);
502
159k
      }
503
159k
    break;
504
159k
  case 0x8: case 0x9: case 0xa: case 0xb:
505
33.5k
  case 0xc: case 0xd: case 0xe: case 0xf:
506
    /* Register relative disp(R0 -- R7).  */
507
33.5k
    disp1 = get_displacement (buffer, aoffsetp);
508
33.5k
    sprintf (result, "%d(r%d)", disp1, addr_mode & 7);
509
33.5k
    break;
510
5.35k
  case 0x10:
511
8.38k
  case 0x11:
512
10.5k
  case 0x12:
513
    /* Memory relative disp2(disp1(FP, SP, SB)).  */
514
10.5k
    disp1 = get_displacement (buffer, aoffsetp);
515
10.5k
    disp2 = get_displacement (buffer, aoffsetp);
516
10.5k
    sprintf (result, "%d(%d(%s))", disp2, disp1,
517
10.5k
       addr_mode == 0x10 ? "fp" : addr_mode == 0x11 ? "sp" : "sb");
518
10.5k
    break;
519
3.10k
  case 0x13:
520
    /* Reserved.  */
521
3.10k
    sprintf (result, "reserved");
522
3.10k
    break;
523
17.4k
  case 0x14:
524
    /* Immediate.  */
525
17.4k
    switch (d)
526
17.4k
      {
527
4.05k
      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
4.05k
        sprintf (result, _("$<undefined>"));
534
4.05k
        break;
535
2.78k
      case 'B':
536
2.78k
        Ivalue = bit_extract (buffer, *aoffsetp, 8);
537
2.78k
        Ivalue = sign_extend (Ivalue, 8);
538
2.78k
        *aoffsetp += 8;
539
2.78k
        sprintf (result, "$%d", Ivalue);
540
2.78k
        break;
541
732
      case 'W':
542
732
        Ivalue = bit_extract (buffer, *aoffsetp, 16);
543
732
        flip_bytes ((char *) & Ivalue, 2);
544
732
        *aoffsetp += 16;
545
732
        Ivalue = sign_extend (Ivalue, 16);
546
732
        sprintf (result, "$%d", Ivalue);
547
732
        break;
548
810
      case 'D':
549
810
        Ivalue = bit_extract (buffer, *aoffsetp, 32);
550
810
        flip_bytes ((char *) & Ivalue, 4);
551
810
        *aoffsetp += 32;
552
810
        sprintf (result, "$%d", Ivalue);
553
810
        break;
554
3.96k
      case 'F':
555
3.96k
        bit_copy (buffer, *aoffsetp, 32, (char *) &value.f);
556
3.96k
        flip_bytes ((char *) &value.f, 4);
557
3.96k
        *aoffsetp += 32;
558
3.96k
        if (INVALID_FLOAT (&value.f, 4))
559
2.27k
    sprintf (result, "<<invalid float 0x%.8x>>", value.i[0]);
560
1.69k
        else /* Assume host has ieee float.  */
561
1.69k
    sprintf (result, "$%g", value.f);
562
3.96k
        break;
563
5.05k
      case 'L':
564
5.05k
        bit_copy (buffer, *aoffsetp, 64, (char *) &value.d);
565
5.05k
        flip_bytes ((char *) &value.d, 8);
566
5.05k
        *aoffsetp += 64;
567
5.05k
        if (INVALID_FLOAT (&value.d, 8))
568
2.65k
    sprintf (result, "<<invalid double 0x%.8x%.8x>>",
569
2.65k
       value.i[1], value.i[0]);
570
2.40k
        else /* Assume host has ieee float.  */
571
2.40k
    sprintf (result, "$%g", value.d);
572
5.05k
        break;
573
17.4k
      }
574
17.3k
    break;
575
17.3k
  case 0x15:
576
    /* Absolute @disp.  */
577
4.62k
    disp1 = get_displacement (buffer, aoffsetp);
578
4.62k
    sprintf (result, "@|%d|", disp1);
579
4.62k
    break;
580
2.18k
  case 0x16:
581
    /* External EXT(disp1) + disp2 (Mod table stuff).  */
582
2.18k
    disp1 = get_displacement (buffer, aoffsetp);
583
2.18k
    disp2 = get_displacement (buffer, aoffsetp);
584
2.18k
    sprintf (result, "EXT(%d) + %d", disp1, disp2);
585
2.18k
    break;
586
4.34k
  case 0x17:
587
    /* Top of stack tos.  */
588
4.34k
    sprintf (result, "tos");
589
4.34k
    break;
590
7.50k
  case 0x18:
591
    /* Memory space disp(FP).  */
592
7.50k
    disp1 = get_displacement (buffer, aoffsetp);
593
7.50k
    sprintf (result, "%d(fp)", disp1);
594
7.50k
    break;
595
2.47k
  case 0x19:
596
    /* Memory space disp(SP).  */
597
2.47k
    disp1 = get_displacement (buffer, aoffsetp);
598
2.47k
    sprintf (result, "%d(sp)", disp1);
599
2.47k
    break;
600
1.52k
  case 0x1a:
601
    /* Memory space disp(SB).  */
602
1.52k
    disp1 = get_displacement (buffer, aoffsetp);
603
1.52k
    sprintf (result, "%d(sb)", disp1);
604
1.52k
    break;
605
1.86k
  case 0x1b:
606
    /* Memory space disp(PC).  */
607
1.86k
    disp1 = get_displacement (buffer, aoffsetp);
608
1.86k
    *result++ = NEXT_IS_ADDR;
609
1.86k
    sprintf (result, "%" PRIx64, (uint64_t) (addr + disp1));
610
1.86k
    result += strlen (result);
611
1.86k
    *result++ = NEXT_IS_ADDR;
612
1.86k
    *result = '\0';
613
1.86k
    break;
614
7.67k
  case 0x1c:
615
13.3k
  case 0x1d:
616
19.3k
  case 0x1e:
617
34.8k
  case 0x1f:
618
34.8k
    {
619
34.8k
      int bit_index;
620
34.8k
      static const char *ind = "bwdq";
621
34.8k
      char *off;
622
623
      /* Scaled index basemode[R0 -- R7:B,W,D,Q].  */
624
34.8k
      bit_index = bit_extract (buffer, index_offset - 8, 3);
625
34.8k
      print_insn_arg (d, index_offset, aoffsetp, buffer, addr,
626
34.8k
          result, 0);
627
34.8k
      off = result + strlen (result);
628
34.8k
      sprintf (off, "[r%d:%c]", bit_index, ind[addr_mode & 3]);
629
34.8k
    }
630
34.8k
    break;
631
283k
  }
632
283k
      break;
633
283k
    case 'H':
634
6.31k
    case 'q':
635
6.31k
      Ivalue = bit_extract (buffer, ioffset-4, 4);
636
6.31k
      Ivalue = sign_extend (Ivalue, 4);
637
6.31k
      sprintf (result, "%d", Ivalue);
638
6.31k
      ioffset -= 4;
639
6.31k
      break;
640
989
    case 'r':
641
989
      Ivalue = bit_extract (buffer, ioffset-3, 3);
642
989
      sprintf (result, "r%d", Ivalue&7);
643
989
      ioffset -= 3;
644
989
      break;
645
2.21k
    case 'd':
646
2.21k
      sprintf (result, "%d", get_displacement (buffer, aoffsetp));
647
2.21k
      break;
648
159
    case 'b':
649
159
      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
159
      size = bit_extract(buffer, ioffset-6, 2);
657
159
      if (size == 0)    /* 00 => b.  */
658
55
  size = 1;
659
104
      else if (size == 1)  /* 01 => w.  */
660
20
  size = 2;
661
84
      else
662
84
  size = 4;   /* 11 => d.  */
663
664
159
      sprintf (result, "%d", (Ivalue / size) + 1);
665
159
      break;
666
7.00k
    case 'p':
667
7.00k
      *result++ = NEXT_IS_ADDR;
668
7.00k
      sprintf (result, "%" PRIx64,
669
7.00k
         (uint64_t) (addr + get_displacement (buffer, aoffsetp)));
670
7.00k
      result += strlen (result);
671
7.00k
      *result++ = NEXT_IS_ADDR;
672
7.00k
      *result = '\0';
673
7.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
1.51k
    case 'u':
680
1.51k
      Ivalue = bit_extract (buffer, *aoffsetp, 8);
681
1.51k
      optlist (Ivalue, opt_u, result);
682
1.51k
      *aoffsetp += 8;
683
1.51k
      break;
684
2.88k
    case 'U':
685
2.88k
      Ivalue = bit_extract (buffer, *aoffsetp, 8);
686
2.88k
      optlist (Ivalue, opt_U, result);
687
2.88k
      *aoffsetp += 8;
688
2.88k
      break;
689
40
    case 'O':
690
40
      Ivalue = bit_extract (buffer, ioffset - 9, 9);
691
40
      optlist (Ivalue, opt_O, result);
692
40
      ioffset -= 9;
693
40
      break;
694
257
    case 'C':
695
257
      Ivalue = bit_extract (buffer, ioffset - 4, 4);
696
257
      optlist (Ivalue, opt_C, result);
697
257
      ioffset -= 4;
698
257
      break;
699
185
    case 'S':
700
185
      Ivalue = bit_extract (buffer, ioffset - 8, 8);
701
185
      optlist (Ivalue, opt_S, result);
702
185
      ioffset -= 8;
703
185
      break;
704
82
    case 'M':
705
82
      Ivalue = bit_extract (buffer, ioffset - 4, 4);
706
82
      list_search (Ivalue, 0 ? list_M032 : list_M532, result);
707
82
      ioffset -= 4;
708
82
      break;
709
4.02k
    case 'P':
710
4.02k
      Ivalue = bit_extract (buffer, ioffset - 4, 4);
711
4.02k
      list_search (Ivalue, 0 ? list_P032 : list_P532, result);
712
4.02k
      ioffset -= 4;
713
4.02k
      break;
714
203
    case 'g':
715
203
      Ivalue = bit_extract (buffer, *aoffsetp, 3);
716
203
      sprintf (result, "%d", Ivalue);
717
203
      *aoffsetp += 3;
718
203
      break;
719
204
    case 'G':
720
204
      Ivalue = bit_extract(buffer, *aoffsetp, 5);
721
204
      sprintf (result, "%d", Ivalue + 1);
722
204
      *aoffsetp += 5;
723
204
      break;
724
309k
    }
725
309k
  return ioffset;
726
309k
}
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
213k
{
735
213k
  unsigned int i;
736
213k
  const char *d;
737
213k
  unsigned short first_word;
738
213k
  int ioffset;    /* Bits into instruction.  */
739
213k
  int aoffset;    /* Bits into arguments.  */
740
213k
  char arg_bufs[MAX_ARGS+1][ARG_LEN];
741
213k
  int argnum;
742
213k
  int maxarg;
743
213k
  struct private priv;
744
213k
  bfd_byte *buffer = priv.the_buffer;
745
213k
  dis_info = info;
746
747
213k
  info->private_data = & priv;
748
213k
  priv.max_fetched = priv.the_buffer;
749
213k
  priv.insn_start = memaddr;
750
213k
  if (OPCODES_SIGSETJMP (priv.bailout) != 0)
751
    /* Error return.  */
752
357
    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
212k
  FETCH_DATA (info, buffer + 1);
757
38.7M
  for (i = 0; i < NOPCODES; i++)
758
38.6M
    if (ns32k_opcodes[i].opcode_id_size <= 8
759
38.6M
  && ((buffer[0]
760
10.8M
       & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
761
10.8M
      == ns32k_opcodes[i].opcode_seed))
762
137k
      break;
763
212k
  if (i == NOPCODES)
764
75.3k
    {
765
      /* Maybe it is 9 to 16 bits big.  */
766
75.3k
      FETCH_DATA (info, buffer + 2);
767
75.3k
      first_word = read_memory_integer(buffer, 2);
768
769
22.9M
      for (i = 0; i < NOPCODES; i++)
770
22.8M
  if ((first_word
771
22.8M
       & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
772
22.8M
      == ns32k_opcodes[i].opcode_seed)
773
12.0k
    break;
774
775
      /* Handle undefined instructions.  */
776
75.3k
      if (i == NOPCODES)
777
63.1k
  {
778
63.1k
    (*dis_info->fprintf_func)(dis_info->stream, "0%o", buffer[0]);
779
63.1k
    return 1;
780
63.1k
  }
781
75.3k
    }
782
783
149k
  (*dis_info->fprintf_func)(dis_info->stream, "%s", ns32k_opcodes[i].name);
784
785
149k
  ioffset = ns32k_opcodes[i].opcode_size;
786
149k
  aoffset = ns32k_opcodes[i].opcode_size;
787
149k
  d = ns32k_opcodes[i].operands;
788
789
149k
  if (*d)
790
142k
    {
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
142k
      int index_offset[2];
794
795
      /* 0 for operand A, 1 for operand B, greater for other args.  */
796
142k
      int whicharg = 0;
797
798
142k
      (*dis_info->fprintf_func)(dis_info->stream, "\t");
799
800
142k
      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
142k
      index_offset[0] = -1;
807
142k
      index_offset[1] = -1;
808
142k
      if (Is_gen (d[1]))
809
131k
  {
810
131k
    int bitoff = d[1] == 'f' ? 10 : 5;
811
131k
    int addr_mode = bit_extract (buffer, ioffset - bitoff, 5);
812
813
131k
    if (Adrmod_is_index (addr_mode))
814
15.7k
      {
815
15.7k
        aoffset += 8;
816
15.7k
        index_offset[0] = aoffset;
817
15.7k
      }
818
131k
  }
819
820
142k
      if (d[2] && Is_gen (d[3]))
821
117k
  {
822
117k
    int addr_mode = bit_extract (buffer, ioffset - 10, 5);
823
824
117k
    if (Adrmod_is_index (addr_mode))
825
10.3k
      {
826
10.3k
        aoffset += 8;
827
10.3k
        index_offset[1] = aoffset;
828
10.3k
      }
829
117k
  }
830
831
417k
      while (*d)
832
274k
  {
833
274k
    argnum = *d - '1';
834
274k
    if (argnum >= MAX_ARGS)
835
0
      abort ();
836
274k
    d++;
837
274k
    if (argnum > maxarg)
838
131k
      maxarg = argnum;
839
274k
    ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
840
274k
            memaddr, arg_bufs[argnum],
841
274k
            whicharg > 1 ? -1 : index_offset[whicharg]);
842
274k
    d++;
843
274k
    whicharg++;
844
274k
  }
845
846
417k
      for (argnum = 0; argnum <= maxarg; argnum++)
847
274k
  {
848
274k
    bfd_vma addr;
849
274k
    char *ch;
850
851
1.74M
    for (ch = arg_bufs[argnum]; *ch;)
852
1.47M
      {
853
1.47M
        if (*ch == NEXT_IS_ADDR)
854
13.4k
    {
855
13.4k
      ++ch;
856
13.4k
      addr = bfd_scan_vma (ch, NULL, 16);
857
13.4k
      (*dis_info->print_address_func) (addr, dis_info);
858
88.7k
      while (*ch && *ch != NEXT_IS_ADDR)
859
75.2k
        ++ch;
860
13.4k
      if (*ch)
861
13.4k
        ++ch;
862
13.4k
    }
863
1.45M
        else
864
1.45M
    (*dis_info->fprintf_func)(dis_info->stream, "%c", *ch++);
865
1.47M
      }
866
274k
    if (argnum < maxarg)
867
131k
      (*dis_info->fprintf_func)(dis_info->stream, ", ");
868
274k
  }
869
142k
    }
870
149k
  return aoffset / 8;
871
149k
}