1 /* Disassemble h8300 instructions. 2 Copyright 1993, 1994, 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005 3 Free Software Foundation, Inc. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 18 MA 02110-1301, USA. */ 19 20 #define DEFINE_TABLE 21 22 #include "sysdep.h" 23 #define h8_opcodes h8ops 24 #include "opcode/h8300.h" 25 #include "dis-asm.h" 26 #include "opintl.h" 27 #include "libiberty.h" 28 29 struct h8_instruction 30 { 31 int length; 32 const struct h8_opcode *opcode; 33 }; 34 35 struct h8_instruction *h8_instructions; 36 37 /* Run through the opcodes and sort them into order to make them easy 38 to disassemble. */ 39 40 static void 41 bfd_h8_disassemble_init (void) 42 { 43 unsigned int i; 44 unsigned int nopcodes; 45 const struct h8_opcode *p; 46 struct h8_instruction *pi; 47 48 nopcodes = sizeof (h8_opcodes) / sizeof (struct h8_opcode); 49 50 h8_instructions = xmalloc (nopcodes * sizeof (struct h8_instruction)); 51 52 for (p = h8_opcodes, pi = h8_instructions; p->name; p++, pi++) 53 { 54 int n1 = 0; 55 int n2 = 0; 56 57 if ((int) p->data.nib[0] < 16) 58 n1 = (int) p->data.nib[0]; 59 else 60 n1 = 0; 61 62 if ((int) p->data.nib[1] < 16) 63 n2 = (int) p->data.nib[1]; 64 else 65 n2 = 0; 66 67 /* Just make sure there are an even number of nibbles in it, and 68 that the count is the same as the length. */ 69 for (i = 0; p->data.nib[i] != (op_type) E; i++) 70 ; 71 72 if (i & 1) 73 { 74 fprintf (stderr, "Internal error, h8_disassemble_init.\n"); 75 abort (); 76 } 77 78 pi->length = i / 2; 79 pi->opcode = p; 80 } 81 82 /* Add entry for the NULL vector terminator. */ 83 pi->length = 0; 84 pi->opcode = p; 85 } 86 87 static void 88 extract_immediate (FILE *stream, 89 op_type looking_for, 90 int thisnib, 91 unsigned char *data, 92 int *cst, 93 int *len, 94 const struct h8_opcode *q) 95 { 96 switch (looking_for & SIZE) 97 { 98 case L_2: 99 *len = 2; 100 *cst = thisnib & 3; 101 102 /* DISP2 special treatment. */ 103 if ((looking_for & MODE) == DISP) 104 { 105 if (OP_KIND (q->how) == O_MOVAB 106 || OP_KIND (q->how) == O_MOVAW 107 || OP_KIND (q->how) == O_MOVAL) 108 { 109 /* Handling for mova insn. */ 110 switch (q->args.nib[0] & MODE) 111 { 112 case INDEXB: 113 default: 114 break; 115 case INDEXW: 116 *cst *= 2; 117 break; 118 case INDEXL: 119 *cst *= 4; 120 break; 121 } 122 } 123 else 124 { 125 /* Handling for non-mova insn. */ 126 switch (OP_SIZE (q->how)) 127 { 128 default: break; 129 case SW: 130 *cst *= 2; 131 break; 132 case SL: 133 *cst *= 4; 134 break; 135 } 136 } 137 } 138 break; 139 case L_8: 140 *len = 8; 141 *cst = data[0]; 142 break; 143 case L_16: 144 case L_16U: 145 *len = 16; 146 *cst = (data[0] << 8) + data [1]; 147 #if 0 148 if ((looking_for & SIZE) == L_16) 149 *cst = (short) *cst; /* Sign extend. */ 150 #endif 151 break; 152 case L_32: 153 *len = 32; 154 *cst = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]; 155 break; 156 default: 157 *len = 0; 158 *cst = 0; 159 fprintf (stream, "DISP bad size\n"); 160 break; 161 } 162 } 163 164 static const char *regnames[] = 165 { 166 "r0h", "r1h", "r2h", "r3h", "r4h", "r5h", "r6h", "r7h", 167 "r0l", "r1l", "r2l", "r3l", "r4l", "r5l", "r6l", "r7l" 168 }; 169 static const char *wregnames[] = 170 { 171 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 172 "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7" 173 }; 174 static const char *lregnames[] = 175 { 176 "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7", 177 "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7" 178 }; 179 static const char *cregnames[] = 180 { 181 "ccr", "exr", "mach", "macl", "", "", "vbr", "sbr" 182 }; 183 184 static void 185 print_one_arg (disassemble_info *info, 186 bfd_vma addr, 187 op_type x, 188 int cst, 189 int cstlen, 190 int rdisp_n, 191 int rn, 192 const char **pregnames, 193 int len) 194 { 195 void * stream = info->stream; 196 fprintf_ftype outfn = info->fprintf_func; 197 198 if ((x & SIZE) == L_3 || (x & SIZE) == L_3NZ) 199 outfn (stream, "#0x%x", (unsigned) cst); 200 else if ((x & MODE) == IMM) 201 outfn (stream, "#0x%x", (unsigned) cst); 202 else if ((x & MODE) == DBIT || (x & MODE) == KBIT) 203 outfn (stream, "#%d", (unsigned) cst); 204 else if ((x & MODE) == CONST_2) 205 outfn (stream, "#2"); 206 else if ((x & MODE) == CONST_4) 207 outfn (stream, "#4"); 208 else if ((x & MODE) == CONST_8) 209 outfn (stream, "#8"); 210 else if ((x & MODE) == CONST_16) 211 outfn (stream, "#16"); 212 else if ((x & MODE) == REG) 213 { 214 switch (x & SIZE) 215 { 216 case L_8: 217 outfn (stream, "%s", regnames[rn]); 218 break; 219 case L_16: 220 case L_16U: 221 outfn (stream, "%s", wregnames[rn]); 222 break; 223 case L_P: 224 case L_32: 225 outfn (stream, "%s", lregnames[rn]); 226 break; 227 } 228 } 229 else if ((x & MODE) == LOWREG) 230 { 231 switch (x & SIZE) 232 { 233 case L_8: 234 /* Always take low half of reg. */ 235 outfn (stream, "%s.b", regnames[rn < 8 ? rn + 8 : rn]); 236 break; 237 case L_16: 238 case L_16U: 239 /* Always take low half of reg. */ 240 outfn (stream, "%s.w", wregnames[rn < 8 ? rn : rn - 8]); 241 break; 242 case L_P: 243 case L_32: 244 outfn (stream, "%s.l", lregnames[rn]); 245 break; 246 } 247 } 248 else if ((x & MODE) == POSTINC) 249 outfn (stream, "@%s+", pregnames[rn]); 250 251 else if ((x & MODE) == POSTDEC) 252 outfn (stream, "@%s-", pregnames[rn]); 253 254 else if ((x & MODE) == PREINC) 255 outfn (stream, "@+%s", pregnames[rn]); 256 257 else if ((x & MODE) == PREDEC) 258 outfn (stream, "@-%s", pregnames[rn]); 259 260 else if ((x & MODE) == IND) 261 outfn (stream, "@%s", pregnames[rn]); 262 263 else if ((x & MODE) == ABS || (x & ABSJMP)) 264 outfn (stream, "@0x%x:%d", (unsigned) cst, cstlen); 265 266 else if ((x & MODE) == MEMIND) 267 outfn (stream, "@@%d (0x%x)", cst, cst); 268 269 else if ((x & MODE) == VECIND) 270 { 271 /* FIXME Multiplier should be 2 or 4, depending on processor mode, 272 by which is meant "normal" vs. "middle", "advanced", "maximum". */ 273 274 int offset = (cst + 0x80) * 4; 275 outfn (stream, "@@%d (0x%x)", offset, offset); 276 } 277 else if ((x & MODE) == PCREL) 278 { 279 if ((x & SIZE) == L_16 || 280 (x & SIZE) == L_16U) 281 { 282 outfn (stream, ".%s%d (0x%lx)", 283 (short) cst > 0 ? "+" : "", 284 (short) cst, 285 (long)(addr + (short) cst + len)); 286 } 287 else 288 { 289 outfn (stream, ".%s%d (0x%lx)", 290 (char) cst > 0 ? "+" : "", 291 (char) cst, 292 (long)(addr + (char) cst + len)); 293 } 294 } 295 else if ((x & MODE) == DISP) 296 outfn (stream, "@(0x%x:%d,%s)", cst, cstlen, pregnames[rdisp_n]); 297 298 else if ((x & MODE) == INDEXB) 299 /* Always take low half of reg. */ 300 outfn (stream, "@(0x%x:%d,%s.b)", cst, cstlen, 301 regnames[rdisp_n < 8 ? rdisp_n + 8 : rdisp_n]); 302 303 else if ((x & MODE) == INDEXW) 304 /* Always take low half of reg. */ 305 outfn (stream, "@(0x%x:%d,%s.w)", cst, cstlen, 306 wregnames[rdisp_n < 8 ? rdisp_n : rdisp_n - 8]); 307 308 else if ((x & MODE) == INDEXL) 309 outfn (stream, "@(0x%x:%d,%s.l)", cst, cstlen, lregnames[rdisp_n]); 310 311 else if (x & CTRL) 312 outfn (stream, cregnames[rn]); 313 314 else if ((x & MODE) == CCR) 315 outfn (stream, "ccr"); 316 317 else if ((x & MODE) == EXR) 318 outfn (stream, "exr"); 319 320 else if ((x & MODE) == MACREG) 321 outfn (stream, "mac%c", cst ? 'l' : 'h'); 322 323 else 324 /* xgettext:c-format */ 325 outfn (stream, _("Hmmmm 0x%x"), x); 326 } 327 328 static unsigned int 329 bfd_h8_disassemble (bfd_vma addr, disassemble_info *info, int mach) 330 { 331 /* Find the first entry in the table for this opcode. */ 332 int regno[3] = { 0, 0, 0 }; 333 int dispregno[3] = { 0, 0, 0 }; 334 int cst[3] = { 0, 0, 0 }; 335 int cstlen[3] = { 0, 0, 0 }; 336 static bfd_boolean init = 0; 337 const struct h8_instruction *qi; 338 char const **pregnames = mach != 0 ? lregnames : wregnames; 339 int status; 340 unsigned int l; 341 unsigned char data[MAX_CODE_NIBBLES]; 342 void *stream = info->stream; 343 fprintf_ftype outfn = info->fprintf_func; 344 345 if (!init) 346 { 347 bfd_h8_disassemble_init (); 348 init = 1; 349 } 350 351 status = info->read_memory_func (addr, data, 2, info); 352 if (status != 0) 353 { 354 info->memory_error_func (status, addr, info); 355 return -1; 356 } 357 358 for (l = 2; status == 0 && l < sizeof (data) / 2; l += 2) 359 status = info->read_memory_func (addr + l, data + l, 2, info); 360 361 /* Find the exact opcode/arg combo. */ 362 for (qi = h8_instructions; qi->opcode->name; qi++) 363 { 364 const struct h8_opcode *q = qi->opcode; 365 op_type *nib = q->data.nib; 366 unsigned int len = 0; 367 368 while (1) 369 { 370 op_type looking_for = *nib; 371 int thisnib = data[len / 2]; 372 int opnr; 373 374 thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib / 16) & 0xf); 375 opnr = ((looking_for & OP3) == OP3 ? 2 376 : (looking_for & DST) == DST ? 1 : 0); 377 378 if (looking_for < 16 && looking_for >= 0) 379 { 380 if (looking_for != thisnib) 381 goto fail; 382 } 383 else 384 { 385 if ((int) looking_for & (int) B31) 386 { 387 if (!((thisnib & 0x8) != 0)) 388 goto fail; 389 390 looking_for = (op_type) ((int) looking_for & ~(int) B31); 391 thisnib &= 0x7; 392 } 393 else if ((int) looking_for & (int) B30) 394 { 395 if (!((thisnib & 0x8) == 0)) 396 goto fail; 397 398 looking_for = (op_type) ((int) looking_for & ~(int) B30); 399 } 400 401 if ((int) looking_for & (int) B21) 402 { 403 if (!((thisnib & 0x4) != 0)) 404 goto fail; 405 406 looking_for = (op_type) ((int) looking_for & ~(int) B21); 407 thisnib &= 0xb; 408 } 409 else if ((int) looking_for & (int) B20) 410 { 411 if (!((thisnib & 0x4) == 0)) 412 goto fail; 413 414 looking_for = (op_type) ((int) looking_for & ~(int) B20); 415 } 416 if ((int) looking_for & (int) B11) 417 { 418 if (!((thisnib & 0x2) != 0)) 419 goto fail; 420 421 looking_for = (op_type) ((int) looking_for & ~(int) B11); 422 thisnib &= 0xd; 423 } 424 else if ((int) looking_for & (int) B10) 425 { 426 if (!((thisnib & 0x2) == 0)) 427 goto fail; 428 429 looking_for = (op_type) ((int) looking_for & ~(int) B10); 430 } 431 432 if ((int) looking_for & (int) B01) 433 { 434 if (!((thisnib & 0x1) != 0)) 435 goto fail; 436 437 looking_for = (op_type) ((int) looking_for & ~(int) B01); 438 thisnib &= 0xe; 439 } 440 else if ((int) looking_for & (int) B00) 441 { 442 if (!((thisnib & 0x1) == 0)) 443 goto fail; 444 445 looking_for = (op_type) ((int) looking_for & ~(int) B00); 446 } 447 448 if (looking_for & IGNORE) 449 { 450 /* Hitachi has declared that IGNORE must be zero. */ 451 if (thisnib != 0) 452 goto fail; 453 } 454 else if ((looking_for & MODE) == DATA) 455 { 456 ; /* Skip embedded data. */ 457 } 458 else if ((looking_for & MODE) == DBIT) 459 { 460 /* Exclude adds/subs by looking at bit 0 and 2, and 461 make sure the operand size, either w or l, 462 matches by looking at bit 1. */ 463 if ((looking_for & 7) != (thisnib & 7)) 464 goto fail; 465 466 cst[opnr] = (thisnib & 0x8) ? 2 : 1; 467 } 468 else if ((looking_for & MODE) == DISP 469 || (looking_for & MODE) == ABS 470 || (looking_for & MODE) == PCREL 471 || (looking_for & MODE) == INDEXB 472 || (looking_for & MODE) == INDEXW 473 || (looking_for & MODE) == INDEXL) 474 { 475 extract_immediate (stream, looking_for, thisnib, 476 data + len / 2, cst + opnr, 477 cstlen + opnr, q); 478 /* Even address == bra, odd == bra/s. */ 479 if (q->how == O (O_BRAS, SB)) 480 cst[opnr] -= 1; 481 } 482 else if ((looking_for & MODE) == REG 483 || (looking_for & MODE) == LOWREG 484 || (looking_for & MODE) == IND 485 || (looking_for & MODE) == PREINC 486 || (looking_for & MODE) == POSTINC 487 || (looking_for & MODE) == PREDEC 488 || (looking_for & MODE) == POSTDEC) 489 { 490 regno[opnr] = thisnib; 491 } 492 else if (looking_for & CTRL) /* Control Register. */ 493 { 494 thisnib &= 7; 495 if (((looking_for & MODE) == CCR && (thisnib != C_CCR)) 496 || ((looking_for & MODE) == EXR && (thisnib != C_EXR)) 497 || ((looking_for & MODE) == MACH && (thisnib != C_MACH)) 498 || ((looking_for & MODE) == MACL && (thisnib != C_MACL)) 499 || ((looking_for & MODE) == VBR && (thisnib != C_VBR)) 500 || ((looking_for & MODE) == SBR && (thisnib != C_SBR))) 501 goto fail; 502 if (((looking_for & MODE) == CCR_EXR 503 && (thisnib != C_CCR && thisnib != C_EXR)) 504 || ((looking_for & MODE) == VBR_SBR 505 && (thisnib != C_VBR && thisnib != C_SBR)) 506 || ((looking_for & MODE) == MACREG 507 && (thisnib != C_MACH && thisnib != C_MACL))) 508 goto fail; 509 if (((looking_for & MODE) == CC_EX_VB_SB 510 && (thisnib != C_CCR && thisnib != C_EXR 511 && thisnib != C_VBR && thisnib != C_SBR))) 512 goto fail; 513 514 regno[opnr] = thisnib; 515 } 516 else if ((looking_for & SIZE) == L_5) 517 { 518 cst[opnr] = data[len / 2] & 31; 519 cstlen[opnr] = 5; 520 } 521 else if ((looking_for & SIZE) == L_4) 522 { 523 cst[opnr] = thisnib; 524 cstlen[opnr] = 4; 525 } 526 else if ((looking_for & SIZE) == L_16 527 || (looking_for & SIZE) == L_16U) 528 { 529 cst[opnr] = (data[len / 2]) * 256 + data[(len + 2) / 2]; 530 cstlen[opnr] = 16; 531 } 532 else if ((looking_for & MODE) == MEMIND) 533 { 534 cst[opnr] = data[1]; 535 } 536 else if ((looking_for & MODE) == VECIND) 537 { 538 cst[opnr] = data[1] & 0x7f; 539 } 540 else if ((looking_for & SIZE) == L_32) 541 { 542 int i = len / 2; 543 544 cst[opnr] = ((data[i] << 24) 545 | (data[i + 1] << 16) 546 | (data[i + 2] << 8) 547 | (data[i + 3])); 548 549 cstlen[opnr] = 32; 550 } 551 else if ((looking_for & SIZE) == L_24) 552 { 553 int i = len / 2; 554 555 cst[opnr] = 556 (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]); 557 cstlen[opnr] = 24; 558 } 559 else if (looking_for & IGNORE) 560 { 561 ; 562 } 563 else if (looking_for & DISPREG) 564 { 565 dispregno[opnr] = thisnib & 7; 566 } 567 else if ((looking_for & MODE) == KBIT) 568 { 569 switch (thisnib) 570 { 571 case 9: 572 cst[opnr] = 4; 573 break; 574 case 8: 575 cst[opnr] = 2; 576 break; 577 case 0: 578 cst[opnr] = 1; 579 break; 580 default: 581 goto fail; 582 } 583 } 584 else if ((looking_for & SIZE) == L_8) 585 { 586 cstlen[opnr] = 8; 587 cst[opnr] = data[len / 2]; 588 } 589 else if ((looking_for & SIZE) == L_3 590 || (looking_for & SIZE) == L_3NZ) 591 { 592 cst[opnr] = thisnib & 0x7; 593 if (cst[opnr] == 0 && (looking_for & SIZE) == L_3NZ) 594 goto fail; 595 } 596 else if ((looking_for & SIZE) == L_2) 597 { 598 cstlen[opnr] = 2; 599 cst[opnr] = thisnib & 0x3; 600 } 601 else if ((looking_for & MODE) == MACREG) 602 { 603 cst[opnr] = (thisnib == 3); 604 } 605 else if (looking_for == (op_type) E) 606 { 607 outfn (stream, "%s\t", q->name); 608 609 /* Gross. Disgusting. */ 610 if (strcmp (q->name, "ldm.l") == 0) 611 { 612 int count, high; 613 614 count = (data[1] / 16) & 0x3; 615 high = regno[1]; 616 617 outfn (stream, "@sp+,er%d-er%d", high - count, high); 618 return qi->length; 619 } 620 621 if (strcmp (q->name, "stm.l") == 0) 622 { 623 int count, low; 624 625 count = (data[1] / 16) & 0x3; 626 low = regno[0]; 627 628 outfn (stream, "er%d-er%d,@-sp", low, low + count); 629 return qi->length; 630 } 631 if (strcmp (q->name, "rte/l") == 0 632 || strcmp (q->name, "rts/l") == 0) 633 { 634 if (regno[0] == 0) 635 outfn (stream, "er%d", regno[1]); 636 else 637 outfn (stream, "er%d-er%d", regno[1] - regno[0], 638 regno[1]); 639 return qi->length; 640 } 641 if (strncmp (q->name, "mova", 4) == 0) 642 { 643 op_type *args = q->args.nib; 644 645 if (args[1] == (op_type) E) 646 { 647 /* Short form. */ 648 print_one_arg (info, addr, args[0], cst[0], 649 cstlen[0], dispregno[0], regno[0], 650 pregnames, qi->length); 651 outfn (stream, ",er%d", dispregno[0]); 652 } 653 else 654 { 655 outfn (stream, "@(0x%x:%d,", cst[0], cstlen[0]); 656 print_one_arg (info, addr, args[1], cst[1], 657 cstlen[1], dispregno[1], regno[1], 658 pregnames, qi->length); 659 outfn (stream, ".%c),", 660 (args[0] & MODE) == INDEXB ? 'b' : 'w'); 661 print_one_arg (info, addr, args[2], cst[2], 662 cstlen[2], dispregno[2], regno[2], 663 pregnames, qi->length); 664 } 665 return qi->length; 666 } 667 /* Fill in the args. */ 668 { 669 op_type *args = q->args.nib; 670 int hadone = 0; 671 int nargs; 672 673 /* Special case handling for the adds and subs instructions 674 since in H8 mode thay can only take the r0-r7 registers 675 but in other (higher) modes they can take the er0-er7 676 registers as well. */ 677 if (strcmp (qi->opcode->name, "adds") == 0 678 || strcmp (qi->opcode->name, "subs") == 0) 679 { 680 outfn (stream, "#%d,%s", cst[0], pregnames[regno[1] & 0x7]); 681 return qi->length; 682 } 683 684 for (nargs = 0; 685 nargs < 3 && args[nargs] != (op_type) E; 686 nargs++) 687 { 688 int x = args[nargs]; 689 690 if (hadone) 691 outfn (stream, ","); 692 693 print_one_arg (info, addr, x, 694 cst[nargs], cstlen[nargs], 695 dispregno[nargs], regno[nargs], 696 pregnames, qi->length); 697 698 hadone = 1; 699 } 700 } 701 702 return qi->length; 703 } 704 else 705 /* xgettext:c-format */ 706 outfn (stream, _("Don't understand 0x%x \n"), looking_for); 707 } 708 709 len++; 710 nib++; 711 } 712 713 fail: 714 ; 715 } 716 717 /* Fell off the end. */ 718 outfn (stream, ".word\tH'%x,H'%x", data[0], data[1]); 719 return 2; 720 } 721 722 int 723 print_insn_h8300 (bfd_vma addr, disassemble_info *info) 724 { 725 return bfd_h8_disassemble (addr, info, 0); 726 } 727 728 int 729 print_insn_h8300h (bfd_vma addr, disassemble_info *info) 730 { 731 return bfd_h8_disassemble (addr, info, 1); 732 } 733 734 int 735 print_insn_h8300s (bfd_vma addr, disassemble_info *info) 736 { 737 return bfd_h8_disassemble (addr, info, 2); 738 } 739