diff options
author | Stephane Carrez <stcarrez@nerim.fr> | 2002-08-13 19:01:25 +0000 |
---|---|---|
committer | Stephane Carrez <stcarrez@nerim.fr> | 2002-08-13 19:01:25 +0000 |
commit | 94777b37cd80335eb3ab847a27c66aee4237f3d1 (patch) | |
tree | a06d055ed138a78d73db3e02c779aca3e4dd6c44 /opcodes/m68hc11-dis.c | |
parent | d38fddb7b0d9ccfc7f5953bf902e7c574089aa5a (diff) | |
download | gdb-94777b37cd80335eb3ab847a27c66aee4237f3d1.tar.gz |
* m68hc11-dis.c (print_insn): Take into account 68HC12 memory
banks and fix disassembling of call instruction.
(print_indexed_operand): New param to tell whether
it was an indirect addressing operand (for disassembling call).
Diffstat (limited to 'opcodes/m68hc11-dis.c')
-rw-r--r-- | opcodes/m68hc11-dis.c | 86 |
1 files changed, 79 insertions, 7 deletions
diff --git a/opcodes/m68hc11-dis.c b/opcodes/m68hc11-dis.c index bb0cc207d4d..c721d16e0c4 100644 --- a/opcodes/m68hc11-dis.c +++ b/opcodes/m68hc11-dis.c @@ -1,6 +1,6 @@ /* m68hc11-dis.c -- Motorola 68HC11 & 68HC12 disassembly - Copyright 1999, 2000, 2001 Free Software Foundation, Inc. - Written by Stephane Carrez (stcarrez@worldnet.fr) + Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Written by Stephane Carrez (stcarrez@nerim.fr) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -40,7 +40,7 @@ static const char *const reg_dst_table[] = { static int read_memory PARAMS ((bfd_vma, bfd_byte *, int, struct disassemble_info *)); static int print_indexed_operand - PARAMS ((bfd_vma, struct disassemble_info *, int)); + PARAMS ((bfd_vma, struct disassemble_info *, int*, int)); static int print_insn PARAMS ((bfd_vma, struct disassemble_info *, int)); @@ -68,9 +68,10 @@ read_memory (memaddr, buffer, size, info) /* Read the 68HC12 indexed operand byte and print the corresponding mode. Returns the number of bytes read or -1 if failure. */ static int -print_indexed_operand (memaddr, info, mov_insn) +print_indexed_operand (memaddr, info, indirect, mov_insn) bfd_vma memaddr; struct disassemble_info *info; + int *indirect; int mov_insn; { bfd_byte buffer[4]; @@ -79,6 +80,9 @@ print_indexed_operand (memaddr, info, mov_insn) short sval; int pos = 1; + if (indirect) + *indirect = 0; + status = read_memory (memaddr, &buffer[0], 1, info); if (status != 0) { @@ -140,6 +144,8 @@ print_indexed_operand (memaddr, info, mov_insn) sval = ((buffer[0] << 8) | (buffer[1] & 0x0FF)); (*info->fprintf_func) (info->stream, "[%u,%s]", sval & 0x0ffff, reg_name[reg]); + if (indirect) + *indirect = 1; } else if ((buffer[0] & 0x4) == 0) { @@ -189,6 +195,8 @@ print_indexed_operand (memaddr, info, mov_insn) case 3: default: (*info->fprintf_func) (info->stream, "[D,%s]", reg_name[reg]); + if (indirect) + *indirect = 1; break; } } @@ -440,12 +448,19 @@ print_insn (memaddr, info, arch) /* Analyze the 68HC12 indexed byte. */ if (format & M6812_INDEXED_FLAGS) { - status = print_indexed_operand (memaddr + pos, info, 0); + int indirect; + + status = print_indexed_operand (memaddr + pos, info, &indirect, 0); if (status < 0) { return status; } pos += status; + + /* The indirect addressing mode of the call instruction does + not need the page code. */ + if ((format & M6812_OP_PAGE) && indirect) + format &= ~M6812_OP_PAGE; } /* 68HC12 dbcc/ibcc/tbcc operands. */ @@ -532,6 +547,8 @@ print_insn (memaddr, info, arch) if (format & (M6811_OP_IMM16 | M6811_OP_IND16)) { int val; + bfd_vma addr; + unsigned page = 0; status = read_memory (memaddr + pos + offset, &buffer[0], 2, info); if (status != 0) @@ -546,6 +563,38 @@ print_insn (memaddr, info, arch) val = ((buffer[0] << 8) | (buffer[1] & 0x0FF)); val &= 0x0FFFF; + addr = val; + if (format & M6812_OP_PAGE) + { + status = read_memory (memaddr + pos + offset, buffer, 1, info); + if (status != 0) + return status; + + page = (unsigned) buffer[0]; + if (addr >= M68HC12_BANK_BASE && addr < 0x0c000) + addr = ((val - M68HC12_BANK_BASE) + | (page << M68HC12_BANK_SHIFT)) + + M68HC12_BANK_VIRT; + } + else if ((arch & cpu6812) + && addr >= M68HC12_BANK_BASE && addr < 0x0c000) + { + int cur_page; + bfd_vma vaddr; + + if (memaddr >= M68HC12_BANK_VIRT) + cur_page = ((memaddr - M68HC12_BANK_VIRT) + >> M68HC12_BANK_SHIFT); + else + cur_page = 0; + + vaddr = ((addr - M68HC12_BANK_BASE) + + (cur_page << M68HC12_BANK_SHIFT)) + + M68HC12_BANK_VIRT; + if (!info->symbol_at_address_func (addr, info) + && info->symbol_at_address_func (vaddr, info)) + addr = vaddr; + } if (format & M6811_OP_IMM16) { format &= ~M6811_OP_IMM16; @@ -554,13 +603,21 @@ print_insn (memaddr, info, arch) else format &= ~M6811_OP_IND16; - (*info->print_address_func) (val, info); + (*info->print_address_func) (addr, info); + if (format & M6812_OP_PAGE) + { + (* info->fprintf_func) (info->stream, " {"); + (* info->print_address_func) (val, info); + (* info->fprintf_func) (info->stream, ", %d}", page); + format &= ~M6812_OP_PAGE; + pos += 1; + } } if (format & M6812_OP_IDX_P2) { (*info->fprintf_func) (info->stream, ", "); - status = print_indexed_operand (memaddr + pos + offset, info, 1); + status = print_indexed_operand (memaddr + pos + offset, info, 0, 1); if (status < 0) return status; pos += status; @@ -584,6 +641,21 @@ print_insn (memaddr, info, arch) (*info->print_address_func) (val, info); } + if (format & M6812_OP_PAGE) + { + int val; + + status = read_memory (memaddr + pos + offset, &buffer[0], 1, info); + if (status != 0) + { + return status; + } + pos += 1; + + val = buffer[0] & 0x0ff; + (*info->fprintf_func) (info->stream, ", %d", val); + } + #ifdef DEBUG /* Consistency check. 'format' must be 0, so that we have handled all formats; and the computed size of the insn must match the |