OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [opcodes/] [h8300-dis.c] - Diff between revs 827 and 840

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 827 Rev 840
/* Disassemble h8300 instructions.
/* Disassemble h8300 instructions.
   Copyright 1993, 1994, 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
   Copyright 1993, 1994, 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
   2007  Free Software Foundation, Inc.
   2007  Free Software Foundation, Inc.
 
 
   This file is part of the GNU opcodes library.
   This file is part of the GNU opcodes library.
 
 
   This library is free software; you can redistribute it and/or modify
   This library is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   the Free Software Foundation; either version 3, or (at your option)
   any later version.
   any later version.
 
 
   It is distributed in the hope that it will be useful, but WITHOUT
   It is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
   License for more details.
   License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */
   MA 02110-1301, USA.  */
 
 
#define DEFINE_TABLE
#define DEFINE_TABLE
 
 
#include "sysdep.h"
#include "sysdep.h"
#define h8_opcodes h8ops
#define h8_opcodes h8ops
#include "opcode/h8300.h"
#include "opcode/h8300.h"
#include "dis-asm.h"
#include "dis-asm.h"
#include "opintl.h"
#include "opintl.h"
#include "libiberty.h"
#include "libiberty.h"
 
 
struct h8_instruction
struct h8_instruction
{
{
  int length;
  int length;
  const struct h8_opcode *opcode;
  const struct h8_opcode *opcode;
};
};
 
 
struct h8_instruction *h8_instructions;
struct h8_instruction *h8_instructions;
 
 
/* Run through the opcodes and sort them into order to make them easy
/* Run through the opcodes and sort them into order to make them easy
   to disassemble.  */
   to disassemble.  */
 
 
static void
static void
bfd_h8_disassemble_init (void)
bfd_h8_disassemble_init (void)
{
{
  unsigned int i;
  unsigned int i;
  unsigned int nopcodes;
  unsigned int nopcodes;
  const struct h8_opcode *p;
  const struct h8_opcode *p;
  struct h8_instruction *pi;
  struct h8_instruction *pi;
 
 
  nopcodes = sizeof (h8_opcodes) / sizeof (struct h8_opcode);
  nopcodes = sizeof (h8_opcodes) / sizeof (struct h8_opcode);
 
 
  h8_instructions = xmalloc (nopcodes * sizeof (struct h8_instruction));
  h8_instructions = xmalloc (nopcodes * sizeof (struct h8_instruction));
 
 
  for (p = h8_opcodes, pi = h8_instructions; p->name; p++, pi++)
  for (p = h8_opcodes, pi = h8_instructions; p->name; p++, pi++)
    {
    {
      int n1 = 0;
      int n1 = 0;
      int n2 = 0;
      int n2 = 0;
 
 
      if ((int) p->data.nib[0] < 16)
      if ((int) p->data.nib[0] < 16)
        n1 = (int) p->data.nib[0];
        n1 = (int) p->data.nib[0];
      else
      else
        n1 = 0;
        n1 = 0;
 
 
      if ((int) p->data.nib[1] < 16)
      if ((int) p->data.nib[1] < 16)
        n2 = (int) p->data.nib[1];
        n2 = (int) p->data.nib[1];
      else
      else
        n2 = 0;
        n2 = 0;
 
 
      /* Just make sure there are an even number of nibbles in it, and
      /* Just make sure there are an even number of nibbles in it, and
         that the count is the same as the length.  */
         that the count is the same as the length.  */
      for (i = 0; p->data.nib[i] != (op_type) E; i++)
      for (i = 0; p->data.nib[i] != (op_type) E; i++)
        ;
        ;
 
 
      if (i & 1)
      if (i & 1)
        {
        {
          fprintf (stderr, "Internal error, h8_disassemble_init.\n");
          fprintf (stderr, "Internal error, h8_disassemble_init.\n");
          abort ();
          abort ();
        }
        }
 
 
      pi->length = i / 2;
      pi->length = i / 2;
      pi->opcode = p;
      pi->opcode = p;
    }
    }
 
 
  /* Add entry for the NULL vector terminator.  */
  /* Add entry for the NULL vector terminator.  */
  pi->length = 0;
  pi->length = 0;
  pi->opcode = p;
  pi->opcode = p;
}
}
 
 
static void
static void
extract_immediate (FILE *stream,
extract_immediate (FILE *stream,
                   op_type looking_for,
                   op_type looking_for,
                   int thisnib,
                   int thisnib,
                   unsigned char *data,
                   unsigned char *data,
                   int *cst,
                   int *cst,
                   int *len,
                   int *len,
                   const struct h8_opcode *q)
                   const struct h8_opcode *q)
{
{
  switch (looking_for & SIZE)
  switch (looking_for & SIZE)
    {
    {
    case L_2:
    case L_2:
      *len = 2;
      *len = 2;
      *cst = thisnib & 3;
      *cst = thisnib & 3;
 
 
      /* DISP2 special treatment.  */
      /* DISP2 special treatment.  */
      if ((looking_for & MODE) == DISP)
      if ((looking_for & MODE) == DISP)
        {
        {
          if (OP_KIND (q->how) == O_MOVAB
          if (OP_KIND (q->how) == O_MOVAB
              || OP_KIND (q->how) == O_MOVAW
              || OP_KIND (q->how) == O_MOVAW
              || OP_KIND (q->how) == O_MOVAL)
              || OP_KIND (q->how) == O_MOVAL)
            {
            {
              /* Handling for mova insn.  */
              /* Handling for mova insn.  */
              switch (q->args.nib[0] & MODE)
              switch (q->args.nib[0] & MODE)
                {
                {
                case INDEXB:
                case INDEXB:
                default:
                default:
                  break;
                  break;
                case INDEXW:
                case INDEXW:
                  *cst *= 2;
                  *cst *= 2;
                  break;
                  break;
                case INDEXL:
                case INDEXL:
                  *cst *= 4;
                  *cst *= 4;
                  break;
                  break;
                }
                }
            }
            }
          else
          else
            {
            {
              /* Handling for non-mova insn.  */
              /* Handling for non-mova insn.  */
              switch (OP_SIZE (q->how))
              switch (OP_SIZE (q->how))
                {
                {
                default: break;
                default: break;
                case SW:
                case SW:
                  *cst *= 2;
                  *cst *= 2;
                  break;
                  break;
                case SL:
                case SL:
                  *cst *= 4;
                  *cst *= 4;
                  break;
                  break;
                }
                }
            }
            }
        }
        }
      break;
      break;
    case L_8:
    case L_8:
      *len = 8;
      *len = 8;
      *cst = data[0];
      *cst = data[0];
      break;
      break;
    case L_16:
    case L_16:
    case L_16U:
    case L_16U:
      *len = 16;
      *len = 16;
      *cst = (data[0] << 8) + data [1];
      *cst = (data[0] << 8) + data [1];
#if 0
#if 0
      if ((looking_for & SIZE) == L_16)
      if ((looking_for & SIZE) == L_16)
        *cst = (short) *cst;    /* Sign extend.  */
        *cst = (short) *cst;    /* Sign extend.  */
#endif
#endif
      break;
      break;
    case L_32:
    case L_32:
      *len = 32;
      *len = 32;
      *cst = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];
      *cst = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];
      break;
      break;
    default:
    default:
      *len = 0;
      *len = 0;
      *cst = 0;
      *cst = 0;
      fprintf (stream, "DISP bad size\n");
      fprintf (stream, "DISP bad size\n");
      break;
      break;
    }
    }
}
}
 
 
static const char *regnames[] =
static const char *regnames[] =
{
{
  "r0h", "r1h", "r2h", "r3h", "r4h", "r5h", "r6h", "r7h",
  "r0h", "r1h", "r2h", "r3h", "r4h", "r5h", "r6h", "r7h",
  "r0l", "r1l", "r2l", "r3l", "r4l", "r5l", "r6l", "r7l"
  "r0l", "r1l", "r2l", "r3l", "r4l", "r5l", "r6l", "r7l"
};
};
static const char *wregnames[] =
static const char *wregnames[] =
{
{
  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
  "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7"
  "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7"
};
};
static const char *lregnames[] =
static const char *lregnames[] =
{
{
  "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7",
  "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7",
  "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7"
  "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7"
};
};
static const char *cregnames[] =
static const char *cregnames[] =
{
{
  "ccr", "exr", "mach", "macl", "", "", "vbr", "sbr"
  "ccr", "exr", "mach", "macl", "", "", "vbr", "sbr"
};
};
 
 
static void
static void
print_one_arg (disassemble_info *info,
print_one_arg (disassemble_info *info,
               bfd_vma addr,
               bfd_vma addr,
               op_type x,
               op_type x,
               int cst,
               int cst,
               int cstlen,
               int cstlen,
               int rdisp_n,
               int rdisp_n,
               int rn,
               int rn,
               const char **pregnames,
               const char **pregnames,
               int len)
               int len)
{
{
  void * stream = info->stream;
  void * stream = info->stream;
  fprintf_ftype outfn = info->fprintf_func;
  fprintf_ftype outfn = info->fprintf_func;
 
 
  if ((x & SIZE) == L_3 || (x & SIZE) == L_3NZ)
  if ((x & SIZE) == L_3 || (x & SIZE) == L_3NZ)
    outfn (stream, "#0x%x", (unsigned) cst);
    outfn (stream, "#0x%x", (unsigned) cst);
  else if ((x & MODE) == IMM)
  else if ((x & MODE) == IMM)
    outfn (stream, "#0x%x", (unsigned) cst);
    outfn (stream, "#0x%x", (unsigned) cst);
  else if ((x & MODE) == DBIT || (x & MODE) == KBIT)
  else if ((x & MODE) == DBIT || (x & MODE) == KBIT)
    outfn (stream, "#%d", (unsigned) cst);
    outfn (stream, "#%d", (unsigned) cst);
  else if ((x & MODE) == CONST_2)
  else if ((x & MODE) == CONST_2)
    outfn (stream, "#2");
    outfn (stream, "#2");
  else if ((x & MODE) == CONST_4)
  else if ((x & MODE) == CONST_4)
    outfn (stream, "#4");
    outfn (stream, "#4");
  else if ((x & MODE) == CONST_8)
  else if ((x & MODE) == CONST_8)
    outfn (stream, "#8");
    outfn (stream, "#8");
  else if ((x & MODE) == CONST_16)
  else if ((x & MODE) == CONST_16)
    outfn (stream, "#16");
    outfn (stream, "#16");
  else if ((x & MODE) == REG)
  else if ((x & MODE) == REG)
    {
    {
      switch (x & SIZE)
      switch (x & SIZE)
        {
        {
        case L_8:
        case L_8:
          outfn (stream, "%s", regnames[rn]);
          outfn (stream, "%s", regnames[rn]);
          break;
          break;
        case L_16:
        case L_16:
        case L_16U:
        case L_16U:
          outfn (stream, "%s", wregnames[rn]);
          outfn (stream, "%s", wregnames[rn]);
          break;
          break;
        case L_P:
        case L_P:
        case L_32:
        case L_32:
          outfn (stream, "%s", lregnames[rn]);
          outfn (stream, "%s", lregnames[rn]);
          break;
          break;
        }
        }
    }
    }
  else if ((x & MODE) == LOWREG)
  else if ((x & MODE) == LOWREG)
    {
    {
      switch (x & SIZE)
      switch (x & SIZE)
        {
        {
        case L_8:
        case L_8:
          /* Always take low half of reg.  */
          /* Always take low half of reg.  */
          outfn (stream, "%s.b", regnames[rn < 8 ? rn + 8 : rn]);
          outfn (stream, "%s.b", regnames[rn < 8 ? rn + 8 : rn]);
          break;
          break;
        case L_16:
        case L_16:
        case L_16U:
        case L_16U:
          /* Always take low half of reg.  */
          /* Always take low half of reg.  */
          outfn (stream, "%s.w", wregnames[rn < 8 ? rn : rn - 8]);
          outfn (stream, "%s.w", wregnames[rn < 8 ? rn : rn - 8]);
          break;
          break;
        case L_P:
        case L_P:
        case L_32:
        case L_32:
          outfn (stream, "%s.l", lregnames[rn]);
          outfn (stream, "%s.l", lregnames[rn]);
          break;
          break;
        }
        }
    }
    }
  else if ((x & MODE) == POSTINC)
  else if ((x & MODE) == POSTINC)
    outfn (stream, "@%s+", pregnames[rn]);
    outfn (stream, "@%s+", pregnames[rn]);
 
 
  else if ((x & MODE) == POSTDEC)
  else if ((x & MODE) == POSTDEC)
    outfn (stream, "@%s-", pregnames[rn]);
    outfn (stream, "@%s-", pregnames[rn]);
 
 
  else if ((x & MODE) == PREINC)
  else if ((x & MODE) == PREINC)
    outfn (stream, "@+%s", pregnames[rn]);
    outfn (stream, "@+%s", pregnames[rn]);
 
 
  else if ((x & MODE) == PREDEC)
  else if ((x & MODE) == PREDEC)
    outfn (stream, "@-%s", pregnames[rn]);
    outfn (stream, "@-%s", pregnames[rn]);
 
 
  else if ((x & MODE) == IND)
  else if ((x & MODE) == IND)
    outfn (stream, "@%s", pregnames[rn]);
    outfn (stream, "@%s", pregnames[rn]);
 
 
  else if ((x & MODE) == ABS || (x & ABSJMP))
  else if ((x & MODE) == ABS || (x & ABSJMP))
    outfn (stream, "@0x%x:%d", (unsigned) cst, cstlen);
    outfn (stream, "@0x%x:%d", (unsigned) cst, cstlen);
 
 
  else if ((x & MODE) == MEMIND)
  else if ((x & MODE) == MEMIND)
    outfn (stream, "@@%d (0x%x)", cst, cst);
    outfn (stream, "@@%d (0x%x)", cst, cst);
 
 
  else if ((x & MODE) == VECIND)
  else if ((x & MODE) == VECIND)
    {
    {
      /* FIXME Multiplier should be 2 or 4, depending on processor mode,
      /* FIXME Multiplier should be 2 or 4, depending on processor mode,
         by which is meant "normal" vs. "middle", "advanced", "maximum".  */
         by which is meant "normal" vs. "middle", "advanced", "maximum".  */
 
 
      int offset = (cst + 0x80) * 4;
      int offset = (cst + 0x80) * 4;
      outfn (stream, "@@%d (0x%x)", offset, offset);
      outfn (stream, "@@%d (0x%x)", offset, offset);
    }
    }
  else if ((x & MODE) == PCREL)
  else if ((x & MODE) == PCREL)
    {
    {
      if ((x & SIZE) == L_16 ||
      if ((x & SIZE) == L_16 ||
          (x & SIZE) == L_16U)
          (x & SIZE) == L_16U)
        {
        {
          outfn (stream, ".%s%d (0x%lx)",
          outfn (stream, ".%s%d (0x%lx)",
                   (short) cst > 0 ? "+" : "",
                   (short) cst > 0 ? "+" : "",
                   (short) cst,
                   (short) cst,
                   (long)(addr + (short) cst + len));
                   (long)(addr + (short) cst + len));
        }
        }
      else
      else
        {
        {
          outfn (stream, ".%s%d (0x%lx)",
          outfn (stream, ".%s%d (0x%lx)",
                   (char) cst > 0 ? "+" : "",
                   (char) cst > 0 ? "+" : "",
                   (char) cst,
                   (char) cst,
                   (long)(addr + (char) cst + len));
                   (long)(addr + (char) cst + len));
        }
        }
    }
    }
  else if ((x & MODE) == DISP)
  else if ((x & MODE) == DISP)
    outfn (stream, "@(0x%x:%d,%s)", cst, cstlen, pregnames[rdisp_n]);
    outfn (stream, "@(0x%x:%d,%s)", cst, cstlen, pregnames[rdisp_n]);
 
 
  else if ((x & MODE) == INDEXB)
  else if ((x & MODE) == INDEXB)
    /* Always take low half of reg.  */
    /* Always take low half of reg.  */
    outfn (stream, "@(0x%x:%d,%s.b)", cst, cstlen,
    outfn (stream, "@(0x%x:%d,%s.b)", cst, cstlen,
           regnames[rdisp_n < 8 ? rdisp_n + 8 : rdisp_n]);
           regnames[rdisp_n < 8 ? rdisp_n + 8 : rdisp_n]);
 
 
  else if ((x & MODE) == INDEXW)
  else if ((x & MODE) == INDEXW)
    /* Always take low half of reg.  */
    /* Always take low half of reg.  */
    outfn (stream, "@(0x%x:%d,%s.w)", cst, cstlen,
    outfn (stream, "@(0x%x:%d,%s.w)", cst, cstlen,
           wregnames[rdisp_n < 8 ? rdisp_n : rdisp_n - 8]);
           wregnames[rdisp_n < 8 ? rdisp_n : rdisp_n - 8]);
 
 
  else if ((x & MODE) == INDEXL)
  else if ((x & MODE) == INDEXL)
    outfn (stream, "@(0x%x:%d,%s.l)", cst, cstlen, lregnames[rdisp_n]);
    outfn (stream, "@(0x%x:%d,%s.l)", cst, cstlen, lregnames[rdisp_n]);
 
 
  else if (x & CTRL)
  else if (x & CTRL)
    outfn (stream, cregnames[rn]);
    outfn (stream, cregnames[rn]);
 
 
  else if ((x & MODE) == CCR)
  else if ((x & MODE) == CCR)
    outfn (stream, "ccr");
    outfn (stream, "ccr");
 
 
  else if ((x & MODE) == EXR)
  else if ((x & MODE) == EXR)
    outfn (stream, "exr");
    outfn (stream, "exr");
 
 
  else if ((x & MODE) == MACREG)
  else if ((x & MODE) == MACREG)
    outfn (stream, "mac%c", cst ? 'l' : 'h');
    outfn (stream, "mac%c", cst ? 'l' : 'h');
 
 
  else
  else
    /* xgettext:c-format */
    /* xgettext:c-format */
    outfn (stream, _("Hmmmm 0x%x"), x);
    outfn (stream, _("Hmmmm 0x%x"), x);
}
}
 
 
static unsigned int
static unsigned int
bfd_h8_disassemble (bfd_vma addr, disassemble_info *info, int mach)
bfd_h8_disassemble (bfd_vma addr, disassemble_info *info, int mach)
{
{
  /* Find the first entry in the table for this opcode.  */
  /* Find the first entry in the table for this opcode.  */
  int regno[3] = { 0, 0, 0 };
  int regno[3] = { 0, 0, 0 };
  int dispregno[3] = { 0, 0, 0 };
  int dispregno[3] = { 0, 0, 0 };
  int cst[3] = { 0, 0, 0 };
  int cst[3] = { 0, 0, 0 };
  int cstlen[3] = { 0, 0, 0 };
  int cstlen[3] = { 0, 0, 0 };
  static bfd_boolean init = 0;
  static bfd_boolean init = 0;
  const struct h8_instruction *qi;
  const struct h8_instruction *qi;
  char const **pregnames = mach != 0 ? lregnames : wregnames;
  char const **pregnames = mach != 0 ? lregnames : wregnames;
  int status;
  int status;
  unsigned int l;
  unsigned int l;
  unsigned char data[MAX_CODE_NIBBLES];
  unsigned char data[MAX_CODE_NIBBLES];
  void *stream = info->stream;
  void *stream = info->stream;
  fprintf_ftype outfn = info->fprintf_func;
  fprintf_ftype outfn = info->fprintf_func;
 
 
  if (!init)
  if (!init)
    {
    {
      bfd_h8_disassemble_init ();
      bfd_h8_disassemble_init ();
      init = 1;
      init = 1;
    }
    }
 
 
  status = info->read_memory_func (addr, data, 2, info);
  status = info->read_memory_func (addr, data, 2, info);
  if (status != 0)
  if (status != 0)
    {
    {
      info->memory_error_func (status, addr, info);
      info->memory_error_func (status, addr, info);
      return -1;
      return -1;
    }
    }
 
 
  for (l = 2; status == 0 && l < sizeof (data) / 2; l += 2)
  for (l = 2; status == 0 && l < sizeof (data) / 2; l += 2)
    status = info->read_memory_func (addr + l, data + l, 2, info);
    status = info->read_memory_func (addr + l, data + l, 2, info);
 
 
  /* Find the exact opcode/arg combo.  */
  /* Find the exact opcode/arg combo.  */
  for (qi = h8_instructions; qi->opcode->name; qi++)
  for (qi = h8_instructions; qi->opcode->name; qi++)
    {
    {
      const struct h8_opcode *q = qi->opcode;
      const struct h8_opcode *q = qi->opcode;
      const op_type *nib = q->data.nib;
      const op_type *nib = q->data.nib;
      unsigned int len = 0;
      unsigned int len = 0;
 
 
      while (1)
      while (1)
        {
        {
          op_type looking_for = *nib;
          op_type looking_for = *nib;
          int thisnib = data[len / 2];
          int thisnib = data[len / 2];
          int opnr;
          int opnr;
 
 
          thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib / 16) & 0xf);
          thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib / 16) & 0xf);
          opnr = ((looking_for & OP3) == OP3 ? 2
          opnr = ((looking_for & OP3) == OP3 ? 2
                  : (looking_for & DST) == DST ? 1 : 0);
                  : (looking_for & DST) == DST ? 1 : 0);
 
 
          if (looking_for < 16 && looking_for >= 0)
          if (looking_for < 16 && looking_for >= 0)
            {
            {
              if (looking_for != thisnib)
              if (looking_for != thisnib)
                goto fail;
                goto fail;
            }
            }
          else
          else
            {
            {
              if ((int) looking_for & (int) B31)
              if ((int) looking_for & (int) B31)
                {
                {
                  if (!((thisnib & 0x8) != 0))
                  if (!((thisnib & 0x8) != 0))
                    goto fail;
                    goto fail;
 
 
                  looking_for = (op_type) ((int) looking_for & ~(int) B31);
                  looking_for = (op_type) ((int) looking_for & ~(int) B31);
                  thisnib &= 0x7;
                  thisnib &= 0x7;
                }
                }
              else if ((int) looking_for & (int) B30)
              else if ((int) looking_for & (int) B30)
                {
                {
                  if (!((thisnib & 0x8) == 0))
                  if (!((thisnib & 0x8) == 0))
                    goto fail;
                    goto fail;
 
 
                  looking_for = (op_type) ((int) looking_for & ~(int) B30);
                  looking_for = (op_type) ((int) looking_for & ~(int) B30);
                }
                }
 
 
              if ((int) looking_for & (int) B21)
              if ((int) looking_for & (int) B21)
                {
                {
                  if (!((thisnib & 0x4) != 0))
                  if (!((thisnib & 0x4) != 0))
                    goto fail;
                    goto fail;
 
 
                  looking_for = (op_type) ((int) looking_for & ~(int) B21);
                  looking_for = (op_type) ((int) looking_for & ~(int) B21);
                  thisnib &= 0xb;
                  thisnib &= 0xb;
                }
                }
              else if ((int) looking_for & (int) B20)
              else if ((int) looking_for & (int) B20)
                {
                {
                  if (!((thisnib & 0x4) == 0))
                  if (!((thisnib & 0x4) == 0))
                    goto fail;
                    goto fail;
 
 
                  looking_for = (op_type) ((int) looking_for & ~(int) B20);
                  looking_for = (op_type) ((int) looking_for & ~(int) B20);
                }
                }
              if ((int) looking_for & (int) B11)
              if ((int) looking_for & (int) B11)
                {
                {
                  if (!((thisnib & 0x2) != 0))
                  if (!((thisnib & 0x2) != 0))
                    goto fail;
                    goto fail;
 
 
                  looking_for = (op_type) ((int) looking_for & ~(int) B11);
                  looking_for = (op_type) ((int) looking_for & ~(int) B11);
                  thisnib &= 0xd;
                  thisnib &= 0xd;
                }
                }
              else if ((int) looking_for & (int) B10)
              else if ((int) looking_for & (int) B10)
                {
                {
                  if (!((thisnib & 0x2) == 0))
                  if (!((thisnib & 0x2) == 0))
                    goto fail;
                    goto fail;
 
 
                  looking_for = (op_type) ((int) looking_for & ~(int) B10);
                  looking_for = (op_type) ((int) looking_for & ~(int) B10);
                }
                }
 
 
              if ((int) looking_for & (int) B01)
              if ((int) looking_for & (int) B01)
                {
                {
                  if (!((thisnib & 0x1) != 0))
                  if (!((thisnib & 0x1) != 0))
                    goto fail;
                    goto fail;
 
 
                  looking_for = (op_type) ((int) looking_for & ~(int) B01);
                  looking_for = (op_type) ((int) looking_for & ~(int) B01);
                  thisnib &= 0xe;
                  thisnib &= 0xe;
                }
                }
              else if ((int) looking_for & (int) B00)
              else if ((int) looking_for & (int) B00)
                {
                {
                  if (!((thisnib & 0x1) == 0))
                  if (!((thisnib & 0x1) == 0))
                    goto fail;
                    goto fail;
 
 
                  looking_for = (op_type) ((int) looking_for & ~(int) B00);
                  looking_for = (op_type) ((int) looking_for & ~(int) B00);
                }
                }
 
 
              if (looking_for & IGNORE)
              if (looking_for & IGNORE)
                {
                {
                  /* Hitachi has declared that IGNORE must be zero.  */
                  /* Hitachi has declared that IGNORE must be zero.  */
                  if (thisnib != 0)
                  if (thisnib != 0)
                    goto fail;
                    goto fail;
                }
                }
              else if ((looking_for & MODE) == DATA)
              else if ((looking_for & MODE) == DATA)
                {
                {
                  ;                     /* Skip embedded data.  */
                  ;                     /* Skip embedded data.  */
                }
                }
              else if ((looking_for & MODE) == DBIT)
              else if ((looking_for & MODE) == DBIT)
                {
                {
                  /* Exclude adds/subs by looking at bit 0 and 2, and
                  /* Exclude adds/subs by looking at bit 0 and 2, and
                     make sure the operand size, either w or l,
                     make sure the operand size, either w or l,
                     matches by looking at bit 1.  */
                     matches by looking at bit 1.  */
                  if ((looking_for & 7) != (thisnib & 7))
                  if ((looking_for & 7) != (thisnib & 7))
                    goto fail;
                    goto fail;
 
 
                  cst[opnr] = (thisnib & 0x8) ? 2 : 1;
                  cst[opnr] = (thisnib & 0x8) ? 2 : 1;
                }
                }
              else if ((looking_for & MODE) == DISP
              else if ((looking_for & MODE) == DISP
                       || (looking_for & MODE) == ABS
                       || (looking_for & MODE) == ABS
                       || (looking_for & MODE) == PCREL
                       || (looking_for & MODE) == PCREL
                       || (looking_for & MODE) == INDEXB
                       || (looking_for & MODE) == INDEXB
                       || (looking_for & MODE) == INDEXW
                       || (looking_for & MODE) == INDEXW
                       || (looking_for & MODE) == INDEXL)
                       || (looking_for & MODE) == INDEXL)
                {
                {
                  extract_immediate (stream, looking_for, thisnib,
                  extract_immediate (stream, looking_for, thisnib,
                                     data + len / 2, cst + opnr,
                                     data + len / 2, cst + opnr,
                                     cstlen + opnr, q);
                                     cstlen + opnr, q);
                  /* Even address == bra, odd == bra/s.  */
                  /* Even address == bra, odd == bra/s.  */
                  if (q->how == O (O_BRAS, SB))
                  if (q->how == O (O_BRAS, SB))
                    cst[opnr] -= 1;
                    cst[opnr] -= 1;
                }
                }
              else if ((looking_for & MODE) == REG
              else if ((looking_for & MODE) == REG
                       || (looking_for & MODE) == LOWREG
                       || (looking_for & MODE) == LOWREG
                       || (looking_for & MODE) == IND
                       || (looking_for & MODE) == IND
                       || (looking_for & MODE) == PREINC
                       || (looking_for & MODE) == PREINC
                       || (looking_for & MODE) == POSTINC
                       || (looking_for & MODE) == POSTINC
                       || (looking_for & MODE) == PREDEC
                       || (looking_for & MODE) == PREDEC
                       || (looking_for & MODE) == POSTDEC)
                       || (looking_for & MODE) == POSTDEC)
                {
                {
                  regno[opnr] = thisnib;
                  regno[opnr] = thisnib;
                }
                }
              else if (looking_for & CTRL)      /* Control Register.  */
              else if (looking_for & CTRL)      /* Control Register.  */
                {
                {
                  thisnib &= 7;
                  thisnib &= 7;
                  if (((looking_for & MODE) == CCR  && (thisnib != C_CCR))
                  if (((looking_for & MODE) == CCR  && (thisnib != C_CCR))
                      || ((looking_for & MODE) == EXR  && (thisnib != C_EXR))
                      || ((looking_for & MODE) == EXR  && (thisnib != C_EXR))
                      || ((looking_for & MODE) == MACH && (thisnib != C_MACH))
                      || ((looking_for & MODE) == MACH && (thisnib != C_MACH))
                      || ((looking_for & MODE) == MACL && (thisnib != C_MACL))
                      || ((looking_for & MODE) == MACL && (thisnib != C_MACL))
                      || ((looking_for & MODE) == VBR  && (thisnib != C_VBR))
                      || ((looking_for & MODE) == VBR  && (thisnib != C_VBR))
                      || ((looking_for & MODE) == SBR  && (thisnib != C_SBR)))
                      || ((looking_for & MODE) == SBR  && (thisnib != C_SBR)))
                    goto fail;
                    goto fail;
                  if (((looking_for & MODE) == CCR_EXR
                  if (((looking_for & MODE) == CCR_EXR
                       && (thisnib != C_CCR && thisnib != C_EXR))
                       && (thisnib != C_CCR && thisnib != C_EXR))
                      || ((looking_for & MODE) == VBR_SBR
                      || ((looking_for & MODE) == VBR_SBR
                          && (thisnib != C_VBR && thisnib != C_SBR))
                          && (thisnib != C_VBR && thisnib != C_SBR))
                      || ((looking_for & MODE) == MACREG
                      || ((looking_for & MODE) == MACREG
                          && (thisnib != C_MACH && thisnib != C_MACL)))
                          && (thisnib != C_MACH && thisnib != C_MACL)))
                    goto fail;
                    goto fail;
                  if (((looking_for & MODE) == CC_EX_VB_SB
                  if (((looking_for & MODE) == CC_EX_VB_SB
                       && (thisnib != C_CCR && thisnib != C_EXR
                       && (thisnib != C_CCR && thisnib != C_EXR
                           && thisnib != C_VBR && thisnib != C_SBR)))
                           && thisnib != C_VBR && thisnib != C_SBR)))
                    goto fail;
                    goto fail;
 
 
                  regno[opnr] = thisnib;
                  regno[opnr] = thisnib;
                }
                }
              else if ((looking_for & SIZE) == L_5)
              else if ((looking_for & SIZE) == L_5)
                {
                {
                  cst[opnr] = data[len / 2] & 31;
                  cst[opnr] = data[len / 2] & 31;
                  cstlen[opnr] = 5;
                  cstlen[opnr] = 5;
                }
                }
              else if ((looking_for & SIZE) == L_4)
              else if ((looking_for & SIZE) == L_4)
                {
                {
                  cst[opnr] = thisnib;
                  cst[opnr] = thisnib;
                  cstlen[opnr] = 4;
                  cstlen[opnr] = 4;
                }
                }
              else if ((looking_for & SIZE) == L_16
              else if ((looking_for & SIZE) == L_16
                       || (looking_for & SIZE) == L_16U)
                       || (looking_for & SIZE) == L_16U)
                {
                {
                  cst[opnr] = (data[len / 2]) * 256 + data[(len + 2) / 2];
                  cst[opnr] = (data[len / 2]) * 256 + data[(len + 2) / 2];
                  cstlen[opnr] = 16;
                  cstlen[opnr] = 16;
                }
                }
              else if ((looking_for & MODE) == MEMIND)
              else if ((looking_for & MODE) == MEMIND)
                {
                {
                  cst[opnr] = data[1];
                  cst[opnr] = data[1];
                }
                }
              else if ((looking_for & MODE) == VECIND)
              else if ((looking_for & MODE) == VECIND)
                {
                {
                  cst[opnr] = data[1] & 0x7f;
                  cst[opnr] = data[1] & 0x7f;
                }
                }
              else if ((looking_for & SIZE) == L_32)
              else if ((looking_for & SIZE) == L_32)
                {
                {
                  int i = len / 2;
                  int i = len / 2;
 
 
                  cst[opnr] = ((data[i] << 24)
                  cst[opnr] = ((data[i] << 24)
                               | (data[i + 1] << 16)
                               | (data[i + 1] << 16)
                               | (data[i + 2] << 8)
                               | (data[i + 2] << 8)
                               | (data[i + 3]));
                               | (data[i + 3]));
 
 
                  cstlen[opnr] = 32;
                  cstlen[opnr] = 32;
                }
                }
              else if ((looking_for & SIZE) == L_24)
              else if ((looking_for & SIZE) == L_24)
                {
                {
                  int i = len / 2;
                  int i = len / 2;
 
 
                  cst[opnr] =
                  cst[opnr] =
                    (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]);
                    (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]);
                  cstlen[opnr] = 24;
                  cstlen[opnr] = 24;
                }
                }
              else if (looking_for & IGNORE)
              else if (looking_for & IGNORE)
                {
                {
                  ;
                  ;
                }
                }
              else if (looking_for & DISPREG)
              else if (looking_for & DISPREG)
                {
                {
                  dispregno[opnr] = thisnib & 7;
                  dispregno[opnr] = thisnib & 7;
                }
                }
              else if ((looking_for & MODE) == KBIT)
              else if ((looking_for & MODE) == KBIT)
                {
                {
                  switch (thisnib)
                  switch (thisnib)
                    {
                    {
                    case 9:
                    case 9:
                      cst[opnr] = 4;
                      cst[opnr] = 4;
                      break;
                      break;
                    case 8:
                    case 8:
                      cst[opnr] = 2;
                      cst[opnr] = 2;
                      break;
                      break;
                    case 0:
                    case 0:
                      cst[opnr] = 1;
                      cst[opnr] = 1;
                      break;
                      break;
                    default:
                    default:
                      goto fail;
                      goto fail;
                    }
                    }
                }
                }
              else if ((looking_for & SIZE) == L_8)
              else if ((looking_for & SIZE) == L_8)
                {
                {
                  cstlen[opnr] = 8;
                  cstlen[opnr] = 8;
                  cst[opnr] = data[len / 2];
                  cst[opnr] = data[len / 2];
                }
                }
              else if ((looking_for & SIZE) == L_3
              else if ((looking_for & SIZE) == L_3
                       || (looking_for & SIZE) == L_3NZ)
                       || (looking_for & SIZE) == L_3NZ)
                {
                {
                  cst[opnr] = thisnib & 0x7;
                  cst[opnr] = thisnib & 0x7;
                  if (cst[opnr] == 0 && (looking_for & SIZE) == L_3NZ)
                  if (cst[opnr] == 0 && (looking_for & SIZE) == L_3NZ)
                    goto fail;
                    goto fail;
                }
                }
              else if ((looking_for & SIZE) == L_2)
              else if ((looking_for & SIZE) == L_2)
                {
                {
                  cstlen[opnr] = 2;
                  cstlen[opnr] = 2;
                  cst[opnr] = thisnib & 0x3;
                  cst[opnr] = thisnib & 0x3;
                }
                }
              else if ((looking_for & MODE) == MACREG)
              else if ((looking_for & MODE) == MACREG)
                {
                {
                  cst[opnr] = (thisnib == 3);
                  cst[opnr] = (thisnib == 3);
                }
                }
              else if (looking_for == (op_type) E)
              else if (looking_for == (op_type) E)
                {
                {
                  outfn (stream, "%s\t", q->name);
                  outfn (stream, "%s\t", q->name);
 
 
                  /* Gross.  Disgusting.  */
                  /* Gross.  Disgusting.  */
                  if (strcmp (q->name, "ldm.l") == 0)
                  if (strcmp (q->name, "ldm.l") == 0)
                    {
                    {
                      int count, high;
                      int count, high;
 
 
                      count = (data[1] / 16) & 0x3;
                      count = (data[1] / 16) & 0x3;
                      high = regno[1];
                      high = regno[1];
 
 
                      outfn (stream, "@sp+,er%d-er%d", high - count, high);
                      outfn (stream, "@sp+,er%d-er%d", high - count, high);
                      return qi->length;
                      return qi->length;
                    }
                    }
 
 
                  if (strcmp (q->name, "stm.l") == 0)
                  if (strcmp (q->name, "stm.l") == 0)
                    {
                    {
                      int count, low;
                      int count, low;
 
 
                      count = (data[1] / 16) & 0x3;
                      count = (data[1] / 16) & 0x3;
                      low = regno[0];
                      low = regno[0];
 
 
                      outfn (stream, "er%d-er%d,@-sp", low, low + count);
                      outfn (stream, "er%d-er%d,@-sp", low, low + count);
                      return qi->length;
                      return qi->length;
                    }
                    }
                  if (strcmp (q->name, "rte/l") == 0
                  if (strcmp (q->name, "rte/l") == 0
                      || strcmp (q->name, "rts/l") == 0)
                      || strcmp (q->name, "rts/l") == 0)
                    {
                    {
                      if (regno[0] == 0)
                      if (regno[0] == 0)
                        outfn (stream, "er%d", regno[1]);
                        outfn (stream, "er%d", regno[1]);
                      else
                      else
                        outfn (stream, "er%d-er%d", regno[1] - regno[0],
                        outfn (stream, "er%d-er%d", regno[1] - regno[0],
                               regno[1]);
                               regno[1]);
                      return qi->length;
                      return qi->length;
                    }
                    }
                  if (CONST_STRNEQ (q->name, "mova"))
                  if (CONST_STRNEQ (q->name, "mova"))
                    {
                    {
                      const op_type *args = q->args.nib;
                      const op_type *args = q->args.nib;
 
 
                      if (args[1] == (op_type) E)
                      if (args[1] == (op_type) E)
                        {
                        {
                          /* Short form.  */
                          /* Short form.  */
                          print_one_arg (info, addr, args[0], cst[0],
                          print_one_arg (info, addr, args[0], cst[0],
                                         cstlen[0], dispregno[0], regno[0],
                                         cstlen[0], dispregno[0], regno[0],
                                         pregnames, qi->length);
                                         pregnames, qi->length);
                          outfn (stream, ",er%d", dispregno[0]);
                          outfn (stream, ",er%d", dispregno[0]);
                        }
                        }
                      else
                      else
                        {
                        {
                          outfn (stream, "@(0x%x:%d,", cst[0], cstlen[0]);
                          outfn (stream, "@(0x%x:%d,", cst[0], cstlen[0]);
                          print_one_arg (info, addr, args[1], cst[1],
                          print_one_arg (info, addr, args[1], cst[1],
                                         cstlen[1], dispregno[1], regno[1],
                                         cstlen[1], dispregno[1], regno[1],
                                         pregnames, qi->length);
                                         pregnames, qi->length);
                          outfn (stream, ".%c),",
                          outfn (stream, ".%c),",
                                 (args[0] & MODE) == INDEXB ? 'b' : 'w');
                                 (args[0] & MODE) == INDEXB ? 'b' : 'w');
                          print_one_arg (info, addr, args[2], cst[2],
                          print_one_arg (info, addr, args[2], cst[2],
                                         cstlen[2], dispregno[2], regno[2],
                                         cstlen[2], dispregno[2], regno[2],
                                         pregnames, qi->length);
                                         pregnames, qi->length);
                        }
                        }
                      return qi->length;
                      return qi->length;
                    }
                    }
                  /* Fill in the args.  */
                  /* Fill in the args.  */
                  {
                  {
                    const op_type *args = q->args.nib;
                    const op_type *args = q->args.nib;
                    int hadone = 0;
                    int hadone = 0;
                    int nargs;
                    int nargs;
 
 
                    /* Special case handling for the adds and subs instructions
                    /* Special case handling for the adds and subs instructions
                       since in H8 mode thay can only take the r0-r7 registers
                       since in H8 mode thay can only take the r0-r7 registers
                       but in other (higher) modes they can take the er0-er7
                       but in other (higher) modes they can take the er0-er7
                       registers as well.  */
                       registers as well.  */
                    if (strcmp (qi->opcode->name, "adds") == 0
                    if (strcmp (qi->opcode->name, "adds") == 0
                        || strcmp (qi->opcode->name, "subs") == 0)
                        || strcmp (qi->opcode->name, "subs") == 0)
                      {
                      {
                        outfn (stream, "#%d,%s", cst[0], pregnames[regno[1] & 0x7]);
                        outfn (stream, "#%d,%s", cst[0], pregnames[regno[1] & 0x7]);
                        return qi->length;
                        return qi->length;
                      }
                      }
 
 
                    for (nargs = 0;
                    for (nargs = 0;
                         nargs < 3 && args[nargs] != (op_type) E;
                         nargs < 3 && args[nargs] != (op_type) E;
                         nargs++)
                         nargs++)
                      {
                      {
                        int x = args[nargs];
                        int x = args[nargs];
 
 
                        if (hadone)
                        if (hadone)
                          outfn (stream, ",");
                          outfn (stream, ",");
 
 
                        print_one_arg (info, addr, x,
                        print_one_arg (info, addr, x,
                                       cst[nargs], cstlen[nargs],
                                       cst[nargs], cstlen[nargs],
                                       dispregno[nargs], regno[nargs],
                                       dispregno[nargs], regno[nargs],
                                       pregnames, qi->length);
                                       pregnames, qi->length);
 
 
                        hadone = 1;
                        hadone = 1;
                      }
                      }
                  }
                  }
 
 
                  return qi->length;
                  return qi->length;
                }
                }
              else
              else
                /* xgettext:c-format */
                /* xgettext:c-format */
                outfn (stream, _("Don't understand 0x%x \n"), looking_for);
                outfn (stream, _("Don't understand 0x%x \n"), looking_for);
            }
            }
 
 
          len++;
          len++;
          nib++;
          nib++;
        }
        }
 
 
    fail:
    fail:
      ;
      ;
    }
    }
 
 
  /* Fell off the end.  */
  /* Fell off the end.  */
  outfn (stream, ".word\tH'%x,H'%x", data[0], data[1]);
  outfn (stream, ".word\tH'%x,H'%x", data[0], data[1]);
  return 2;
  return 2;
}
}
 
 
int
int
print_insn_h8300 (bfd_vma addr, disassemble_info *info)
print_insn_h8300 (bfd_vma addr, disassemble_info *info)
{
{
  return bfd_h8_disassemble (addr, info, 0);
  return bfd_h8_disassemble (addr, info, 0);
}
}
 
 
int
int
print_insn_h8300h (bfd_vma addr, disassemble_info *info)
print_insn_h8300h (bfd_vma addr, disassemble_info *info)
{
{
  return bfd_h8_disassemble (addr, info, 1);
  return bfd_h8_disassemble (addr, info, 1);
}
}
 
 
int
int
print_insn_h8300s (bfd_vma addr, disassemble_info *info)
print_insn_h8300s (bfd_vma addr, disassemble_info *info)
{
{
  return bfd_h8_disassemble (addr, info, 2);
  return bfd_h8_disassemble (addr, info, 2);
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.