00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "bfd.h"
00027 #include "sysdep.h"
00028 #include "dis-asm.h"
00029 #if !defined(const) && !defined(__STDC__)
00030 #define const
00031 #endif
00032 #include "opcode/ns32k.h"
00033 #include "opintl.h"
00034
00035 static disassemble_info *dis_info;
00036
00037
00038
00039
00040 #define INVALID_FLOAT(val, size) invalid_float((bfd_byte *)val, size)
00041
00042 static int print_insn_arg
00043 PARAMS ((int, int, int *, bfd_byte *, bfd_vma, char *, int));
00044 static int get_displacement PARAMS ((bfd_byte *, int *));
00045 static int invalid_float PARAMS ((bfd_byte *, int));
00046 static long int read_memory_integer PARAMS ((unsigned char *, int));
00047 static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
00048 struct ns32k_option;
00049 static void optlist PARAMS ((int, const struct ns32k_option *, char *));
00050 static void list_search PARAMS ((int, const struct ns32k_option *, char *));
00051 static int bit_extract PARAMS ((bfd_byte *, int, int));
00052 static int bit_extract_simple PARAMS ((bfd_byte *, int, int));
00053 static void bit_copy PARAMS ((bfd_byte *, int, int, char *));
00054 static int sign_extend PARAMS ((int, int));
00055 static void flip_bytes PARAMS ((char *, int));
00056
00057 static long read_memory_integer(addr, nr)
00058 unsigned char *addr;
00059 int nr;
00060 {
00061 long val;
00062 int i;
00063 for (val = 0, i = nr - 1; i >= 0; i--) {
00064 val = (val << 8);
00065 val |= (0xff & *(addr + i));
00066 }
00067 return val;
00068 }
00069
00070
00071 #define MAXLEN 62
00072
00073
00074 #include <setjmp.h>
00075
00076 struct private
00077 {
00078
00079 bfd_byte *max_fetched;
00080 bfd_byte the_buffer[MAXLEN];
00081 bfd_vma insn_start;
00082 jmp_buf bailout;
00083 };
00084
00085
00086
00087
00088
00089 #define FETCH_DATA(info, addr) \
00090 ((addr) <= ((struct private *)(info->private_data))->max_fetched \
00091 ? 1 : fetch_data ((info), (addr)))
00092
00093 static int
00094 fetch_data (info, addr)
00095 struct disassemble_info *info;
00096 bfd_byte *addr;
00097 {
00098 int status;
00099 struct private *priv = (struct private *)info->private_data;
00100 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
00101
00102 status = (*info->read_memory_func) (start,
00103 priv->max_fetched,
00104 addr - priv->max_fetched,
00105 info);
00106 if (status != 0)
00107 {
00108 (*info->memory_error_func) (status, start, info);
00109 longjmp (priv->bailout, 1);
00110 }
00111 else
00112 priv->max_fetched = addr;
00113 return 1;
00114 }
00115
00116 #define NOPCODES (sizeof ns32k_opcodes / sizeof ns32k_opcodes[0])
00117
00118 #define NEXT_IS_ADDR '|'
00119
00120
00121 struct ns32k_option {
00122 char *pattern;
00123 unsigned long value;
00124 unsigned long match;
00125 };
00126
00127
00128 static const struct ns32k_option opt_u[]=
00129 {
00130 { "r0", 0x80, 0x80 },
00131 { "r1", 0x40, 0x40 },
00132 { "r2", 0x20, 0x20 },
00133 { "r3", 0x10, 0x10 },
00134 { "r4", 0x08, 0x08 },
00135 { "r5", 0x04, 0x04 },
00136 { "r6", 0x02, 0x02 },
00137 { "r7", 0x01, 0x01 },
00138 { 0 , 0x00, 0x00 }
00139 };
00140
00141 static const struct ns32k_option opt_U[]=
00142 {
00143 { "r0", 0x01, 0x01 },
00144 { "r1", 0x02, 0x02 },
00145 { "r2", 0x04, 0x04 },
00146 { "r3", 0x08, 0x08 },
00147 { "r4", 0x10, 0x10 },
00148 { "r5", 0x20, 0x20 },
00149 { "r6", 0x40, 0x40 },
00150 { "r7", 0x80, 0x80 },
00151 { 0 , 0x00, 0x00 }
00152 };
00153
00154 static const struct ns32k_option opt_O[]=
00155 {
00156 { "c", 0x8, 0x8 },
00157 { "m", 0x4, 0x4 },
00158 { "f", 0x2, 0x2 },
00159 { "i", 0x1, 0x1 },
00160 { 0 , 0x0, 0x0 }
00161 };
00162
00163 static const struct ns32k_option opt_C[]=
00164 {
00165 { "a", 0x4, 0x4 },
00166 { "i", 0x2, 0x2 },
00167 { "d", 0x1, 0x1 },
00168 { 0 , 0x0, 0x0 }
00169 };
00170
00171 static const struct ns32k_option opt_S[]=
00172 {
00173 { "b", 0x1, 0x1 },
00174 { "u", 0x6, 0x6 },
00175 { "w", 0x2, 0x2 },
00176 { 0 , 0x0, 0x0 }
00177 };
00178
00179 static const struct ns32k_option list_P532[]=
00180 {
00181 { "us", 0x0, 0xf },
00182 { "dcr", 0x1, 0xf },
00183 { "bpc", 0x2, 0xf },
00184 { "dsr", 0x3, 0xf },
00185 { "car", 0x4, 0xf },
00186 { "fp", 0x8, 0xf },
00187 { "sp", 0x9, 0xf },
00188 { "sb", 0xa, 0xf },
00189 { "usp", 0xb, 0xf },
00190 { "cfg", 0xc, 0xf },
00191 { "psr", 0xd, 0xf },
00192 { "intbase", 0xe, 0xf },
00193 { "mod", 0xf, 0xf },
00194 { 0 , 0x00, 0xf }
00195 };
00196
00197 static const struct ns32k_option list_M532[]=
00198 {
00199 { "mcr", 0x9, 0xf },
00200 { "msr", 0xa, 0xf },
00201 { "tear", 0xb, 0xf },
00202 { "ptb0", 0xc, 0xf },
00203 { "ptb1", 0xd, 0xf },
00204 { "ivar0", 0xe, 0xf },
00205 { "ivar1", 0xf, 0xf },
00206 { 0 , 0x0, 0xf }
00207 };
00208
00209 static const struct ns32k_option list_P032[]=
00210 {
00211 { "upsr", 0x0, 0xf },
00212 { "fp", 0x8, 0xf },
00213 { "sp", 0x9, 0xf },
00214 { "sb", 0xa, 0xf },
00215 { "psr", 0xb, 0xf },
00216 { "intbase", 0xe, 0xf },
00217 { "mod", 0xf, 0xf },
00218 { 0 , 0x0, 0xf }
00219 };
00220
00221 static const struct ns32k_option list_M032[]=
00222 {
00223 { "bpr0", 0x0, 0xf },
00224 { "bpr1", 0x1, 0xf },
00225 { "pf0", 0x4, 0xf },
00226 { "pf1", 0x5, 0xf },
00227 { "sc", 0x8, 0xf },
00228 { "msr", 0xa, 0xf },
00229 { "bcnt", 0xb, 0xf },
00230 { "ptb0", 0xc, 0xf },
00231 { "ptb1", 0xd, 0xf },
00232 { "eia", 0xf, 0xf },
00233 { 0 , 0x0, 0xf }
00234 };
00235
00236
00237
00238
00239
00240 static void
00241 optlist(options, optionP, result)
00242 int options;
00243 const struct ns32k_option *optionP;
00244 char *result;
00245 {
00246 if (options == 0) {
00247 sprintf(result, "[]");
00248 return;
00249 }
00250 sprintf(result, "[");
00251
00252 for (; (options != 0) && optionP->pattern; optionP++) {
00253 if ((options & optionP->match) == optionP->value) {
00254
00255 strcat(result, optionP->pattern);
00256 options &= ~optionP->value;
00257 if (options != 0)
00258 strcat(result, ",");
00259 }
00260 }
00261 if (options != 0)
00262 strcat(result, "undefined");
00263
00264 strcat(result, "]");
00265 }
00266
00267 static void
00268 list_search (reg_value, optionP, result)
00269 int reg_value;
00270 const struct ns32k_option *optionP;
00271 char *result;
00272 {
00273 for (; optionP->pattern; optionP++) {
00274 if ((reg_value & optionP->match) == optionP->value) {
00275 sprintf(result, "%s", optionP->pattern);
00276 return;
00277 }
00278 }
00279 sprintf(result, "undefined");
00280 }
00281
00282
00283
00284
00285
00286
00287 static int
00288 bit_extract (buffer, offset, count)
00289 bfd_byte *buffer;
00290 int offset;
00291 int count;
00292 {
00293 int result;
00294 int bit;
00295
00296 buffer += offset >> 3;
00297 offset &= 7;
00298 bit = 1;
00299 result = 0;
00300 while (count--)
00301 {
00302 FETCH_DATA(dis_info, buffer + 1);
00303 if ((*buffer & (1 << offset)))
00304 result |= bit;
00305 if (++offset == 8)
00306 {
00307 offset = 0;
00308 buffer++;
00309 }
00310 bit <<= 1;
00311 }
00312 return result;
00313 }
00314
00315
00316
00317
00318 static int
00319 bit_extract_simple (buffer, offset, count)
00320 bfd_byte *buffer;
00321 int offset;
00322 int count;
00323 {
00324 int result;
00325 int bit;
00326
00327 buffer += offset >> 3;
00328 offset &= 7;
00329 bit = 1;
00330 result = 0;
00331 while (count--)
00332 {
00333 if ((*buffer & (1 << offset)))
00334 result |= bit;
00335 if (++offset == 8)
00336 {
00337 offset = 0;
00338 buffer++;
00339 }
00340 bit <<= 1;
00341 }
00342 return result;
00343 }
00344
00345 static void
00346 bit_copy (buffer, offset, count, to)
00347 bfd_byte *buffer;
00348 int offset;
00349 int count;
00350 char *to;
00351 {
00352 for(; count > 8; count -= 8, to++, offset += 8)
00353 *to = bit_extract (buffer, offset, 8);
00354 *to = bit_extract (buffer, offset, count);
00355 }
00356
00357
00358 static int
00359 sign_extend (value, bits)
00360 int value, bits;
00361 {
00362 value = value & ((1 << bits) - 1);
00363 return (value & (1 << (bits-1))
00364 ? value | (~((1 << bits) - 1))
00365 : value);
00366 }
00367
00368 static void
00369 flip_bytes (ptr, count)
00370 char *ptr;
00371 int count;
00372 {
00373 char tmp;
00374
00375 while (count > 0)
00376 {
00377 tmp = ptr[0];
00378 ptr[0] = ptr[count-1];
00379 ptr[count-1] = tmp;
00380 ptr++;
00381 count -= 2;
00382 }
00383 }
00384
00385
00386 #define Is_gen(c) \
00387 ((c) == 'F' || (c) == 'L' || (c) == 'B' \
00388 || (c) == 'W' || (c) == 'D' || (c) == 'A' || (c) == 'I' || (c) == 'Z')
00389
00390
00391 #define Adrmod_index_byte 0x1c
00392 #define Adrmod_index_word 0x1d
00393 #define Adrmod_index_doubleword 0x1e
00394 #define Adrmod_index_quadword 0x1f
00395
00396
00397 #define Adrmod_is_index(mode) \
00398 (mode == Adrmod_index_byte \
00399 || mode == Adrmod_index_word \
00400 || mode == Adrmod_index_doubleword \
00401 || mode == Adrmod_index_quadword)
00402
00403
00404
00405
00406
00407 int
00408 print_insn_ns32k (memaddr, info)
00409 bfd_vma memaddr;
00410 disassemble_info *info;
00411 {
00412 unsigned int i;
00413 const char *d;
00414 unsigned short first_word;
00415 int ioffset;
00416 int aoffset;
00417 char arg_bufs[MAX_ARGS+1][ARG_LEN];
00418 int argnum;
00419 int maxarg;
00420 struct private priv;
00421 bfd_byte *buffer = priv.the_buffer;
00422 dis_info = info;
00423
00424 info->private_data = (PTR) &priv;
00425 priv.max_fetched = priv.the_buffer;
00426 priv.insn_start = memaddr;
00427 if (setjmp (priv.bailout) != 0)
00428
00429 return -1;
00430
00431
00432
00433
00434 FETCH_DATA(info, buffer + 1);
00435 for (i = 0; i < NOPCODES; i++)
00436 if (ns32k_opcodes[i].opcode_id_size <= 8
00437 && ((buffer[0]
00438 & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
00439 == ns32k_opcodes[i].opcode_seed))
00440 break;
00441 if (i == NOPCODES) {
00442
00443 FETCH_DATA(info, buffer + 2);
00444 first_word = read_memory_integer(buffer, 2);
00445
00446 for (i = 0; i < NOPCODES; i++)
00447 if ((first_word
00448 & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
00449 == ns32k_opcodes[i].opcode_seed)
00450 break;
00451
00452
00453 if (i == NOPCODES)
00454 {
00455 (*dis_info->fprintf_func)(dis_info->stream, "0%o", buffer[0]);
00456 return 1;
00457 }
00458 }
00459
00460 (*dis_info->fprintf_func)(dis_info->stream, "%s", ns32k_opcodes[i].name);
00461
00462 ioffset = ns32k_opcodes[i].opcode_size;
00463 aoffset = ns32k_opcodes[i].opcode_size;
00464 d = ns32k_opcodes[i].operands;
00465
00466 if (*d)
00467 {
00468
00469
00470
00471
00472 int index_offset[MAX_ARGS];
00473
00474
00475 int whicharg = 0;
00476
00477 (*dis_info->fprintf_func)(dis_info->stream, "\t");
00478
00479 maxarg = 0;
00480
00481
00482
00483
00484
00485 if (Is_gen(d[1]))
00486 {
00487 int addr_mode = bit_extract (buffer, ioffset - 5, 5);
00488
00489 if (Adrmod_is_index (addr_mode))
00490 {
00491 aoffset += 8;
00492 index_offset[0] = aoffset;
00493 }
00494 }
00495 if (d[2] && Is_gen(d[3]))
00496 {
00497 int addr_mode = bit_extract (buffer, ioffset - 10, 5);
00498
00499 if (Adrmod_is_index (addr_mode))
00500 {
00501 aoffset += 8;
00502 index_offset[1] = aoffset;
00503 }
00504 }
00505
00506 while (*d)
00507 {
00508 argnum = *d - '1';
00509 d++;
00510 if (argnum > maxarg && argnum < MAX_ARGS)
00511 maxarg = argnum;
00512 ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
00513 memaddr, arg_bufs[argnum],
00514 index_offset[whicharg]);
00515 d++;
00516 whicharg++;
00517 }
00518 for (argnum = 0; argnum <= maxarg; argnum++)
00519 {
00520 bfd_vma addr;
00521 char *ch;
00522 for (ch = arg_bufs[argnum]; *ch;)
00523 {
00524 if (*ch == NEXT_IS_ADDR)
00525 {
00526 ++ch;
00527 addr = bfd_scan_vma (ch, NULL, 16);
00528 (*dis_info->print_address_func) (addr, dis_info);
00529 while (*ch && *ch != NEXT_IS_ADDR)
00530 ++ch;
00531 if (*ch)
00532 ++ch;
00533 }
00534 else
00535 (*dis_info->fprintf_func)(dis_info->stream, "%c", *ch++);
00536 }
00537 if (argnum < maxarg)
00538 (*dis_info->fprintf_func)(dis_info->stream, ", ");
00539 }
00540 }
00541 return aoffset / 8;
00542 }
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554 static int
00555 print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset)
00556 int d;
00557 int ioffset, *aoffsetp;
00558 bfd_byte *buffer;
00559 bfd_vma addr;
00560 char *result;
00561 int index_offset;
00562 {
00563 union {
00564 float f;
00565 double d;
00566 int i[2];
00567 } value;
00568 int Ivalue;
00569 int addr_mode;
00570 int disp1, disp2;
00571 int index;
00572 int size;
00573
00574 switch (d)
00575 {
00576 case 'f':
00577
00578 ioffset -= 5;
00579 case 'Z':
00580 case 'F':
00581 case 'L':
00582 case 'I':
00583 case 'B':
00584 case 'W':
00585 case 'D':
00586 case 'A':
00587 addr_mode = bit_extract (buffer, ioffset-5, 5);
00588 ioffset -= 5;
00589 switch (addr_mode)
00590 {
00591 case 0x0: case 0x1: case 0x2: case 0x3:
00592 case 0x4: case 0x5: case 0x6: case 0x7:
00593
00594 switch (d)
00595 {
00596 case 'F':
00597 case 'L':
00598 case 'Z':
00599 sprintf (result, "f%d", addr_mode);
00600 break;
00601 default:
00602 sprintf (result, "r%d", addr_mode);
00603 }
00604 break;
00605 case 0x8: case 0x9: case 0xa: case 0xb:
00606 case 0xc: case 0xd: case 0xe: case 0xf:
00607
00608 disp1 = get_displacement (buffer, aoffsetp);
00609 sprintf (result, "%d(r%d)", disp1, addr_mode & 7);
00610 break;
00611 case 0x10:
00612 case 0x11:
00613 case 0x12:
00614
00615 disp1 = get_displacement (buffer, aoffsetp);
00616 disp2 = get_displacement (buffer, aoffsetp);
00617 sprintf (result, "%d(%d(%s))", disp2, disp1,
00618 addr_mode==0x10?"fp":addr_mode==0x11?"sp":"sb");
00619 break;
00620 case 0x13:
00621
00622 sprintf (result, "reserved");
00623 break;
00624 case 0x14:
00625
00626 switch (d)
00627 {
00628 case 'I': case 'Z': case 'A':
00629
00630
00631
00632
00633
00634
00635 sprintf (result, _("$<undefined>"));
00636 break;
00637 case 'B':
00638 Ivalue = bit_extract (buffer, *aoffsetp, 8);
00639 Ivalue = sign_extend (Ivalue, 8);
00640 *aoffsetp += 8;
00641 sprintf (result, "$%d", Ivalue);
00642 break;
00643 case 'W':
00644 Ivalue = bit_extract (buffer, *aoffsetp, 16);
00645 flip_bytes ((char *) & Ivalue, 2);
00646 *aoffsetp += 16;
00647 Ivalue = sign_extend (Ivalue, 16);
00648 sprintf (result, "$%d", Ivalue);
00649 break;
00650 case 'D':
00651 Ivalue = bit_extract (buffer, *aoffsetp, 32);
00652 flip_bytes ((char *) & Ivalue, 4);
00653 *aoffsetp += 32;
00654 sprintf (result, "$%d", Ivalue);
00655 break;
00656 case 'F':
00657 bit_copy (buffer, *aoffsetp, 32, (char *) &value.f);
00658 flip_bytes ((char *) &value.f, 4);
00659 *aoffsetp += 32;
00660 if (INVALID_FLOAT (&value.f, 4))
00661 sprintf (result, "<<invalid float 0x%.8x>>", value.i[0]);
00662 else
00663 sprintf (result, "$%g", value.f);
00664 break;
00665 case 'L':
00666 bit_copy (buffer, *aoffsetp, 64, (char *) &value.d);
00667 flip_bytes ((char *) &value.d, 8);
00668 *aoffsetp += 64;
00669 if (INVALID_FLOAT (&value.d, 8))
00670 sprintf (result, "<<invalid double 0x%.8x%.8x>>",
00671 value.i[1], value.i[0]);
00672 else
00673 sprintf (result, "$%g", value.d);
00674 break;
00675 }
00676 break;
00677 case 0x15:
00678
00679 disp1 = get_displacement (buffer, aoffsetp);
00680 sprintf (result, "@|%d|", disp1);
00681 break;
00682 case 0x16:
00683
00684 disp1 = get_displacement (buffer, aoffsetp);
00685 disp2 = get_displacement (buffer, aoffsetp);
00686 sprintf (result, "EXT(%d) + %d", disp1, disp2);
00687 break;
00688 case 0x17:
00689
00690 sprintf (result, "tos");
00691 break;
00692 case 0x18:
00693
00694 disp1 = get_displacement (buffer, aoffsetp);
00695 sprintf (result, "%d(fp)", disp1);
00696 break;
00697 case 0x19:
00698
00699 disp1 = get_displacement (buffer, aoffsetp);
00700 sprintf (result, "%d(sp)", disp1);
00701 break;
00702 case 0x1a:
00703
00704 disp1 = get_displacement (buffer, aoffsetp);
00705 sprintf (result, "%d(sb)", disp1);
00706 break;
00707 case 0x1b:
00708
00709 disp1 = get_displacement (buffer, aoffsetp);
00710 *result++ = NEXT_IS_ADDR;
00711 sprintf_vma (result, addr + disp1);
00712 result += strlen (result);
00713 *result++ = NEXT_IS_ADDR;
00714 *result = '\0';
00715 break;
00716 case 0x1c:
00717 case 0x1d:
00718 case 0x1e:
00719 case 0x1f:
00720
00721 index = bit_extract (buffer, index_offset - 8, 3);
00722 print_insn_arg (d, index_offset, aoffsetp, buffer, addr,
00723 result, 0);
00724 {
00725 static const char *ind = "bwdq";
00726 char *off;
00727
00728 off = result + strlen (result);
00729 sprintf (off, "[r%d:%c]", index,
00730 ind[addr_mode & 3]);
00731 }
00732 break;
00733 }
00734 break;
00735 case 'H':
00736 case 'q':
00737 Ivalue = bit_extract (buffer, ioffset-4, 4);
00738 Ivalue = sign_extend (Ivalue, 4);
00739 sprintf (result, "%d", Ivalue);
00740 ioffset -= 4;
00741 break;
00742 case 'r':
00743 Ivalue = bit_extract (buffer, ioffset-3, 3);
00744 sprintf (result, "r%d", Ivalue&7);
00745 ioffset -= 3;
00746 break;
00747 case 'd':
00748 sprintf (result, "%d", get_displacement (buffer, aoffsetp));
00749 break;
00750 case 'b':
00751 Ivalue = get_displacement (buffer, aoffsetp);
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761 size = bit_extract(buffer, ioffset-6, 2);
00762 if (size == 0)
00763 size = 1;
00764 else if (size == 1)
00765 size = 2;
00766 else
00767 size = 4;
00768
00769 sprintf (result, "%d", (Ivalue / size) + 1);
00770 break;
00771 case 'p':
00772 *result++ = NEXT_IS_ADDR;
00773 sprintf_vma (result, addr + get_displacement (buffer, aoffsetp));
00774 result += strlen (result);
00775 *result++ = NEXT_IS_ADDR;
00776 *result = '\0';
00777 break;
00778 case 'i':
00779 Ivalue = bit_extract (buffer, *aoffsetp, 8);
00780 *aoffsetp += 8;
00781 sprintf (result, "0x%x", Ivalue);
00782 break;
00783 case 'u':
00784 Ivalue = bit_extract (buffer, *aoffsetp, 8);
00785 optlist(Ivalue, opt_u, result);
00786 *aoffsetp += 8;
00787 break;
00788 case 'U':
00789 Ivalue = bit_extract(buffer, *aoffsetp, 8);
00790 optlist(Ivalue, opt_U, result);
00791 *aoffsetp += 8;
00792 break;
00793 case 'O':
00794 Ivalue = bit_extract(buffer, ioffset-9, 9);
00795 optlist(Ivalue, opt_O, result);
00796 ioffset -= 9;
00797 break;
00798 case 'C':
00799 Ivalue = bit_extract(buffer, ioffset-4, 4);
00800 optlist(Ivalue, opt_C, result);
00801 ioffset -= 4;
00802 break;
00803 case 'S':
00804 Ivalue = bit_extract(buffer, ioffset - 8, 8);
00805 optlist(Ivalue, opt_S, result);
00806 ioffset -= 8;
00807 break;
00808 case 'M':
00809 Ivalue = bit_extract(buffer, ioffset-4, 4);
00810 list_search(Ivalue, 0 ? list_M032 : list_M532, result);
00811 ioffset -= 4;
00812 break;
00813 case 'P':
00814 Ivalue = bit_extract(buffer, ioffset-4, 4);
00815 list_search(Ivalue, 0 ? list_P032 : list_P532, result);
00816 ioffset -= 4;
00817 break;
00818 case 'g':
00819 Ivalue = bit_extract(buffer, *aoffsetp, 3);
00820 sprintf(result, "%d", Ivalue);
00821 *aoffsetp += 3;
00822 break;
00823 case 'G':
00824 Ivalue = bit_extract(buffer, *aoffsetp, 5);
00825 sprintf(result, "%d", Ivalue + 1);
00826 *aoffsetp += 5;
00827 break;
00828 }
00829 return ioffset;
00830 }
00831
00832 static int
00833 get_displacement (buffer, aoffsetp)
00834 bfd_byte *buffer;
00835 int *aoffsetp;
00836 {
00837 int Ivalue;
00838 short Ivalue2;
00839
00840 Ivalue = bit_extract (buffer, *aoffsetp, 8);
00841 switch (Ivalue & 0xc0)
00842 {
00843 case 0x00:
00844 case 0x40:
00845 Ivalue = sign_extend (Ivalue, 7);
00846 *aoffsetp += 8;
00847 break;
00848 case 0x80:
00849 Ivalue2 = bit_extract (buffer, *aoffsetp, 16);
00850 flip_bytes ((char *) & Ivalue2, 2);
00851 Ivalue = sign_extend (Ivalue2, 14);
00852 *aoffsetp += 16;
00853 break;
00854 case 0xc0:
00855 Ivalue = bit_extract (buffer, *aoffsetp, 32);
00856 flip_bytes ((char *) & Ivalue, 4);
00857 Ivalue = sign_extend (Ivalue, 30);
00858 *aoffsetp += 32;
00859 break;
00860 }
00861 return Ivalue;
00862 }
00863
00864
00865 #if 1
00866 static int
00867 invalid_float (p, len)
00868 register bfd_byte *p;
00869 register int len;
00870 {
00871 register int val;
00872
00873 if ( len == 4 )
00874 val = (bit_extract_simple(p, 23, 8) == 0xff
00875 || (bit_extract_simple(p, 23, 8) == 0 &&
00876 bit_extract_simple(p, 0, 23) != 0));
00877 else if ( len == 8 )
00878 val = (bit_extract_simple(p, 52, 11) == 0x7ff
00879 || (bit_extract_simple(p, 52, 11) == 0
00880 && (bit_extract_simple(p, 0, 32) != 0
00881 || bit_extract_simple(p, 32, 20) != 0)));
00882 else
00883 val = 1;
00884 return (val);
00885 }
00886 #else
00887
00888
00889 typedef union { double d;
00890 float f;
00891 struct { unsigned m:23, e:8, :1;} sf;
00892 struct { unsigned lm; unsigned m:20, e:11, :1;} sd;
00893 } float_type_u;
00894
00895 static int
00896 invalid_float (p, len)
00897 register float_type_u *p;
00898 register int len;
00899 {
00900 register int val;
00901 if ( len == sizeof (float) )
00902 val = (p->sf.e == 0xff
00903 || (p->sf.e == 0 && p->sf.m != 0));
00904 else if ( len == sizeof (double) )
00905 val = (p->sd.e == 0x7ff
00906 || (p->sd.e == 0 && (p->sd.m != 0 || p->sd.lm != 0)));
00907 else
00908 val = 1;
00909 return (val);
00910 }
00911 #endif