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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [opcodes/] [ns32k-dis.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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