OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [gdb-5.0/] [opcodes/] [ns32k-dis.c] - Blame information for rev 1778

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 106 markom
/* Print National Semiconductor 32000 instructions.
2
   Copyright (c) 1986, 88, 91, 92, 94, 95, 1998 Free Software Foundation, Inc.
3
 
4
This file is part of opcodes library.
5
 
6
This program 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 2 of the License, or
9
(at your option) any later version.
10
 
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
 
20
 
21
#include "bfd.h"
22
#include "sysdep.h"
23
#include "dis-asm.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
/*
33
 * Hacks to get it to compile <= READ THESE AS FIXES NEEDED
34
 */
35
#define INVALID_FLOAT(val, size) invalid_float((char *)val, size)
36
 
37
static int print_insn_arg
38
  PARAMS ((int, int, int *, char *, bfd_vma, char *, int));
39
static int get_displacement PARAMS ((char *, int *));
40
static int invalid_float PARAMS ((char *, int));
41
 
42
static long read_memory_integer(addr, nr)
43
     unsigned char *addr;
44
     int nr;
45
{
46
  long val;
47
  int i;
48
  for (val = 0, i = nr - 1; i >= 0; i--) {
49
    val =  (val << 8);
50
    val |= (0xff & *(addr + i));
51
  }
52
  return val;
53
}
54
 
55
/* 32000 instructions are never longer than this.  */
56
#define MAXLEN 62
57
 
58
 
59
#include <setjmp.h>
60
 
61
struct private
62
{
63
  /* Points to first byte not fetched.  */
64
  bfd_byte *max_fetched;
65
  bfd_byte the_buffer[MAXLEN];
66
  bfd_vma insn_start;
67
  jmp_buf bailout;
68
};
69
 
70
 
71
/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
72
   to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
73
   on error.  */
74
#define FETCH_DATA(info, addr) \
75
  ((addr) <= ((struct private *)(info->private_data))->max_fetched \
76
   ? 1 : fetch_data ((info), (addr)))
77
 
78
static int
79
fetch_data (info, addr)
80
     struct disassemble_info *info;
81
     bfd_byte *addr;
82
{
83
  int status;
84
  struct private *priv = (struct private *)info->private_data;
85
  bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
86
 
87
  status = (*info->read_memory_func) (start,
88
                                      priv->max_fetched,
89
                                      addr - priv->max_fetched,
90
                                      info);
91
  if (status != 0)
92
    {
93
      (*info->memory_error_func) (status, start, info);
94
      longjmp (priv->bailout, 1);
95
    }
96
  else
97
    priv->max_fetched = addr;
98
  return 1;
99
}
100
/* Number of elements in the opcode table.  */
101
#define NOPCODES (sizeof ns32k_opcodes / sizeof ns32k_opcodes[0])
102
 
103
#define NEXT_IS_ADDR    '|'
104
 
105
 
106
struct ns32k_option {
107
  char *pattern;                /* the option itself */
108
  unsigned long value;          /* binary value of the option */
109
  unsigned long match;          /* these bits must match */
110
};
111
 
112
 
113
static const struct ns32k_option opt_u[]= /* restore, exit */
114
{
115
  { "r0",       0x80,   0x80    },
116
  { "r1",       0x40,   0x40    },
117
  { "r2",       0x20,   0x20    },
118
  { "r3",       0x10,   0x10    },
119
  { "r4",       0x08,   0x08    },
120
  { "r5",       0x04,   0x04    },
121
  { "r6",       0x02,   0x02    },
122
  { "r7",       0x01,   0x01    },
123
  {  0 , 0x00,   0x00    }
124
};
125
 
126
static const struct ns32k_option opt_U[]= /* save, enter */
127
{
128
  { "r0",       0x01,   0x01    },
129
  { "r1",       0x02,   0x02    },
130
  { "r2",       0x04,   0x04    },
131
  { "r3",       0x08,   0x08    },
132
  { "r4",       0x10,   0x10    },
133
  { "r5",       0x20,   0x20    },
134
  { "r6",       0x40,   0x40    },
135
  { "r7",       0x80,   0x80    },
136
  {  0 , 0x00,   0x00    }
137
};
138
 
139
static const struct ns32k_option opt_O[]= /* setcfg */
140
{
141
  { "c",        0x8,    0x8     },
142
  { "m",        0x4,    0x4     },
143
  { "f",        0x2,    0x2     },
144
  { "i",        0x1,    0x1     },
145
  {  0 , 0x0,    0x0     }
146
};
147
 
148
static const struct ns32k_option opt_C[]= /* cinv */
149
{
150
  { "a",        0x4,    0x4     },
151
  { "i",        0x2,    0x2     },
152
  { "d",        0x1,    0x1     },
153
  {  0 , 0x0,    0x0     }
154
};
155
 
156
static const struct ns32k_option opt_S[]= /* string inst */
157
{
158
  { "b",        0x1,    0x1     },
159
  { "u",        0x6,    0x6     },
160
  { "w",        0x2,    0x2     },
161
  {  0 , 0x0,    0x0     }
162
};
163
 
164
static const struct ns32k_option list_P532[]= /* lpr spr */
165
{
166
  { "us",       0x0,    0xf     },
167
  { "dcr",      0x1,    0xf     },
168
  { "bpc",      0x2,    0xf     },
169
  { "dsr",      0x3,    0xf     },
170
  { "car",      0x4,    0xf     },
171
  { "fp",       0x8,    0xf     },
172
  { "sp",       0x9,    0xf     },
173
  { "sb",       0xa,    0xf     },
174
  { "usp",      0xb,    0xf     },
175
  { "cfg",      0xc,    0xf     },
176
  { "psr",      0xd,    0xf     },
177
  { "intbase",  0xe,    0xf     },
178
  { "mod",      0xf,    0xf     },
179
  {  0 , 0x00,   0xf     }
180
};
181
 
182
static const struct ns32k_option list_M532[]= /* lmr smr */
183
{
184
  { "mcr",      0x9,    0xf     },
185
  { "msr",      0xa,    0xf     },
186
  { "tear",     0xb,    0xf     },
187
  { "ptb0",     0xc,    0xf     },
188
  { "ptb1",     0xd,    0xf     },
189
  { "ivar0",    0xe,    0xf     },
190
  { "ivar1",    0xf,    0xf     },
191
  {  0 , 0x0,    0xf     }
192
};
193
 
194
static const struct ns32k_option list_P032[]= /* lpr spr */
195
{
196
  { "upsr",     0x0,    0xf     },
197
  { "fp",       0x8,    0xf     },
198
  { "sp",       0x9,    0xf     },
199
  { "sb",       0xa,    0xf     },
200
  { "psr",      0xb,    0xf     },
201
  { "intbase",  0xe,    0xf     },
202
  { "mod",      0xf,    0xf     },
203
  {  0 , 0x0,    0xf     }
204
};
205
 
206
static const struct ns32k_option list_M032[]= /* lmr smr */
207
{
208
  { "bpr0",     0x0,    0xf     },
209
  { "bpr1",     0x1,    0xf     },
210
  { "pf0",      0x4,    0xf     },
211
  { "pf1",      0x5,    0xf     },
212
  { "sc",       0x8,    0xf     },
213
  { "msr",      0xa,    0xf     },
214
  { "bcnt",     0xb,    0xf     },
215
  { "ptb0",     0xc,    0xf     },
216
  { "ptb1",     0xd,    0xf     },
217
  { "eia",      0xf,    0xf     },
218
  {  0 , 0x0,    0xf     }
219
};
220
 
221
 
222
/*
223
 * figure out which options are present
224
 */
225
static void
226
optlist(options, optionP, result)
227
     int options;
228
     const struct ns32k_option *optionP;
229
     char *result;
230
{
231
    if (options == 0) {
232
        sprintf(result, "[]");
233
        return;
234
    }
235
    sprintf(result, "[");
236
 
237
    for (; (options != 0) && optionP->pattern; optionP++) {
238
        if ((options & optionP->match) == optionP->value) {
239
            /* we found a match, update result and options */
240
            strcat(result, optionP->pattern);
241
            options &= ~optionP->value;
242
            if (options != 0)    /* more options to come */
243
                strcat(result, ",");
244
        }
245
    }
246
    if (options != 0)
247
        strcat(result, "undefined");
248
 
249
    strcat(result, "]");
250
}
251
 
252
static void
253
list_search (reg_value, optionP, result)
254
     int reg_value;
255
     const struct ns32k_option *optionP;
256
     char *result;
257
{
258
    for (; optionP->pattern; optionP++) {
259
        if ((reg_value & optionP->match) == optionP->value) {
260
            sprintf(result, "%s", optionP->pattern);
261
            return;
262
        }
263
    }
264
    sprintf(result, "undefined");
265
}
266
 
267
/*
268
 * extract "count" bits starting "offset" bits
269
 * into buffer
270
 */
271
 
272
static int
273
bit_extract (buffer, offset, count)
274
     bfd_byte *buffer;
275
     int offset;
276
     int count;
277
{
278
  int result;
279
  int bit;
280
 
281
  buffer += offset >> 3;
282
  offset &= 7;
283
  bit = 1;
284
  result = 0;
285
  while (count--)
286
    {
287
      FETCH_DATA(dis_info, buffer + 1);
288
      if ((*buffer & (1 << offset)))
289
        result |= bit;
290
      if (++offset == 8)
291
        {
292
          offset = 0;
293
          buffer++;
294
        }
295
      bit <<= 1;
296
    }
297
  return result;
298
}
299
 
300
/* Like bit extract but the buffer is valid and doen't need to be
301
 * fetched
302
 */
303
static int
304
bit_extract_simple (buffer, offset, count)
305
     bfd_byte *buffer;
306
     int offset;
307
     int count;
308
{
309
  int result;
310
  int mask;
311
  int bit;
312
 
313
  buffer += offset >> 3;
314
  offset &= 7;
315
  bit = 1;
316
  result = 0;
317
  while (count--)
318
    {
319
      if ((*buffer & (1 << offset)))
320
        result |= bit;
321
      if (++offset == 8)
322
        {
323
          offset = 0;
324
          buffer++;
325
        }
326
      bit <<= 1;
327
    }
328
  return result;
329
}
330
 
331
static void
332
bit_copy (buffer, offset, count, to)
333
     char *buffer;
334
     int offset;
335
     int count;
336
     char *to;
337
{
338
  for(; count > 8; count -= 8, to++, offset += 8)
339
    *to = bit_extract (buffer, offset, 8);
340
  *to = bit_extract (buffer, offset, count);
341
}
342
 
343
 
344
static int
345
sign_extend (value, bits)
346
     int value, bits;
347
{
348
  value = value & ((1 << bits) - 1);
349
  return (value & (1 << (bits-1))
350
          ? value | (~((1 << bits) - 1))
351
          : value);
352
}
353
 
354
static void
355
flip_bytes (ptr, count)
356
     char *ptr;
357
     int count;
358
{
359
  char tmp;
360
 
361
  while (count > 0)
362
    {
363
      tmp = ptr[0];
364
      ptr[0] = ptr[count-1];
365
      ptr[count-1] = tmp;
366
      ptr++;
367
      count -= 2;
368
    }
369
}
370
 
371
/* Given a character C, does it represent a general addressing mode?  */
372
#define Is_gen(c) \
373
  ((c) == 'F' || (c) == 'L' || (c) == 'B' \
374
   || (c) == 'W' || (c) == 'D' || (c) == 'A' || (c) == 'I' || (c) == 'Z')
375
 
376
/* Adressing modes.  */
377
#define Adrmod_index_byte 0x1c
378
#define Adrmod_index_word 0x1d
379
#define Adrmod_index_doubleword 0x1e
380
#define Adrmod_index_quadword 0x1f
381
 
382
/* Is MODE an indexed addressing mode?  */
383
#define Adrmod_is_index(mode) \
384
  (mode == Adrmod_index_byte \
385
   || mode == Adrmod_index_word \
386
   || mode == Adrmod_index_doubleword \
387
   || mode == Adrmod_index_quadword)
388
 
389
 
390
/* Print the 32000 instruction at address MEMADDR in debugged memory,
391
   on STREAM.  Returns length of the instruction, in bytes.  */
392
 
393
int
394
print_insn_ns32k (memaddr, info)
395
     bfd_vma memaddr;
396
     disassemble_info *info;
397
{
398
  register unsigned int i;
399
  register char *d;
400
  unsigned short first_word;
401
  int ioffset;          /* bits into instruction */
402
  int aoffset;          /* bits into arguments */
403
  char arg_bufs[MAX_ARGS+1][ARG_LEN];
404
  int argnum;
405
  int maxarg;
406
  struct private priv;
407
  bfd_byte *buffer = priv.the_buffer;
408
  dis_info = info;
409
 
410
  info->private_data = (PTR) &priv;
411
  priv.max_fetched = priv.the_buffer;
412
  priv.insn_start = memaddr;
413
  if (setjmp (priv.bailout) != 0)
414
    /* Error return.  */
415
    return -1;
416
 
417
  /* Look for 8bit opcodes first. Other wise, fetching two bytes could take
418
   * us over the end of accessible data unnecessarilly
419
   */
420
  FETCH_DATA(info, buffer + 1);
421
  for (i = 0; i < NOPCODES; i++)
422
    if (ns32k_opcodes[i].opcode_id_size <= 8
423
        && ((buffer[0]
424
             & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
425
            == ns32k_opcodes[i].opcode_seed))
426
      break;
427
  if (i == NOPCODES) {
428
    /* Maybe it is 9 to 16 bits big */
429
    FETCH_DATA(info, buffer + 2);
430
    first_word = read_memory_integer(buffer, 2);
431
 
432
    for (i = 0; i < NOPCODES; i++)
433
      if ((first_word
434
           & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
435
          == ns32k_opcodes[i].opcode_seed)
436
        break;
437
 
438
    /* Handle undefined instructions.  */
439
    if (i == NOPCODES)
440
      {
441
        (*dis_info->fprintf_func)(dis_info->stream, "0%o", buffer[0]);
442
        return 1;
443
      }
444
  }
445
 
446
  (*dis_info->fprintf_func)(dis_info->stream, "%s", ns32k_opcodes[i].name);
447
 
448
  ioffset = ns32k_opcodes[i].opcode_size;
449
  aoffset = ns32k_opcodes[i].opcode_size;
450
  d = ns32k_opcodes[i].operands;
451
 
452
  if (*d)
453
    {
454
      /* Offset in bits of the first thing beyond each index byte.
455
         Element 0 is for operand A and element 1 is for operand B.
456
         The rest are irrelevant, but we put them here so we don't
457
         index outside the array.  */
458
      int index_offset[MAX_ARGS];
459
 
460
      /* 0 for operand A, 1 for operand B, greater for other args.  */
461
      int whicharg = 0;
462
 
463
      (*dis_info->fprintf_func)(dis_info->stream, "\t");
464
 
465
      maxarg = 0;
466
 
467
      /* First we have to find and keep track of the index bytes,
468
         if we are using scaled indexed addressing mode, since the index
469
         bytes occur right after the basic instruction, not as part
470
         of the addressing extension.  */
471
      if (Is_gen(d[1]))
472
        {
473
          int addr_mode = bit_extract (buffer, ioffset - 5, 5);
474
 
475
          if (Adrmod_is_index (addr_mode))
476
            {
477
              aoffset += 8;
478
              index_offset[0] = aoffset;
479
            }
480
        }
481
      if (d[2] && Is_gen(d[3]))
482
        {
483
          int addr_mode = bit_extract (buffer, ioffset - 10, 5);
484
 
485
          if (Adrmod_is_index (addr_mode))
486
            {
487
              aoffset += 8;
488
              index_offset[1] = aoffset;
489
            }
490
        }
491
 
492
      while (*d)
493
        {
494
          argnum = *d - '1';
495
          d++;
496
          if (argnum > maxarg && argnum < MAX_ARGS)
497
            maxarg = argnum;
498
          ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
499
                                    memaddr, arg_bufs[argnum],
500
                                    index_offset[whicharg]);
501
          d++;
502
          whicharg++;
503
        }
504
      for (argnum = 0; argnum <= maxarg; argnum++)
505
        {
506
          bfd_vma addr;
507
          char *ch;
508
          for (ch = arg_bufs[argnum]; *ch;)
509
            {
510
              if (*ch == NEXT_IS_ADDR)
511
                {
512
                  ++ch;
513
                  addr = bfd_scan_vma (ch, NULL, 16);
514
                  (*dis_info->print_address_func) (addr, dis_info);
515
                  while (*ch && *ch != NEXT_IS_ADDR)
516
                    ++ch;
517
                  if (*ch)
518
                    ++ch;
519
                }
520
              else
521
                (*dis_info->fprintf_func)(dis_info->stream, "%c", *ch++);
522
            }
523
          if (argnum < maxarg)
524
            (*dis_info->fprintf_func)(dis_info->stream, ", ");
525
        }
526
    }
527
  return aoffset / 8;
528
}
529
 
530
/* Print an instruction operand of category given by d.  IOFFSET is
531
   the bit position below which small (<1 byte) parts of the operand can
532
   be found (usually in the basic instruction, but for indexed
533
   addressing it can be in the index byte).  AOFFSETP is a pointer to the
534
   bit position of the addressing extension.  BUFFER contains the
535
   instruction.  ADDR is where BUFFER was read from.  Put the disassembled
536
   version of the operand in RESULT.  INDEX_OFFSET is the bit position
537
   of the index byte (it contains garbage if this operand is not a
538
   general operand using scaled indexed addressing mode).  */
539
 
540
static int
541
print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset)
542
     int d;
543
     int ioffset, *aoffsetp;
544
     char *buffer;
545
     bfd_vma addr;
546
     char *result;
547
     int index_offset;
548
{
549
  int addr_mode;
550
  float Fvalue;
551
  double Lvalue;
552
  int Ivalue;
553
  int disp1, disp2;
554
  int index;
555
  int size;
556
 
557
  switch (d)
558
    {
559
    case 'f':
560
      /* a "gen" operand but 5 bits from the end of instruction */
561
      ioffset -= 5;
562
    case 'Z':
563
    case 'F':
564
    case 'L':
565
    case 'I':
566
    case 'B':
567
    case 'W':
568
    case 'D':
569
    case 'A':
570
      addr_mode = bit_extract (buffer, ioffset-5, 5);
571
      ioffset -= 5;
572
      switch (addr_mode)
573
        {
574
        case 0x0: case 0x1: case 0x2: case 0x3:
575
        case 0x4: case 0x5: case 0x6: case 0x7:
576
          /* register mode R0 -- R7 */
577
          switch (d)
578
            {
579
            case 'F':
580
            case 'L':
581
            case 'Z':
582
              sprintf (result, "f%d", addr_mode);
583
              break;
584
            default:
585
              sprintf (result, "r%d", addr_mode);
586
            }
587
          break;
588
        case 0x8: case 0x9: case 0xa: case 0xb:
589
        case 0xc: case 0xd: case 0xe: case 0xf:
590
          /* Register relative disp(R0 -- R7) */
591
          disp1 = get_displacement (buffer, aoffsetp);
592
          sprintf (result, "%d(r%d)", disp1, addr_mode & 7);
593
          break;
594
        case 0x10:
595
        case 0x11:
596
        case 0x12:
597
          /* Memory relative disp2(disp1(FP, SP, SB)) */
598
          disp1 = get_displacement (buffer, aoffsetp);
599
          disp2 = get_displacement (buffer, aoffsetp);
600
          sprintf (result, "%d(%d(%s))", disp2, disp1,
601
                   addr_mode==0x10?"fp":addr_mode==0x11?"sp":"sb");
602
          break;
603
        case 0x13:
604
          /* reserved */
605
          sprintf (result, "reserved");
606
          break;
607
        case 0x14:
608
          /* Immediate */
609
          switch (d)
610
            {
611
            case 'I': case 'Z': case 'A':
612
              /* I and Z are output operands and can`t be immediate
613
               * A is an address and we can`t have the address of
614
               * an immediate either. We don't know how much to increase
615
               * aoffsetp by since whatever generated this is broken
616
               * anyway!
617
               */
618
              sprintf (result, _("$<undefined>"));
619
              break;
620
            case 'B':
621
              Ivalue = bit_extract (buffer, *aoffsetp, 8);
622
              Ivalue = sign_extend (Ivalue, 8);
623
              *aoffsetp += 8;
624
              sprintf (result, "$%d", Ivalue);
625
              break;
626
            case 'W':
627
              Ivalue = bit_extract (buffer, *aoffsetp, 16);
628
              flip_bytes (&Ivalue, 2);
629
              *aoffsetp += 16;
630
              Ivalue = sign_extend (Ivalue, 16);
631
              sprintf (result, "$%d", Ivalue);
632
              break;
633
            case 'D':
634
              Ivalue = bit_extract (buffer, *aoffsetp, 32);
635
              flip_bytes (&Ivalue, 4);
636
              *aoffsetp += 32;
637
              sprintf (result, "$%d", Ivalue);
638
              break;
639
            case 'F':
640
              bit_copy (buffer, *aoffsetp, 32, (char *) &Fvalue);
641
              flip_bytes (&Fvalue, 4);
642
              *aoffsetp += 32;
643
              if (INVALID_FLOAT (&Fvalue, 4))
644
                sprintf (result, "<<invalid float 0x%.8x>>", *(int *) &Fvalue);
645
              else /* assume host has ieee float */
646
                sprintf (result, "$%g", Fvalue);
647
              break;
648
            case 'L':
649
              bit_copy (buffer, *aoffsetp, 64, (char *) &Lvalue);
650
              flip_bytes (&Lvalue, 8);
651
              *aoffsetp += 64;
652
              if (INVALID_FLOAT (&Lvalue, 8))
653
                sprintf (result, "<<invalid long 0x%.8x%.8x>>",
654
                         *(((int *) &Lvalue) + 1), *(int *) &Lvalue);
655
              else /* assume host has ieee float */
656
                sprintf (result, "$%g", Lvalue);
657
              break;
658
            }
659
          break;
660
        case 0x15:
661
          /* Absolute @disp */
662
          disp1 = get_displacement (buffer, aoffsetp);
663
          sprintf (result, "@|%d|", disp1);
664
          break;
665
        case 0x16:
666
          /* External EXT(disp1) + disp2 (Mod table stuff) */
667
          disp1 = get_displacement (buffer, aoffsetp);
668
          disp2 = get_displacement (buffer, aoffsetp);
669
          sprintf (result, "EXT(%d) + %d", disp1, disp2);
670
          break;
671
        case 0x17:
672
          /* Top of stack tos */
673
          sprintf (result, "tos");
674
          break;
675
        case 0x18:
676
          /* Memory space disp(FP) */
677
          disp1 = get_displacement (buffer, aoffsetp);
678
          sprintf (result, "%d(fp)", disp1);
679
          break;
680
        case 0x19:
681
          /* Memory space disp(SP) */
682
          disp1 = get_displacement (buffer, aoffsetp);
683
          sprintf (result, "%d(sp)", disp1);
684
          break;
685
        case 0x1a:
686
          /* Memory space disp(SB) */
687
          disp1 = get_displacement (buffer, aoffsetp);
688
          sprintf (result, "%d(sb)", disp1);
689
          break;
690
        case 0x1b:
691
          /* Memory space disp(PC) */
692
          disp1 = get_displacement (buffer, aoffsetp);
693
          *result++ = NEXT_IS_ADDR;
694
          sprintf_vma (result, addr + disp1);
695
          result += strlen (result);
696
          *result++ = NEXT_IS_ADDR;
697
          *result = '\0';
698
          break;
699
        case 0x1c:
700
        case 0x1d:
701
        case 0x1e:
702
        case 0x1f:
703
          /* Scaled index basemode[R0 -- R7:B,W,D,Q] */
704
          index = bit_extract (buffer, index_offset - 8, 3);
705
          print_insn_arg (d, index_offset, aoffsetp, buffer, addr,
706
                          result, 0);
707
          {
708
            static const char *ind = "bwdq";
709
            char *off;
710
 
711
            off = result + strlen (result);
712
            sprintf (off, "[r%d:%c]", index,
713
                     ind[addr_mode & 3]);
714
          }
715
          break;
716
        }
717
      break;
718
    case 'H':
719
    case 'q':
720
      Ivalue = bit_extract (buffer, ioffset-4, 4);
721
      Ivalue = sign_extend (Ivalue, 4);
722
      sprintf (result, "%d", Ivalue);
723
      ioffset -= 4;
724
      break;
725
    case 'r':
726
      Ivalue = bit_extract (buffer, ioffset-3, 3);
727
      sprintf (result, "r%d", Ivalue&7);
728
      ioffset -= 3;
729
      break;
730
    case 'd':
731
      sprintf (result, "%d", get_displacement (buffer, aoffsetp));
732
      break;
733
    case 'b':
734
      Ivalue = get_displacement (buffer, aoffsetp);
735
      /*
736
       * Warning!!  HACK ALERT!
737
       * Operand type 'b' is only used by the cmp{b,w,d} and
738
       * movm{b,w,d} instructions; we need to know whether
739
       * it's a `b' or `w' or `d' instruction; and for both
740
       * cmpm and movm it's stored at the same place so we
741
       * just grab two bits of the opcode and look at it...
742
       *
743
       */
744
      size = bit_extract(buffer, ioffset-6, 2);
745
      if (size == 0)             /* 00 => b */
746
        size = 1;
747
      else if (size == 1)       /* 01 => w */
748
        size = 2;
749
      else
750
        size = 4;               /* 11 => d */
751
 
752
      sprintf (result, "%d", (Ivalue / size) + 1);
753
      break;
754
    case 'p':
755
      *result++ = NEXT_IS_ADDR;
756
      sprintf_vma (result, addr + get_displacement (buffer, aoffsetp));
757
      result += strlen (result);
758
      *result++ = NEXT_IS_ADDR;
759
      *result = '\0';
760
      break;
761
    case 'i':
762
      Ivalue = bit_extract (buffer, *aoffsetp, 8);
763
      *aoffsetp += 8;
764
      sprintf (result, "0x%x", Ivalue);
765
      break;
766
    case 'u':
767
      Ivalue = bit_extract (buffer, *aoffsetp, 8);
768
      optlist(Ivalue, opt_u, result);
769
      *aoffsetp += 8;
770
      break;
771
    case 'U':
772
      Ivalue = bit_extract(buffer, *aoffsetp, 8);
773
      optlist(Ivalue, opt_U, result);
774
      *aoffsetp += 8;
775
      break;
776
    case 'O':
777
      Ivalue = bit_extract(buffer, ioffset-9, 9);
778
      optlist(Ivalue, opt_O, result);
779
      ioffset -= 9;
780
      break;
781
    case 'C':
782
      Ivalue = bit_extract(buffer, ioffset-4, 4);
783
      optlist(Ivalue, opt_C, result);
784
      ioffset -= 4;
785
      break;
786
    case 'S':
787
      Ivalue = bit_extract(buffer, ioffset - 8, 8);
788
      optlist(Ivalue, opt_S, result);
789
      ioffset -= 8;
790
      break;
791
    case 'M':
792
      Ivalue = bit_extract(buffer, ioffset-4, 4);
793
      list_search(Ivalue, 0 ? list_M032 : list_M532, result);
794
      ioffset -= 4;
795
      break;
796
    case 'P':
797
      Ivalue = bit_extract(buffer, ioffset-4, 4);
798
      list_search(Ivalue, 0 ? list_P032 : list_P532, result);
799
      ioffset -= 4;
800
      break;
801
    case 'g':
802
      Ivalue = bit_extract(buffer, *aoffsetp, 3);
803
      sprintf(result, "%d", Ivalue);
804
      *aoffsetp += 3;
805
      break;
806
    case 'G':
807
      Ivalue = bit_extract(buffer, *aoffsetp, 5);
808
      sprintf(result, "%d", Ivalue + 1);
809
      *aoffsetp += 5;
810
      break;
811
    }
812
  return ioffset;
813
}
814
 
815
static int
816
get_displacement (buffer, aoffsetp)
817
     char *buffer;
818
     int *aoffsetp;
819
{
820
  int Ivalue;
821
  short Ivalue2;
822
 
823
  Ivalue = bit_extract (buffer, *aoffsetp, 8);
824
  switch (Ivalue & 0xc0)
825
    {
826
    case 0x00:
827
    case 0x40:
828
      Ivalue = sign_extend (Ivalue, 7);
829
      *aoffsetp += 8;
830
      break;
831
    case 0x80:
832
      Ivalue2 = bit_extract (buffer, *aoffsetp, 16);
833
      flip_bytes (&Ivalue2, 2);
834
      Ivalue = sign_extend (Ivalue2, 14);
835
      *aoffsetp += 16;
836
      break;
837
    case 0xc0:
838
      Ivalue = bit_extract (buffer, *aoffsetp, 32);
839
      flip_bytes (&Ivalue, 4);
840
      Ivalue = sign_extend (Ivalue, 30);
841
      *aoffsetp += 32;
842
      break;
843
    }
844
  return Ivalue;
845
}
846
 
847
 
848
#if 1 /* a version that should work on ns32k f's&d's on any machine */
849
static int
850
invalid_float (p, len)
851
     register char *p;
852
     register int len;
853
{
854
  register int val;
855
 
856
  if ( len == 4 )
857
    val = (bit_extract_simple(p, 23, 8)/*exponent*/ == 0xff
858
           || (bit_extract_simple(p, 23, 8)/*exponent*/ == 0 &&
859
               bit_extract_simple(p, 0, 23)/*mantisa*/ != 0));
860
  else if ( len == 8 )
861
    val = (bit_extract_simple(p, 52, 11)/*exponent*/ == 0x7ff
862
           || (bit_extract_simple(p, 52, 11)/*exponent*/ == 0
863
               && (bit_extract_simple(p, 0, 32)/*low mantisa*/ != 0
864
                   || bit_extract_simple(p, 32, 20)/*high mantisa*/ != 0)));
865
  else
866
    val = 1;
867
  return (val);
868
}
869
#else
870
 
871
/* assumes the bytes have been swapped to local order */
872
typedef union { double d;
873
                float f;
874
                struct { unsigned m:23, e:8, :1;} sf;
875
                struct { unsigned lm; unsigned m:20, e:11, :1;} sd;
876
              } float_type_u;
877
 
878
static int
879
invalid_float (p, len)
880
     register float_type_u *p;
881
     register int len;
882
{
883
  register int val;
884
  if ( len == sizeof (float) )
885
    val = (p->sf.e == 0xff
886
           || (p->sf.e == 0 && p->sf.m != 0));
887
  else if ( len == sizeof (double) )
888
    val = (p->sd.e == 0x7ff
889
           || (p->sd.e == 0 && (p->sd.m != 0 || p->sd.lm != 0)));
890
  else
891
    val = 1;
892
  return (val);
893
}
894
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.