1 /* s12z-dis.c -- Freescale S12Z disassembly 2 Copyright (C) 2018 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 #include "sysdep.h" 22 #include <stdio.h> 23 #include <stdint.h> 24 #include <stdbool.h> 25 #include <assert.h> 26 27 #include "s12z.h" 28 29 #include "bfd.h" 30 #include "dis-asm.h" 31 32 33 #include "disassemble.h" 34 35 static int 36 read_memory (bfd_vma memaddr, bfd_byte* buffer, int size, 37 struct disassemble_info* info) 38 { 39 int status = (*info->read_memory_func) (memaddr, buffer, size, info); 40 if (status != 0) 41 { 42 (*info->memory_error_func) (status, memaddr, info); 43 return -1; 44 } 45 return 0; 46 } 47 48 typedef int (* insn_bytes_f) (bfd_vma memaddr, 49 struct disassemble_info* info); 50 51 typedef void (*operands_f) (bfd_vma memaddr, struct disassemble_info* info); 52 53 enum OPR_MODE 54 { 55 OPR_IMMe4, 56 OPR_REG, 57 OPR_OFXYS, 58 OPR_XY_PRE_INC, 59 OPR_XY_POST_INC, 60 OPR_XY_PRE_DEC, 61 OPR_XY_POST_DEC, 62 OPR_S_PRE_DEC, 63 OPR_S_POST_INC, 64 OPR_REG_DIRECT, 65 OPR_REG_INDIRECT, 66 OPR_IDX_DIRECT, 67 OPR_IDX_INDIRECT, 68 OPR_EXT1, 69 OPR_IDX2_REG, 70 OPR_IDX3_DIRECT, 71 OPR_IDX3_INDIRECT, 72 73 OPR_EXT18, 74 OPR_IDX3_DIRECT_REG, 75 OPR_EXT3_DIRECT, 76 OPR_EXT3_INDIRECT 77 }; 78 79 struct opr_pb 80 { 81 uint8_t mask; 82 uint8_t value; 83 int n_operands; 84 enum OPR_MODE mode; 85 }; 86 87 static const struct opr_pb opr_pb[] = { 88 {0xF0, 0x70, 1, OPR_IMMe4}, 89 {0xF8, 0xB8, 1, OPR_REG}, 90 {0xC0, 0x40, 1, OPR_OFXYS}, 91 {0xEF, 0xE3, 1, OPR_XY_PRE_INC}, 92 {0xEF, 0xE7, 1, OPR_XY_POST_INC}, 93 {0xEF, 0xC3, 1, OPR_XY_PRE_DEC}, 94 {0xEF, 0xC7, 1, OPR_XY_POST_DEC}, 95 {0xFF, 0xFB, 1, OPR_S_PRE_DEC}, 96 {0xFF, 0xFF, 1, OPR_S_POST_INC}, 97 {0xC8, 0x88, 1, OPR_REG_DIRECT}, 98 {0xE8, 0xC8, 1, OPR_REG_INDIRECT}, 99 100 {0xCE, 0xC0, 2, OPR_IDX_DIRECT}, 101 {0xCE, 0xC4, 2, OPR_IDX_INDIRECT}, 102 {0xC0, 0x00, 2, OPR_EXT1}, 103 104 {0xC8, 0x80, 3, OPR_IDX2_REG}, 105 {0xFA, 0xF8, 3, OPR_EXT18}, 106 107 {0xCF, 0xC2, 4, OPR_IDX3_DIRECT}, 108 {0xCF, 0xC6, 4, OPR_IDX3_INDIRECT}, 109 110 {0xF8, 0xE8, 4, OPR_IDX3_DIRECT_REG}, 111 {0xFF, 0xFA, 4, OPR_EXT3_DIRECT}, 112 {0xFF, 0xFE, 4, OPR_EXT3_INDIRECT}, 113 }; 114 115 116 /* Return the number of bytes in a OPR operand, including the XB postbyte. 117 It does not include any preceeding opcodes. */ 118 static int 119 opr_n_bytes (bfd_vma memaddr, struct disassemble_info* info) 120 { 121 bfd_byte xb; 122 int status = read_memory (memaddr, &xb, 1, info); 123 if (status < 0) 124 return status; 125 126 size_t i; 127 for (i = 0; i < sizeof (opr_pb) / sizeof (opr_pb[0]); ++i) 128 { 129 const struct opr_pb *pb = opr_pb + i; 130 if ((xb & pb->mask) == pb->value) 131 { 132 return pb->n_operands; 133 } 134 } 135 136 return 1; 137 } 138 139 static int 140 opr_n_bytes_p1 (bfd_vma memaddr, struct disassemble_info* info) 141 { 142 return 1 + opr_n_bytes (memaddr, info); 143 } 144 145 static int 146 opr_n_bytes2 (bfd_vma memaddr, struct disassemble_info* info) 147 { 148 int s = opr_n_bytes (memaddr, info); 149 s += opr_n_bytes (memaddr + s, info); 150 return s + 1; 151 } 152 153 enum BB_MODE 154 { 155 BB_REG_REG_REG, 156 BB_REG_REG_IMM, 157 BB_REG_OPR_REG, 158 BB_OPR_REG_REG, 159 BB_REG_OPR_IMM, 160 BB_OPR_REG_IMM 161 }; 162 163 struct opr_bb 164 { 165 uint8_t mask; 166 uint8_t value; 167 int n_operands; 168 bool opr; 169 enum BB_MODE mode; 170 }; 171 172 static const struct opr_bb bb_modes[] = 173 { 174 {0x60, 0x00, 2, false, BB_REG_REG_REG}, 175 {0x60, 0x20, 3, false, BB_REG_REG_IMM}, 176 {0x70, 0x40, 2, true, BB_REG_OPR_REG}, 177 {0x70, 0x50, 2, true, BB_OPR_REG_REG}, 178 {0x70, 0x60, 3, true, BB_REG_OPR_IMM}, 179 {0x70, 0x70, 3, true, BB_OPR_REG_IMM} 180 }; 181 182 static int 183 bfextins_n_bytes (bfd_vma memaddr, struct disassemble_info* info) 184 { 185 bfd_byte bb; 186 int status = read_memory (memaddr, &bb, 1, info); 187 if (status < 0) 188 return status; 189 190 size_t i; 191 const struct opr_bb *bbs = 0; 192 for (i = 0; i < sizeof (bb_modes) / sizeof (bb_modes[0]); ++i) 193 { 194 bbs = bb_modes + i; 195 if ((bb & bbs->mask) == bbs->value) 196 { 197 break; 198 } 199 } 200 201 int n = bbs->n_operands; 202 if (bbs->opr) 203 n += opr_n_bytes (memaddr + n - 1, info); 204 205 return n; 206 } 207 208 static int 209 single (bfd_vma memaddr ATTRIBUTE_UNUSED, 210 struct disassemble_info* info ATTRIBUTE_UNUSED) 211 { 212 return 1; 213 } 214 215 static int 216 two (bfd_vma memaddr ATTRIBUTE_UNUSED, 217 struct disassemble_info* info ATTRIBUTE_UNUSED) 218 { 219 return 2; 220 } 221 222 static int 223 three (bfd_vma memaddr ATTRIBUTE_UNUSED, 224 struct disassemble_info* info ATTRIBUTE_UNUSED) 225 { 226 return 3; 227 } 228 229 static int 230 four (bfd_vma memaddr ATTRIBUTE_UNUSED, 231 struct disassemble_info* info ATTRIBUTE_UNUSED) 232 { 233 return 4; 234 } 235 236 static int 237 five (bfd_vma memaddr ATTRIBUTE_UNUSED, 238 struct disassemble_info* info ATTRIBUTE_UNUSED) 239 { 240 return 5; 241 } 242 243 static int 244 pcrel_15bit (bfd_vma memaddr, struct disassemble_info* info) 245 { 246 bfd_byte byte; 247 int status = read_memory (memaddr, &byte, 1, info); 248 if (status < 0) 249 return status; 250 return (byte & 0x80) ? 3 : 2; 251 } 252 253 254 255 256 static void 257 operand_separator (struct disassemble_info *info) 258 { 259 if ((info->flags & 0x2)) 260 { 261 (*info->fprintf_func) (info->stream, ", "); 262 } 263 else 264 { 265 (*info->fprintf_func) (info->stream, " "); 266 } 267 268 info->flags |= 0x2; 269 } 270 271 272 273 static void 274 imm1 (bfd_vma memaddr, struct disassemble_info* info) 275 { 276 bfd_byte byte; 277 int status = read_memory (memaddr, &byte, 1, info); 278 if (status < 0) 279 return; 280 281 operand_separator (info); 282 (*info->fprintf_func) (info->stream, "#%d", byte); 283 } 284 285 static void 286 trap_decode (bfd_vma memaddr, struct disassemble_info* info) 287 { 288 imm1 (memaddr - 1, info); 289 } 290 291 292 const struct reg registers[S12Z_N_REGISTERS] = 293 { 294 {"d2", 2}, 295 {"d3", 2}, 296 {"d4", 2}, 297 {"d5", 2}, 298 299 {"d0", 1}, 300 {"d1", 1}, 301 302 {"d6", 4}, 303 {"d7", 4}, 304 305 {"x", 3}, 306 {"y", 3}, 307 {"s", 3}, 308 {"p", 3}, 309 {"cch", 1}, 310 {"ccl", 1}, 311 {"ccw", 2} 312 }; 313 314 static char * 315 xys_from_postbyte (uint8_t postbyte) 316 { 317 char *reg = "?"; 318 switch ((postbyte & 0x30) >> 4) 319 { 320 case 0: 321 reg = "x"; 322 break; 323 case 1: 324 reg = "y"; 325 break; 326 case 2: 327 reg = "s"; 328 break; 329 default: 330 reg = "?"; 331 break; 332 } 333 return reg; 334 } 335 336 static char * 337 xysp_from_postbyte (uint8_t postbyte) 338 { 339 char *reg = "?"; 340 switch ((postbyte & 0x30) >> 4) 341 { 342 case 0: 343 reg = "x"; 344 break; 345 case 1: 346 reg = "y"; 347 break; 348 case 2: 349 reg = "s"; 350 break; 351 default: 352 reg = "p"; 353 break; 354 } 355 return reg; 356 } 357 358 /* Render the symbol name whose value is ADDR or the adddress itself if there is 359 no symbol. */ 360 static void 361 decode_possible_symbol (bfd_vma addr, struct disassemble_info *info) 362 { 363 if (!info->symbol_at_address_func (addr, info)) 364 { 365 (*info->fprintf_func) (info->stream, "%" BFD_VMA_FMT "d", addr); 366 } 367 else 368 { 369 asymbol *sym = NULL; 370 int j; 371 for (j = 0; j < info->symtab_size; ++j) 372 { 373 sym = info->symtab[j]; 374 if (bfd_asymbol_value (sym) == addr) 375 { 376 break; 377 } 378 } 379 if (j < info->symtab_size) 380 (*info->fprintf_func) (info->stream, "%s", bfd_asymbol_name (sym)); 381 } 382 } 383 384 static void ld_18bit_decode (bfd_vma memaddr, struct disassemble_info* info); 385 386 static void 387 ext24_decode (bfd_vma memaddr, struct disassemble_info* info) 388 { 389 uint8_t buffer[3]; 390 int status = read_memory (memaddr, buffer, 3, info); 391 if (status < 0) 392 return; 393 394 int i; 395 uint32_t addr = 0; 396 for (i = 0; i < 3; ++i) 397 { 398 addr <<= 8; 399 addr |= buffer[i]; 400 } 401 402 operand_separator (info); 403 decode_possible_symbol (addr, info); 404 } 405 406 407 static uint32_t 408 decode_signed_value (bfd_vma memaddr, struct disassemble_info* info, short size) 409 { 410 assert (size >0); 411 assert (size <= 4); 412 bfd_byte buffer[4]; 413 if (0 > read_memory (memaddr, buffer, size, info)) 414 { 415 return 0; 416 } 417 418 int i; 419 uint32_t value = 0; 420 for (i = 0; i < size; ++i) 421 { 422 value |= buffer[i] << (8 * (size - i - 1)); 423 } 424 425 if (buffer[0] & 0x80) 426 { 427 /* Deal with negative values */ 428 value -= 0x1UL << (size * 8); 429 } 430 return value; 431 } 432 433 434 static void 435 opr_decode (bfd_vma memaddr, struct disassemble_info* info) 436 { 437 bfd_byte postbyte; 438 int status = read_memory (memaddr, &postbyte, 1, info); 439 if (status < 0) 440 return; 441 442 enum OPR_MODE mode = -1; 443 size_t i; 444 for (i = 0; i < sizeof (opr_pb) / sizeof (opr_pb[0]); ++i) 445 { 446 const struct opr_pb *pb = opr_pb + i; 447 if ((postbyte & pb->mask) == pb->value) 448 { 449 mode = pb->mode; 450 break; 451 } 452 } 453 454 operand_separator (info); 455 switch (mode) 456 { 457 case OPR_IMMe4: 458 { 459 int n; 460 uint8_t x = (postbyte & 0x0F); 461 if (x == 0) 462 n = -1; 463 else 464 n = x; 465 466 (*info->fprintf_func) (info->stream, "#%d", n); 467 break; 468 } 469 case OPR_REG: 470 { 471 uint8_t x = (postbyte & 0x07); 472 (*info->fprintf_func) (info->stream, "%s", registers[x].name); 473 break; 474 } 475 case OPR_OFXYS: 476 { 477 const char *reg = xys_from_postbyte (postbyte); 478 (*info->fprintf_func) (info->stream, "(%d,%s)", postbyte & 0x0F, reg); 479 break; 480 } 481 case OPR_REG_DIRECT: 482 { 483 (*info->fprintf_func) (info->stream, "(%s,%s)", registers[postbyte & 0x07].name, 484 xys_from_postbyte (postbyte)); 485 break; 486 } 487 case OPR_REG_INDIRECT: 488 { 489 (*info->fprintf_func) (info->stream, "[%s,%s]", registers[postbyte & 0x07].name, 490 (postbyte & 0x10) ? "y": "x"); 491 break; 492 } 493 494 case OPR_IDX_INDIRECT: 495 { 496 uint8_t x1; 497 read_memory (memaddr + 1, &x1, 1, info); 498 int idx = x1; 499 500 if (postbyte & 0x01) 501 { 502 /* Deal with negative values */ 503 idx -= 0x1UL << 8; 504 } 505 506 (*info->fprintf_func) (info->stream, "[%d,%s]", idx, 507 xysp_from_postbyte (postbyte)); 508 break; 509 } 510 511 case OPR_IDX3_DIRECT: 512 { 513 uint8_t x[3]; 514 read_memory (memaddr + 1, x, 3, info); 515 int idx = x[0] << 16 | x[1] << 8 | x[2]; 516 517 if (x[0] & 0x80) 518 { 519 /* Deal with negative values */ 520 idx -= 0x1UL << 24; 521 } 522 523 (*info->fprintf_func) (info->stream, "(%d,%s)", idx, 524 xysp_from_postbyte (postbyte)); 525 break; 526 } 527 528 case OPR_IDX3_DIRECT_REG: 529 { 530 uint8_t x[3]; 531 read_memory (memaddr + 1, x, 3, info); 532 int idx = x[0] << 16 | x[1] << 8 | x[2]; 533 534 if (x[0] & 0x80) 535 { 536 /* Deal with negative values */ 537 idx -= 0x1UL << 24; 538 } 539 540 (*info->fprintf_func) (info->stream, "(%d,%s)", idx, 541 registers[postbyte & 0x07].name); 542 break; 543 } 544 545 case OPR_IDX3_INDIRECT: 546 { 547 uint8_t x[3]; 548 read_memory (memaddr + 1, x, 3, info); 549 int idx = x[0] << 16 | x[1] << 8 | x[2]; 550 551 if (x[0] & 0x80) 552 { 553 /* Deal with negative values */ 554 idx -= 0x1UL << 24; 555 } 556 557 (*info->fprintf_func) (info->stream, "[%d,%s]", idx, 558 xysp_from_postbyte (postbyte)); 559 break; 560 } 561 562 case OPR_IDX_DIRECT: 563 { 564 uint8_t x1; 565 read_memory (memaddr + 1, &x1, 1, info); 566 int idx = x1; 567 568 if (postbyte & 0x01) 569 { 570 /* Deal with negative values */ 571 idx -= 0x1UL << 8; 572 } 573 574 (*info->fprintf_func) (info->stream, "(%d,%s)", idx, 575 xysp_from_postbyte (postbyte)); 576 break; 577 } 578 579 case OPR_IDX2_REG: 580 { 581 uint8_t x[2]; 582 read_memory (memaddr + 1, x, 2, info); 583 uint32_t offset = x[1] | x[0] << 8 ; 584 offset |= (postbyte & 0x30) << 12; 585 586 (*info->fprintf_func) (info->stream, "(%d,%s)", offset, 587 registers[postbyte & 0x07].name); 588 break; 589 } 590 591 case OPR_XY_PRE_INC: 592 { 593 (*info->fprintf_func) (info->stream, "(+%s)", 594 (postbyte & 0x10) ? "y": "x"); 595 596 break; 597 } 598 case OPR_XY_POST_INC: 599 { 600 (*info->fprintf_func) (info->stream, "(%s+)", 601 (postbyte & 0x10) ? "y": "x"); 602 603 break; 604 } 605 case OPR_XY_PRE_DEC: 606 { 607 (*info->fprintf_func) (info->stream, "(-%s)", 608 (postbyte & 0x10) ? "y": "x"); 609 610 break; 611 } 612 case OPR_XY_POST_DEC: 613 { 614 (*info->fprintf_func) (info->stream, "(%s-)", 615 (postbyte & 0x10) ? "y": "x"); 616 617 break; 618 } 619 case OPR_S_PRE_DEC: 620 { 621 (*info->fprintf_func) (info->stream, "(-s)"); 622 break; 623 } 624 case OPR_S_POST_INC: 625 { 626 (*info->fprintf_func) (info->stream, "(s+)"); 627 break; 628 } 629 630 case OPR_EXT18: 631 { 632 const size_t size = 2; 633 bfd_byte buffer[4]; 634 status = read_memory (memaddr + 1, buffer, size, info); 635 if (status < 0) 636 return; 637 638 uint32_t ext18 = 0; 639 for (i = 0; i < size; ++i) 640 { 641 ext18 <<= 8; 642 ext18 |= buffer[i]; 643 } 644 645 ext18 |= (postbyte & 0x01) << 16; 646 ext18 |= (postbyte & 0x04) << 15; 647 648 decode_possible_symbol (ext18, info); 649 break; 650 } 651 652 case OPR_EXT1: 653 { 654 uint8_t x1 = 0; 655 read_memory (memaddr + 1, &x1, 1, info); 656 int16_t addr; 657 addr = x1; 658 addr |= (postbyte & 0x3f) << 8; 659 660 decode_possible_symbol (addr, info); 661 break; 662 } 663 664 case OPR_EXT3_DIRECT: 665 { 666 const size_t size = 3; 667 bfd_byte buffer[4]; 668 status = read_memory (memaddr + 1, buffer, size, info); 669 if (status < 0) 670 return; 671 672 uint32_t ext24 = 0; 673 for (i = 0; i < size; ++i) 674 { 675 ext24 |= buffer[i] << (8 * (size - i - 1)); 676 } 677 678 decode_possible_symbol (ext24, info); 679 break; 680 } 681 682 case OPR_EXT3_INDIRECT: 683 { 684 const size_t size = 3; 685 bfd_byte buffer[4]; 686 status = read_memory (memaddr + 1, buffer, size, info); 687 if (status < 0) 688 return; 689 690 uint32_t ext24 = 0; 691 for (i = 0; i < size; ++i) 692 { 693 ext24 |= buffer[i] << (8 * (size - i - 1)); 694 } 695 696 (*info->fprintf_func) (info->stream, "[%d]", ext24); 697 698 break; 699 } 700 701 default: 702 (*info->fprintf_func) (info->stream, "Unknown OPR mode #0x%x (%d)", postbyte, mode); 703 } 704 } 705 706 707 static void 708 opr_decode2 (bfd_vma memaddr, struct disassemble_info* info) 709 { 710 int n = opr_n_bytes (memaddr, info); 711 opr_decode (memaddr, info); 712 opr_decode (memaddr + n, info); 713 } 714 715 static void 716 imm1234 (bfd_vma memaddr, struct disassemble_info* info, int base) 717 { 718 bfd_byte opcode; 719 int status = read_memory (memaddr - 1, &opcode, 1, info); 720 if (status < 0) 721 return; 722 723 opcode -= base; 724 725 int size = registers[opcode & 0xF].bytes; 726 727 uint32_t imm = decode_signed_value (memaddr, info, size); 728 operand_separator (info); 729 (*info->fprintf_func) (info->stream, "#%d", imm); 730 } 731 732 733 /* Special case of LD and CMP with register S and IMM operand */ 734 static void 735 reg_s_imm (bfd_vma memaddr, struct disassemble_info* info) 736 { 737 operand_separator (info); 738 (*info->fprintf_func) (info->stream, "s"); 739 740 uint32_t imm = decode_signed_value (memaddr, info, 3); 741 operand_separator (info); 742 (*info->fprintf_func) (info->stream, "#%d", imm); 743 } 744 745 /* Special case of LD, CMP and ST with register S and OPR operand */ 746 static void 747 reg_s_opr (bfd_vma memaddr, struct disassemble_info* info) 748 { 749 operand_separator (info); 750 (*info->fprintf_func) (info->stream, "s"); 751 752 opr_decode (memaddr, info); 753 } 754 755 static void 756 imm1234_8base (bfd_vma memaddr, struct disassemble_info* info) 757 { 758 imm1234 (memaddr, info, 8); 759 } 760 761 static void 762 imm1234_0base (bfd_vma memaddr, struct disassemble_info* info) 763 { 764 imm1234 (memaddr, info, 0); 765 } 766 767 static void 768 tfr (bfd_vma memaddr, struct disassemble_info* info) 769 { 770 bfd_byte byte; 771 int status = read_memory (memaddr, &byte, 1, info); 772 if (status < 0) 773 return; 774 775 operand_separator (info); 776 (*info->fprintf_func) (info->stream, "%s, %s", 777 registers[byte >> 4].name, 778 registers[byte & 0xF].name); 779 } 780 781 782 static void 783 reg (bfd_vma memaddr, struct disassemble_info* info) 784 { 785 bfd_byte byte; 786 int status = read_memory (memaddr - 1, &byte, 1, info); 787 if (status < 0) 788 return; 789 790 operand_separator (info); 791 (*info->fprintf_func) (info->stream, "%s", registers[byte & 0x07].name); 792 } 793 794 static void 795 reg_xy (bfd_vma memaddr, struct disassemble_info* info) 796 { 797 bfd_byte byte; 798 int status = read_memory (memaddr - 1, &byte, 1, info); 799 if (status < 0) 800 return; 801 802 operand_separator (info); 803 (*info->fprintf_func) (info->stream, "%s", (byte & 0x01) ? "y" : "x"); 804 } 805 806 static void 807 lea_reg_xys_opr (bfd_vma memaddr, struct disassemble_info* info) 808 { 809 bfd_byte byte; 810 int status = read_memory (memaddr - 1, &byte, 1, info); 811 if (status < 0) 812 return; 813 814 char *reg = NULL; 815 switch (byte & 0x03) 816 { 817 case 0x00: 818 reg = "x"; 819 break; 820 case 0x01: 821 reg = "y"; 822 break; 823 case 0x02: 824 reg = "s"; 825 break; 826 } 827 828 operand_separator (info); 829 (*info->fprintf_func) (info->stream, "%s", reg); 830 opr_decode (memaddr, info); 831 } 832 833 834 835 static void 836 lea_reg_xys (bfd_vma memaddr, struct disassemble_info* info) 837 { 838 bfd_byte byte; 839 int status = read_memory (memaddr - 1, &byte, 1, info); 840 if (status < 0) 841 return; 842 843 char *reg = NULL; 844 switch (byte & 0x03) 845 { 846 case 0x00: 847 reg = "x"; 848 break; 849 case 0x01: 850 reg = "y"; 851 break; 852 case 0x02: 853 reg = "s"; 854 break; 855 } 856 857 status = read_memory (memaddr, &byte, 1, info); 858 if (status < 0) 859 return; 860 861 int8_t v = byte; 862 863 operand_separator (info); 864 (*info->fprintf_func) (info->stream, "%s, (%d,%s)", reg, v, reg); 865 } 866 867 868 /* PC Relative offsets of size 15 or 7 bits */ 869 static void 870 rel_15_7 (bfd_vma memaddr, struct disassemble_info* info, int offset) 871 { 872 bfd_byte upper; 873 int status = read_memory (memaddr, &upper, 1, info); 874 if (status < 0) 875 return; 876 877 bool rel_size = (upper & 0x80); 878 879 int16_t addr = upper; 880 if (rel_size) 881 { 882 /* 15 bits. Get the next byte */ 883 bfd_byte lower; 884 status = read_memory (memaddr + 1, &lower, 1, info); 885 if (status < 0) 886 return; 887 888 addr <<= 8; 889 addr |= lower; 890 addr &= 0x7FFF; 891 892 bool negative = (addr & 0x4000); 893 addr &= 0x3FFF; 894 if (negative) 895 addr = addr - 0x4000; 896 } 897 else 898 { 899 /* 7 bits. */ 900 bool negative = (addr & 0x40); 901 addr &= 0x3F; 902 if (negative) 903 addr = addr - 0x40; 904 } 905 906 operand_separator (info); 907 if (!info->symbol_at_address_func (addr + memaddr - offset, info)) 908 { 909 (*info->fprintf_func) (info->stream, "*%+d", addr); 910 } 911 else 912 { 913 asymbol *sym = NULL; 914 int i; 915 for (i = 0; i < info->symtab_size; ++i) 916 { 917 sym = info->symtab[i]; 918 if (bfd_asymbol_value (sym) == addr + memaddr - offset) 919 { 920 break; 921 } 922 } 923 if (i < info->symtab_size) 924 (*info->fprintf_func) (info->stream, "%s", bfd_asymbol_name (sym)); 925 } 926 } 927 928 929 /* PC Relative offsets of size 15 or 7 bits */ 930 static void 931 decode_rel_15_7 (bfd_vma memaddr, struct disassemble_info* info) 932 { 933 rel_15_7 (memaddr, info, 1); 934 } 935 936 struct opcode 937 { 938 const char *mnemonic; 939 insn_bytes_f insn_bytes; 940 operands_f operands; 941 operands_f operands2; 942 }; 943 944 static int shift_n_bytes (bfd_vma memaddr, struct disassemble_info* info); 945 static int mov_imm_opr_n_bytes (bfd_vma memaddr, struct disassemble_info* info); 946 static int loop_prim_n_bytes (bfd_vma memaddr, struct disassemble_info* info); 947 static void mov_imm_opr (bfd_vma memaddr, struct disassemble_info* info); 948 static void bm_rel_decode (bfd_vma memaddr, struct disassemble_info* info); 949 static int bm_rel_n_bytes (bfd_vma memaddr, struct disassemble_info* info); 950 static int mul_n_bytes (bfd_vma memaddr, struct disassemble_info* info); 951 static void mul_decode (bfd_vma memaddr, struct disassemble_info* info); 952 static int bm_n_bytes (bfd_vma memaddr, struct disassemble_info* info); 953 static void bm_decode (bfd_vma memaddr, struct disassemble_info* info); 954 955 static void 956 cmp_xy (bfd_vma memaddr ATTRIBUTE_UNUSED, struct disassemble_info* info) 957 { 958 operand_separator (info); 959 (*info->fprintf_func) (info->stream, "x, y"); 960 } 961 962 static void 963 sub_d6_x_y (bfd_vma memaddr ATTRIBUTE_UNUSED, struct disassemble_info* info) 964 { 965 operand_separator (info); 966 (*info->fprintf_func) (info->stream, "d6, x, y"); 967 } 968 969 static void 970 sub_d6_y_x (bfd_vma memaddr ATTRIBUTE_UNUSED, struct disassemble_info* info) 971 { 972 operand_separator (info); 973 (*info->fprintf_func) (info->stream, "d6, y, x"); 974 } 975 976 static const char shift_size_table[] = { 977 'b', 'w', 'p', 'l' 978 }; 979 980 static const struct opcode page2[] = 981 { 982 [0x00] = {"ld", opr_n_bytes_p1, 0, reg_s_opr}, 983 [0x01] = {"st", opr_n_bytes_p1, 0, reg_s_opr}, 984 [0x02] = {"cmp", opr_n_bytes_p1, 0, reg_s_opr}, 985 [0x03] = {"ld", four, 0, reg_s_imm}, 986 [0x04] = {"cmp", four, 0, reg_s_imm}, 987 [0x05] = {"stop", single, 0, 0}, 988 [0x06] = {"wai", single, 0, 0}, 989 [0x07] = {"sys", single, 0, 0}, 990 [0x08] = {NULL, bfextins_n_bytes, 0, 0}, /* BFEXT / BFINS */ 991 [0x09] = {NULL, bfextins_n_bytes, 0, 0}, 992 [0x0a] = {NULL, bfextins_n_bytes, 0, 0}, 993 [0x0b] = {NULL, bfextins_n_bytes, 0, 0}, 994 [0x0c] = {NULL, bfextins_n_bytes, 0, 0}, 995 [0x0d] = {NULL, bfextins_n_bytes, 0, 0}, 996 [0x0e] = {NULL, bfextins_n_bytes, 0, 0}, 997 [0x0f] = {NULL, bfextins_n_bytes, 0, 0}, 998 [0x10] = {"minu", opr_n_bytes_p1, reg, opr_decode}, 999 [0x11] = {"minu", opr_n_bytes_p1, reg, opr_decode}, 1000 [0x12] = {"minu", opr_n_bytes_p1, reg, opr_decode}, 1001 [0x13] = {"minu", opr_n_bytes_p1, reg, opr_decode}, 1002 [0x14] = {"minu", opr_n_bytes_p1, reg, opr_decode}, 1003 [0x15] = {"minu", opr_n_bytes_p1, reg, opr_decode}, 1004 [0x16] = {"minu", opr_n_bytes_p1, reg, opr_decode}, 1005 [0x17] = {"minu", opr_n_bytes_p1, reg, opr_decode}, 1006 [0x18] = {"maxu", opr_n_bytes_p1, reg, opr_decode}, 1007 [0x19] = {"maxu", opr_n_bytes_p1, reg, opr_decode}, 1008 [0x1a] = {"maxu", opr_n_bytes_p1, reg, opr_decode}, 1009 [0x1b] = {"maxu", opr_n_bytes_p1, reg, opr_decode}, 1010 [0x1c] = {"maxu", opr_n_bytes_p1, reg, opr_decode}, 1011 [0x1d] = {"maxu", opr_n_bytes_p1, reg, opr_decode}, 1012 [0x1e] = {"maxu", opr_n_bytes_p1, reg, opr_decode}, 1013 [0x1f] = {"maxu", opr_n_bytes_p1, reg, opr_decode}, 1014 [0x20] = {"mins", opr_n_bytes_p1, reg, opr_decode}, 1015 [0x21] = {"mins", opr_n_bytes_p1, reg, opr_decode}, 1016 [0x22] = {"mins", opr_n_bytes_p1, reg, opr_decode}, 1017 [0x23] = {"mins", opr_n_bytes_p1, reg, opr_decode}, 1018 [0x24] = {"mins", opr_n_bytes_p1, reg, opr_decode}, 1019 [0x25] = {"mins", opr_n_bytes_p1, reg, opr_decode}, 1020 [0x26] = {"mins", opr_n_bytes_p1, reg, opr_decode}, 1021 [0x27] = {"mins", opr_n_bytes_p1, reg, opr_decode}, 1022 [0x28] = {"maxs", opr_n_bytes_p1, reg, opr_decode}, 1023 [0x29] = {"maxs", opr_n_bytes_p1, reg, opr_decode}, 1024 [0x2a] = {"maxs", opr_n_bytes_p1, reg, opr_decode}, 1025 [0x2b] = {"maxs", opr_n_bytes_p1, reg, opr_decode}, 1026 [0x2c] = {"maxs", opr_n_bytes_p1, reg, opr_decode}, 1027 [0x2d] = {"maxs", opr_n_bytes_p1, reg, opr_decode}, 1028 [0x2e] = {"maxs", opr_n_bytes_p1, reg, opr_decode}, 1029 [0x2f] = {"maxs", opr_n_bytes_p1, reg, opr_decode}, 1030 [0x30] = {"div", mul_n_bytes, mul_decode, 0}, 1031 [0x31] = {"div", mul_n_bytes, mul_decode, 0}, 1032 [0x32] = {"div", mul_n_bytes, mul_decode, 0}, 1033 [0x33] = {"div", mul_n_bytes, mul_decode, 0}, 1034 [0x34] = {"div", mul_n_bytes, mul_decode, 0}, 1035 [0x35] = {"div", mul_n_bytes, mul_decode, 0}, 1036 [0x36] = {"div", mul_n_bytes, mul_decode, 0}, 1037 [0x37] = {"div", mul_n_bytes, mul_decode, 0}, 1038 [0x38] = {"mod", mul_n_bytes, mul_decode, 0}, 1039 [0x39] = {"mod", mul_n_bytes, mul_decode, 0}, 1040 [0x3a] = {"mod", mul_n_bytes, mul_decode, 0}, 1041 [0x3b] = {"mod", mul_n_bytes, mul_decode, 0}, 1042 [0x3c] = {"mod", mul_n_bytes, mul_decode, 0}, 1043 [0x3d] = {"mod", mul_n_bytes, mul_decode, 0}, 1044 [0x3e] = {"mod", mul_n_bytes, mul_decode, 0}, 1045 [0x3f] = {"mod", mul_n_bytes, mul_decode, 0}, 1046 [0x40] = {"abs", single, reg, 0}, 1047 [0x41] = {"abs", single, reg, 0}, 1048 [0x42] = {"abs", single, reg, 0}, 1049 [0x43] = {"abs", single, reg, 0}, 1050 [0x44] = {"abs", single, reg, 0}, 1051 [0x45] = {"abs", single, reg, 0}, 1052 [0x46] = {"abs", single, reg, 0}, 1053 [0x47] = {"abs", single, reg, 0}, 1054 [0x48] = {"mac", mul_n_bytes, mul_decode, 0}, 1055 [0x49] = {"mac", mul_n_bytes, mul_decode, 0}, 1056 [0x4a] = {"mac", mul_n_bytes, mul_decode, 0}, 1057 [0x4b] = {"mac", mul_n_bytes, mul_decode, 0}, 1058 [0x4c] = {"mac", mul_n_bytes, mul_decode, 0}, 1059 [0x4d] = {"mac", mul_n_bytes, mul_decode, 0}, 1060 [0x4e] = {"mac", mul_n_bytes, mul_decode, 0}, 1061 [0x4f] = {"mac", mul_n_bytes, mul_decode, 0}, 1062 [0x50] = {"adc", three, reg, imm1234_0base}, 1063 [0x51] = {"adc", three, reg, imm1234_0base}, 1064 [0x52] = {"adc", three, reg, imm1234_0base}, 1065 [0x53] = {"adc", three, reg, imm1234_0base}, 1066 [0x54] = {"adc", two, reg, imm1234_0base}, 1067 [0x55] = {"adc", two, reg, imm1234_0base}, 1068 [0x56] = {"adc", five, reg, imm1234_0base}, 1069 [0x57] = {"adc", five, reg, imm1234_0base}, 1070 [0x58] = {"bit", three, reg, imm1234_8base}, 1071 [0x59] = {"bit", three, reg, imm1234_8base}, 1072 [0x5a] = {"bit", three, reg, imm1234_8base}, 1073 [0x5b] = {"bit", three, reg, imm1234_8base}, 1074 [0x5c] = {"bit", two, reg, imm1234_8base}, 1075 [0x5d] = {"bit", two, reg, imm1234_8base}, 1076 [0x5e] = {"bit", five, reg, imm1234_8base}, 1077 [0x5f] = {"bit", five, reg, imm1234_8base}, 1078 [0x60] = {"adc", opr_n_bytes_p1, reg, opr_decode}, 1079 [0x61] = {"adc", opr_n_bytes_p1, reg, opr_decode}, 1080 [0x62] = {"adc", opr_n_bytes_p1, reg, opr_decode}, 1081 [0x63] = {"adc", opr_n_bytes_p1, reg, opr_decode}, 1082 [0x64] = {"adc", opr_n_bytes_p1, reg, opr_decode}, 1083 [0x65] = {"adc", opr_n_bytes_p1, reg, opr_decode}, 1084 [0x66] = {"adc", opr_n_bytes_p1, reg, opr_decode}, 1085 [0x67] = {"adc", opr_n_bytes_p1, reg, opr_decode}, 1086 [0x68] = {"bit", opr_n_bytes_p1, reg, opr_decode}, 1087 [0x69] = {"bit", opr_n_bytes_p1, reg, opr_decode}, 1088 [0x6a] = {"bit", opr_n_bytes_p1, reg, opr_decode}, 1089 [0x6b] = {"bit", opr_n_bytes_p1, reg, opr_decode}, 1090 [0x6c] = {"bit", opr_n_bytes_p1, reg, opr_decode}, 1091 [0x6d] = {"bit", opr_n_bytes_p1, reg, opr_decode}, 1092 [0x6e] = {"bit", opr_n_bytes_p1, reg, opr_decode}, 1093 [0x6f] = {"bit", opr_n_bytes_p1, reg, opr_decode}, 1094 [0x70] = {"sbc", three, reg, imm1234_0base}, 1095 [0x71] = {"sbc", three, reg, imm1234_0base}, 1096 [0x72] = {"sbc", three, reg, imm1234_0base}, 1097 [0x73] = {"sbc", three, reg, imm1234_0base}, 1098 [0x74] = {"sbc", two, reg, imm1234_0base}, 1099 [0x75] = {"sbc", two, reg, imm1234_0base}, 1100 [0x76] = {"sbc", five, reg, imm1234_0base}, 1101 [0x77] = {"sbc", five, reg, imm1234_0base}, 1102 [0x78] = {"eor", three, reg, imm1234_8base}, 1103 [0x79] = {"eor", three, reg, imm1234_8base}, 1104 [0x7a] = {"eor", three, reg, imm1234_8base}, 1105 [0x7b] = {"eor", three, reg, imm1234_8base}, 1106 [0x7c] = {"eor", two, reg, imm1234_8base}, 1107 [0x7d] = {"eor", two, reg, imm1234_8base}, 1108 [0x7e] = {"eor", five, reg, imm1234_8base}, 1109 [0x7f] = {"eor", five, reg, imm1234_8base}, 1110 [0x80] = {"sbc", opr_n_bytes_p1, reg, opr_decode}, 1111 [0x81] = {"sbc", opr_n_bytes_p1, reg, opr_decode}, 1112 [0x82] = {"sbc", opr_n_bytes_p1, reg, opr_decode}, 1113 [0x83] = {"sbc", opr_n_bytes_p1, reg, opr_decode}, 1114 [0x84] = {"sbc", opr_n_bytes_p1, reg, opr_decode}, 1115 [0x85] = {"sbc", opr_n_bytes_p1, reg, opr_decode}, 1116 [0x86] = {"sbc", opr_n_bytes_p1, reg, opr_decode}, 1117 [0x87] = {"sbc", opr_n_bytes_p1, reg, opr_decode}, 1118 [0x88] = {"eor", opr_n_bytes_p1, reg, opr_decode}, 1119 [0x89] = {"eor", opr_n_bytes_p1, reg, opr_decode}, 1120 [0x8a] = {"eor", opr_n_bytes_p1, reg, opr_decode}, 1121 [0x8b] = {"eor", opr_n_bytes_p1, reg, opr_decode}, 1122 [0x8c] = {"eor", opr_n_bytes_p1, reg, opr_decode}, 1123 [0x8d] = {"eor", opr_n_bytes_p1, reg, opr_decode}, 1124 [0x8e] = {"eor", opr_n_bytes_p1, reg, opr_decode}, 1125 [0x8f] = {"eor", opr_n_bytes_p1, reg, opr_decode}, 1126 [0x90] = {"rti", single, 0, 0}, 1127 [0x91] = {"clb", two, tfr, 0}, 1128 [0x92] = {"trap", single, trap_decode, 0}, 1129 [0x93] = {"trap", single, trap_decode, 0}, 1130 [0x94] = {"trap", single, trap_decode, 0}, 1131 [0x95] = {"trap", single, trap_decode, 0}, 1132 [0x96] = {"trap", single, trap_decode, 0}, 1133 [0x97] = {"trap", single, trap_decode, 0}, 1134 [0x98] = {"trap", single, trap_decode, 0}, 1135 [0x99] = {"trap", single, trap_decode, 0}, 1136 [0x9a] = {"trap", single, trap_decode, 0}, 1137 [0x9b] = {"trap", single, trap_decode, 0}, 1138 [0x9c] = {"trap", single, trap_decode, 0}, 1139 [0x9d] = {"trap", single, trap_decode, 0}, 1140 [0x9e] = {"trap", single, trap_decode, 0}, 1141 [0x9f] = {"trap", single, trap_decode, 0}, 1142 [0xa0] = {"sat", single, reg, 0}, 1143 [0xa1] = {"sat", single, reg, 0}, 1144 [0xa2] = {"sat", single, reg, 0}, 1145 [0xa3] = {"sat", single, reg, 0}, 1146 [0xa4] = {"sat", single, reg, 0}, 1147 [0xa5] = {"sat", single, reg, 0}, 1148 [0xa6] = {"sat", single, reg, 0}, 1149 [0xa7] = {"sat", single, reg, 0}, 1150 [0xa8] = {"trap", single, trap_decode, 0}, 1151 [0xa9] = {"trap", single, trap_decode, 0}, 1152 [0xaa] = {"trap", single, trap_decode, 0}, 1153 [0xab] = {"trap", single, trap_decode, 0}, 1154 [0xac] = {"trap", single, trap_decode, 0}, 1155 [0xad] = {"trap", single, trap_decode, 0}, 1156 [0xae] = {"trap", single, trap_decode, 0}, 1157 [0xaf] = {"trap", single, trap_decode, 0}, 1158 [0xb0] = {"qmul", mul_n_bytes, mul_decode, 0}, 1159 [0xb1] = {"qmul", mul_n_bytes, mul_decode, 0}, 1160 [0xb2] = {"qmul", mul_n_bytes, mul_decode, 0}, 1161 [0xb3] = {"qmul", mul_n_bytes, mul_decode, 0}, 1162 [0xb4] = {"qmul", mul_n_bytes, mul_decode, 0}, 1163 [0xb5] = {"qmul", mul_n_bytes, mul_decode, 0}, 1164 [0xb6] = {"qmul", mul_n_bytes, mul_decode, 0}, 1165 [0xb7] = {"qmul", mul_n_bytes, mul_decode, 0}, 1166 [0xb8] = {"trap", single, trap_decode, 0}, 1167 [0xb9] = {"trap", single, trap_decode, 0}, 1168 [0xba] = {"trap", single, trap_decode, 0}, 1169 [0xbb] = {"trap", single, trap_decode, 0}, 1170 [0xbc] = {"trap", single, trap_decode, 0}, 1171 [0xbd] = {"trap", single, trap_decode, 0}, 1172 [0xbe] = {"trap", single, trap_decode, 0}, 1173 [0xbf] = {"trap", single, trap_decode, 0}, 1174 [0xc0] = {"trap", single, trap_decode, 0}, 1175 [0xc1] = {"trap", single, trap_decode, 0}, 1176 [0xc2] = {"trap", single, trap_decode, 0}, 1177 [0xc3] = {"trap", single, trap_decode, 0}, 1178 [0xc4] = {"trap", single, trap_decode, 0}, 1179 [0xc5] = {"trap", single, trap_decode, 0}, 1180 [0xc6] = {"trap", single, trap_decode, 0}, 1181 [0xc7] = {"trap", single, trap_decode, 0}, 1182 [0xc8] = {"trap", single, trap_decode, 0}, 1183 [0xc9] = {"trap", single, trap_decode, 0}, 1184 [0xca] = {"trap", single, trap_decode, 0}, 1185 [0xcb] = {"trap", single, trap_decode, 0}, 1186 [0xcc] = {"trap", single, trap_decode, 0}, 1187 [0xcd] = {"trap", single, trap_decode, 0}, 1188 [0xce] = {"trap", single, trap_decode, 0}, 1189 [0xcf] = {"trap", single, trap_decode, 0}, 1190 [0xd0] = {"trap", single, trap_decode, 0}, 1191 [0xd1] = {"trap", single, trap_decode, 0}, 1192 [0xd2] = {"trap", single, trap_decode, 0}, 1193 [0xd3] = {"trap", single, trap_decode, 0}, 1194 [0xd4] = {"trap", single, trap_decode, 0}, 1195 [0xd5] = {"trap", single, trap_decode, 0}, 1196 [0xd6] = {"trap", single, trap_decode, 0}, 1197 [0xd7] = {"trap", single, trap_decode, 0}, 1198 [0xd8] = {"trap", single, trap_decode, 0}, 1199 [0xd9] = {"trap", single, trap_decode, 0}, 1200 [0xda] = {"trap", single, trap_decode, 0}, 1201 [0xdb] = {"trap", single, trap_decode, 0}, 1202 [0xdc] = {"trap", single, trap_decode, 0}, 1203 [0xdd] = {"trap", single, trap_decode, 0}, 1204 [0xde] = {"trap", single, trap_decode, 0}, 1205 [0xdf] = {"trap", single, trap_decode, 0}, 1206 [0xe0] = {"trap", single, trap_decode, 0}, 1207 [0xe1] = {"trap", single, trap_decode, 0}, 1208 [0xe2] = {"trap", single, trap_decode, 0}, 1209 [0xe3] = {"trap", single, trap_decode, 0}, 1210 [0xe4] = {"trap", single, trap_decode, 0}, 1211 [0xe5] = {"trap", single, trap_decode, 0}, 1212 [0xe6] = {"trap", single, trap_decode, 0}, 1213 [0xe7] = {"trap", single, trap_decode, 0}, 1214 [0xe8] = {"trap", single, trap_decode, 0}, 1215 [0xe9] = {"trap", single, trap_decode, 0}, 1216 [0xea] = {"trap", single, trap_decode, 0}, 1217 [0xeb] = {"trap", single, trap_decode, 0}, 1218 [0xec] = {"trap", single, trap_decode, 0}, 1219 [0xed] = {"trap", single, trap_decode, 0}, 1220 [0xee] = {"trap", single, trap_decode, 0}, 1221 [0xef] = {"trap", single, trap_decode, 0}, 1222 [0xf0] = {"trap", single, trap_decode, 0}, 1223 [0xf1] = {"trap", single, trap_decode, 0}, 1224 [0xf2] = {"trap", single, trap_decode, 0}, 1225 [0xf3] = {"trap", single, trap_decode, 0}, 1226 [0xf4] = {"trap", single, trap_decode, 0}, 1227 [0xf5] = {"trap", single, trap_decode, 0}, 1228 [0xf6] = {"trap", single, trap_decode, 0}, 1229 [0xf7] = {"trap", single, trap_decode, 0}, 1230 [0xf8] = {"trap", single, trap_decode, 0}, 1231 [0xf9] = {"trap", single, trap_decode, 0}, 1232 [0xfa] = {"trap", single, trap_decode, 0}, 1233 [0xfb] = {"trap", single, trap_decode, 0}, 1234 [0xfc] = {"trap", single, trap_decode, 0}, 1235 [0xfd] = {"trap", single, trap_decode, 0}, 1236 [0xfe] = {"trap", single, trap_decode, 0}, 1237 [0xff] = {"trap", single, trap_decode, 0}, 1238 }; 1239 1240 static const struct opcode page1[] = 1241 { 1242 [0x00] = {"bgnd", single, 0, 0}, 1243 [0x01] = {"nop", single, 0, 0}, 1244 [0x02] = {"brclr", bm_rel_n_bytes, bm_rel_decode, 0}, 1245 [0x03] = {"brset", bm_rel_n_bytes, bm_rel_decode, 0}, 1246 [0x04] = {NULL, two, 0, 0}, /* psh/pul */ 1247 [0x05] = {"rts", single, 0, 0}, 1248 [0x06] = {"lea", opr_n_bytes_p1, reg, opr_decode}, 1249 [0x07] = {"lea", opr_n_bytes_p1, reg, opr_decode}, 1250 [0x08] = {"lea", opr_n_bytes_p1, lea_reg_xys_opr, 0}, 1251 [0x09] = {"lea", opr_n_bytes_p1, lea_reg_xys_opr, 0}, 1252 [0x0a] = {"lea", opr_n_bytes_p1, lea_reg_xys_opr, 0}, 1253 [0x0b] = {NULL, loop_prim_n_bytes, 0, 0}, /* Loop primitives TBcc / DBcc */ 1254 [0x0c] = {"mov.b", mov_imm_opr_n_bytes, mov_imm_opr, 0}, 1255 [0x0d] = {"mov.w", mov_imm_opr_n_bytes, mov_imm_opr, 0}, 1256 [0x0e] = {"mov.p", mov_imm_opr_n_bytes, mov_imm_opr, 0}, 1257 [0x0f] = {"mov.l", mov_imm_opr_n_bytes, mov_imm_opr, 0}, 1258 [0x10] = {NULL, shift_n_bytes, 0, 0}, /* lsr/lsl/asl/asr/rol/ror */ 1259 [0x11] = {NULL, shift_n_bytes, 0, 0}, 1260 [0x12] = {NULL, shift_n_bytes, 0, 0}, 1261 [0x13] = {NULL, shift_n_bytes, 0, 0}, 1262 [0x14] = {NULL, shift_n_bytes, 0, 0}, 1263 [0x15] = {NULL, shift_n_bytes, 0, 0}, 1264 [0x16] = {NULL, shift_n_bytes, 0, 0}, 1265 [0x17] = {NULL, shift_n_bytes, 0, 0}, 1266 [0x18] = {"lea", two, lea_reg_xys, NULL}, 1267 [0x19] = {"lea", two, lea_reg_xys, NULL}, 1268 [0x1a] = {"lea", two, lea_reg_xys, NULL}, 1269 /* 0x1b PG2 */ 1270 [0x1c] = {"mov.b", opr_n_bytes2, 0, opr_decode2}, 1271 [0x1d] = {"mov.w", opr_n_bytes2, 0, opr_decode2}, 1272 [0x1e] = {"mov.p", opr_n_bytes2, 0, opr_decode2}, 1273 [0x1f] = {"mov.l", opr_n_bytes2, 0, opr_decode2}, 1274 [0x20] = {"bra", pcrel_15bit, decode_rel_15_7, 0}, 1275 [0x21] = {"bsr", pcrel_15bit, decode_rel_15_7, 0}, 1276 [0x22] = {"bhi", pcrel_15bit, decode_rel_15_7, 0}, 1277 [0x23] = {"bls", pcrel_15bit, decode_rel_15_7, 0}, 1278 [0x24] = {"bcc", pcrel_15bit, decode_rel_15_7, 0}, 1279 [0x25] = {"bcs", pcrel_15bit, decode_rel_15_7, 0}, 1280 [0x26] = {"bne", pcrel_15bit, decode_rel_15_7, 0}, 1281 [0x27] = {"beq", pcrel_15bit, decode_rel_15_7, 0}, 1282 [0x28] = {"bvc", pcrel_15bit, decode_rel_15_7, 0}, 1283 [0x29] = {"bvs", pcrel_15bit, decode_rel_15_7, 0}, 1284 [0x2a] = {"bpl", pcrel_15bit, decode_rel_15_7, 0}, 1285 [0x2b] = {"bmi", pcrel_15bit, decode_rel_15_7, 0}, 1286 [0x2c] = {"bge", pcrel_15bit, decode_rel_15_7, 0}, 1287 [0x2d] = {"blt", pcrel_15bit, decode_rel_15_7, 0}, 1288 [0x2e] = {"bgt", pcrel_15bit, decode_rel_15_7, 0}, 1289 [0x2f] = {"ble", pcrel_15bit, decode_rel_15_7, 0}, 1290 [0x30] = {"inc", single, reg, 0}, 1291 [0x31] = {"inc", single, reg, 0}, 1292 [0x32] = {"inc", single, reg, 0}, 1293 [0x33] = {"inc", single, reg, 0}, 1294 [0x34] = {"inc", single, reg, 0}, 1295 [0x35] = {"inc", single, reg, 0}, 1296 [0x36] = {"inc", single, reg, 0}, 1297 [0x37] = {"inc", single, reg, 0}, 1298 [0x38] = {"clr", single, reg, 0}, 1299 [0x39] = {"clr", single, reg, 0}, 1300 [0x3a] = {"clr", single, reg, 0}, 1301 [0x3b] = {"clr", single, reg, 0}, 1302 [0x3c] = {"clr", single, reg, 0}, 1303 [0x3d] = {"clr", single, reg, 0}, 1304 [0x3e] = {"clr", single, reg, 0}, 1305 [0x3f] = {"clr", single, reg, 0}, 1306 [0x40] = {"dec", single, reg, 0}, 1307 [0x41] = {"dec", single, reg, 0}, 1308 [0x42] = {"dec", single, reg, 0}, 1309 [0x43] = {"dec", single, reg, 0}, 1310 [0x44] = {"dec", single, reg, 0}, 1311 [0x45] = {"dec", single, reg, 0}, 1312 [0x46] = {"dec", single, reg, 0}, 1313 [0x47] = {"dec", single, reg, 0}, 1314 [0x48] = {"mul", mul_n_bytes, mul_decode, 0}, 1315 [0x49] = {"mul", mul_n_bytes, mul_decode, 0}, 1316 [0x4a] = {"mul", mul_n_bytes, mul_decode, 0}, 1317 [0x4b] = {"mul", mul_n_bytes, mul_decode, 0}, 1318 [0x4c] = {"mul", mul_n_bytes, mul_decode, 0}, 1319 [0x4d] = {"mul", mul_n_bytes, mul_decode, 0}, 1320 [0x4e] = {"mul", mul_n_bytes, mul_decode, 0}, 1321 [0x4f] = {"mul", mul_n_bytes, mul_decode, 0}, 1322 [0x50] = {"add", three, reg, imm1234_0base}, 1323 [0x51] = {"add", three, reg, imm1234_0base}, 1324 [0x52] = {"add", three, reg, imm1234_0base}, 1325 [0x53] = {"add", three, reg, imm1234_0base}, 1326 [0x54] = {"add", two, reg, imm1234_0base}, 1327 [0x55] = {"add", two, reg, imm1234_0base}, 1328 [0x56] = {"add", five, reg, imm1234_0base}, 1329 [0x57] = {"add", five, reg, imm1234_0base}, 1330 [0x58] = {"and", three, reg, imm1234_8base}, 1331 [0x59] = {"and", three, reg, imm1234_8base}, 1332 [0x5a] = {"and", three, reg, imm1234_8base}, 1333 [0x5b] = {"and", three, reg, imm1234_8base}, 1334 [0x5c] = {"and", two, reg, imm1234_8base}, 1335 [0x5d] = {"and", two, reg, imm1234_8base}, 1336 [0x5e] = {"and", five, reg, imm1234_8base}, 1337 [0x5f] = {"and", five, reg, imm1234_8base}, 1338 [0x60] = {"add", opr_n_bytes_p1, reg, opr_decode}, 1339 [0x61] = {"add", opr_n_bytes_p1, reg, opr_decode}, 1340 [0x62] = {"add", opr_n_bytes_p1, reg, opr_decode}, 1341 [0x63] = {"add", opr_n_bytes_p1, reg, opr_decode}, 1342 [0x64] = {"add", opr_n_bytes_p1, reg, opr_decode}, 1343 [0x65] = {"add", opr_n_bytes_p1, reg, opr_decode}, 1344 [0x66] = {"add", opr_n_bytes_p1, reg, opr_decode}, 1345 [0x67] = {"add", opr_n_bytes_p1, reg, opr_decode}, 1346 [0x68] = {"and", opr_n_bytes_p1, reg, opr_decode}, 1347 [0x69] = {"and", opr_n_bytes_p1, reg, opr_decode}, 1348 [0x6a] = {"and", opr_n_bytes_p1, reg, opr_decode}, 1349 [0x6b] = {"and", opr_n_bytes_p1, reg, opr_decode}, 1350 [0x6c] = {"and", opr_n_bytes_p1, reg, opr_decode}, 1351 [0x6d] = {"and", opr_n_bytes_p1, reg, opr_decode}, 1352 [0x6e] = {"and", opr_n_bytes_p1, reg, opr_decode}, 1353 [0x6f] = {"and", opr_n_bytes_p1, reg, opr_decode}, 1354 [0x70] = {"sub", three, reg, imm1234_0base}, 1355 [0x71] = {"sub", three, reg, imm1234_0base}, 1356 [0x72] = {"sub", three, reg, imm1234_0base}, 1357 [0x73] = {"sub", three, reg, imm1234_0base}, 1358 [0x74] = {"sub", two, reg, imm1234_0base}, 1359 [0x75] = {"sub", two, reg, imm1234_0base}, 1360 [0x76] = {"sub", five, reg, imm1234_0base}, 1361 [0x77] = {"sub", five, reg, imm1234_0base}, 1362 [0x78] = {"or", three, reg, imm1234_8base}, 1363 [0x79] = {"or", three, reg, imm1234_8base}, 1364 [0x7a] = {"or", three, reg, imm1234_8base}, 1365 [0x7b] = {"or", three, reg, imm1234_8base}, 1366 [0x7c] = {"or", two, reg, imm1234_8base}, 1367 [0x7d] = {"or", two, reg, imm1234_8base}, 1368 [0x7e] = {"or", five, reg, imm1234_8base}, 1369 [0x7f] = {"or", five, reg, imm1234_8base}, 1370 [0x80] = {"sub", opr_n_bytes_p1, reg, opr_decode}, 1371 [0x81] = {"sub", opr_n_bytes_p1, reg, opr_decode}, 1372 [0x82] = {"sub", opr_n_bytes_p1, reg, opr_decode}, 1373 [0x83] = {"sub", opr_n_bytes_p1, reg, opr_decode}, 1374 [0x84] = {"sub", opr_n_bytes_p1, reg, opr_decode}, 1375 [0x85] = {"sub", opr_n_bytes_p1, reg, opr_decode}, 1376 [0x86] = {"sub", opr_n_bytes_p1, reg, opr_decode}, 1377 [0x87] = {"sub", opr_n_bytes_p1, reg, opr_decode}, 1378 [0x88] = {"or", opr_n_bytes_p1, reg, opr_decode}, 1379 [0x89] = {"or", opr_n_bytes_p1, reg, opr_decode}, 1380 [0x8a] = {"or", opr_n_bytes_p1, reg, opr_decode}, 1381 [0x8b] = {"or", opr_n_bytes_p1, reg, opr_decode}, 1382 [0x8c] = {"or", opr_n_bytes_p1, reg, opr_decode}, 1383 [0x8d] = {"or", opr_n_bytes_p1, reg, opr_decode}, 1384 [0x8e] = {"or", opr_n_bytes_p1, reg, opr_decode}, 1385 [0x8f] = {"or", opr_n_bytes_p1, reg, opr_decode}, 1386 [0x90] = {"ld", three, reg, imm1234_0base}, 1387 [0x91] = {"ld", three, reg, imm1234_0base}, 1388 [0x92] = {"ld", three, reg, imm1234_0base}, 1389 [0x93] = {"ld", three, reg, imm1234_0base}, 1390 [0x94] = {"ld", two, reg, imm1234_0base}, 1391 [0x95] = {"ld", two, reg, imm1234_0base}, 1392 [0x96] = {"ld", five, reg, imm1234_0base}, 1393 [0x97] = {"ld", five, reg, imm1234_0base}, 1394 [0x98] = {"ld", four, reg_xy, imm1234_0base}, 1395 [0x99] = {"ld", four, reg_xy, imm1234_0base}, 1396 [0x9a] = {"clr", single, reg_xy, 0}, 1397 [0x9b] = {"clr", single, reg_xy, 0}, 1398 [0x9c] = {"inc.b", opr_n_bytes_p1, 0, opr_decode}, 1399 [0x9d] = {"inc.w", opr_n_bytes_p1, 0, opr_decode}, 1400 [0x9e] = {"tfr", two, tfr, NULL}, 1401 [0x9f] = {"inc.l", opr_n_bytes_p1, 0, opr_decode}, 1402 [0xa0] = {"ld", opr_n_bytes_p1, reg, opr_decode}, 1403 [0xa1] = {"ld", opr_n_bytes_p1, reg, opr_decode}, 1404 [0xa2] = {"ld", opr_n_bytes_p1, reg, opr_decode}, 1405 [0xa3] = {"ld", opr_n_bytes_p1, reg, opr_decode}, 1406 [0xa4] = {"ld", opr_n_bytes_p1, reg, opr_decode}, 1407 [0xa5] = {"ld", opr_n_bytes_p1, reg, opr_decode}, 1408 [0xa6] = {"ld", opr_n_bytes_p1, reg, opr_decode}, 1409 [0xa7] = {"ld", opr_n_bytes_p1, reg, opr_decode}, 1410 [0xa8] = {"ld", opr_n_bytes_p1, reg_xy, opr_decode}, 1411 [0xa9] = {"ld", opr_n_bytes_p1, reg_xy, opr_decode}, 1412 [0xaa] = {"jmp", opr_n_bytes_p1, opr_decode, 0}, 1413 [0xab] = {"jsr", opr_n_bytes_p1, opr_decode, 0}, 1414 [0xac] = {"dec.b", opr_n_bytes_p1, 0, opr_decode}, 1415 [0xad] = {"dec.w", opr_n_bytes_p1, 0, opr_decode}, 1416 [0xae] = {NULL, two, 0, 0}, /* EXG / SEX */ 1417 [0xaf] = {"dec.l", opr_n_bytes_p1, 0, opr_decode}, 1418 [0xb0] = {"ld", four, reg, ext24_decode}, 1419 [0xb1] = {"ld", four, reg, ext24_decode}, 1420 [0xb2] = {"ld", four, reg, ext24_decode}, 1421 [0xb3] = {"ld", four, reg, ext24_decode}, 1422 [0xb4] = {"ld", four, reg, ext24_decode}, 1423 [0xb5] = {"ld", four, reg, ext24_decode}, 1424 [0xb6] = {"ld", four, reg, ext24_decode}, 1425 [0xb7] = {"ld", four, reg, ext24_decode}, 1426 [0xb8] = {"ld", four, reg_xy, ext24_decode}, 1427 [0xb9] = {"ld", four, reg_xy, ext24_decode}, 1428 [0xba] = {"jmp", four, ext24_decode, 0}, 1429 [0xbb] = {"jsr", four, ext24_decode, 0}, 1430 [0xbc] = {"clr.b", opr_n_bytes_p1, 0, opr_decode}, 1431 [0xbd] = {"clr.w", opr_n_bytes_p1, 0, opr_decode}, 1432 [0xbe] = {"clr.p", opr_n_bytes_p1, 0, opr_decode}, 1433 [0xbf] = {"clr.l", opr_n_bytes_p1, 0, opr_decode}, 1434 [0xc0] = {"st", opr_n_bytes_p1, reg, opr_decode}, 1435 [0xc1] = {"st", opr_n_bytes_p1, reg, opr_decode}, 1436 [0xc2] = {"st", opr_n_bytes_p1, reg, opr_decode}, 1437 [0xc3] = {"st", opr_n_bytes_p1, reg, opr_decode}, 1438 [0xc4] = {"st", opr_n_bytes_p1, reg, opr_decode}, 1439 [0xc5] = {"st", opr_n_bytes_p1, reg, opr_decode}, 1440 [0xc6] = {"st", opr_n_bytes_p1, reg, opr_decode}, 1441 [0xc7] = {"st", opr_n_bytes_p1, reg, opr_decode}, 1442 [0xc8] = {"st", opr_n_bytes_p1, reg_xy, opr_decode}, 1443 [0xc9] = {"st", opr_n_bytes_p1, reg_xy, opr_decode}, 1444 [0xca] = {"ld", three, reg_xy, ld_18bit_decode}, 1445 [0xcb] = {"ld", three, reg_xy, ld_18bit_decode}, 1446 [0xcc] = {"com.b", opr_n_bytes_p1, NULL, opr_decode}, 1447 [0xcd] = {"com.w", opr_n_bytes_p1, NULL, opr_decode}, 1448 [0xce] = {"andcc", two, imm1, 0}, 1449 [0xcf] = {"com.l", opr_n_bytes_p1, NULL, opr_decode}, 1450 [0xd0] = {"st", four, reg, ext24_decode}, 1451 [0xd1] = {"st", four, reg, ext24_decode}, 1452 [0xd2] = {"st", four, reg, ext24_decode}, 1453 [0xd3] = {"st", four, reg, ext24_decode}, 1454 [0xd4] = {"st", four, reg, ext24_decode}, 1455 [0xd5] = {"st", four, reg, ext24_decode}, 1456 [0xd6] = {"st", four, reg, ext24_decode}, 1457 [0xd7] = {"st", four, reg, ext24_decode}, 1458 [0xd8] = {"st", four, reg_xy, ext24_decode}, 1459 [0xd9] = {"st", four, reg_xy, ext24_decode}, 1460 [0xda] = {"ld", three, reg_xy, ld_18bit_decode}, 1461 [0xdb] = {"ld", three, reg_xy, ld_18bit_decode}, 1462 [0xdc] = {"neg.b", opr_n_bytes_p1, NULL, opr_decode}, 1463 [0xdd] = {"neg.w", opr_n_bytes_p1, NULL, opr_decode}, 1464 [0xde] = {"orcc", two, imm1, 0}, 1465 [0xdf] = {"neg.l", opr_n_bytes_p1, NULL, opr_decode}, 1466 [0xe0] = {"cmp", three, reg, imm1234_0base}, 1467 [0xe1] = {"cmp", three, reg, imm1234_0base}, 1468 [0xe2] = {"cmp", three, reg, imm1234_0base}, 1469 [0xe3] = {"cmp", three, reg, imm1234_0base}, 1470 [0xe4] = {"cmp", two, reg, imm1234_0base}, 1471 [0xe5] = {"cmp", two, reg, imm1234_0base}, 1472 [0xe6] = {"cmp", five, reg, imm1234_0base}, 1473 [0xe7] = {"cmp", five, reg, imm1234_0base}, 1474 [0xe8] = {"cmp", four, reg_xy, imm1234_0base}, 1475 [0xe9] = {"cmp", four, reg_xy, imm1234_0base}, 1476 [0xea] = {"ld", three, reg_xy, ld_18bit_decode}, 1477 [0xeb] = {"ld", three, reg_xy, ld_18bit_decode}, 1478 [0xec] = {"bclr", bm_n_bytes, bm_decode, 0}, 1479 [0xed] = {"bset", bm_n_bytes, bm_decode, 0}, 1480 [0xee] = {"btgl", bm_n_bytes, bm_decode, 0}, 1481 [0xef] = {"!!invalid!!", NULL, NULL, NULL}, /* SPARE */ 1482 [0xf0] = {"cmp", opr_n_bytes_p1, reg, opr_decode}, 1483 [0xf1] = {"cmp", opr_n_bytes_p1, reg, opr_decode}, 1484 [0xf2] = {"cmp", opr_n_bytes_p1, reg, opr_decode}, 1485 [0xf3] = {"cmp", opr_n_bytes_p1, reg, opr_decode}, 1486 [0xf4] = {"cmp", opr_n_bytes_p1, reg, opr_decode}, 1487 [0xf5] = {"cmp", opr_n_bytes_p1, reg, opr_decode}, 1488 [0xf6] = {"cmp", opr_n_bytes_p1, reg, opr_decode}, 1489 [0xf7] = {"cmp", opr_n_bytes_p1, reg, opr_decode}, 1490 [0xf8] = {"cmp", opr_n_bytes_p1, reg_xy, opr_decode}, 1491 [0xf9] = {"cmp", opr_n_bytes_p1, reg_xy, opr_decode}, 1492 [0xfa] = {"ld", three, reg_xy, ld_18bit_decode}, 1493 [0xfb] = {"ld", three, reg_xy, ld_18bit_decode}, 1494 [0xfc] = {"cmp", single, cmp_xy, 0}, 1495 [0xfd] = {"sub", single, sub_d6_x_y, 0}, 1496 [0xfe] = {"sub", single, sub_d6_y_x, 0}, 1497 [0xff] = {"swi", single, 0, 0} 1498 }; 1499 1500 1501 static const char *oprregs1[] = 1502 { 1503 "d3", "d2", "d1", "d0", "ccl", "cch" 1504 }; 1505 1506 static const char *oprregs2[] = 1507 { 1508 "y", "x", "d7", "d6", "d5", "d4" 1509 }; 1510 1511 1512 1513 1514 enum MUL_MODE 1515 { 1516 MUL_REG_REG, 1517 MUL_REG_OPR, 1518 MUL_REG_IMM, 1519 MUL_OPR_OPR 1520 }; 1521 1522 struct mb 1523 { 1524 uint8_t mask; 1525 uint8_t value; 1526 enum MUL_MODE mode; 1527 }; 1528 1529 static const struct mb mul_table[] = { 1530 {0x40, 0x00, MUL_REG_REG}, 1531 1532 {0x47, 0x40, MUL_REG_OPR}, 1533 {0x47, 0x41, MUL_REG_OPR}, 1534 {0x47, 0x43, MUL_REG_OPR}, 1535 1536 {0x47, 0x44, MUL_REG_IMM}, 1537 {0x47, 0x45, MUL_REG_IMM}, 1538 {0x47, 0x47, MUL_REG_IMM}, 1539 1540 {0x43, 0x42, MUL_OPR_OPR}, 1541 }; 1542 1543 static void 1544 mul_decode (bfd_vma memaddr, struct disassemble_info* info) 1545 { 1546 uint8_t mb; 1547 int status = read_memory (memaddr, &mb, 1, info); 1548 if (status < 0) 1549 return; 1550 1551 1552 uint8_t byte; 1553 status = read_memory (memaddr - 1, &byte, 1, info); 1554 if (status < 0) 1555 return; 1556 1557 (*info->fprintf_func) (info->stream, "%c", (mb & 0x80) ? 's' : 'u'); 1558 1559 enum MUL_MODE mode = -1; 1560 size_t i; 1561 for (i = 0; i < sizeof (mul_table) / sizeof (mul_table[0]); ++i) 1562 { 1563 const struct mb *mm = mul_table + i; 1564 if ((mb & mm->mask) == mm->value) 1565 { 1566 mode = mm->mode; 1567 break; 1568 } 1569 } 1570 1571 switch (mode) 1572 { 1573 case MUL_REG_REG: 1574 break; 1575 case MUL_OPR_OPR: 1576 { 1577 int size1 = (mb & 0x30) >> 4; 1578 int size2 = (mb & 0x0c) >> 2; 1579 (*info->fprintf_func) (info->stream, ".%c%c", 1580 shift_size_table [size1], 1581 shift_size_table [size2]); 1582 } 1583 break; 1584 default: 1585 { 1586 int size = (mb & 0x3); 1587 (*info->fprintf_func) (info->stream, ".%c", shift_size_table [size]); 1588 } 1589 break; 1590 } 1591 1592 operand_separator (info); 1593 (*info->fprintf_func) (info->stream, "%s", registers[byte & 0x7].name); 1594 1595 switch (mode) 1596 { 1597 case MUL_REG_REG: 1598 case MUL_REG_IMM: 1599 case MUL_REG_OPR: 1600 operand_separator (info); 1601 (*info->fprintf_func) (info->stream, "%s", registers[(mb & 0x38) >> 3].name); 1602 break; 1603 default: 1604 break; 1605 } 1606 1607 switch (mode) 1608 { 1609 case MUL_REG_IMM: 1610 operand_separator (info); 1611 int size = (mb & 0x3); 1612 uint32_t imm = decode_signed_value (memaddr + 1, info, size + 1); 1613 (*info->fprintf_func) (info->stream, "#%d", imm); 1614 break; 1615 case MUL_REG_REG: 1616 operand_separator (info); 1617 (*info->fprintf_func) (info->stream, "%s", registers[mb & 0x07].name); 1618 break; 1619 case MUL_REG_OPR: 1620 opr_decode (memaddr + 1, info); 1621 break; 1622 case MUL_OPR_OPR: 1623 { 1624 int first = opr_n_bytes (memaddr + 1, info); 1625 opr_decode (memaddr + 1, info); 1626 opr_decode (memaddr + first + 1, info); 1627 break; 1628 } 1629 } 1630 } 1631 1632 1633 static int 1634 mul_n_bytes (bfd_vma memaddr, struct disassemble_info* info) 1635 { 1636 int nx = 2; 1637 uint8_t mb; 1638 int status = read_memory (memaddr, &mb, 1, info); 1639 if (status < 0) 1640 return 0; 1641 1642 enum MUL_MODE mode = -1; 1643 size_t i; 1644 for (i = 0; i < sizeof (mul_table) / sizeof (mul_table[0]); ++i) 1645 { 1646 const struct mb *mm = mul_table + i; 1647 if ((mb & mm->mask) == mm->value) 1648 { 1649 mode = mm->mode; 1650 break; 1651 } 1652 } 1653 1654 int size = (mb & 0x3) + 1; 1655 1656 switch (mode) 1657 { 1658 case MUL_REG_IMM: 1659 nx += size; 1660 break; 1661 case MUL_REG_REG: 1662 break; 1663 case MUL_REG_OPR: 1664 nx += opr_n_bytes (memaddr + 1, info); 1665 break; 1666 case MUL_OPR_OPR: 1667 { 1668 int first = opr_n_bytes (memaddr + nx - 1, info); 1669 nx += first; 1670 int second = opr_n_bytes (memaddr + nx - 1, info); 1671 nx += second; 1672 } 1673 break; 1674 } 1675 1676 return nx; 1677 } 1678 1679 1680 enum BM_MODE { 1681 BM_REG_IMM, 1682 BM_RESERVED0, 1683 BM_OPR_B, 1684 BM_OPR_W, 1685 BM_OPR_L, 1686 BM_OPR_REG, 1687 BM_RESERVED1 1688 }; 1689 1690 struct bm 1691 { 1692 uint8_t mask; 1693 uint8_t value; 1694 enum BM_MODE mode; 1695 }; 1696 1697 static const struct bm bm_table[] = { 1698 { 0xC6, 0x04, BM_REG_IMM}, 1699 { 0x84, 0x00, BM_REG_IMM}, 1700 { 0x06, 0x06, BM_REG_IMM}, 1701 { 0xC6, 0x44, BM_RESERVED0}, 1702 // 00 1703 { 0x8F, 0x80, BM_OPR_B}, 1704 { 0x8E, 0x82, BM_OPR_W}, 1705 { 0x8C, 0x88, BM_OPR_L}, 1706 1707 { 0x83, 0x81, BM_OPR_REG}, 1708 { 0x87, 0x84, BM_RESERVED1}, 1709 }; 1710 1711 static void 1712 bm_decode (bfd_vma memaddr, struct disassemble_info* info) 1713 { 1714 uint8_t bm; 1715 int status = read_memory (memaddr, &bm, 1, info); 1716 if (status < 0) 1717 return; 1718 1719 size_t i; 1720 enum BM_MODE mode = -1; 1721 for (i = 0; i < sizeof (bm_table) / sizeof (bm_table[0]); ++i) 1722 { 1723 const struct bm *bme = bm_table + i; 1724 if ((bm & bme->mask) == bme->value) 1725 { 1726 mode = bme->mode; 1727 break; 1728 } 1729 } 1730 1731 switch (mode) 1732 { 1733 case BM_REG_IMM: 1734 operand_separator (info); 1735 (*info->fprintf_func) (info->stream, "%s", registers[bm & 0x07].name); 1736 break; 1737 case BM_OPR_B: 1738 (*info->fprintf_func) (info->stream, ".%c", 'b'); 1739 opr_decode (memaddr + 1, info); 1740 break; 1741 case BM_OPR_W: 1742 (*info->fprintf_func) (info->stream, ".%c", 'w'); 1743 opr_decode (memaddr + 1, info); 1744 break; 1745 case BM_OPR_L: 1746 (*info->fprintf_func) (info->stream, ".%c", 'l'); 1747 opr_decode (memaddr + 1, info); 1748 break; 1749 case BM_OPR_REG: 1750 { 1751 uint8_t xb; 1752 read_memory (memaddr + 1, &xb, 1, info); 1753 /* Don't emit a size suffix for register operands */ 1754 if ((xb & 0xF8) != 0xB8) 1755 (*info->fprintf_func) (info->stream, ".%c", shift_size_table[(bm & 0x0c) >> 2]); 1756 opr_decode (memaddr + 1, info); 1757 } 1758 break; 1759 case BM_RESERVED0: 1760 case BM_RESERVED1: 1761 assert (0); 1762 break; 1763 } 1764 1765 uint8_t imm = 0; 1766 operand_separator (info); 1767 switch (mode) 1768 { 1769 case BM_REG_IMM: 1770 { 1771 imm = (bm & 0xF8) >> 3; 1772 (*info->fprintf_func) (info->stream, "#%d", imm); 1773 } 1774 break; 1775 case BM_OPR_L: 1776 imm |= (bm & 0x03) << 3; 1777 /* fallthrough */ 1778 case BM_OPR_W: 1779 imm |= (bm & 0x01) << 3; 1780 /* fallthrough */ 1781 case BM_OPR_B: 1782 imm |= (bm & 0x70) >> 4; 1783 (*info->fprintf_func) (info->stream, "#%d", imm); 1784 break; 1785 case BM_OPR_REG: 1786 (*info->fprintf_func) (info->stream, "%s", registers[(bm & 0x70) >> 4].name); 1787 break; 1788 case BM_RESERVED0: 1789 case BM_RESERVED1: 1790 assert (0); 1791 break; 1792 } 1793 } 1794 1795 1796 static void 1797 bm_rel_decode (bfd_vma memaddr, struct disassemble_info* info) 1798 { 1799 uint8_t bm; 1800 int status = read_memory (memaddr, &bm, 1, info); 1801 if (status < 0) 1802 return; 1803 1804 size_t i; 1805 enum BM_MODE mode = -1; 1806 for (i = 0; i < sizeof (bm_table) / sizeof (bm_table[0]); ++i) 1807 { 1808 const struct bm *bme = bm_table + i; 1809 if ((bm & bme->mask) == bme->value) 1810 { 1811 mode = bme->mode; 1812 break; 1813 } 1814 } 1815 1816 switch (mode) 1817 { 1818 case BM_REG_IMM: 1819 break; 1820 case BM_OPR_B: 1821 (*info->fprintf_func) (info->stream, ".%c", 'b'); 1822 break; 1823 case BM_OPR_W: 1824 (*info->fprintf_func) (info->stream, ".%c", 'w'); 1825 break; 1826 case BM_OPR_L: 1827 (*info->fprintf_func) (info->stream, ".%c", 'l'); 1828 break; 1829 case BM_OPR_REG: 1830 { 1831 uint8_t xb; 1832 read_memory (memaddr + 1, &xb, 1, info); 1833 /* Don't emit a size suffix for register operands */ 1834 if ((xb & 0xF8) != 0xB8) 1835 (*info->fprintf_func) (info->stream, ".%c", 1836 shift_size_table[(bm & 0x0C) >> 2]); 1837 } 1838 break; 1839 case BM_RESERVED0: 1840 case BM_RESERVED1: 1841 assert (0); 1842 break; 1843 } 1844 1845 int n = 1; 1846 switch (mode) 1847 { 1848 case BM_REG_IMM: 1849 operand_separator (info); 1850 (*info->fprintf_func) (info->stream, "%s", registers[bm & 0x07].name); 1851 break; 1852 case BM_OPR_B: 1853 case BM_OPR_W: 1854 case BM_OPR_L: 1855 opr_decode (memaddr + 1, info); 1856 n = 1 + opr_n_bytes (memaddr + 1, info); 1857 break; 1858 case BM_OPR_REG: 1859 opr_decode (memaddr + 1, info); 1860 break; 1861 case BM_RESERVED0: 1862 case BM_RESERVED1: 1863 assert (0); 1864 break; 1865 } 1866 1867 1868 int imm = 0; 1869 operand_separator (info); 1870 switch (mode) 1871 { 1872 case BM_OPR_L: 1873 imm |= (bm & 0x02) << 3; 1874 /* fall through */ 1875 case BM_OPR_W: 1876 imm |= (bm & 0x01) << 3; 1877 /* fall through */ 1878 case BM_OPR_B: 1879 imm |= (bm & 0x70) >> 4; 1880 (*info->fprintf_func) (info->stream, "#%d", imm); 1881 break; 1882 case BM_REG_IMM: 1883 imm = (bm & 0xF8) >> 3; 1884 (*info->fprintf_func) (info->stream, "#%d", imm); 1885 break; 1886 case BM_RESERVED0: 1887 case BM_RESERVED1: 1888 assert (0); 1889 break; 1890 case BM_OPR_REG: 1891 (*info->fprintf_func) (info->stream, "%s", registers[(bm & 0x70) >> 4].name); 1892 n += opr_n_bytes (memaddr + 1, info); 1893 break; 1894 } 1895 1896 rel_15_7 (memaddr + n, info, n + 1); 1897 } 1898 1899 static int 1900 bm_n_bytes (bfd_vma memaddr, struct disassemble_info* info) 1901 { 1902 uint8_t bm; 1903 int status = read_memory (memaddr, &bm, 1, info); 1904 if (status < 0) 1905 return status; 1906 1907 size_t i; 1908 enum BM_MODE mode = -1; 1909 for (i = 0; i < sizeof (bm_table) / sizeof (bm_table[0]); ++i) 1910 { 1911 const struct bm *bme = bm_table + i; 1912 if ((bm & bme->mask) == bme->value) 1913 { 1914 mode = bme->mode; 1915 break; 1916 } 1917 } 1918 1919 int n = 2; 1920 switch (mode) 1921 { 1922 case BM_REG_IMM: 1923 break; 1924 1925 case BM_OPR_B: 1926 case BM_OPR_W: 1927 case BM_OPR_L: 1928 n += opr_n_bytes (memaddr + 1, info); 1929 break; 1930 case BM_OPR_REG: 1931 n += opr_n_bytes (memaddr + 1, info); 1932 break; 1933 default: 1934 break; 1935 } 1936 1937 return n; 1938 } 1939 1940 static int 1941 bm_rel_n_bytes (bfd_vma memaddr, struct disassemble_info* info) 1942 { 1943 int n = 1 + bm_n_bytes (memaddr, info); 1944 1945 bfd_byte rb; 1946 int status = read_memory (memaddr + n - 2, &rb, 1, info); 1947 if (status != 0) 1948 return status; 1949 1950 if (rb & 0x80) 1951 n++; 1952 1953 return n; 1954 } 1955 1956 1957 1958 1959 1960 /* shift direction */ 1961 enum SB_DIR 1962 { 1963 SB_LEFT, 1964 SB_RIGHT 1965 }; 1966 1967 enum SB_TYPE 1968 { 1969 SB_ARITHMETIC, 1970 SB_LOGICAL 1971 }; 1972 1973 1974 enum SB_MODE 1975 { 1976 SB_REG_REG_N_EFF, 1977 SB_REG_REG_N, 1978 SB_REG_OPR_EFF, 1979 SB_ROT, 1980 SB_REG_OPR_OPR, 1981 SB_OPR_N 1982 }; 1983 1984 struct sb 1985 { 1986 uint8_t mask; 1987 uint8_t value; 1988 enum SB_MODE mode; 1989 }; 1990 1991 static const struct sb sb_table[] = { 1992 {0x30, 0x00, SB_REG_REG_N_EFF}, 1993 {0x30, 0x10, SB_REG_REG_N}, 1994 {0x34, 0x20, SB_REG_OPR_EFF}, 1995 {0x34, 0x24, SB_ROT}, 1996 {0x34, 0x30, SB_REG_OPR_OPR}, 1997 {0x34, 0x34, SB_OPR_N}, 1998 }; 1999 2000 static int 2001 shift_n_bytes (bfd_vma memaddr, struct disassemble_info* info) 2002 { 2003 bfd_byte sb; 2004 int status = read_memory (memaddr++, &sb, 1, info); 2005 if (status != 0) 2006 return status; 2007 2008 size_t i; 2009 enum SB_MODE mode = -1; 2010 for (i = 0; i < sizeof (sb_table) / sizeof (sb_table[0]); ++i) 2011 { 2012 const struct sb *sbe = sb_table + i; 2013 if ((sb & sbe->mask) == sbe->value) 2014 mode = sbe->mode; 2015 } 2016 2017 switch (mode) 2018 { 2019 case SB_REG_REG_N_EFF: 2020 return 2; 2021 break; 2022 case SB_REG_OPR_EFF: 2023 case SB_ROT: 2024 return 2 + opr_n_bytes (memaddr, info); 2025 break; 2026 case SB_REG_OPR_OPR: 2027 { 2028 int opr1 = opr_n_bytes (memaddr, info); 2029 int opr2 = 0; 2030 if ((sb & 0x30) != 0x20) 2031 opr2 = opr_n_bytes (memaddr + opr1, info); 2032 return 2 + opr1 + opr2; 2033 } 2034 break; 2035 default: 2036 return 3; 2037 } 2038 2039 /* not reached */ 2040 return -1; 2041 } 2042 2043 2044 static int 2045 mov_imm_opr_n_bytes (bfd_vma memaddr, struct disassemble_info* info) 2046 { 2047 bfd_byte byte; 2048 int status = read_memory (memaddr - 1, &byte, 1, info); 2049 if (status < 0) 2050 return status; 2051 2052 int size = byte - 0x0c + 1; 2053 2054 return size + opr_n_bytes (memaddr + size, info) + 1; 2055 } 2056 2057 static void 2058 mov_imm_opr (bfd_vma memaddr, struct disassemble_info* info) 2059 { 2060 bfd_byte byte; 2061 int status = read_memory (memaddr - 1, &byte, 1, info); 2062 if (status < 0) 2063 return ; 2064 2065 int size = byte - 0x0c + 1; 2066 uint32_t imm = decode_signed_value (memaddr, info, size); 2067 2068 operand_separator (info); 2069 (*info->fprintf_func) (info->stream, "#%d", imm); 2070 opr_decode (memaddr + size, info); 2071 } 2072 2073 2074 2075 static void 2076 ld_18bit_decode (bfd_vma memaddr, struct disassemble_info* info) 2077 { 2078 size_t size = 3; 2079 bfd_byte buffer[3]; 2080 int status = read_memory (memaddr, buffer + 1, 2, info); 2081 if (status < 0) 2082 return ; 2083 2084 2085 status = read_memory (memaddr - 1, buffer, 1, info); 2086 if (status < 0) 2087 return ; 2088 2089 buffer[0] = (buffer[0] & 0x30) >> 4; 2090 2091 size_t i; 2092 uint32_t imm = 0; 2093 for (i = 0; i < size; ++i) 2094 { 2095 imm |= buffer[i] << (8 * (size - i - 1)); 2096 } 2097 2098 operand_separator (info); 2099 (*info->fprintf_func) (info->stream, "#%d", imm); 2100 } 2101 2102 2103 2104 /* Loop Primitives */ 2105 2106 enum LP_MODE { 2107 LP_REG, 2108 LP_XY, 2109 LP_OPR 2110 }; 2111 2112 struct lp 2113 { 2114 uint8_t mask; 2115 uint8_t value; 2116 enum LP_MODE mode; 2117 }; 2118 2119 static const struct lp lp_mode[] = { 2120 {0x08, 0x00, LP_REG}, 2121 {0x0C, 0x08, LP_XY}, 2122 {0x0C, 0x0C, LP_OPR}, 2123 }; 2124 2125 2126 static const char *lb_condition[] = 2127 { 2128 "ne", "eq", "pl", "mi", "gt", "le", 2129 "??", "??" 2130 }; 2131 2132 static int 2133 loop_prim_n_bytes (bfd_vma memaddr, struct disassemble_info* info) 2134 { 2135 int mx = 0; 2136 uint8_t lb; 2137 read_memory (memaddr + mx++, &lb, 1, info); 2138 2139 enum LP_MODE mode = -1; 2140 size_t i; 2141 for (i = 0; i < sizeof (lp_mode) / sizeof (lp_mode[0]); ++i) 2142 { 2143 const struct lp *pb = lp_mode + i; 2144 if ((lb & pb->mask) == pb->value) 2145 { 2146 mode = pb->mode; 2147 break; 2148 } 2149 } 2150 2151 if (mode == LP_OPR) 2152 { 2153 mx += opr_n_bytes (memaddr + mx, info) ; 2154 } 2155 2156 uint8_t rb; 2157 read_memory (memaddr + mx++, &rb, 1, info); 2158 if (rb & 0x80) 2159 mx++; 2160 2161 return mx + 1; 2162 } 2163 2164 2165 2166 2167 static int 2168 print_insn_exg_sex (bfd_vma memaddr, struct disassemble_info* info) 2169 { 2170 uint8_t eb; 2171 int status = read_memory (memaddr, &eb, 1, info); 2172 if (status < 0) 2173 return -1; 2174 2175 const struct reg *first = ®isters[(eb & 0xf0) >> 4]; 2176 const struct reg *second = ®isters[(eb & 0xf)]; 2177 2178 if (first->bytes < second->bytes) 2179 (*info->fprintf_func) (info->stream, "sex"); 2180 else 2181 (*info->fprintf_func) (info->stream, "exg"); 2182 2183 operand_separator (info); 2184 (*info->fprintf_func) (info->stream, "%s", first->name); 2185 operand_separator (info); 2186 (*info->fprintf_func) (info->stream, "%s", second->name); 2187 return 0; 2188 } 2189 2190 2191 2192 static int 2193 print_insn_loop_primitive (bfd_vma memaddr, struct disassemble_info* info) 2194 { 2195 int offs = 1; 2196 uint8_t lb; 2197 int status = read_memory (memaddr, &lb, 1, info); 2198 2199 char mnemonic[7]; 2200 int x = 0; 2201 mnemonic[x++] = (lb & 0x80) ? 'd' : 't'; 2202 mnemonic[x++] = 'b'; 2203 stpcpy (mnemonic + x, lb_condition [(lb & 0x70) >> 4]); 2204 x += 2; 2205 2206 const char *reg = NULL; 2207 enum LP_MODE mode = -1; 2208 size_t i; 2209 for (i = 0; i < sizeof (lp_mode) / sizeof (lp_mode[0]); ++i) 2210 { 2211 const struct lp *pb = lp_mode + i; 2212 if ((lb & pb->mask) == pb->value) 2213 { 2214 mode = pb->mode; 2215 break; 2216 } 2217 } 2218 2219 switch (mode) 2220 { 2221 case LP_REG: 2222 reg = registers [lb & 0x07].name; 2223 break; 2224 case LP_XY: 2225 reg = (lb & 0x1) ? "y" : "x"; 2226 break; 2227 case LP_OPR: 2228 mnemonic[x++] = '.'; 2229 mnemonic[x++] = shift_size_table [lb & 0x03]; 2230 offs += opr_n_bytes (memaddr + 1, info); 2231 break; 2232 } 2233 2234 mnemonic[x++] = '\0'; 2235 2236 (*info->fprintf_func) (info->stream, "%s", mnemonic); 2237 2238 if (mode == LP_OPR) 2239 opr_decode (memaddr + 1, info); 2240 else 2241 { 2242 operand_separator (info); 2243 (*info->fprintf_func) (info->stream, "%s", reg); 2244 } 2245 2246 rel_15_7 (memaddr + offs, info, offs + 1); 2247 2248 return status; 2249 } 2250 2251 2252 static int 2253 print_insn_shift (bfd_vma memaddr, struct disassemble_info* info, uint8_t byte) 2254 { 2255 size_t i; 2256 uint8_t sb; 2257 int status = read_memory (memaddr, &sb, 1, info); 2258 if (status < 0) 2259 return status; 2260 2261 enum SB_DIR dir = (sb & 0x40) ? SB_LEFT : SB_RIGHT; 2262 enum SB_TYPE type = (sb & 0x80) ? SB_ARITHMETIC : SB_LOGICAL; 2263 enum SB_MODE mode = -1; 2264 for (i = 0; i < sizeof (sb_table) / sizeof (sb_table[0]); ++i) 2265 { 2266 const struct sb *sbe = sb_table + i; 2267 if ((sb & sbe->mask) == sbe->value) 2268 mode = sbe->mode; 2269 } 2270 2271 char mnemonic[6]; 2272 int x = 0; 2273 if (mode == SB_ROT) 2274 { 2275 mnemonic[x++] = 'r'; 2276 mnemonic[x++] = 'o'; 2277 } 2278 else 2279 { 2280 mnemonic[x++] = (type == SB_LOGICAL) ? 'l' : 'a'; 2281 mnemonic[x++] = 's'; 2282 } 2283 2284 mnemonic[x++] = (dir == SB_LEFT) ? 'l' : 'r'; 2285 2286 switch (mode) 2287 { 2288 case SB_REG_OPR_EFF: 2289 case SB_ROT: 2290 case SB_REG_OPR_OPR: 2291 mnemonic[x++] = '.'; 2292 mnemonic[x++] = shift_size_table[sb & 0x03]; 2293 break; 2294 case SB_OPR_N: 2295 { 2296 uint8_t xb; 2297 read_memory (memaddr + 1, &xb, 1, info); 2298 /* The size suffix is not printed if the OPR operand refers 2299 directly to a register, because the size is implied by the 2300 size of that register. */ 2301 if ((xb & 0xF8) != 0xB8) 2302 { 2303 mnemonic[x++] = '.'; 2304 mnemonic[x++] = shift_size_table[sb & 0x03]; 2305 } 2306 } 2307 break; 2308 default: 2309 break; 2310 }; 2311 2312 mnemonic[x++] = '\0'; 2313 2314 (*info->fprintf_func) (info->stream, "%s", mnemonic); 2315 2316 /* Destination register */ 2317 switch (mode) 2318 { 2319 case SB_REG_REG_N_EFF: 2320 case SB_REG_REG_N: 2321 case SB_REG_OPR_EFF: 2322 case SB_REG_OPR_OPR: 2323 operand_separator (info); 2324 (*info->fprintf_func) (info->stream, "%s", registers[byte & 0x7].name); 2325 break; 2326 2327 case SB_ROT: 2328 opr_decode (memaddr + 1, info); 2329 break; 2330 2331 default: 2332 break; 2333 } 2334 2335 /* Source register */ 2336 switch (mode) 2337 { 2338 case SB_REG_REG_N_EFF: 2339 case SB_REG_REG_N: 2340 operand_separator (info); 2341 (*info->fprintf_func) (info->stream, "%s", registers[sb & 0x7].name); 2342 break; 2343 2344 case SB_REG_OPR_OPR: 2345 opr_decode (memaddr + 1, info); 2346 break; 2347 2348 default: 2349 break; 2350 } 2351 2352 /* 3rd arg */ 2353 switch (mode) 2354 { 2355 case SB_REG_OPR_EFF: 2356 case SB_OPR_N: 2357 opr_decode (memaddr + 1, info); 2358 break; 2359 2360 case SB_REG_REG_N: 2361 if (sb & 0x08) 2362 { 2363 operand_separator (info); 2364 if (byte & 0x10) 2365 { 2366 uint8_t xb; 2367 read_memory (memaddr + 1, &xb, 1, info); 2368 int shift = ((sb & 0x08) >> 3) | ((xb & 0x0f) << 1); 2369 (*info->fprintf_func) (info->stream, "#%d", shift); 2370 } 2371 else 2372 { 2373 (*info->fprintf_func) (info->stream, "%s:%d", __FILE__, __LINE__); 2374 } 2375 } 2376 else 2377 { 2378 opr_decode (memaddr + 1, info); 2379 } 2380 break; 2381 case SB_REG_OPR_OPR: 2382 { 2383 uint8_t xb; 2384 int n = opr_n_bytes (memaddr + 1, info); 2385 read_memory (memaddr + 1 + n, &xb, 1, info); 2386 2387 if ((xb & 0xF0) == 0x70) 2388 { 2389 int imm = xb & 0x0F; 2390 imm <<= 1; 2391 imm |= (sb & 0x08) >> 3; 2392 operand_separator (info); 2393 (*info->fprintf_func) (info->stream, "#%d", imm); 2394 } 2395 else 2396 { 2397 opr_decode (memaddr + 1 + n, info); 2398 } 2399 } 2400 break; 2401 default: 2402 break; 2403 } 2404 2405 switch (mode) 2406 { 2407 case SB_REG_REG_N_EFF: 2408 case SB_REG_OPR_EFF: 2409 case SB_OPR_N: 2410 operand_separator (info); 2411 (*info->fprintf_func) (info->stream, "#%d", 2412 (sb & 0x08) ? 2 : 1); 2413 break; 2414 2415 default: 2416 break; 2417 } 2418 2419 return 0; 2420 } 2421 2422 int 2423 print_insn_s12z (bfd_vma memaddr, struct disassemble_info* info) 2424 { 2425 bfd_byte byte; 2426 int status = read_memory (memaddr++, &byte, 1, info); 2427 if (status != 0) 2428 return status; 2429 2430 const struct opcode *opc2 = NULL; 2431 const struct opcode *opc = page1 + byte; 2432 if (opc->mnemonic) 2433 { 2434 (*info->fprintf_func) (info->stream, "%s", opc->mnemonic); 2435 } 2436 else 2437 { 2438 /* The special cases ... */ 2439 switch (byte) 2440 { 2441 case PAGE2_PREBYTE: 2442 { 2443 bfd_byte byte2; 2444 read_memory (memaddr++, &byte2, 1, info); 2445 opc2 = page2 + byte2; 2446 if (opc2->mnemonic) 2447 { 2448 (*info->fprintf_func) (info->stream, "%s", opc2->mnemonic); 2449 2450 if (opc2->operands) 2451 { 2452 opc2->operands (memaddr, info); 2453 } 2454 2455 if (opc2->operands2) 2456 { 2457 opc2->operands2 (memaddr, info); 2458 } 2459 } 2460 else if (byte2 >= 0x08 && byte2 <= 0x1F) 2461 { 2462 bfd_byte bb; 2463 read_memory (memaddr, &bb, 1, info); 2464 if (bb & 0x80) 2465 (*info->fprintf_func) (info->stream, "bfins"); 2466 else 2467 (*info->fprintf_func) (info->stream, "bfext"); 2468 2469 enum BB_MODE mode = -1; 2470 size_t i; 2471 const struct opr_bb *bbs = 0; 2472 for (i = 0; i < sizeof (bb_modes) / sizeof (bb_modes[0]); ++i) 2473 { 2474 bbs = bb_modes + i; 2475 if ((bb & bbs->mask) == bbs->value) 2476 { 2477 mode = bbs->mode; 2478 break; 2479 } 2480 } 2481 2482 switch (mode) 2483 { 2484 case BB_REG_OPR_REG: 2485 case BB_REG_OPR_IMM: 2486 case BB_OPR_REG_REG: 2487 case BB_OPR_REG_IMM: 2488 { 2489 int size = (bb >> 2) & 0x03; 2490 (*info->fprintf_func) (info->stream, ".%c", 2491 shift_size_table [size]); 2492 } 2493 break; 2494 default: 2495 break; 2496 } 2497 2498 int reg1 = byte2 & 0x07; 2499 /* First operand */ 2500 switch (mode) 2501 { 2502 case BB_REG_REG_REG: 2503 case BB_REG_REG_IMM: 2504 case BB_REG_OPR_REG: 2505 case BB_REG_OPR_IMM: 2506 operand_separator (info); 2507 (*info->fprintf_func) (info->stream, "%s", 2508 registers[reg1].name); 2509 break; 2510 case BB_OPR_REG_REG: 2511 opr_decode (memaddr + 1, info); 2512 break; 2513 case BB_OPR_REG_IMM: 2514 opr_decode (memaddr + 2, info); 2515 break; 2516 } 2517 2518 /* Second operand */ 2519 switch (mode) 2520 { 2521 case BB_REG_REG_REG: 2522 case BB_REG_REG_IMM: 2523 { 2524 int reg_src = (bb >> 2) & 0x07; 2525 operand_separator (info); 2526 (*info->fprintf_func) (info->stream, "%s", 2527 registers[reg_src].name); 2528 } 2529 break; 2530 case BB_OPR_REG_REG: 2531 case BB_OPR_REG_IMM: 2532 { 2533 int reg_src = (byte2 & 0x07); 2534 operand_separator (info); 2535 (*info->fprintf_func) (info->stream, "%s", 2536 registers[reg_src].name); 2537 } 2538 break; 2539 case BB_REG_OPR_REG: 2540 opr_decode (memaddr + 1, info); 2541 break; 2542 case BB_REG_OPR_IMM: 2543 opr_decode (memaddr + 2, info); 2544 break; 2545 } 2546 2547 /* Third operand */ 2548 operand_separator (info); 2549 switch (mode) 2550 { 2551 case BB_REG_REG_REG: 2552 case BB_OPR_REG_REG: 2553 case BB_REG_OPR_REG: 2554 { 2555 int reg_parm = bb & 0x03; 2556 (*info->fprintf_func) (info->stream, "%s", 2557 registers[reg_parm].name); 2558 } 2559 break; 2560 case BB_REG_REG_IMM: 2561 case BB_OPR_REG_IMM: 2562 case BB_REG_OPR_IMM: 2563 { 2564 bfd_byte i1; 2565 read_memory (memaddr + 1, &i1, 1, info); 2566 int offset = i1 & 0x1f; 2567 int width = bb & 0x03; 2568 width <<= 3; 2569 width |= i1 >> 5; 2570 (*info->fprintf_func) (info->stream, "#%d:%d", width, offset); 2571 } 2572 break; 2573 } 2574 } 2575 } 2576 break; 2577 case 0xae: /* EXG / SEX */ 2578 status = print_insn_exg_sex (memaddr, info); 2579 break; 2580 case 0x0b: /* Loop Primitives TBcc and DBcc */ 2581 status = print_insn_loop_primitive (memaddr, info); 2582 break; 2583 case 0x10: /* shift */ 2584 case 0x11: /* shift */ 2585 case 0x12: /* shift */ 2586 case 0x13: /* shift */ 2587 case 0x14: /* shift */ 2588 case 0x15: /* shift */ 2589 case 0x16: /* shift */ 2590 case 0x17: /* shift */ 2591 status = print_insn_shift (memaddr, info, byte); 2592 break; 2593 case 0x04: /* psh / pul */ 2594 { 2595 read_memory (memaddr, &byte, 1, info); 2596 (*info->fprintf_func) (info->stream, (byte & 0x80) ? "pul" : "psh"); 2597 int bit; 2598 if (byte & 0x40) 2599 { 2600 if ((byte & 0x3F) == 0) 2601 { 2602 operand_separator (info); 2603 (*info->fprintf_func) (info->stream, "%s", "ALL16b"); 2604 } 2605 else 2606 for (bit = 5; bit >= 0; --bit) 2607 { 2608 if (byte & (0x1 << bit)) 2609 { 2610 operand_separator (info); 2611 (*info->fprintf_func) (info->stream, "%s", oprregs2[bit]); 2612 } 2613 } 2614 } 2615 else 2616 { 2617 if ((byte & 0x3F) == 0) 2618 { 2619 operand_separator (info); 2620 (*info->fprintf_func) (info->stream, "%s", "ALL"); 2621 } 2622 else 2623 for (bit = 5; bit >= 0; --bit) 2624 { 2625 if (byte & (0x1 << bit)) 2626 { 2627 operand_separator (info); 2628 (*info->fprintf_func) (info->stream, "%s", oprregs1[bit]); 2629 } 2630 } 2631 } 2632 } 2633 break; 2634 default: 2635 operand_separator (info); 2636 (*info->fprintf_func) (info->stream, "???"); 2637 break; 2638 } 2639 } 2640 2641 if (opc2 == NULL) 2642 { 2643 if (opc->operands) 2644 { 2645 opc->operands (memaddr, info); 2646 } 2647 2648 if (opc->operands2) 2649 { 2650 opc->operands2 (memaddr, info); 2651 } 2652 } 2653 2654 int n = 0; 2655 2656 /* Opcodes in page2 have an additional byte */ 2657 if (opc2) 2658 n++; 2659 2660 if (opc2 && opc2->insn_bytes == 0) 2661 return n; 2662 2663 if (!opc2 && opc->insn_bytes == 0) 2664 return n; 2665 2666 if (opc2) 2667 n += opc2->insn_bytes (memaddr, info); 2668 else 2669 n += opc->insn_bytes (memaddr, info); 2670 2671 return n; 2672 } 2673