Changeset 609 for branches/GNU/src/binutils/opcodes/m68hc11-dis.c
- Timestamp:
- Aug 16, 2003, 6:59:22 PM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/GNU/src/binutils/opcodes/m68hc11-dis.c
-
Property cvs2svn:cvs-rev
changed from
1.1
to1.1.1.2
r608 r609 1 1 /* m68hc11-dis.c -- Motorola 68HC11 & 68HC12 disassembly 2 Copyright 1999, 2000 Free Software Foundation, Inc.3 Written by Stephane Carrez (stcarrez@ worldnet.fr)2 Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. 3 Written by Stephane Carrez (stcarrez@nerim.fr) 4 4 5 5 This program is free software; you can redistribute it and/or modify … … 23 23 #include "dis-asm.h" 24 24 25 #define PC_REGNUM 3 26 25 27 static const char *const reg_name[] = { 26 28 "X", "Y", "SP", "PC" … … 36 38 37 39 #define OP_PAGE_MASK (M6811_OP_PAGE2|M6811_OP_PAGE3|M6811_OP_PAGE4) 40 41 /* Prototypes for local functions. */ 42 static int read_memory 43 PARAMS ((bfd_vma, bfd_byte *, int, struct disassemble_info *)); 44 static int print_indexed_operand 45 PARAMS ((bfd_vma, struct disassemble_info *, int*, int, int, bfd_vma)); 46 static int print_insn 47 PARAMS ((bfd_vma, struct disassemble_info *, int)); 38 48 39 49 static int … … 61 71 Returns the number of bytes read or -1 if failure. */ 62 72 static int 63 print_indexed_operand (memaddr, info, mov_insn)73 print_indexed_operand (memaddr, info, indirect, mov_insn, pc_offset, endaddr) 64 74 bfd_vma memaddr; 65 75 struct disassemble_info *info; 76 int *indirect; 66 77 int mov_insn; 78 int pc_offset; 79 bfd_vma endaddr; 67 80 { 68 81 bfd_byte buffer[4]; … … 72 85 int pos = 1; 73 86 87 if (indirect) 88 *indirect = 0; 89 74 90 status = read_memory (memaddr, &buffer[0], 1, info); 75 91 if (status != 0) … … 85 101 if (sval & 0x10) 86 102 sval |= 0xfff0; 103 /* 68HC12 requires an adjustment for movb/movw pc relative modes. */ 104 if (reg == PC_REGNUM && info->mach == bfd_mach_m6812 && mov_insn) 105 sval += pc_offset; 87 106 (*info->fprintf_func) (info->stream, "%d,%s", 88 107 (int) sval, reg_name[reg]); 108 109 if (reg == PC_REGNUM) 110 { 111 (* info->fprintf_func) (info->stream, " {"); 112 (* info->print_address_func) (endaddr + sval, info); 113 (* info->fprintf_func) (info->stream, "}"); 114 } 89 115 } 90 116 … … 133 159 (*info->fprintf_func) (info->stream, "[%u,%s]", 134 160 sval & 0x0ffff, reg_name[reg]); 135 } 161 if (indirect) 162 *indirect = 1; 163 } 164 165 /* n,r with 9 and 16 bit signed constant. */ 136 166 else if ((buffer[0] & 0x4) == 0) 137 167 { … … 154 184 sval &= 0x0FFFF; 155 185 pos += 2; 186 endaddr += 2; 156 187 } 157 188 else … … 161 192 sval |= 0xff00; 162 193 pos++; 194 endaddr++; 163 195 } 164 196 (*info->fprintf_func) (info->stream, "%d,%s", 165 197 (int) sval, reg_name[reg]); 198 if (reg == PC_REGNUM) 199 { 200 (* info->fprintf_func) (info->stream, " {"); 201 (* info->print_address_func) (endaddr + sval, info); 202 (* info->fprintf_func) (info->stream, "}"); 203 } 166 204 } 167 205 else … … 182 220 default: 183 221 (*info->fprintf_func) (info->stream, "[D,%s]", reg_name[reg]); 222 if (indirect) 223 *indirect = 1; 184 224 break; 185 225 } … … 284 324 { 285 325 int offset; 326 int pc_src_offset; 327 int pc_dst_offset; 286 328 287 329 if ((opcode->arch & arch) == 0) … … 359 401 } 360 402 361 /* The movb and movw must be handled in a special way... */ 362 offset = 0; 363 if (format & (M6812_OP_IDX_P2 | M6812_OP_IND16_P2)) 364 { 365 if ((format & M6812_OP_IDX_P2) 366 && (format & (M6811_OP_IMM8 | M6811_OP_IMM16 | M6811_OP_IND16))) 367 offset = 1; 368 } 403 /* The movb and movw must be handled in a special way... 404 The source constant 'ii' is not always at the same place. 405 This is the same for the destination for the post-indexed byte. 406 The 'offset' is used to do the appropriate correction. 407 408 offset offset 409 for constant for destination 410 movb 18 OB ii hh ll 0 0 411 18 08 xb ii 1 -1 412 18 0C hh ll hh ll 0 0 413 18 09 xb hh ll 1 -1 414 18 0D xb hh ll 0 0 415 18 0A xb xb 0 0 416 417 movw 18 03 jj kk hh ll 0 0 418 18 00 xb jj kk 1 -1 419 18 04 hh ll hh ll 0 0 420 18 01 xb hh ll 1 -1 421 18 05 xb hh ll 0 0 422 18 02 xb xb 0 0 423 424 After the source operand is read, the position 'pos' is incremented 425 this explains the negative offset for destination. 426 427 movb/movw above are the only instructions with this matching 428 format. */ 429 offset = ((format & M6812_OP_IDX_P2) 430 && (format & (M6811_OP_IMM8 | M6811_OP_IMM16 | 431 M6811_OP_IND16))); 369 432 370 433 /* Operand with one more byte: - immediate, offset, … … 380 443 381 444 pos++; 382 offset = -1; 445 446 /* This movb/movw is special (see above). */ 447 offset = -offset; 448 449 pc_dst_offset = 2; 383 450 if (format & M6811_OP_IMM8) 384 451 { 385 452 (*info->fprintf_func) (info->stream, "#%d", (int) buffer[0]); 386 453 format &= ~M6811_OP_IMM8; 454 /* Set PC destination offset. */ 455 pc_dst_offset = 1; 387 456 } 388 457 else if (format & M6811_OP_IX) … … 405 474 } 406 475 476 #define M6812_DST_MOVE (M6812_OP_IND16_P2 | M6812_OP_IDX_P2) 407 477 #define M6812_INDEXED_FLAGS (M6812_OP_IDX|M6812_OP_IDX_1|M6812_OP_IDX_2) 408 478 /* Analyze the 68HC12 indexed byte. */ 409 479 if (format & M6812_INDEXED_FLAGS) 410 480 { 411 status = print_indexed_operand (memaddr + pos, info, 0); 481 int indirect; 482 bfd_vma endaddr; 483 484 endaddr = memaddr + pos + 1; 485 if (format & M6811_OP_IND16) 486 endaddr += 2; 487 pc_src_offset = -1; 488 pc_dst_offset = 1; 489 status = print_indexed_operand (memaddr + pos, info, &indirect, 490 (format & M6812_DST_MOVE), 491 pc_src_offset, endaddr); 412 492 if (status < 0) 413 493 { … … 415 495 } 416 496 pos += status; 497 498 /* The indirect addressing mode of the call instruction does 499 not need the page code. */ 500 if ((format & M6812_OP_PAGE) && indirect) 501 format &= ~M6812_OP_PAGE; 417 502 } 418 503 … … 449 534 } 450 535 536 if (format & (M6811_OP_IMM16 | M6811_OP_IND16)) 537 { 538 int val; 539 bfd_vma addr; 540 unsigned page = 0; 541 542 status = read_memory (memaddr + pos + offset, &buffer[0], 2, info); 543 if (status != 0) 544 { 545 return status; 546 } 547 if (format & M6812_OP_IDX_P2) 548 offset = -2; 549 else 550 offset = 0; 551 pos += 2; 552 553 val = ((buffer[0] << 8) | (buffer[1] & 0x0FF)); 554 val &= 0x0FFFF; 555 addr = val; 556 pc_dst_offset = 2; 557 if (format & M6812_OP_PAGE) 558 { 559 status = read_memory (memaddr + pos + offset, buffer, 1, info); 560 if (status != 0) 561 return status; 562 563 page = (unsigned) buffer[0]; 564 if (addr >= M68HC12_BANK_BASE && addr < 0x0c000) 565 addr = ((val - M68HC12_BANK_BASE) 566 | (page << M68HC12_BANK_SHIFT)) 567 + M68HC12_BANK_VIRT; 568 } 569 else if ((arch & cpu6812) 570 && addr >= M68HC12_BANK_BASE && addr < 0x0c000) 571 { 572 int cur_page; 573 bfd_vma vaddr; 574 575 if (memaddr >= M68HC12_BANK_VIRT) 576 cur_page = ((memaddr - M68HC12_BANK_VIRT) 577 >> M68HC12_BANK_SHIFT); 578 else 579 cur_page = 0; 580 581 vaddr = ((addr - M68HC12_BANK_BASE) 582 + (cur_page << M68HC12_BANK_SHIFT)) 583 + M68HC12_BANK_VIRT; 584 if (!info->symbol_at_address_func (addr, info) 585 && info->symbol_at_address_func (vaddr, info)) 586 addr = vaddr; 587 } 588 if (format & M6811_OP_IMM16) 589 { 590 format &= ~M6811_OP_IMM16; 591 (*info->fprintf_func) (info->stream, "#"); 592 } 593 else 594 format &= ~M6811_OP_IND16; 595 596 (*info->print_address_func) (addr, info); 597 if (format & M6812_OP_PAGE) 598 { 599 (* info->fprintf_func) (info->stream, " {"); 600 (* info->print_address_func) (val, info); 601 (* info->fprintf_func) (info->stream, ", %d}", page); 602 format &= ~M6812_OP_PAGE; 603 pos += 1; 604 } 605 } 606 607 if (format & M6812_OP_IDX_P2) 608 { 609 (*info->fprintf_func) (info->stream, ", "); 610 status = print_indexed_operand (memaddr + pos + offset, info, 611 0, 1, pc_dst_offset, 612 memaddr + pos + offset + 1); 613 if (status < 0) 614 return status; 615 pos += status; 616 } 617 618 if (format & M6812_OP_IND16_P2) 619 { 620 int val; 621 622 (*info->fprintf_func) (info->stream, ", "); 623 624 status = read_memory (memaddr + pos + offset, &buffer[0], 2, info); 625 if (status != 0) 626 { 627 return status; 628 } 629 pos += 2; 630 631 val = ((buffer[0] << 8) | (buffer[1] & 0x0FF)); 632 val &= 0x0FFFF; 633 (*info->print_address_func) (val, info); 634 } 635 451 636 /* M6811_OP_BITMASK and M6811_OP_JUMP_REL must be treated separately 452 637 and in that order. The brset/brclr insn have a bitmask and then … … 498 683 format &= ~M6812_OP_JUMP_REL16; 499 684 } 500 if (format & (M6811_OP_IMM16 | M6811_OP_IND16)) 685 686 if (format & M6812_OP_PAGE) 501 687 { 502 688 int val; 503 689 504 status = read_memory (memaddr + pos + offset, &buffer[0], 2, info); 505 if (status != 0) 506 { 507 return status; 508 } 509 if (format & M6812_OP_IDX_P2) 510 offset = -2; 511 else 512 offset = 0; 513 pos += 2; 514 515 val = ((buffer[0] << 8) | (buffer[1] & 0x0FF)); 516 val &= 0x0FFFF; 517 if (format & M6811_OP_IMM16) 518 { 519 format &= ~M6811_OP_IMM16; 520 (*info->fprintf_func) (info->stream, "#"); 521 } 522 else 523 format &= ~M6811_OP_IND16; 524 525 (*info->print_address_func) (val, info); 526 } 527 528 if (format & M6812_OP_IDX_P2) 529 { 530 (*info->fprintf_func) (info->stream, ", "); 531 status = print_indexed_operand (memaddr + pos + offset, info, 1); 532 if (status < 0) 533 return status; 534 pos += status; 535 } 536 537 if (format & M6812_OP_IND16_P2) 538 { 539 int val; 540 541 (*info->fprintf_func) (info->stream, ", "); 542 543 status = read_memory (memaddr + pos + offset, &buffer[0], 2, info); 544 if (status != 0) 545 { 546 return status; 547 } 548 pos += 2; 549 550 val = ((buffer[0] << 8) | (buffer[1] & 0x0FF)); 551 val &= 0x0FFFF; 552 (*info->print_address_func) (val, info); 553 } 554 690 status = read_memory (memaddr + pos + offset, &buffer[0], 1, info); 691 if (status != 0) 692 { 693 return status; 694 } 695 pos += 1; 696 697 val = buffer[0] & 0x0ff; 698 (*info->fprintf_func) (info->stream, ", %d", val); 699 } 700 555 701 #ifdef DEBUG 556 702 /* Consistency check. 'format' must be 0, so that we have handled -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.