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