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

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [gdb-5.0/] [opcodes/] [h8300-dis.c] - Diff between revs 579 and 1765

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

Rev 579 Rev 1765
/* Disassemble h8300 instructions.
/* Disassemble h8300 instructions.
   Copyright (C) 1993, 1998 Free Software Foundation, Inc.
   Copyright (C) 1993, 1998 Free Software Foundation, Inc.
 
 
This program is free software; you can redistribute it and/or modify
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
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
(at your option) any later version.
 
 
This program is distributed in the hope that it will be useful,
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
GNU General Public 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 
#define DEFINE_TABLE
#define DEFINE_TABLE
 
 
#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"
 
 
 
 
/* 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 ()
bfd_h8_disassemble_init ()
{
{
  unsigned int i;
  unsigned int i;
 
 
 
 
  struct h8_opcode *p;
  struct h8_opcode *p;
 
 
  for (p = h8_opcodes; p->name; p++)
  for (p = h8_opcodes; p->name; p++)
    {
    {
      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 s the length */
         that the count is the same s the length */
      for (i = 0; p->data.nib[i] != E; i++)
      for (i = 0; p->data.nib[i] != E; i++)
        /*EMPTY*/ ;
        /*EMPTY*/ ;
      if (i & 1)
      if (i & 1)
        abort ();
        abort ();
      p->length = i / 2;
      p->length = i / 2;
    }
    }
 
 
}
}
 
 
 
 
unsigned int
unsigned int
bfd_h8_disassemble (addr, info, mode)
bfd_h8_disassemble (addr, info, mode)
     bfd_vma addr;
     bfd_vma addr;
     disassemble_info *info;
     disassemble_info *info;
     int mode;
     int mode;
{
{
  /* Find the first entry in the table for this opcode */
  /* Find the first entry in the table for this opcode */
  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"
      }
      }
  ;
  ;
 
 
  int rs = 0;
  int rs = 0;
  int rd = 0;
  int rd = 0;
  int rdisp = 0;
  int rdisp = 0;
  int abs = 0;
  int abs = 0;
  int bit = 0;
  int bit = 0;
  int plen = 0;
  int plen = 0;
  static boolean init = 0;
  static boolean init = 0;
  struct h8_opcode *q = h8_opcodes;
  struct h8_opcode *q = h8_opcodes;
  char CONST **pregnames = mode != 0 ? lregnames : wregnames;
  char CONST **pregnames = mode != 0 ? lregnames : wregnames;
  int status;
  int status;
  int l;
  int l;
 
 
  unsigned char data[20];
  unsigned char data[20];
  void *stream = info->stream;
  void *stream = info->stream;
  fprintf_ftype fprintf = info->fprintf_func;
  fprintf_ftype fprintf = 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 < 10; l+=2)
  for (l = 2; status == 0 && l < 10; 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 */
  while (q->name)
  while (q->name)
    {
    {
      op_type *nib;
      op_type *nib;
      unsigned int len = 0;
      unsigned int len = 0;
 
 
      nib = q->data.nib;
      nib = q->data.nib;
 
 
      while (1)
      while (1)
        {
        {
          op_type looking_for = *nib;
          op_type looking_for = *nib;
          int thisnib = data[len >> 1];
          int thisnib = data[len >> 1];
 
 
          thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib >> 4) & 0xf);
          thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib >> 4) & 0xf);
 
 
          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 (! (((int) thisnib & 0x8) != 0))
                  if (! (((int) 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);
                }
                }
              if ((int) looking_for & (int) B30)
              if ((int) looking_for & (int) B30)
                {
                {
                  if (!(((int) thisnib & 0x8) == 0))
                  if (!(((int) 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 (looking_for & DBIT)
              if (looking_for & DBIT)
                {
                {
                  if ((looking_for & 5) != (thisnib &5)) goto fail;
                  if ((looking_for & 5) != (thisnib &5)) goto fail;
                  abs = (thisnib & 0x8) ? 2 : 1;
                  abs = (thisnib & 0x8) ? 2 : 1;
                }
                }
 
 
              else  if (looking_for & (REG | IND|INC|DEC))
              else  if (looking_for & (REG | IND|INC|DEC))
                {
                {
                  if (looking_for & SRC)
                  if (looking_for & SRC)
                    {
                    {
                      rs = thisnib;
                      rs = thisnib;
                    }
                    }
                  else
                  else
                    {
                    {
                      rd = thisnib;
                      rd = thisnib;
                    }
                    }
                }
                }
              else if (looking_for & L_16)
              else if (looking_for & L_16)
                {
                {
                  abs = (data[len >> 1]) * 256 + data[(len + 2) >> 1];
                  abs = (data[len >> 1]) * 256 + data[(len + 2) >> 1];
                  plen = 16;
                  plen = 16;
 
 
                }
                }
              else if(looking_for & ABSJMP)
              else if(looking_for & ABSJMP)
                {
                {
                  abs =
                  abs =
                    (data[1] << 16)
                    (data[1] << 16)
                      | (data[2] << 8)
                      | (data[2] << 8)
                        | (data[3]);
                        | (data[3]);
                }
                }
              else if(looking_for & MEMIND)
              else if(looking_for & MEMIND)
                {
                {
                  abs = data[1];
                  abs = data[1];
                }
                }
              else if (looking_for & L_32)
              else if (looking_for & L_32)
                {
                {
                  int i = len >> 1;
                  int i = len >> 1;
                  abs = (data[i] << 24)
                  abs = (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]);
 
 
                  plen =32;
                  plen =32;
 
 
                }
                }
              else if (looking_for & L_24)
              else if (looking_for & L_24)
                {
                {
                  int i = len >> 1;
                  int i = len >> 1;
                  abs = (data[i] << 16) | (data[i + 1] << 8)|  (data[i+2]);
                  abs = (data[i] << 16) | (data[i + 1] << 8)|  (data[i+2]);
                  plen =24;
                  plen =24;
                }
                }
              else if (looking_for & IGNORE)
              else if (looking_for & IGNORE)
                {
                {
 
 
                }
                }
              else if (looking_for & DISPREG)
              else if (looking_for & DISPREG)
                {
                {
                  rdisp = thisnib;
                  rdisp = thisnib;
                }
                }
              else if (looking_for & KBIT)
              else if (looking_for & KBIT)
                {
                {
                  switch (thisnib)
                  switch (thisnib)
                    {
                    {
                    case 9:
                    case 9:
                      abs = 4;
                      abs = 4;
                      break;
                      break;
                    case 8:
                    case 8:
                      abs = 2;
                      abs = 2;
                      break;
                      break;
                    case 0:
                    case 0:
                      abs = 1;
                      abs = 1;
                      break;
                      break;
                    default:
                    default:
                      goto fail;
                      goto fail;
                    }
                    }
                }
                }
              else if (looking_for & L_8)
              else if (looking_for & L_8)
                {
                {
                  plen = 8;
                  plen = 8;
                  abs = data[len >> 1];
                  abs = data[len >> 1];
                }
                }
              else if (looking_for & L_3)
              else if (looking_for & L_3)
                {
                {
                  bit = thisnib & 0x7;
                  bit = thisnib & 0x7;
                }
                }
              else if (looking_for & L_2)
              else if (looking_for & L_2)
                {
                {
                  plen = 2;
                  plen = 2;
                  abs = thisnib & 0x3;
                  abs = thisnib & 0x3;
                }
                }
              else if (looking_for & MACREG)
              else if (looking_for & MACREG)
                {
                {
                  abs = (thisnib == 3);
                  abs = (thisnib == 3);
                }
                }
              else if (looking_for == E)
              else if (looking_for == E)
                {
                {
 
 
                  {
                  {
                    int i;
                    int i;
 
 
                    for (i = 0; i < q->length; i++)
                    for (i = 0; i < q->length; i++)
                      {
                      {
                        fprintf (stream, "%02x ", data[i]);
                        fprintf (stream, "%02x ", data[i]);
                      }
                      }
                    for (; i < 6; i++)
                    for (; i < 6; i++)
                      {
                      {
                        fprintf (stream, "   ");
                        fprintf (stream, "   ");
                      }
                      }
                  }
                  }
                  fprintf (stream, "%s\t", q->name);
                  fprintf (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] >> 4) & 0x3;
                      count = (data[1] >> 4) & 0x3;
                      high = data[3] & 0x7;
                      high = data[3] & 0x7;
 
 
                      fprintf (stream, "@sp+,er%d-er%d", high - count, high);
                      fprintf (stream, "@sp+,er%d-er%d", high - count, high);
                      return q->length;
                      return q->length;
                    }
                    }
 
 
                  if (strcmp (q->name, "stm.l") == 0)
                  if (strcmp (q->name, "stm.l") == 0)
                    {
                    {
                      int count, low;
                      int count, low;
 
 
                      count = (data[1] >> 4) & 0x3;
                      count = (data[1] >> 4) & 0x3;
                      low = data[3] & 0x7;
                      low = data[3] & 0x7;
 
 
                      fprintf (stream, "er%d-er%d,@-sp", low, low + count);
                      fprintf (stream, "er%d-er%d,@-sp", low, low + count);
                      return q->length;
                      return q->length;
                    }
                    }
 
 
                  /* Fill in the args */
                  /* Fill in the args */
                  {
                  {
                    op_type *args = q->args.nib;
                    op_type *args = q->args.nib;
                    int hadone = 0;
                    int hadone = 0;
 
 
 
 
                    while (*args != E)
                    while (*args != E)
                      {
                      {
                        int x = *args;
                        int x = *args;
                        if (hadone)
                        if (hadone)
                          fprintf (stream, ",");
                          fprintf (stream, ",");
 
 
 
 
                        if (x & L_3)
                        if (x & L_3)
                          {
                          {
                            fprintf (stream, "#0x%x", (unsigned) bit);
                            fprintf (stream, "#0x%x", (unsigned) bit);
                          }
                          }
                        else if (x & (IMM|KBIT|DBIT))
                        else if (x & (IMM|KBIT|DBIT))
                          {
                          {
                            /* Bletch.  For shal #2,er0 and friends.  */
                            /* Bletch.  For shal #2,er0 and friends.  */
                            if (*(args+1) & SRC_IN_DST)
                            if (*(args+1) & SRC_IN_DST)
                              abs = 2;
                              abs = 2;
 
 
                            fprintf (stream, "#0x%x", (unsigned) abs);
                            fprintf (stream, "#0x%x", (unsigned) abs);
                          }
                          }
                        else if (x & REG)
                        else if (x & REG)
                          {
                          {
                            int rn = (x & DST) ? rd : rs;
                            int rn = (x & DST) ? rd : rs;
                            switch (x & SIZE)
                            switch (x & SIZE)
                              {
                              {
                              case L_8:
                              case L_8:
                                fprintf (stream, "%s", regnames[rn]);
                                fprintf (stream, "%s", regnames[rn]);
                                break;
                                break;
                              case L_16:
                              case L_16:
                                fprintf (stream, "%s", wregnames[rn]);
                                fprintf (stream, "%s", wregnames[rn]);
                                break;
                                break;
                              case L_P:
                              case L_P:
                              case L_32:
                              case L_32:
                                fprintf (stream, "%s", lregnames[rn]);
                                fprintf (stream, "%s", lregnames[rn]);
                                break;
                                break;
 
 
                              }
                              }
                          }
                          }
                        else if (x & MACREG)
                        else if (x & MACREG)
                          {
                          {
                            fprintf (stream, "mac%c", abs ? 'l' : 'h');
                            fprintf (stream, "mac%c", abs ? 'l' : 'h');
                          }
                          }
                        else if (x & INC)
                        else if (x & INC)
                          {
                          {
                            fprintf (stream, "@%s+", pregnames[rs]);
                            fprintf (stream, "@%s+", pregnames[rs]);
                          }
                          }
                        else if (x & DEC)
                        else if (x & DEC)
                          {
                          {
                            fprintf (stream, "@-%s", pregnames[rd]);
                            fprintf (stream, "@-%s", pregnames[rd]);
                          }
                          }
 
 
                        else if (x & IND)
                        else if (x & IND)
                          {
                          {
                            int rn = (x & DST) ? rd : rs;
                            int rn = (x & DST) ? rd : rs;
                            fprintf (stream, "@%s", pregnames[rn]);
                            fprintf (stream, "@%s", pregnames[rn]);
                          }
                          }
 
 
                        else if (x & ABS8MEM)
                        else if (x & ABS8MEM)
                          {
                          {
                            fprintf (stream, "@0x%x:8", (unsigned) abs);
                            fprintf (stream, "@0x%x:8", (unsigned) abs);
                          }
                          }
 
 
                        else if (x & (ABS|ABSJMP))
                        else if (x & (ABS|ABSJMP))
                          {
                          {
                            fprintf (stream, "@0x%x:%d", (unsigned) abs, plen);
                            fprintf (stream, "@0x%x:%d", (unsigned) abs, plen);
                          }
                          }
 
 
                        else if (x & MEMIND)
                        else if (x & MEMIND)
                          {
                          {
                            fprintf (stream, "@@%d (%x)", abs, abs);
                            fprintf (stream, "@@%d (%x)", abs, abs);
                          }
                          }
 
 
                        else if (x & PCREL)
                        else if (x & PCREL)
                          {
                          {
                            if (x & L_16)
                            if (x & L_16)
                              {
                              {
                                abs  +=2;
                                abs  +=2;
                                fprintf (stream, ".%s%d (%x)", (short) abs > 0 ? "+" : "", (short) abs,
                                fprintf (stream, ".%s%d (%x)", (short) abs > 0 ? "+" : "", (short) abs,
                                         addr + (short) abs + 2);
                                         addr + (short) abs + 2);
                              }
                              }
                            else {
                            else {
                              fprintf (stream, ".%s%d (%x)", (char) abs > 0 ? "+" : "", (char) abs,
                              fprintf (stream, ".%s%d (%x)", (char) abs > 0 ? "+" : "", (char) abs,
                                       addr + (char) abs + 2);
                                       addr + (char) abs + 2);
                            }
                            }
                          }
                          }
                        else if (x & DISP)
                        else if (x & DISP)
                          {
                          {
                            fprintf (stream, "@(0x%x:%d,%s)", abs,plen, pregnames[rdisp]);
                            fprintf (stream, "@(0x%x:%d,%s)", abs,plen, pregnames[rdisp]);
                          }
                          }
 
 
                        else if (x & CCR)
                        else if (x & CCR)
                          {
                          {
                            fprintf (stream, "ccr");
                            fprintf (stream, "ccr");
                          }
                          }
                        else if (x & EXR)
                        else if (x & EXR)
                          {
                          {
                            fprintf (stream, "exr");
                            fprintf (stream, "exr");
                          }
                          }
                        else
                        else
                          /* xgettext:c-format */
                          /* xgettext:c-format */
                          fprintf (stream, _("Hmmmm %x"), x);
                          fprintf (stream, _("Hmmmm %x"), x);
                        hadone = 1;
                        hadone = 1;
                        args++;
                        args++;
                      }
                      }
                  }
                  }
                  return q->length;
                  return q->length;
                }
                }
 
 
 
 
              else
              else
                {
                {
                  /* xgettext:c-format */
                  /* xgettext:c-format */
                  fprintf (stream, _("Don't understand %x \n"), looking_for);
                  fprintf (stream, _("Don't understand %x \n"), looking_for);
                }
                }
            }
            }
 
 
          len++;
          len++;
          nib++;
          nib++;
        }
        }
 
 
    fail:
    fail:
      q++;
      q++;
    }
    }
 
 
  /* Fell of the end */
  /* Fell of the end */
  fprintf (stream, "%02x %02x        .word\tH'%x,H'%x",
  fprintf (stream, "%02x %02x        .word\tH'%x,H'%x",
           data[0], data[1],
           data[0], data[1],
           data[0], data[1]);
           data[0], data[1]);
  return 2;
  return 2;
}
}
 
 
int
int
print_insn_h8300 (addr, info)
print_insn_h8300 (addr, info)
bfd_vma addr;
bfd_vma addr;
disassemble_info *info;
disassemble_info *info;
{
{
  return bfd_h8_disassemble (addr, info , 0);
  return bfd_h8_disassemble (addr, info , 0);
}
}
 
 
int
int
print_insn_h8300h (addr, info)
print_insn_h8300h (addr, info)
bfd_vma addr;
bfd_vma addr;
disassemble_info *info;
disassemble_info *info;
{
{
  return bfd_h8_disassemble (addr, info , 1);
  return bfd_h8_disassemble (addr, info , 1);
}
}
 
 
int
int
print_insn_h8300s (addr, info)
print_insn_h8300s (addr, info)
bfd_vma addr;
bfd_vma addr;
disassemble_info *info;
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.