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