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