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