00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "sysdep.h"
00023 #include "dis-asm.h"
00024 #include "libhppa.h"
00025 #include "opcode/hppa.h"
00026
00027
00028
00029 static const char *const reg_names[] =
00030 {"flags", "r1", "rp", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
00031 "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19",
00032 "r20", "r21", "r22", "r23", "r24", "r25", "r26", "dp", "ret0", "ret1",
00033 "sp", "r31"};
00034
00035
00036
00037 static const char *const fp_reg_names[] =
00038 {"fpsr", "fpe2", "fpe4", "fpe6",
00039 "fr4", "fr5", "fr6", "fr7", "fr8",
00040 "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
00041 "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23",
00042 "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31"};
00043
00044 typedef unsigned int CORE_ADDR;
00045
00046
00047
00048 #define MASK_5 0x1f
00049 #define MASK_10 0x3ff
00050 #define MASK_11 0x7ff
00051 #define MASK_14 0x3fff
00052 #define MASK_16 0xffff
00053 #define MASK_21 0x1fffff
00054
00055
00056
00057 #define GET_FIELD(X, FROM, TO) \
00058 ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
00059
00060 #define GET_BIT(X, WHICH) \
00061 GET_FIELD (X, WHICH, WHICH)
00062
00063
00064
00065
00066 static const char *const control_reg[] = {
00067 "rctr", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
00068 "pidr1", "pidr2", "ccr", "sar", "pidr3", "pidr4",
00069 "iva", "eiem", "itmr", "pcsq", "pcoq", "iir", "isr",
00070 "ior", "ipsw", "eirr", "tr0", "tr1", "tr2", "tr3",
00071 "tr4", "tr5", "tr6", "tr7"
00072 };
00073
00074 static const char *const compare_cond_names[] = {
00075 "", ",=", ",<", ",<=", ",<<", ",<<=", ",sv", ",od",
00076 ",tr", ",<>", ",>=", ",>", ",>>=", ",>>", ",nsv", ",ev"
00077 };
00078 static const char *const compare_cond_64_names[] = {
00079 "", ",*=", ",*<", ",*<=", ",*<<", ",*<<=", ",*sv", ",*od",
00080 ",*tr", ",*<>", ",*>=", ",*>", ",*>>=", ",*>>", ",*nsv", ",*ev"
00081 };
00082 static const char *const cmpib_cond_64_names[] = {
00083 ",*<<", ",*=", ",*<", ",*<=", ",*>>=", ",*<>", ",*>=", ",*>"
00084 };
00085 static const char *const add_cond_names[] = {
00086 "", ",=", ",<", ",<=", ",nuv", ",znv", ",sv", ",od",
00087 ",tr", ",<>", ",>=", ",>", ",uv", ",vnz", ",nsv", ",ev"
00088 };
00089 static const char *const add_cond_64_names[] = {
00090 "", ",*=", ",*<", ",*<=", ",*nuv", ",*znv", ",*sv", ",*od",
00091 ",*tr", ",*<>", ",*>=", ",*>", ",*uv", ",*vnz", ",*nsv", ",*ev"
00092 };
00093 static const char *const wide_add_cond_names[] = {
00094 "", ",=", ",<", ",<=", ",nuv", ",*=", ",*<", ",*<=",
00095 ",tr", ",<>", ",>=", ",>", ",uv", ",*<>", ",*>=", ",*>"
00096 };
00097 static const char *const logical_cond_names[] = {
00098 "", ",=", ",<", ",<=", 0, 0, 0, ",od",
00099 ",tr", ",<>", ",>=", ",>", 0, 0, 0, ",ev"};
00100 static const char *const logical_cond_64_names[] = {
00101 "", ",*=", ",*<", ",*<=", 0, 0, 0, ",*od",
00102 ",*tr", ",*<>", ",*>=", ",*>", 0, 0, 0, ",*ev"};
00103 static const char *const unit_cond_names[] = {
00104 "", ",swz", ",sbz", ",shz", ",sdc", ",swc", ",sbc", ",shc",
00105 ",tr", ",nwz", ",nbz", ",nhz", ",ndc", ",nwc", ",nbc", ",nhc"
00106 };
00107 static const char *const unit_cond_64_names[] = {
00108 "", ",*swz", ",*sbz", ",*shz", ",*sdc", ",*swc", ",*sbc", ",*shc",
00109 ",*tr", ",*nwz", ",*nbz", ",*nhz", ",*ndc", ",*nwc", ",*nbc", ",*nhc"
00110 };
00111 static const char *const shift_cond_names[] = {
00112 "", ",=", ",<", ",od", ",tr", ",<>", ",>=", ",ev"
00113 };
00114 static const char *const shift_cond_64_names[] = {
00115 "", ",*=", ",*<", ",*od", ",*tr", ",*<>", ",*>=", ",*ev"
00116 };
00117 static const char *const bb_cond_64_names[] = {
00118 ",*<", ",*>="
00119 };
00120 static const char *const index_compl_names[] = {"", ",m", ",s", ",sm"};
00121 static const char *const short_ldst_compl_names[] = {"", ",ma", "", ",mb"};
00122 static const char *const short_bytes_compl_names[] = {
00123 "", ",b,m", ",e", ",e,m"
00124 };
00125 static const char *const float_format_names[] = {",sgl", ",dbl", "", ",quad"};
00126 static const char *const fcnv_fixed_names[] = {",w", ",dw", "", ",qw"};
00127 static const char *const fcnv_ufixed_names[] = {",uw", ",udw", "", ",uqw"};
00128 static const char *const float_comp_names[] =
00129 {
00130 ",false?", ",false", ",?", ",!<=>", ",=", ",=t", ",?=", ",!<>",
00131 ",!?>=", ",<", ",?<", ",!>=", ",!?>", ",<=", ",?<=", ",!>",
00132 ",!?<=", ",>", ",?>", ",!<=", ",!?<", ",>=", ",?>=", ",!<",
00133 ",!?=", ",<>", ",!=", ",!=t", ",!?", ",<=>", ",true?", ",true"
00134 };
00135 static const char *const signed_unsigned_names[] = {",u", ",s"};
00136 static const char *const mix_half_names[] = {",l", ",r"};
00137 static const char *const saturation_names[] = {",us", ",ss", 0, ""};
00138 static const char *const read_write_names[] = {",r", ",w"};
00139 static const char *const add_compl_names[] = { 0, "", ",l", ",tsv" };
00140
00141
00142
00143 #define GET_COMPL(insn) (GET_FIELD (insn, 26, 26) | \
00144 GET_FIELD (insn, 18, 18) << 1)
00145
00146 #define GET_COND(insn) (GET_FIELD ((insn), 16, 18) + \
00147 (GET_FIELD ((insn), 19, 19) ? 8 : 0))
00148
00149 static void fput_reg PARAMS ((unsigned int, disassemble_info *));
00150 static void fput_fp_reg PARAMS ((unsigned int, disassemble_info *));
00151 static void fput_fp_reg_r PARAMS ((unsigned int, disassemble_info *));
00152 static void fput_creg PARAMS ((unsigned int, disassemble_info *));
00153 static void fput_const PARAMS ((unsigned int, disassemble_info *));
00154 static int extract_3 PARAMS ((unsigned int));
00155 static int extract_5_load PARAMS ((unsigned int));
00156 static int extract_5_store PARAMS ((unsigned int));
00157 static unsigned extract_5r_store PARAMS ((unsigned int));
00158 static unsigned extract_5R_store PARAMS ((unsigned int));
00159 static unsigned extract_10U_store PARAMS ((unsigned int));
00160 static unsigned extract_5Q_store PARAMS ((unsigned int));
00161 static int extract_11 PARAMS ((unsigned int));
00162 static int extract_14 PARAMS ((unsigned int));
00163 static int extract_16 PARAMS ((unsigned int));
00164 static int extract_21 PARAMS ((unsigned int));
00165 static int extract_12 PARAMS ((unsigned int));
00166 static int extract_17 PARAMS ((unsigned int));
00167 static int extract_22 PARAMS ((unsigned int));
00168
00169
00170
00171
00172 #define fputs_filtered(STR,F) (*info->fprintf_func) (info->stream, "%s", STR)
00173
00174 static void
00175 fput_reg (reg, info)
00176 unsigned reg;
00177 disassemble_info *info;
00178 {
00179 (*info->fprintf_func) (info->stream, reg ? reg_names[reg] : "r0");
00180 }
00181
00182 static void
00183 fput_fp_reg (reg, info)
00184 unsigned reg;
00185 disassemble_info *info;
00186 {
00187 (*info->fprintf_func) (info->stream, reg ? fp_reg_names[reg] : "fr0");
00188 }
00189
00190 static void
00191 fput_fp_reg_r (reg, info)
00192 unsigned reg;
00193 disassemble_info *info;
00194 {
00195
00196 if (reg < 4)
00197 (*info->fprintf_func) (info->stream, "fpe%d", reg * 2 + 1);
00198 else
00199 (*info->fprintf_func) (info->stream, "%sR",
00200 reg ? fp_reg_names[reg] : "fr0");
00201 }
00202
00203 static void
00204 fput_creg (reg, info)
00205 unsigned reg;
00206 disassemble_info *info;
00207 {
00208 (*info->fprintf_func) (info->stream, control_reg[reg]);
00209 }
00210
00211
00212
00213 static void
00214 fput_const (num, info)
00215 unsigned num;
00216 disassemble_info *info;
00217 {
00218 if ((int)num < 0)
00219 (*info->fprintf_func) (info->stream, "-%x", -(int)num);
00220 else
00221 (*info->fprintf_func) (info->stream, "%x", num);
00222 }
00223
00224
00225
00226
00227
00228 static int
00229 extract_3 (word)
00230 unsigned word;
00231 {
00232 return GET_FIELD (word, 18, 18) << 2 | GET_FIELD (word, 16, 17);
00233 }
00234
00235 static int
00236 extract_5_load (word)
00237 unsigned word;
00238 {
00239 return low_sign_extend (word >> 16 & MASK_5, 5);
00240 }
00241
00242
00243 static int
00244 extract_5_store (word)
00245 unsigned word;
00246 {
00247 return low_sign_extend (word & MASK_5, 5);
00248 }
00249
00250
00251 static unsigned
00252 extract_5r_store (word)
00253 unsigned word;
00254 {
00255 return (word & MASK_5);
00256 }
00257
00258
00259 static unsigned
00260 extract_5R_store (word)
00261 unsigned word;
00262 {
00263 return (word >> 16 & MASK_5);
00264 }
00265
00266
00267 static unsigned
00268 extract_10U_store (word)
00269 unsigned word;
00270 {
00271 return (word >> 16 & MASK_10);
00272 }
00273
00274
00275 static unsigned
00276 extract_5Q_store (word)
00277 unsigned word;
00278 {
00279 return (word >> 21 & MASK_5);
00280 }
00281
00282
00283 static int
00284 extract_11 (word)
00285 unsigned word;
00286 {
00287 return low_sign_extend (word & MASK_11, 11);
00288 }
00289
00290
00291 static int
00292 extract_14 (word)
00293 unsigned word;
00294 {
00295 return low_sign_extend (word & MASK_14, 14);
00296 }
00297
00298
00299 static int
00300 extract_16 (word)
00301 unsigned word;
00302 {
00303 int m15, m0, m1;
00304 m0 = GET_BIT (word, 16);
00305 m1 = GET_BIT (word, 17);
00306 m15 = GET_BIT (word, 31);
00307 word = (word >> 1) & 0x1fff;
00308 word = word | (m15 << 15) | ((m15 ^ m0) << 14) | ((m15 ^ m1) << 13);
00309 return sign_extend (word, 16);
00310 }
00311
00312
00313
00314 static int
00315 extract_21 (word)
00316 unsigned word;
00317 {
00318 int val;
00319
00320 word &= MASK_21;
00321 word <<= 11;
00322 val = GET_FIELD (word, 20, 20);
00323 val <<= 11;
00324 val |= GET_FIELD (word, 9, 19);
00325 val <<= 2;
00326 val |= GET_FIELD (word, 5, 6);
00327 val <<= 5;
00328 val |= GET_FIELD (word, 0, 4);
00329 val <<= 2;
00330 val |= GET_FIELD (word, 7, 8);
00331 return sign_extend (val, 21) << 11;
00332 }
00333
00334
00335
00336 static int
00337 extract_12 (word)
00338 unsigned word;
00339 {
00340 return sign_extend (GET_FIELD (word, 19, 28) |
00341 GET_FIELD (word, 29, 29) << 10 |
00342 (word & 0x1) << 11, 12) << 2;
00343 }
00344
00345
00346
00347
00348 static int
00349 extract_17 (word)
00350 unsigned word;
00351 {
00352 return sign_extend (GET_FIELD (word, 19, 28) |
00353 GET_FIELD (word, 29, 29) << 10 |
00354 GET_FIELD (word, 11, 15) << 11 |
00355 (word & 0x1) << 16, 17) << 2;
00356 }
00357
00358 static int
00359 extract_22 (word)
00360 unsigned word;
00361 {
00362 return sign_extend (GET_FIELD (word, 19, 28) |
00363 GET_FIELD (word, 29, 29) << 10 |
00364 GET_FIELD (word, 11, 15) << 11 |
00365 GET_FIELD (word, 6, 10) << 16 |
00366 (word & 0x1) << 21, 22) << 2;
00367 }
00368
00369
00370 int
00371 print_insn_hppa (memaddr, info)
00372 bfd_vma memaddr;
00373 disassemble_info *info;
00374 {
00375 bfd_byte buffer[4];
00376 unsigned int insn, i;
00377
00378 {
00379 int status =
00380 (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
00381 if (status != 0)
00382 {
00383 (*info->memory_error_func) (status, memaddr, info);
00384 return -1;
00385 }
00386 }
00387
00388 insn = bfd_getb32 (buffer);
00389
00390 for (i = 0; i < NUMOPCODES; ++i)
00391 {
00392 const struct pa_opcode *opcode = &pa_opcodes[i];
00393 if ((insn & opcode->mask) == opcode->match)
00394 {
00395 register const char *s;
00396 #ifndef BFD64
00397 if (opcode->arch == pa20w)
00398 continue;
00399 #endif
00400 (*info->fprintf_func) (info->stream, "%s", opcode->name);
00401
00402 if (!strchr ("cfCY?-+nHNZFIuv{", opcode->args[0]))
00403 (*info->fprintf_func) (info->stream, " ");
00404 for (s = opcode->args; *s != '\0'; ++s)
00405 {
00406 switch (*s)
00407 {
00408 case 'x':
00409 fput_reg (GET_FIELD (insn, 11, 15), info);
00410 break;
00411 case 'a':
00412 case 'b':
00413 fput_reg (GET_FIELD (insn, 6, 10), info);
00414 break;
00415 case '^':
00416 fput_creg (GET_FIELD (insn, 6, 10), info);
00417 break;
00418 case 't':
00419 fput_reg (GET_FIELD (insn, 27, 31), info);
00420 break;
00421
00422
00423 case 'f':
00424 switch (*++s)
00425 {
00426 case 't':
00427 fput_fp_reg (GET_FIELD (insn, 27, 31), info);
00428 break;
00429 case 'T':
00430 if (GET_FIELD (insn, 25, 25))
00431 fput_fp_reg_r (GET_FIELD (insn, 27, 31), info);
00432 else
00433 fput_fp_reg (GET_FIELD (insn, 27, 31), info);
00434 break;
00435 case 'a':
00436 if (GET_FIELD (insn, 25, 25))
00437 fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
00438 else
00439 fput_fp_reg (GET_FIELD (insn, 6, 10), info);
00440 break;
00441
00442
00443
00444
00445
00446 case 'X':
00447 fputs_filtered (" ", info);
00448
00449
00450 case 'A':
00451 if (GET_FIELD (insn, 24, 24))
00452 fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
00453 else
00454 fput_fp_reg (GET_FIELD (insn, 6, 10), info);
00455 break;
00456 case 'b':
00457 if (GET_FIELD (insn, 25, 25))
00458 fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
00459 else
00460 fput_fp_reg (GET_FIELD (insn, 11, 15), info);
00461 break;
00462 case 'B':
00463 if (GET_FIELD (insn, 19, 19))
00464 fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
00465 else
00466 fput_fp_reg (GET_FIELD (insn, 11, 15), info);
00467 break;
00468 case 'C':
00469 {
00470 int reg = GET_FIELD (insn, 21, 22);
00471 reg |= GET_FIELD (insn, 16, 18) << 2;
00472 if (GET_FIELD (insn, 23, 23) != 0)
00473 fput_fp_reg_r (reg, info);
00474 else
00475 fput_fp_reg (reg, info);
00476 break;
00477 }
00478 case 'i':
00479 {
00480 int reg = GET_FIELD (insn, 6, 10);
00481
00482 reg |= (GET_FIELD (insn, 26, 26) << 4);
00483 fput_fp_reg (reg, info);
00484 break;
00485 }
00486 case 'j':
00487 {
00488 int reg = GET_FIELD (insn, 11, 15);
00489
00490 reg |= (GET_FIELD (insn, 26, 26) << 4);
00491 fput_fp_reg (reg, info);
00492 break;
00493 }
00494 case 'k':
00495 {
00496 int reg = GET_FIELD (insn, 27, 31);
00497
00498 reg |= (GET_FIELD (insn, 26, 26) << 4);
00499 fput_fp_reg (reg, info);
00500 break;
00501 }
00502 case 'l':
00503 {
00504 int reg = GET_FIELD (insn, 21, 25);
00505
00506 reg |= (GET_FIELD (insn, 26, 26) << 4);
00507 fput_fp_reg (reg, info);
00508 break;
00509 }
00510 case 'm':
00511 {
00512 int reg = GET_FIELD (insn, 16, 20);
00513
00514 reg |= (GET_FIELD (insn, 26, 26) << 4);
00515 fput_fp_reg (reg, info);
00516 break;
00517 }
00518
00519
00520
00521
00522
00523 case 'E':
00524 fputs_filtered (" ", info);
00525
00526
00527 case 'e':
00528 if (GET_FIELD (insn, 30, 30))
00529 fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
00530 else
00531 fput_fp_reg (GET_FIELD (insn, 11, 15), info);
00532 break;
00533 case 'x':
00534 fput_fp_reg (GET_FIELD (insn, 11, 15), info);
00535 break;
00536 }
00537 break;
00538
00539 case '5':
00540 fput_const (extract_5_load (insn), info);
00541 break;
00542 case 's':
00543 {
00544 int space = GET_FIELD (insn, 16, 17);
00545
00546 if (space != 0)
00547 (*info->fprintf_func) (info->stream, "sr%d", space);
00548 }
00549 break;
00550
00551 case 'S':
00552 (*info->fprintf_func) (info->stream, "sr%d",
00553 extract_3 (insn));
00554 break;
00555
00556
00557 case 'c':
00558 switch (*++s)
00559 {
00560 case 'x':
00561 (*info->fprintf_func)
00562 (info->stream, "%s",
00563 index_compl_names[GET_COMPL (insn)]);
00564 break;
00565 case 'X':
00566 (*info->fprintf_func)
00567 (info->stream, "%s ",
00568 index_compl_names[GET_COMPL (insn)]);
00569 break;
00570 case 'm':
00571 (*info->fprintf_func)
00572 (info->stream, "%s",
00573 short_ldst_compl_names[GET_COMPL (insn)]);
00574 break;
00575 case 'M':
00576 (*info->fprintf_func)
00577 (info->stream, "%s ",
00578 short_ldst_compl_names[GET_COMPL (insn)]);
00579 break;
00580 case 'A':
00581 (*info->fprintf_func)
00582 (info->stream, "%s ",
00583 short_bytes_compl_names[GET_COMPL (insn)]);
00584 break;
00585 case 's':
00586 (*info->fprintf_func)
00587 (info->stream, "%s",
00588 short_bytes_compl_names[GET_COMPL (insn)]);
00589 break;
00590 case 'c':
00591 case 'C':
00592 switch (GET_FIELD (insn, 20, 21))
00593 {
00594 case 1:
00595 (*info->fprintf_func) (info->stream, ",bc ");
00596 break;
00597 case 2:
00598 (*info->fprintf_func) (info->stream, ",sl ");
00599 break;
00600 default:
00601 (*info->fprintf_func) (info->stream, " ");
00602 }
00603 break;
00604 case 'd':
00605 switch (GET_FIELD (insn, 20, 21))
00606 {
00607 case 1:
00608 (*info->fprintf_func) (info->stream, ",co ");
00609 break;
00610 default:
00611 (*info->fprintf_func) (info->stream, " ");
00612 }
00613 break;
00614 case 'o':
00615 (*info->fprintf_func) (info->stream, ",o");
00616 break;
00617 case 'g':
00618 (*info->fprintf_func) (info->stream, ",gate");
00619 break;
00620 case 'p':
00621 (*info->fprintf_func) (info->stream, ",l,push");
00622 break;
00623 case 'P':
00624 (*info->fprintf_func) (info->stream, ",pop");
00625 break;
00626 case 'l':
00627 case 'L':
00628 (*info->fprintf_func) (info->stream, ",l");
00629 break;
00630 case 'w':
00631 (*info->fprintf_func)
00632 (info->stream, "%s ",
00633 read_write_names[GET_FIELD (insn, 25, 25)]);
00634 break;
00635 case 'W':
00636 (*info->fprintf_func) (info->stream, ",w");
00637 break;
00638 case 'r':
00639 if (GET_FIELD (insn, 23, 26) == 5)
00640 (*info->fprintf_func) (info->stream, ",r");
00641 break;
00642 case 'Z':
00643 if (GET_FIELD (insn, 26, 26))
00644 (*info->fprintf_func) (info->stream, ",m ");
00645 else
00646 (*info->fprintf_func) (info->stream, " ");
00647 break;
00648 case 'i':
00649 if (GET_FIELD (insn, 25, 25))
00650 (*info->fprintf_func) (info->stream, ",i");
00651 break;
00652 case 'z':
00653 if (!GET_FIELD (insn, 21, 21))
00654 (*info->fprintf_func) (info->stream, ",z");
00655 break;
00656 case 'a':
00657 (*info->fprintf_func)
00658 (info->stream, "%s",
00659 add_compl_names[GET_FIELD (insn, 20, 21)]);
00660 break;
00661 case 'Y':
00662 (*info->fprintf_func)
00663 (info->stream, ",dc%s",
00664 add_compl_names[GET_FIELD (insn, 20, 21)]);
00665 break;
00666 case 'y':
00667 (*info->fprintf_func)
00668 (info->stream, ",c%s",
00669 add_compl_names[GET_FIELD (insn, 20, 21)]);
00670 break;
00671 case 'v':
00672 if (GET_FIELD (insn, 20, 20))
00673 (*info->fprintf_func) (info->stream, ",tsv");
00674 break;
00675 case 't':
00676 (*info->fprintf_func) (info->stream, ",tc");
00677 if (GET_FIELD (insn, 20, 20))
00678 (*info->fprintf_func) (info->stream, ",tsv");
00679 break;
00680 case 'B':
00681 (*info->fprintf_func) (info->stream, ",db");
00682 if (GET_FIELD (insn, 20, 20))
00683 (*info->fprintf_func) (info->stream, ",tsv");
00684 break;
00685 case 'b':
00686 (*info->fprintf_func) (info->stream, ",b");
00687 if (GET_FIELD (insn, 20, 20))
00688 (*info->fprintf_func) (info->stream, ",tsv");
00689 break;
00690 case 'T':
00691 if (GET_FIELD (insn, 25, 25))
00692 (*info->fprintf_func) (info->stream, ",tc");
00693 break;
00694 case 'S':
00695
00696 if (*(s + 1) == '?')
00697 (*info->fprintf_func)
00698 (info->stream, "%s",
00699 signed_unsigned_names[GET_FIELD (insn, 21, 21)]);
00700 else
00701 (*info->fprintf_func)
00702 (info->stream, "%s ",
00703 signed_unsigned_names[GET_FIELD (insn, 21, 21)]);
00704 break;
00705 case 'h':
00706 (*info->fprintf_func)
00707 (info->stream, "%s",
00708 mix_half_names[GET_FIELD (insn, 17, 17)]);
00709 break;
00710 case 'H':
00711 (*info->fprintf_func)
00712 (info->stream, "%s ",
00713 saturation_names[GET_FIELD (insn, 24, 25)]);
00714 break;
00715 case '*':
00716 (*info->fprintf_func)
00717 (info->stream, ",%d%d%d%d ",
00718 GET_FIELD (insn, 17, 18), GET_FIELD (insn, 20, 21),
00719 GET_FIELD (insn, 22, 23), GET_FIELD (insn, 24, 25));
00720 break;
00721
00722 case 'q':
00723 {
00724 int m, a;
00725
00726 m = GET_FIELD (insn, 28, 28);
00727 a = GET_FIELD (insn, 29, 29);
00728
00729 if (m && !a)
00730 fputs_filtered (",ma ", info);
00731 else if (m && a)
00732 fputs_filtered (",mb ", info);
00733 else
00734 fputs_filtered (" ", info);
00735 break;
00736 }
00737
00738 case 'J':
00739 {
00740 int opc = GET_FIELD (insn, 0, 5);
00741
00742 if (opc == 0x16 || opc == 0x1e)
00743 {
00744 if (GET_FIELD (insn, 29, 29) == 0)
00745 fputs_filtered (",ma ", info);
00746 else
00747 fputs_filtered (",mb ", info);
00748 }
00749 else
00750 fputs_filtered (" ", info);
00751 break;
00752 }
00753
00754 case 'e':
00755 {
00756 int opc = GET_FIELD (insn, 0, 5);
00757
00758 if (opc == 0x13 || opc == 0x1b)
00759 {
00760 if (GET_FIELD (insn, 18, 18) == 1)
00761 fputs_filtered (",mb ", info);
00762 else
00763 fputs_filtered (",ma ", info);
00764 }
00765 else if (opc == 0x17 || opc == 0x1f)
00766 {
00767 if (GET_FIELD (insn, 31, 31) == 1)
00768 fputs_filtered (",ma ", info);
00769 else
00770 fputs_filtered (",mb ", info);
00771 }
00772 else
00773 fputs_filtered (" ", info);
00774
00775 break;
00776 }
00777 }
00778 break;
00779
00780
00781 case '?':
00782 {
00783 s++;
00784 switch (*s)
00785 {
00786 case 'f':
00787 (*info->fprintf_func)
00788 (info->stream, "%s ",
00789 float_comp_names[GET_FIELD (insn, 27, 31)]);
00790 break;
00791
00792
00793
00794
00795
00796 case 't':
00797 fputs_filtered
00798 (compare_cond_names[GET_FIELD (insn, 16, 18)], info);
00799 break;
00800 case 'n':
00801 fputs_filtered
00802 (compare_cond_names[GET_FIELD (insn, 16, 18)
00803 + GET_FIELD (insn, 4, 4) * 8],
00804 info);
00805 break;
00806 case 'N':
00807 fputs_filtered
00808 (compare_cond_64_names[GET_FIELD (insn, 16, 18)
00809 + GET_FIELD (insn, 2, 2) * 8],
00810 info);
00811 break;
00812 case 'Q':
00813 fputs_filtered
00814 (cmpib_cond_64_names[GET_FIELD (insn, 16, 18)],
00815 info);
00816 break;
00817 case '@':
00818 fputs_filtered
00819 (add_cond_names[GET_FIELD (insn, 16, 18)
00820 + GET_FIELD (insn, 4, 4) * 8],
00821 info);
00822 break;
00823 case 's':
00824 (*info->fprintf_func)
00825 (info->stream, "%s ",
00826 compare_cond_names[GET_COND (insn)]);
00827 break;
00828 case 'S':
00829 (*info->fprintf_func)
00830 (info->stream, "%s ",
00831 compare_cond_64_names[GET_COND (insn)]);
00832 break;
00833 case 'a':
00834 (*info->fprintf_func)
00835 (info->stream, "%s ",
00836 add_cond_names[GET_COND (insn)]);
00837 break;
00838 case 'A':
00839 (*info->fprintf_func)
00840 (info->stream, "%s ",
00841 add_cond_64_names[GET_COND (insn)]);
00842 break;
00843 case 'd':
00844 (*info->fprintf_func)
00845 (info->stream, "%s",
00846 add_cond_names[GET_FIELD (insn, 16, 18)]);
00847 break;
00848
00849 case 'W':
00850 (*info->fprintf_func)
00851 (info->stream, "%s",
00852 wide_add_cond_names[GET_FIELD (insn, 16, 18) +
00853 GET_FIELD (insn, 4, 4) * 8]);
00854 break;
00855
00856 case 'l':
00857 (*info->fprintf_func)
00858 (info->stream, "%s ",
00859 logical_cond_names[GET_COND (insn)]);
00860 break;
00861 case 'L':
00862 (*info->fprintf_func)
00863 (info->stream, "%s ",
00864 logical_cond_64_names[GET_COND (insn)]);
00865 break;
00866 case 'u':
00867 (*info->fprintf_func)
00868 (info->stream, "%s ",
00869 unit_cond_names[GET_COND (insn)]);
00870 break;
00871 case 'U':
00872 (*info->fprintf_func)
00873 (info->stream, "%s ",
00874 unit_cond_64_names[GET_COND (insn)]);
00875 break;
00876 case 'y':
00877 case 'x':
00878 case 'b':
00879 (*info->fprintf_func)
00880 (info->stream, "%s",
00881 shift_cond_names[GET_FIELD (insn, 16, 18)]);
00882
00883
00884
00885 if (s[1] != 'n')
00886 (*info->fprintf_func) (info->stream, " ");
00887 break;
00888 case 'X':
00889 (*info->fprintf_func)
00890 (info->stream, "%s ",
00891 shift_cond_64_names[GET_FIELD (insn, 16, 18)]);
00892 break;
00893 case 'B':
00894 (*info->fprintf_func)
00895 (info->stream, "%s",
00896 bb_cond_64_names[GET_FIELD (insn, 16, 16)]);
00897
00898
00899
00900 if (s[1] != 'n')
00901 (*info->fprintf_func) (info->stream, " ");
00902 break;
00903 }
00904 break;
00905 }
00906
00907 case 'V':
00908 fput_const (extract_5_store (insn), info);
00909 break;
00910 case 'r':
00911 fput_const (extract_5r_store (insn), info);
00912 break;
00913 case 'R':
00914 fput_const (extract_5R_store (insn), info);
00915 break;
00916 case 'U':
00917 fput_const (extract_10U_store (insn), info);
00918 break;
00919 case 'B':
00920 case 'Q':
00921 fput_const (extract_5Q_store (insn), info);
00922 break;
00923 case 'i':
00924 fput_const (extract_11 (insn), info);
00925 break;
00926 case 'j':
00927 fput_const (extract_14 (insn), info);
00928 break;
00929 case 'k':
00930 fput_const (extract_21 (insn), info);
00931 break;
00932 case '<':
00933 case 'l':
00934
00935 fput_const (extract_16 (insn), info);
00936 break;
00937 case 'n':
00938 if (insn & 0x2)
00939 (*info->fprintf_func) (info->stream, ",n ");
00940 else
00941 (*info->fprintf_func) (info->stream, " ");
00942 break;
00943 case 'N':
00944 if ((insn & 0x20) && s[1])
00945 (*info->fprintf_func) (info->stream, ",n ");
00946 else if (insn & 0x20)
00947 (*info->fprintf_func) (info->stream, ",n");
00948 else if (s[1])
00949 (*info->fprintf_func) (info->stream, " ");
00950 break;
00951 case 'w':
00952 (*info->print_address_func)
00953 (memaddr + 8 + extract_12 (insn), info);
00954 break;
00955 case 'W':
00956
00957 (*info->print_address_func)
00958 ((memaddr + 8 + extract_17 (insn)), info);
00959 break;
00960 case 'z':
00961
00962
00963
00964 fput_const (extract_17 (insn), info);
00965 break;
00966
00967 case 'Z':
00968
00969 (*info->fprintf_func) (info->stream, "%%r1");
00970 break;
00971
00972 case 'Y':
00973
00974 (*info->fprintf_func) (info->stream, "%%sr0,%%r31");
00975 break;
00976
00977 case '@':
00978 (*info->fprintf_func) (info->stream, "0");
00979 break;
00980
00981 case '.':
00982 (*info->fprintf_func) (info->stream, "%d",
00983 GET_FIELD (insn, 24, 25));
00984 break;
00985 case '*':
00986 (*info->fprintf_func) (info->stream, "%d",
00987 GET_FIELD (insn, 22, 25));
00988 break;
00989 case '!':
00990 (*info->fprintf_func) (info->stream, "%%sar");
00991 break;
00992 case 'p':
00993 (*info->fprintf_func) (info->stream, "%d",
00994 31 - GET_FIELD (insn, 22, 26));
00995 break;
00996 case '~':
00997 {
00998 int num;
00999 num = GET_FIELD (insn, 20, 20) << 5;
01000 num |= GET_FIELD (insn, 22, 26);
01001 (*info->fprintf_func) (info->stream, "%d", 63 - num);
01002 break;
01003 }
01004 case 'P':
01005 (*info->fprintf_func) (info->stream, "%d",
01006 GET_FIELD (insn, 22, 26));
01007 break;
01008 case 'q':
01009 {
01010 int num;
01011 num = GET_FIELD (insn, 20, 20) << 5;
01012 num |= GET_FIELD (insn, 22, 26);
01013 (*info->fprintf_func) (info->stream, "%d", num);
01014 break;
01015 }
01016 case 'T':
01017 (*info->fprintf_func) (info->stream, "%d",
01018 32 - GET_FIELD (insn, 27, 31));
01019 break;
01020 case '%':
01021 {
01022 int num;
01023 num = (GET_FIELD (insn, 23, 23) + 1) * 32;
01024 num -= GET_FIELD (insn, 27, 31);
01025 (*info->fprintf_func) (info->stream, "%d", num);
01026 break;
01027 }
01028 case '|':
01029 {
01030 int num;
01031 num = (GET_FIELD (insn, 19, 19) + 1) * 32;
01032 num -= GET_FIELD (insn, 27, 31);
01033 (*info->fprintf_func) (info->stream, "%d", num);
01034 break;
01035 }
01036 case '$':
01037 fput_const (GET_FIELD (insn, 20, 28), info);
01038 break;
01039 case 'A':
01040 fput_const (GET_FIELD (insn, 6, 18), info);
01041 break;
01042 case 'D':
01043 fput_const (GET_FIELD (insn, 6, 31), info);
01044 break;
01045 case 'v':
01046 (*info->fprintf_func) (info->stream, ",%d",
01047 GET_FIELD (insn, 23, 25));
01048 break;
01049 case 'O':
01050 fput_const ((GET_FIELD (insn, 6,20) << 5 |
01051 GET_FIELD (insn, 27, 31)), info);
01052 break;
01053 case 'o':
01054 fput_const (GET_FIELD (insn, 6, 20), info);
01055 break;
01056 case '2':
01057 fput_const ((GET_FIELD (insn, 6, 22) << 5 |
01058 GET_FIELD (insn, 27, 31)), info);
01059 break;
01060 case '1':
01061 fput_const ((GET_FIELD (insn, 11, 20) << 5 |
01062 GET_FIELD (insn, 27, 31)), info);
01063 break;
01064 case '0':
01065 fput_const ((GET_FIELD (insn, 16, 20) << 5 |
01066 GET_FIELD (insn, 27, 31)), info);
01067 break;
01068 case 'u':
01069 (*info->fprintf_func) (info->stream, ",%d",
01070 GET_FIELD (insn, 23, 25));
01071 break;
01072 case 'F':
01073
01074
01075 if (s[1] == 'G' || s[1] == '?')
01076 fputs_filtered
01077 (float_format_names[GET_FIELD (insn, 19, 20)], info);
01078 else
01079 (*info->fprintf_func)
01080 (info->stream, "%s ",
01081 float_format_names[GET_FIELD (insn, 19, 20)]);
01082 break;
01083 case 'G':
01084 (*info->fprintf_func)
01085 (info->stream, "%s ",
01086 float_format_names[GET_FIELD (insn, 17, 18)]);
01087 break;
01088 case 'H':
01089 if (GET_FIELD (insn, 26, 26) == 1)
01090 (*info->fprintf_func) (info->stream, "%s ",
01091 float_format_names[0]);
01092 else
01093 (*info->fprintf_func) (info->stream, "%s ",
01094 float_format_names[1]);
01095 break;
01096 case 'I':
01097
01098
01099 if (s[1] == '?')
01100 fputs_filtered
01101 (float_format_names[GET_FIELD (insn, 20, 20)], info);
01102 else
01103 (*info->fprintf_func)
01104 (info->stream, "%s ",
01105 float_format_names[GET_FIELD (insn, 20, 20)]);
01106 break;
01107
01108 case 'J':
01109 fput_const (extract_14 (insn), info);
01110 break;
01111
01112 case '#':
01113 {
01114 int sign = GET_FIELD (insn, 31, 31);
01115 int imm10 = GET_FIELD (insn, 18, 27);
01116 int disp;
01117
01118 if (sign)
01119 disp = (-1 << 10) | imm10;
01120 else
01121 disp = imm10;
01122
01123 disp <<= 3;
01124 fput_const (disp, info);
01125 break;
01126 }
01127 case 'K':
01128 case 'd':
01129 {
01130 int sign = GET_FIELD (insn, 31, 31);
01131 int imm11 = GET_FIELD (insn, 18, 28);
01132 int disp;
01133
01134 if (sign)
01135 disp = (-1 << 11) | imm11;
01136 else
01137 disp = imm11;
01138
01139 disp <<= 2;
01140 fput_const (disp, info);
01141 break;
01142 }
01143
01144 case '>':
01145 case 'y':
01146 {
01147
01148 int disp = extract_16 (insn);
01149 disp &= ~3;
01150 fput_const (disp, info);
01151 break;
01152 }
01153
01154 case '&':
01155 {
01156
01157 int disp = extract_16 (insn);
01158 disp &= ~7;
01159 fput_const (disp, info);
01160 break;
01161 }
01162
01163 case '_':
01164 break;
01165
01166 case '{':
01167 {
01168 int sub = GET_FIELD (insn, 14, 16);
01169 int df = GET_FIELD (insn, 17, 18);
01170 int sf = GET_FIELD (insn, 19, 20);
01171 const char * const * source = float_format_names;
01172 const char * const * dest = float_format_names;
01173 char *t = "";
01174 if (sub == 4)
01175 {
01176 fputs_filtered (",UND ", info);
01177 break;
01178 }
01179 if ((sub & 3) == 3)
01180 t = ",t";
01181 if ((sub & 3) == 1)
01182 source = sub & 4 ? fcnv_ufixed_names : fcnv_fixed_names;
01183 if (sub & 2)
01184 dest = sub & 4 ? fcnv_ufixed_names : fcnv_fixed_names;
01185
01186 (*info->fprintf_func) (info->stream, "%s%s%s ",
01187 t, source[sf], dest[df]);
01188 break;
01189 }
01190
01191 case 'm':
01192 {
01193 int y = GET_FIELD (insn, 16, 18);
01194
01195 if (y != 1)
01196 fput_const ((y ^ 1) - 1, info);
01197 }
01198 break;
01199
01200 case 'h':
01201 {
01202 int cbit;
01203
01204 cbit = GET_FIELD (insn, 16, 18);
01205
01206 if (cbit > 0)
01207 (*info->fprintf_func) (info->stream, ",%d", cbit - 1);
01208 break;
01209 }
01210
01211 case '=':
01212 {
01213 int cond = GET_FIELD (insn, 27, 31);
01214
01215 if (cond == 0)
01216 fputs_filtered (" ", info);
01217 else if (cond == 1)
01218 fputs_filtered ("acc ", info);
01219 else if (cond == 2)
01220 fputs_filtered ("rej ", info);
01221 else if (cond == 5)
01222 fputs_filtered ("acc8 ", info);
01223 else if (cond == 6)
01224 fputs_filtered ("rej8 ", info);
01225 else if (cond == 9)
01226 fputs_filtered ("acc6 ", info);
01227 else if (cond == 13)
01228 fputs_filtered ("acc4 ", info);
01229 else if (cond == 17)
01230 fputs_filtered ("acc2 ", info);
01231 break;
01232 }
01233
01234 case 'X':
01235 (*info->print_address_func)
01236 (memaddr + 8 + extract_22 (insn), info);
01237 break;
01238 case 'L':
01239 fputs_filtered (",%r2", info);
01240 break;
01241 default:
01242 (*info->fprintf_func) (info->stream, "%c", *s);
01243 break;
01244 }
01245 }
01246 return sizeof(insn);
01247 }
01248 }
01249 (*info->fprintf_func) (info->stream, "#%8x", insn);
01250 return sizeof(insn);
01251 }