source: vendor/binutils/current/opcodes/ns32k-dis.c

Last change on this file was 609, checked in by bird, 22 years ago

binutils v2.14 - offical sources.

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