Ignore:
Timestamp:
Aug 16, 2003, 6:59:22 PM (22 years ago)
Author:
bird
Message:

binutils v2.14 - offical sources.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/GNU/src/binutils/opcodes/m68hc11-dis.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.1.1.2
    r608 r609  
    11/* 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)
    44
    55This program is free software; you can redistribute it and/or modify
     
    2323#include "dis-asm.h"
    2424
     25#define PC_REGNUM 3
     26
    2527static const char *const reg_name[] = {
    2628  "X", "Y", "SP", "PC"
     
    3638
    3739#define OP_PAGE_MASK (M6811_OP_PAGE2|M6811_OP_PAGE3|M6811_OP_PAGE4)
     40
     41/* Prototypes for local functions.  */
     42static int read_memory
     43  PARAMS ((bfd_vma, bfd_byte *, int, struct disassemble_info *));
     44static int print_indexed_operand
     45  PARAMS ((bfd_vma, struct disassemble_info *, int*, int, int, bfd_vma));
     46static int print_insn
     47  PARAMS ((bfd_vma, struct disassemble_info *, int));
    3848
    3949static int
     
    6171   Returns the number of bytes read or -1 if failure.  */
    6272static int
    63 print_indexed_operand (memaddr, info, mov_insn)
     73print_indexed_operand (memaddr, info, indirect, mov_insn, pc_offset, endaddr)
    6474     bfd_vma memaddr;
    6575     struct disassemble_info *info;
     76     int *indirect;
    6677     int mov_insn;
     78     int pc_offset;
     79     bfd_vma endaddr;
    6780{
    6881  bfd_byte buffer[4];
     
    7285  int pos = 1;
    7386
     87  if (indirect)
     88    *indirect = 0;
     89
    7490  status = read_memory (memaddr, &buffer[0], 1, info);
    7591  if (status != 0)
     
    85101      if (sval & 0x10)
    86102        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;
    87106      (*info->fprintf_func) (info->stream, "%d,%s",
    88107                             (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        }
    89115    }
    90116
     
    133159      (*info->fprintf_func) (info->stream, "[%u,%s]",
    134160                             sval & 0x0ffff, reg_name[reg]);
    135     }
     161      if (indirect)
     162        *indirect = 1;
     163    }
     164
     165  /* n,r with 9 and 16 bit signed constant.  */
    136166  else if ((buffer[0] & 0x4) == 0)
    137167    {
     
    154184          sval &= 0x0FFFF;
    155185          pos += 2;
     186          endaddr += 2;
    156187        }
    157188      else
     
    161192            sval |= 0xff00;
    162193          pos++;
     194          endaddr++;
    163195        }
    164196      (*info->fprintf_func) (info->stream, "%d,%s",
    165197                             (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        }
    166204    }
    167205  else
     
    182220        default:
    183221          (*info->fprintf_func) (info->stream, "[D,%s]", reg_name[reg]);
     222          if (indirect)
     223            *indirect = 1;
    184224          break;
    185225        }
     
    284324    {
    285325      int offset;
     326      int pc_src_offset;
     327      int pc_dst_offset;
    286328
    287329      if ((opcode->arch & arch) == 0)
     
    359401        }
    360402
    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)));
    369432
    370433      /* Operand with one more byte: - immediate, offset,
     
    380443
    381444          pos++;
    382           offset = -1;
     445
     446          /* This movb/movw is special (see above).  */
     447          offset = -offset;
     448
     449          pc_dst_offset = 2;
    383450          if (format & M6811_OP_IMM8)
    384451            {
    385452              (*info->fprintf_func) (info->stream, "#%d", (int) buffer[0]);
    386453              format &= ~M6811_OP_IMM8;
     454              /* Set PC destination offset.  */
     455              pc_dst_offset = 1;
    387456            }
    388457          else if (format & M6811_OP_IX)
     
    405474        }
    406475
     476#define M6812_DST_MOVE  (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)
    407477#define M6812_INDEXED_FLAGS (M6812_OP_IDX|M6812_OP_IDX_1|M6812_OP_IDX_2)
    408478      /* Analyze the 68HC12 indexed byte.  */
    409479      if (format & M6812_INDEXED_FLAGS)
    410480        {
    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);
    412492          if (status < 0)
    413493            {
     
    415495            }
    416496          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;
    417502        }
    418503
     
    449534        }
    450535
     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
    451636      /* M6811_OP_BITMASK and M6811_OP_JUMP_REL must be treated separately
    452637         and in that order.  The brset/brclr insn have a bitmask and then
     
    498683          format &= ~M6812_OP_JUMP_REL16;
    499684        }
    500       if (format & (M6811_OP_IMM16 | M6811_OP_IND16))
     685
     686      if (format & M6812_OP_PAGE)
    501687        {
    502688          int val;
    503689
    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     
    555701#ifdef DEBUG
    556702      /* Consistency check.  'format' must be 0, so that we have handled
Note: See TracChangeset for help on using the changeset viewer.