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