1 /* Disassembler for the PA-RISC. Somewhat derived from sparc-pinsn.c. 2 Copyright 1989, 1990, 1992, 1993 Free Software Foundation, Inc. 3 4 Contributed by the Center for Software Science at the 5 University of Utah (pa-gdb-bugs@cs.utah.edu). 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 #include "sysdep.h" 22 #include "dis-asm.h" 23 #include "libhppa.h" 24 #include "opcode/hppa.h" 25 26 /* Integer register names, indexed by the numbers which appear in the 27 opcodes. */ 28 static const char *const reg_names[] = 29 {"flags", "r1", "rp", "r3", "r4", "r5", "r6", "r7", "r8", "r9", 30 "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", 31 "r20", "r21", "r22", "r23", "r24", "r25", "r26", "dp", "ret0", "ret1", 32 "sp", "r31"}; 33 34 /* Floating point register names, indexed by the numbers which appear in the 35 opcodes. */ 36 static const char *const fp_reg_names[] = 37 {"fpsr", "fpe2", "fpe4", "fpe6", 38 "fr4", "fr5", "fr6", "fr7", "fr8", 39 "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15", 40 "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23", 41 "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31"}; 42 43 typedef unsigned int CORE_ADDR; 44 45 /* Get at various relevent fields of an instruction word. */ 46 47 #define MASK_5 0x1f 48 #define MASK_10 0x3ff 49 #define MASK_11 0x7ff 50 #define MASK_14 0x3fff 51 #define MASK_21 0x1fffff 52 53 /* This macro gets bit fields using HP's numbering (MSB = 0) */ 54 55 #define GET_FIELD(X, FROM, TO) \ 56 ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1)) 57 58 /* Some of these have been converted to 2-d arrays because they 59 consume less storage this way. If the maintenance becomes a 60 problem, convert them back to const 1-d pointer arrays. */ 61 static const char *const control_reg[] = { 62 "rctr", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", 63 "pidr1", "pidr2", "ccr", "sar", "pidr3", "pidr4", 64 "iva", "eiem", "itmr", "pcsq", "pcoq", "iir", "isr", 65 "ior", "ipsw", "eirr", "tr0", "tr1", "tr2", "tr3", 66 "tr4", "tr5", "tr6", "tr7" 67 }; 68 69 static const char *const compare_cond_names[] = { 70 "", ",=", ",<", ",<=", ",<<", ",<<=", ",sv", ",od", 71 ",tr", ",<>", ",>=", ",>", ",>>=", ",>>", ",nsv", ",ev" 72 }; 73 static const char *const compare_cond_64_names[] = { 74 "", ",*=", ",*<", ",*<=", ",*<<", ",*<<=", ",*sv", ",*od", 75 ",*tr", ",*<>", ",*>=", ",*>", ",*>>=", ",*>>", ",*nsv", ",*ev" 76 }; 77 static const char *const cmpib_cond_64_names[] = { 78 ",*<<", ",*=", ",*<", ",*<=", ",*>>=", ",*<>", ",*>=", ",*>" 79 }; 80 static const char *const add_cond_names[] = { 81 "", ",=", ",<", ",<=", ",nuv", ",znv", ",sv", ",od", 82 ",tr", ",<>", ",>=", ",>", ",uv", ",vnz", ",nsv", ",ev" 83 }; 84 static const char *const add_cond_64_names[] = { 85 "", ",*=", ",*<", ",*<=", ",*nuv", ",*znv", ",*sv", ",*od", 86 ",*tr", ",*<>", ",*>=", ",*>", ",*uv", ",*vnz", ",*nsv", ",*ev" 87 }; 88 static const char *const wide_add_cond_names[] = { 89 "", ",=", ",<", ",<=", ",nuv", ",*=", ",*<", ",*<=", 90 ",tr", ",<>", ",>=", ",>", ",uv", ",*<>", ",*>=", ",*>" 91 }; 92 static const char *const logical_cond_names[] = { 93 "", ",=", ",<", ",<=", 0, 0, 0, ",od", 94 ",tr", ",<>", ",>=", ",>", 0, 0, 0, ",ev"}; 95 static const char *const logical_cond_64_names[] = { 96 "", ",*=", ",*<", ",*<=", 0, 0, 0, ",*od", 97 ",*tr", ",*<>", ",*>=", ",*>", 0, 0, 0, ",*ev"}; 98 static const char *const unit_cond_names[] = { 99 "", ",swz", ",sbz", ",shz", ",sdc", ",swc", ",sbc", ",shc", 100 ",tr", ",nwz", ",nbz", ",nhz", ",ndc", ",nwc", ",nbc", ",nhc" 101 }; 102 static const char *const unit_cond_64_names[] = { 103 "", ",*swz", ",*sbz", ",*shz", ",*sdc", ",*swc", ",*sbc", ",*shc", 104 ",*tr", ",*nwz", ",*nbz", ",*nhz", ",*ndc", ",*nwc", ",*nbc", ",*nhc" 105 }; 106 static const char *const shift_cond_names[] = { 107 "", ",=", ",<", ",od", ",tr", ",<>", ",>=", ",ev" 108 }; 109 static const char *const shift_cond_64_names[] = { 110 "", ",*=", ",*<", ",*od", ",*tr", ",*<>", ",*>=", ",*ev" 111 }; 112 static const char *const bb_cond_64_names[] = { 113 ",*<", ",*>=" 114 }; 115 static const char *const index_compl_names[] = {"", ",m", ",s", ",sm"}; 116 static const char *const short_ldst_compl_names[] = {"", ",ma", "", ",mb"}; 117 static const char *const short_bytes_compl_names[] = { 118 "", ",b,m", ",e", ",e,m" 119 }; 120 static const char *const float_format_names[] = {",sgl", ",dbl", "", ",quad"}; 121 static const char *const float_comp_names[] = 122 { 123 ",false?", ",false", ",?", ",!<=>", ",=", ",=t", ",?=", ",!<>", 124 ",!?>=", ",<", ",?<", ",!>=", ",!?>", ",<=", ",?<=", ",!>", 125 ",!?<=", ",>", ",?>", ",!<=", ",!?<", ",>=", ",?>=", ",!<", 126 ",!?=", ",<>", ",!=", ",!=t", ",!?", ",<=>", ",true?", ",true" 127 }; 128 static const char *const signed_unsigned_names[] = {",u", ",s"}; 129 static const char *const mix_half_names[] = {",l", ",r"}; 130 static const char *const saturation_names[] = {",us", ",ss", 0, ""}; 131 static const char *const read_write_names[] = {",r", ",w"}; 132 static const char *const add_compl_names[] = { 0, "", ",l", ",tsv" }; 133 134 /* For a bunch of different instructions form an index into a 135 completer name table. */ 136 #define GET_COMPL(insn) (GET_FIELD (insn, 26, 26) | \ 137 GET_FIELD (insn, 18, 18) << 1) 138 139 #define GET_COND(insn) (GET_FIELD ((insn), 16, 18) + \ 140 (GET_FIELD ((insn), 19, 19) ? 8 : 0)) 141 142 /* Utility function to print registers. Put these first, so gcc's function 143 inlining can do its stuff. */ 144 145 #define fputs_filtered(STR,F) (*info->fprintf_func) (info->stream, "%s", STR) 146 147 static void 148 fput_reg (reg, info) 149 unsigned reg; 150 disassemble_info *info; 151 { 152 (*info->fprintf_func) (info->stream, reg ? reg_names[reg] : "r0"); 153 } 154 155 static void 156 fput_fp_reg (reg, info) 157 unsigned reg; 158 disassemble_info *info; 159 { 160 (*info->fprintf_func) (info->stream, reg ? fp_reg_names[reg] : "fr0"); 161 } 162 163 static void 164 fput_fp_reg_r (reg, info) 165 unsigned reg; 166 disassemble_info *info; 167 { 168 /* Special case floating point exception registers. */ 169 if (reg < 4) 170 (*info->fprintf_func) (info->stream, "fpe%d", reg * 2 + 1); 171 else 172 (*info->fprintf_func) (info->stream, "%sR", reg ? fp_reg_names[reg] 173 : "fr0"); 174 } 175 176 static void 177 fput_creg (reg, info) 178 unsigned reg; 179 disassemble_info *info; 180 { 181 (*info->fprintf_func) (info->stream, control_reg[reg]); 182 } 183 184 /* print constants with sign */ 185 186 static void 187 fput_const (num, info) 188 unsigned num; 189 disassemble_info *info; 190 { 191 if ((int)num < 0) 192 (*info->fprintf_func) (info->stream, "-%x", -(int)num); 193 else 194 (*info->fprintf_func) (info->stream, "%x", num); 195 } 196 197 /* Routines to extract various sized constants out of hppa 198 instructions. */ 199 200 /* extract a 3-bit space register number from a be, ble, mtsp or mfsp */ 201 static int 202 extract_3 (word) 203 unsigned word; 204 { 205 return GET_FIELD (word, 18, 18) << 2 | GET_FIELD (word, 16, 17); 206 } 207 208 static int 209 extract_5_load (word) 210 unsigned word; 211 { 212 return low_sign_extend (word >> 16 & MASK_5, 5); 213 } 214 215 /* extract the immediate field from a st{bhw}s instruction */ 216 static int 217 extract_5_store (word) 218 unsigned word; 219 { 220 return low_sign_extend (word & MASK_5, 5); 221 } 222 223 /* extract the immediate field from a break instruction */ 224 static unsigned 225 extract_5r_store (word) 226 unsigned word; 227 { 228 return (word & MASK_5); 229 } 230 231 /* extract the immediate field from a {sr}sm instruction */ 232 static unsigned 233 extract_5R_store (word) 234 unsigned word; 235 { 236 return (word >> 16 & MASK_5); 237 } 238 239 /* extract the 10 bit immediate field from a {sr}sm instruction */ 240 static unsigned 241 extract_10U_store (word) 242 unsigned word; 243 { 244 return (word >> 16 & MASK_10); 245 } 246 247 /* extract the immediate field from a bb instruction */ 248 static unsigned 249 extract_5Q_store (word) 250 unsigned word; 251 { 252 return (word >> 21 & MASK_5); 253 } 254 255 /* extract an 11 bit immediate field */ 256 static int 257 extract_11 (word) 258 unsigned word; 259 { 260 return low_sign_extend (word & MASK_11, 11); 261 } 262 263 /* extract a 14 bit immediate field */ 264 static int 265 extract_14 (word) 266 unsigned word; 267 { 268 return low_sign_extend (word & MASK_14, 14); 269 } 270 271 /* extract a 21 bit constant */ 272 273 static int 274 extract_21 (word) 275 unsigned word; 276 { 277 int val; 278 279 word &= MASK_21; 280 word <<= 11; 281 val = GET_FIELD (word, 20, 20); 282 val <<= 11; 283 val |= GET_FIELD (word, 9, 19); 284 val <<= 2; 285 val |= GET_FIELD (word, 5, 6); 286 val <<= 5; 287 val |= GET_FIELD (word, 0, 4); 288 val <<= 2; 289 val |= GET_FIELD (word, 7, 8); 290 return sign_extend (val, 21) << 11; 291 } 292 293 /* extract a 12 bit constant from branch instructions */ 294 295 static int 296 extract_12 (word) 297 unsigned word; 298 { 299 return sign_extend (GET_FIELD (word, 19, 28) | 300 GET_FIELD (word, 29, 29) << 10 | 301 (word & 0x1) << 11, 12) << 2; 302 } 303 304 /* extract a 17 bit constant from branch instructions, returning the 305 19 bit signed value. */ 306 307 static int 308 extract_17 (word) 309 unsigned word; 310 { 311 return sign_extend (GET_FIELD (word, 19, 28) | 312 GET_FIELD (word, 29, 29) << 10 | 313 GET_FIELD (word, 11, 15) << 11 | 314 (word & 0x1) << 16, 17) << 2; 315 } 316 317 static int 318 extract_22 (word) 319 unsigned word; 320 { 321 return sign_extend (GET_FIELD (word, 19, 28) | 322 GET_FIELD (word, 29, 29) << 10 | 323 GET_FIELD (word, 11, 15) << 11 | 324 GET_FIELD (word, 6, 10) << 16 | 325 (word & 0x1) << 21, 22) << 2; 326 } 327 328 /* Print one instruction. */ 329 int 330 print_insn_hppa (memaddr, info) 331 bfd_vma memaddr; 332 disassemble_info *info; 333 { 334 bfd_byte buffer[4]; 335 unsigned int insn, i; 336 337 { 338 int status = 339 (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info); 340 if (status != 0) 341 { 342 (*info->memory_error_func) (status, memaddr, info); 343 return -1; 344 } 345 } 346 347 insn = bfd_getb32 (buffer); 348 349 for (i = 0; i < NUMOPCODES; ++i) 350 { 351 const struct pa_opcode *opcode = &pa_opcodes[i]; 352 if ((insn & opcode->mask) == opcode->match) 353 { 354 register const char *s; 355 356 (*info->fprintf_func) (info->stream, "%s", opcode->name); 357 358 if (!strchr ("cfCY?-+nHNZFIuv", opcode->args[0])) 359 (*info->fprintf_func) (info->stream, " "); 360 for (s = opcode->args; *s != '\0'; ++s) 361 { 362 switch (*s) 363 { 364 case 'x': 365 fput_reg (GET_FIELD (insn, 11, 15), info); 366 break; 367 case 'a': 368 case 'b': 369 fput_reg (GET_FIELD (insn, 6, 10), info); 370 break; 371 case '^': 372 fput_creg (GET_FIELD (insn, 6, 10), info); 373 break; 374 case 't': 375 fput_reg (GET_FIELD (insn, 27, 31), info); 376 break; 377 378 /* Handle floating point registers. */ 379 case 'f': 380 switch (*++s) 381 { 382 case 't': 383 fput_fp_reg (GET_FIELD (insn, 27, 31), info); 384 break; 385 case 'T': 386 if (GET_FIELD (insn, 25, 25)) 387 fput_fp_reg_r (GET_FIELD (insn, 27, 31), info); 388 else 389 fput_fp_reg (GET_FIELD (insn, 27, 31), info); 390 break; 391 case 'a': 392 if (GET_FIELD (insn, 25, 25)) 393 fput_fp_reg_r (GET_FIELD (insn, 6, 10), info); 394 else 395 fput_fp_reg (GET_FIELD (insn, 6, 10), info); 396 break; 397 398 /* 'fA' will not generate a space before the regsiter 399 name. Normally that is fine. Except that it 400 causes problems with xmpyu which has no FP format 401 completer. */ 402 case 'X': 403 fputs_filtered (" ", info); 404 405 /* FALLTHRU */ 406 407 case 'A': 408 if (GET_FIELD (insn, 24, 24)) 409 fput_fp_reg_r (GET_FIELD (insn, 6, 10), info); 410 else 411 fput_fp_reg (GET_FIELD (insn, 6, 10), info); 412 413 break; 414 case 'b': 415 if (GET_FIELD (insn, 25, 25)) 416 fput_fp_reg_r (GET_FIELD (insn, 11, 15), info); 417 else 418 fput_fp_reg (GET_FIELD (insn, 11, 15), info); 419 break; 420 case 'B': 421 if (GET_FIELD (insn, 19, 19)) 422 fput_fp_reg_r (GET_FIELD (insn, 11, 15), info); 423 else 424 fput_fp_reg (GET_FIELD (insn, 11, 15), info); 425 break; 426 case 'C': 427 { 428 int reg = GET_FIELD (insn, 21, 22); 429 reg |= GET_FIELD (insn, 16, 18) << 2; 430 if (GET_FIELD (insn, 23, 23) != 0) 431 fput_fp_reg_r (reg, info); 432 else 433 fput_fp_reg (reg, info); 434 break; 435 } 436 case 'i': 437 { 438 int reg = GET_FIELD (insn, 6, 10); 439 440 reg |= (GET_FIELD (insn, 26, 26) << 4); 441 fput_fp_reg (reg, info); 442 break; 443 } 444 case 'j': 445 { 446 int reg = GET_FIELD (insn, 11, 15); 447 448 reg |= (GET_FIELD (insn, 26, 26) << 4); 449 fput_fp_reg (reg, info); 450 break; 451 } 452 case 'k': 453 { 454 int reg = GET_FIELD (insn, 27, 31); 455 456 reg |= (GET_FIELD (insn, 26, 26) << 4); 457 fput_fp_reg (reg, info); 458 break; 459 } 460 case 'l': 461 { 462 int reg = GET_FIELD (insn, 21, 25); 463 464 reg |= (GET_FIELD (insn, 26, 26) << 4); 465 fput_fp_reg (reg, info); 466 break; 467 } 468 case 'm': 469 { 470 int reg = GET_FIELD (insn, 16, 20); 471 472 reg |= (GET_FIELD (insn, 26, 26) << 4); 473 fput_fp_reg (reg, info); 474 break; 475 } 476 case 'e': 477 if (GET_FIELD (insn, 25, 25)) 478 fput_fp_reg_r (GET_FIELD (insn, 11, 15), info); 479 else 480 fput_fp_reg (GET_FIELD (insn, 11, 15), info); 481 break; 482 483 } 484 break; 485 486 case '5': 487 fput_const (extract_5_load (insn), info); 488 break; 489 case 's': 490 (*info->fprintf_func) (info->stream, 491 "sr%d", GET_FIELD (insn, 16, 17)); 492 break; 493 494 case 'S': 495 (*info->fprintf_func) (info->stream, "sr%d", extract_3 (insn)); 496 break; 497 498 /* Handle completers. */ 499 case 'c': 500 switch (*++s) 501 { 502 case 'x': 503 (*info->fprintf_func) (info->stream, "%s ", 504 index_compl_names[GET_COMPL (insn)]); 505 break; 506 case 'm': 507 (*info->fprintf_func) (info->stream, "%s ", 508 short_ldst_compl_names[GET_COMPL (insn)]); 509 break; 510 case 's': 511 (*info->fprintf_func) (info->stream, "%s ", 512 short_bytes_compl_names[GET_COMPL (insn)]); 513 break; 514 case 'c': 515 case 'C': 516 switch (GET_FIELD (insn, 20, 21)) 517 { 518 case 1: 519 (*info->fprintf_func) (info->stream, ",bc "); 520 break; 521 case 2: 522 (*info->fprintf_func) (info->stream, ",sl "); 523 break; 524 default: 525 (*info->fprintf_func) (info->stream, " "); 526 } 527 break; 528 case 'd': 529 switch (GET_FIELD (insn, 20, 21)) 530 { 531 case 1: 532 (*info->fprintf_func) (info->stream, ",co "); 533 break; 534 default: 535 (*info->fprintf_func) (info->stream, " "); 536 } 537 break; 538 case 'o': 539 (*info->fprintf_func) (info->stream, ",o"); 540 break; 541 case 'g': 542 (*info->fprintf_func) (info->stream, ",gate"); 543 break; 544 case 'p': 545 (*info->fprintf_func) (info->stream, ",l,push"); 546 break; 547 case 'P': 548 (*info->fprintf_func) (info->stream, ",pop"); 549 break; 550 case 'l': 551 case 'L': 552 (*info->fprintf_func) (info->stream, ",l"); 553 break; 554 case 'w': 555 (*info->fprintf_func) (info->stream, "%s ", 556 read_write_names[GET_FIELD (insn, 25, 25)]); 557 break; 558 case 'W': 559 (*info->fprintf_func) (info->stream, ",w"); 560 break; 561 case 'r': 562 if (GET_FIELD (insn, 23, 26) == 5) 563 (*info->fprintf_func) (info->stream, ",r"); 564 break; 565 case 'Z': 566 if (GET_FIELD (insn, 26, 26)) 567 (*info->fprintf_func) (info->stream, ",m "); 568 else 569 (*info->fprintf_func) (info->stream, " "); 570 break; 571 case 'i': 572 if (GET_FIELD (insn, 25, 25)) 573 (*info->fprintf_func) (info->stream, ",i"); 574 break; 575 case 'z': 576 if (!GET_FIELD (insn, 21, 21)) 577 (*info->fprintf_func) (info->stream, ",z"); 578 break; 579 case 'a': 580 (*info->fprintf_func) 581 (info->stream, "%s", add_compl_names[GET_FIELD 582 (insn, 20, 21)]); 583 break; 584 case 'Y': 585 (*info->fprintf_func) 586 (info->stream, ",dc%s", add_compl_names[GET_FIELD 587 (insn, 20, 21)]); 588 break; 589 case 'y': 590 (*info->fprintf_func) 591 (info->stream, ",c%s", add_compl_names[GET_FIELD 592 (insn, 20, 21)]); 593 break; 594 case 'v': 595 if (GET_FIELD (insn, 20, 20)) 596 (*info->fprintf_func) (info->stream, ",tsv"); 597 break; 598 case 't': 599 (*info->fprintf_func) (info->stream, ",tc"); 600 if (GET_FIELD (insn, 20, 20)) 601 (*info->fprintf_func) (info->stream, ",tsv"); 602 break; 603 case 'B': 604 (*info->fprintf_func) (info->stream, ",db"); 605 if (GET_FIELD (insn, 20, 20)) 606 (*info->fprintf_func) (info->stream, ",tsv"); 607 break; 608 case 'b': 609 (*info->fprintf_func) (info->stream, ",b"); 610 if (GET_FIELD (insn, 20, 20)) 611 (*info->fprintf_func) (info->stream, ",tsv"); 612 break; 613 case 'T': 614 if (GET_FIELD (insn, 25, 25)) 615 (*info->fprintf_func) (info->stream, ",tc"); 616 break; 617 case 'S': 618 /* EXTRD/W has a following condition. */ 619 if (*(s + 1) == '?') 620 (*info->fprintf_func) 621 (info->stream, "%s", signed_unsigned_names[GET_FIELD 622 (insn, 21, 21)]); 623 else 624 (*info->fprintf_func) 625 (info->stream, "%s ", signed_unsigned_names[GET_FIELD 626 (insn, 21, 21)]); 627 break; 628 case 'h': 629 (*info->fprintf_func) 630 (info->stream, "%s", mix_half_names[GET_FIELD 631 (insn, 17, 17)]); 632 break; 633 case 'H': 634 (*info->fprintf_func) 635 (info->stream, "%s", saturation_names[GET_FIELD 636 (insn, 24, 25)]); 637 break; 638 case '*': 639 (*info->fprintf_func) 640 (info->stream, ",%d%d%d%d ", 641 GET_FIELD (insn, 17, 18), GET_FIELD (insn, 20, 21), 642 GET_FIELD (insn, 22, 23), GET_FIELD (insn, 24, 25)); 643 break; 644 645 case 'q': 646 { 647 int m, a; 648 649 m = GET_FIELD (insn, 28, 28); 650 a = GET_FIELD (insn, 29, 29); 651 652 if (m && !a) 653 fputs_filtered (",ma ", info); 654 else if (m && a) 655 fputs_filtered (",mb ", info); 656 else 657 fputs_filtered (" ", info); 658 break; 659 } 660 661 case 'J': 662 { 663 int opcode = GET_FIELD (insn, 0, 5); 664 665 if (opcode == 0x16 || opcode == 0x1e) 666 { 667 if (GET_FIELD (insn, 29, 29) == 0) 668 fputs_filtered (",ma ", info); 669 else 670 fputs_filtered (",mb ", info); 671 } 672 else 673 fputs_filtered (" ", info); 674 break; 675 } 676 677 case 'e': 678 { 679 int opcode = GET_FIELD (insn, 0, 5); 680 681 if (opcode == 0x13 || opcode == 0x1b) 682 { 683 if (GET_FIELD (insn, 18, 18) == 1) 684 fputs_filtered (",mb ", info); 685 else 686 fputs_filtered (",ma ", info); 687 } 688 else if (opcode == 0x17 || opcode == 0x1f) 689 { 690 if (GET_FIELD (insn, 31, 31) == 1) 691 fputs_filtered (",ma ", info); 692 else 693 fputs_filtered (",mb ", info); 694 } 695 else 696 fputs_filtered (" ", info); 697 698 break; 699 } 700 } 701 break; 702 703 /* Handle conditions. */ 704 case '?': 705 { 706 s++; 707 switch (*s) 708 { 709 case 'f': 710 (*info->fprintf_func) (info->stream, "%s ", 711 float_comp_names[GET_FIELD 712 (insn, 27, 31)]); 713 break; 714 715 /* these four conditions are for the set of instructions 716 which distinguish true/false conditions by opcode 717 rather than by the 'f' bit (sigh): comb, comib, 718 addb, addib */ 719 case 't': 720 fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)], 721 info); 722 break; 723 case 'n': 724 fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18) 725 + GET_FIELD (insn, 4, 4) * 8], info); 726 break; 727 case 'N': 728 fputs_filtered (compare_cond_64_names[GET_FIELD (insn, 16, 18) 729 + GET_FIELD (insn, 2, 2) * 8], info); 730 break; 731 case 'Q': 732 fputs_filtered (cmpib_cond_64_names[GET_FIELD (insn, 16, 18)], 733 info); 734 break; 735 case '@': 736 fputs_filtered (add_cond_names[GET_FIELD (insn, 16, 18) 737 + GET_FIELD (insn, 4, 4) * 8], info); 738 break; 739 case 's': 740 (*info->fprintf_func) (info->stream, "%s ", 741 compare_cond_names[GET_COND (insn)]); 742 break; 743 case 'S': 744 (*info->fprintf_func) (info->stream, "%s ", 745 compare_cond_64_names[GET_COND (insn)]); 746 break; 747 case 'a': 748 (*info->fprintf_func) (info->stream, "%s ", 749 add_cond_names[GET_COND (insn)]); 750 break; 751 case 'A': 752 (*info->fprintf_func) (info->stream, "%s ", 753 add_cond_64_names[GET_COND (insn)]); 754 break; 755 case 'd': 756 (*info->fprintf_func) (info->stream, "%s", 757 add_cond_names[GET_FIELD (insn, 16, 18)]); 758 break; 759 760 case 'W': 761 (*info->fprintf_func) 762 (info->stream, "%s", 763 wide_add_cond_names[GET_FIELD (insn, 16, 18) + 764 GET_FIELD (insn, 4, 4) * 8]); 765 break; 766 767 case 'l': 768 (*info->fprintf_func) (info->stream, "%s ", 769 logical_cond_names[GET_COND (insn)]); 770 break; 771 case 'L': 772 (*info->fprintf_func) (info->stream, "%s ", 773 logical_cond_64_names[GET_COND (insn)]); 774 break; 775 case 'u': 776 (*info->fprintf_func) (info->stream, "%s ", 777 unit_cond_names[GET_COND (insn)]); 778 break; 779 case 'U': 780 (*info->fprintf_func) (info->stream, "%s ", 781 unit_cond_64_names[GET_COND (insn)]); 782 break; 783 case 'y': 784 case 'x': 785 case 'b': 786 (*info->fprintf_func) 787 (info->stream, "%s", 788 shift_cond_names[GET_FIELD (insn, 16, 18)]); 789 790 /* If the next character in args is 'n', it will handle 791 putting out the space. */ 792 if (s[1] != 'n') 793 (*info->fprintf_func) (info->stream, " "); 794 break; 795 case 'X': 796 (*info->fprintf_func) (info->stream, "%s ", 797 shift_cond_64_names[GET_FIELD (insn, 16, 18)]); 798 break; 799 case 'B': 800 (*info->fprintf_func) 801 (info->stream, "%s", 802 bb_cond_64_names[GET_FIELD (insn, 16, 16)]); 803 804 /* If the next character in args is 'n', it will handle 805 putting out the space. */ 806 if (s[1] != 'n') 807 (*info->fprintf_func) (info->stream, " "); 808 break; 809 } 810 break; 811 } 812 813 case 'V': 814 fput_const (extract_5_store (insn), info); 815 break; 816 case 'r': 817 fput_const (extract_5r_store (insn), info); 818 break; 819 case 'R': 820 fput_const (extract_5R_store (insn), info); 821 break; 822 case 'U': 823 fput_const (extract_10U_store (insn), info); 824 break; 825 case 'B': 826 case 'Q': 827 fput_const (extract_5Q_store (insn), info); 828 break; 829 case 'i': 830 fput_const (extract_11 (insn), info); 831 break; 832 case 'j': 833 fput_const (extract_14 (insn), info); 834 break; 835 case 'k': 836 fput_const (extract_21 (insn), info); 837 break; 838 case 'n': 839 if (insn & 0x2) 840 (*info->fprintf_func) (info->stream, ",n "); 841 else 842 (*info->fprintf_func) (info->stream, " "); 843 break; 844 case 'N': 845 if ((insn & 0x20) && s[1]) 846 (*info->fprintf_func) (info->stream, ",n "); 847 else if (insn & 0x20) 848 (*info->fprintf_func) (info->stream, ",n"); 849 else if (s[1]) 850 (*info->fprintf_func) (info->stream, " "); 851 break; 852 case 'w': 853 (*info->print_address_func) (memaddr + 8 + extract_12 (insn), 854 info); 855 break; 856 case 'W': 857 /* 17 bit PC-relative branch. */ 858 (*info->print_address_func) ((memaddr + 8 859 + extract_17 (insn)), 860 info); 861 break; 862 case 'z': 863 /* 17 bit displacement. This is an offset from a register 864 so it gets disasssembled as just a number, not any sort 865 of address. */ 866 fput_const (extract_17 (insn), info); 867 break; 868 869 case 'Z': 870 /* addil %r1 implicit output. */ 871 (*info->fprintf_func) (info->stream, "%%r1"); 872 break; 873 874 case 'Y': 875 /* be,l %sr0,%r31 implicit output. */ 876 (*info->fprintf_func) (info->stream, "%%sr0,%%r31"); 877 break; 878 879 case '@': 880 (*info->fprintf_func) (info->stream, "0"); 881 break; 882 883 case '.': 884 (*info->fprintf_func) (info->stream, "%d", 885 GET_FIELD (insn, 24, 25)); 886 break; 887 case '*': 888 (*info->fprintf_func) (info->stream, "%d", 889 GET_FIELD (insn, 22, 25)); 890 break; 891 case '!': 892 (*info->fprintf_func) (info->stream, "%%sar"); 893 break; 894 case 'p': 895 (*info->fprintf_func) (info->stream, "%d", 896 31 - GET_FIELD (insn, 22, 26)); 897 break; 898 case '~': 899 { 900 int num; 901 num = GET_FIELD (insn, 20, 20) << 5; 902 num |= GET_FIELD (insn, 22, 26); 903 (*info->fprintf_func) (info->stream, "%d", 63 - num); 904 break; 905 } 906 case 'P': 907 (*info->fprintf_func) (info->stream, "%d", 908 GET_FIELD (insn, 22, 26)); 909 break; 910 case 'q': 911 { 912 int num; 913 num = GET_FIELD (insn, 20, 20) << 5; 914 num |= GET_FIELD (insn, 22, 26); 915 (*info->fprintf_func) (info->stream, "%d", num); 916 break; 917 } 918 case 'T': 919 (*info->fprintf_func) (info->stream, "%d", 920 32 - GET_FIELD (insn, 27, 31)); 921 break; 922 case '%': 923 { 924 int num; 925 num = (GET_FIELD (insn, 23, 23) + 1) * 32; 926 num -= GET_FIELD (insn, 27, 31); 927 (*info->fprintf_func) (info->stream, "%d", num); 928 break; 929 } 930 case '|': 931 { 932 int num; 933 num = (GET_FIELD (insn, 19, 19) + 1) * 32; 934 num -= GET_FIELD (insn, 27, 31); 935 (*info->fprintf_func) (info->stream, "%d", num); 936 break; 937 } 938 case '$': 939 fput_const (GET_FIELD (insn, 20, 28), info); 940 break; 941 case 'A': 942 fput_const (GET_FIELD (insn, 6, 18), info); 943 break; 944 case 'D': 945 fput_const (GET_FIELD (insn, 6, 31), info); 946 break; 947 case 'v': 948 (*info->fprintf_func) (info->stream, ",%d", GET_FIELD (insn, 23, 25)); 949 break; 950 case 'O': 951 fput_const ((GET_FIELD (insn, 6,20) << 5 | 952 GET_FIELD (insn, 27, 31)), info); 953 break; 954 case 'o': 955 fput_const (GET_FIELD (insn, 6, 20), info); 956 break; 957 case '2': 958 fput_const ((GET_FIELD (insn, 6, 22) << 5 | 959 GET_FIELD (insn, 27, 31)), info); 960 break; 961 case '1': 962 fput_const ((GET_FIELD (insn, 11, 20) << 5 | 963 GET_FIELD (insn, 27, 31)), info); 964 break; 965 case '0': 966 fput_const ((GET_FIELD (insn, 16, 20) << 5 | 967 GET_FIELD (insn, 27, 31)), info); 968 break; 969 case 'u': 970 (*info->fprintf_func) (info->stream, ",%d", GET_FIELD (insn, 23, 25)); 971 break; 972 case 'F': 973 /* if no destination completer and not before a completer 974 for fcmp, need a space here */ 975 if (s[1] == 'G' || s[1] == '?') 976 fputs_filtered (float_format_names[GET_FIELD (insn, 19, 20)], 977 info); 978 else 979 (*info->fprintf_func) (info->stream, "%s ", 980 float_format_names[GET_FIELD 981 (insn, 19, 20)]); 982 break; 983 case 'G': 984 (*info->fprintf_func) (info->stream, "%s ", 985 float_format_names[GET_FIELD (insn, 986 17, 18)]); 987 break; 988 case 'H': 989 if (GET_FIELD (insn, 26, 26) == 1) 990 (*info->fprintf_func) (info->stream, "%s ", 991 float_format_names[0]); 992 else 993 (*info->fprintf_func) (info->stream, "%s ", 994 float_format_names[1]); 995 break; 996 case 'I': 997 /* if no destination completer and not before a completer 998 for fcmp, need a space here */ 999 if (s[1] == '?') 1000 fputs_filtered (float_format_names[GET_FIELD (insn, 20, 20)], 1001 info); 1002 else 1003 (*info->fprintf_func) (info->stream, "%s ", 1004 float_format_names[GET_FIELD 1005 (insn, 20, 20)]); 1006 break; 1007 1008 case 'J': 1009 fput_const (extract_14 (insn), info); 1010 break; 1011 1012 case '#': 1013 { 1014 int sign = GET_FIELD (insn, 31, 31); 1015 int imm10 = GET_FIELD (insn, 18, 27); 1016 int disp; 1017 1018 if (sign) 1019 disp = (-1 << 10) | imm10; 1020 else 1021 disp = imm10; 1022 1023 disp <<= 3; 1024 fput_const (disp, info); 1025 break; 1026 } 1027 case 'K': 1028 case 'd': 1029 { 1030 int sign = GET_FIELD (insn, 31, 31); 1031 int imm11 = GET_FIELD (insn, 18, 28); 1032 int disp; 1033 1034 if (sign) 1035 disp = (-1 << 11) | imm11; 1036 else 1037 disp = imm11; 1038 1039 disp <<= 2; 1040 fput_const (disp, info); 1041 break; 1042 } 1043 1044 /* ?!? FIXME */ 1045 case '_': 1046 case '{': 1047 fputs_filtered ("Disassembler botch.\n", info); 1048 break; 1049 1050 case 'm': 1051 { 1052 int y = GET_FIELD (insn, 16, 18); 1053 1054 if (y != 1) 1055 fput_const ((y ^ 1) - 1, info); 1056 } 1057 break; 1058 1059 case 'h': 1060 { 1061 int cbit; 1062 1063 cbit = GET_FIELD (insn, 16, 18); 1064 1065 if (cbit > 0) 1066 (*info->fprintf_func) (info->stream, ",%d", cbit - 1); 1067 break; 1068 } 1069 1070 case '=': 1071 { 1072 int cond = GET_FIELD (insn, 27, 31); 1073 1074 if (cond == 0) 1075 fputs_filtered (" ", info); 1076 else if (cond == 1) 1077 fputs_filtered ("acc ", info); 1078 else if (cond == 2) 1079 fputs_filtered ("rej ", info); 1080 else if (cond == 5) 1081 fputs_filtered ("acc8 ", info); 1082 else if (cond == 6) 1083 fputs_filtered ("rej8 ", info); 1084 else if (cond == 9) 1085 fputs_filtered ("acc6 ", info); 1086 else if (cond == 13) 1087 fputs_filtered ("acc4 ", info); 1088 else if (cond == 17) 1089 fputs_filtered ("acc2 ", info); 1090 break; 1091 } 1092 1093 case 'X': 1094 (*info->print_address_func) ((memaddr + 8 1095 + extract_22 (insn)), 1096 info); 1097 break; 1098 case 'L': 1099 fputs_filtered (",%r2", info); 1100 break; 1101 default: 1102 (*info->fprintf_func) (info->stream, "%c", *s); 1103 break; 1104 } 1105 } 1106 return sizeof(insn); 1107 } 1108 } 1109 (*info->fprintf_func) (info->stream, "#%8x", insn); 1110 return sizeof(insn); 1111 } 1112