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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [opcodes/] [m68k-dis.c] - Diff between revs 157 and 225

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 157 Rev 225
Line 1... Line 1...
/* Print Motorola 68k instructions.
/* Print Motorola 68k instructions.
   Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
   Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
   Free Software Foundation, Inc.
   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
Line 58... Line 58...
#else
#else
#define COERCE_SIGNED_CHAR(ch) ((int) (((ch) ^ 0x80) & 0xFF) - 128)
#define COERCE_SIGNED_CHAR(ch) ((int) (((ch) ^ 0x80) & 0xFF) - 128)
#endif
#endif
 
 
/* Get a 1 byte signed integer.  */
/* Get a 1 byte signed integer.  */
#define NEXTBYTE(p)  (p += 2, FETCH_DATA (info, p), COERCE_SIGNED_CHAR(p[-1]))
#define NEXTBYTE(p, val)                        \
 
  do                                            \
 
    {                                           \
 
      p += 2;                                   \
 
      if (!FETCH_DATA (info, p))                \
 
        return -3;                              \
 
      val = COERCE_SIGNED_CHAR (p[-1]);         \
 
    }                                           \
 
  while (0)
 
 
/* Get a 2 byte signed integer.  */
/* Get a 2 byte signed integer.  */
#define COERCE16(x) ((int) (((x) ^ 0x8000) - 0x8000))
#define COERCE16(x) ((int) (((x) ^ 0x8000) - 0x8000))
#define NEXTWORD(p)  \
 
  (p += 2, FETCH_DATA (info, p), \
#define NEXTWORD(p, val, ret_val)               \
   COERCE16 ((p[-2] << 8) + p[-1]))
  do                                            \
 
    {                                           \
 
      p += 2;                                   \
 
      if (!FETCH_DATA (info, p))                \
 
        return ret_val;                         \
 
      val = COERCE16 ((p[-2] << 8) + p[-1]);    \
 
    }                                           \
 
  while (0)
 
 
/* Get a 4 byte signed integer.  */
/* Get a 4 byte signed integer.  */
#define COERCE32(x) ((bfd_signed_vma) ((x) ^ 0x80000000) - 0x80000000)
#define COERCE32(x) ((bfd_signed_vma) ((x) ^ 0x80000000) - 0x80000000)
#define NEXTLONG(p)  \
 
  (p += 4, FETCH_DATA (info, p), \
#define NEXTLONG(p, val, ret_val)                                       \
   (COERCE32 ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])))
  do                                                                    \
 
    {                                                                   \
 
      p += 4;                                                           \
 
      if (!FETCH_DATA (info, p))                                        \
 
        return ret_val;                                                 \
 
      val = COERCE32 ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]); \
 
    }                                                                   \
 
  while (0)
 
 
/* Get a 4 byte unsigned integer.  */
/* Get a 4 byte unsigned integer.  */
#define NEXTULONG(p)  \
#define NEXTULONG(p, val)                                               \
  (p += 4, FETCH_DATA (info, p), \
  do                                                                    \
   (unsigned int) ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]))
    {                                                                   \
 
      p += 4;                                                           \
 
      if (!FETCH_DATA (info, p))                                        \
 
        return -3;                                                      \
 
      val = (unsigned int) ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]); \
 
    }                                                                   \
 
  while (0)
 
 
/* Get a single precision float.  */
/* Get a single precision float.  */
#define NEXTSINGLE(val, p) \
#define NEXTSINGLE(val, p) \
  (p += 4, FETCH_DATA (info, p), \
  do                                                            \
   floatformat_to_double (&floatformat_ieee_single_big, (char *) p - 4, &val))
    {                                                           \
 
      p += 4;                                                   \
 
      if (!FETCH_DATA (info, p))                                \
 
        return -3;                                              \
 
      floatformat_to_double (& floatformat_ieee_single_big,     \
 
                             (char *) p - 4, & val);            \
 
    }                                                           \
 
  while (0)
 
 
/* Get a double precision float.  */
/* Get a double precision float.  */
#define NEXTDOUBLE(val, p) \
#define NEXTDOUBLE(val, p) \
  (p += 8, FETCH_DATA (info, p), \
  do                                                            \
   floatformat_to_double (&floatformat_ieee_double_big, (char *) p - 8, &val))
    {                                                           \
 
      p += 8;                                                   \
 
      if (!FETCH_DATA (info, p))                                \
 
        return -3;                                              \
 
      floatformat_to_double (& floatformat_ieee_double_big,     \
 
                             (char *) p - 8, & val);            \
 
    }                                                           \
 
  while (0)
 
 
/* Get an extended precision float.  */
/* Get an extended precision float.  */
#define NEXTEXTEND(val, p) \
#define NEXTEXTEND(val, p) \
  (p += 12, FETCH_DATA (info, p), \
  do                                                    \
   floatformat_to_double (&floatformat_m68881_ext, (char *) p - 12, &val))
    {                                                   \
 
      p += 12;                                          \
 
      if (!FETCH_DATA (info, p))                        \
 
        return -3;                                      \
 
      floatformat_to_double (& floatformat_m68881_ext,  \
 
                             (char *) p - 12, & val);   \
 
    }                                                   \
 
  while (0)
 
 
/* Need a function to convert from packed to double
/* Need a function to convert from packed to double
   precision.   Actually, it's easier to print a
   precision.   Actually, it's easier to print a
   packed number than a double anyway, so maybe
   packed number than a double anyway, so maybe
   there should be a special case to handle this... */
   there should be a special case to handle this... */
#define NEXTPACKED(p) \
#define NEXTPACKED(p, val)                      \
  (p += 12, FETCH_DATA (info, p), 0.0)
  do                                            \
 
    {                                           \
 
      p += 12;                                  \
 
      if (!FETCH_DATA (info, p))                \
 
        return -3;                              \
 
      val = 0.0;                                \
 
    }                                           \
 
  while (0)
 
 


/* Maximum length of an instruction.  */
/* Maximum length of an instruction.  */
#define MAXLEN 22
#define MAXLEN 22
 
 
#include <setjmp.h>
#include <setjmp.h>
Line 110... Line 167...
{
{
  /* Points to first byte not fetched.  */
  /* Points to first byte not fetched.  */
  bfd_byte *max_fetched;
  bfd_byte *max_fetched;
  bfd_byte the_buffer[MAXLEN];
  bfd_byte the_buffer[MAXLEN];
  bfd_vma insn_start;
  bfd_vma insn_start;
  jmp_buf bailout;
 
};
};
 
 
/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
   to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
   to ADDR (exclusive) are valid.  Returns 1 for success, 0 on error.  */
   on error.  */
 
#define FETCH_DATA(info, addr) \
#define FETCH_DATA(info, addr) \
  ((addr) <= ((struct private *) (info->private_data))->max_fetched \
  ((addr) <= ((struct private *) (info->private_data))->max_fetched \
   ? 1 : fetch_data ((info), (addr)))
   ? 1 : fetch_data ((info), (addr)))
 
 
static int
static int
Line 134... Line 189...
                                      addr - priv->max_fetched,
                                      addr - priv->max_fetched,
                                      info);
                                      info);
  if (status != 0)
  if (status != 0)
    {
    {
      (*info->memory_error_func) (status, start, info);
      (*info->memory_error_func) (status, start, info);
      longjmp (priv->bailout, 1);
      return 0;
    }
    }
  else
  else
    priv->max_fetched = addr;
    priv->max_fetched = addr;
  return 1;
  return 1;
}
}
Line 159... Line 214...
}
}
 
 
/* Fetch BITS bits from a position in the instruction specified by CODE.
/* Fetch BITS bits from a position in the instruction specified by CODE.
   CODE is a "place to put an argument", or 'x' for a destination
   CODE is a "place to put an argument", or 'x' for a destination
   that is a general address (mode and register).
   that is a general address (mode and register).
   BUFFER contains the instruction.  */
   BUFFER contains the instruction.
 
   Returns -1 on failure.  */
 
 
static int
static int
fetch_arg (unsigned char *buffer,
fetch_arg (unsigned char *buffer,
           int code,
           int code,
           int bits,
           int bits,
Line 214... Line 270...
      val = (buffer[0] << 8) + buffer[1];
      val = (buffer[0] << 8) + buffer[1];
      val >>= 6;
      val >>= 6;
      break;
      break;
 
 
    case 'k':
    case 'k':
      FETCH_DATA (info, buffer + 3);
      if (! FETCH_DATA (info, buffer + 3))
 
        return -1;
      val = (buffer[3] >> 4);
      val = (buffer[3] >> 4);
      break;
      break;
 
 
    case 'C':
    case 'C':
      FETCH_DATA (info, buffer + 3);
      if (! FETCH_DATA (info, buffer + 3))
 
        return -1;
      val = buffer[3];
      val = buffer[3];
      break;
      break;
 
 
    case '1':
    case '1':
      FETCH_DATA (info, buffer + 3);
      if (! FETCH_DATA (info, buffer + 3))
 
        return -1;
      val = (buffer[2] << 8) + buffer[3];
      val = (buffer[2] << 8) + buffer[3];
      val >>= 12;
      val >>= 12;
      break;
      break;
 
 
    case '2':
    case '2':
      FETCH_DATA (info, buffer + 3);
      if (! FETCH_DATA (info, buffer + 3))
 
        return -1;
      val = (buffer[2] << 8) + buffer[3];
      val = (buffer[2] << 8) + buffer[3];
      val >>= 6;
      val >>= 6;
      break;
      break;
 
 
    case '3':
    case '3':
    case 'j':
    case 'j':
      FETCH_DATA (info, buffer + 3);
      if (! FETCH_DATA (info, buffer + 3))
 
        return -1;
      val = (buffer[2] << 8) + buffer[3];
      val = (buffer[2] << 8) + buffer[3];
      break;
      break;
 
 
    case '4':
    case '4':
      FETCH_DATA (info, buffer + 5);
      if (! FETCH_DATA (info, buffer + 5))
 
        return -1;
      val = (buffer[4] << 8) + buffer[5];
      val = (buffer[4] << 8) + buffer[5];
      val >>= 12;
      val >>= 12;
      break;
      break;
 
 
    case '5':
    case '5':
      FETCH_DATA (info, buffer + 5);
      if (! FETCH_DATA (info, buffer + 5))
 
        return -1;
      val = (buffer[4] << 8) + buffer[5];
      val = (buffer[4] << 8) + buffer[5];
      val >>= 6;
      val >>= 6;
      break;
      break;
 
 
    case '6':
    case '6':
      FETCH_DATA (info, buffer + 5);
      if (! FETCH_DATA (info, buffer + 5))
 
        return -1;
      val = (buffer[4] << 8) + buffer[5];
      val = (buffer[4] << 8) + buffer[5];
      break;
      break;
 
 
    case '7':
    case '7':
      FETCH_DATA (info, buffer + 3);
      if (! FETCH_DATA (info, buffer + 3))
 
        return -1;
      val = (buffer[2] << 8) + buffer[3];
      val = (buffer[2] << 8) + buffer[3];
      val >>= 7;
      val >>= 7;
      break;
      break;
 
 
    case '8':
    case '8':
      FETCH_DATA (info, buffer + 3);
      if (! FETCH_DATA (info, buffer + 3))
 
        return -1;
      val = (buffer[2] << 8) + buffer[3];
      val = (buffer[2] << 8) + buffer[3];
      val >>= 10;
      val >>= 10;
      break;
      break;
 
 
    case '9':
    case '9':
      FETCH_DATA (info, buffer + 3);
      if (! FETCH_DATA (info, buffer + 3))
 
        return -1;
      val = (buffer[2] << 8) + buffer[3];
      val = (buffer[2] << 8) + buffer[3];
      val >>= 5;
      val >>= 5;
      break;
      break;
 
 
    case 'e':
    case 'e':
      val = (buffer[1] >> 6);
      val = (buffer[1] >> 6);
      break;
      break;
 
 
    case 'E':
    case 'E':
      FETCH_DATA (info, buffer + 3);
      if (! FETCH_DATA (info, buffer + 3))
 
        return -1;
      val = (buffer[2] >> 1);
      val = (buffer[2] >> 1);
      break;
      break;
 
 
    case 'm':
    case 'm':
      val = (buffer[1] & 0x40 ? 0x8 : 0)
      val = (buffer[1] & 0x40 ? 0x8 : 0)
Line 448... Line 516...
    }
    }
}
}
 
 
/* Print an indexed argument.  The base register is BASEREG (-1 for pc).
/* Print an indexed argument.  The base register is BASEREG (-1 for pc).
   P points to extension word, in buffer.
   P points to extension word, in buffer.
   ADDR is the nominal core address of that extension word.  */
   ADDR is the nominal core address of that extension word.
 
   Returns NULL upon error.  */
 
 
static unsigned char *
static unsigned char *
print_indexed (int basereg,
print_indexed (int basereg,
               unsigned char *p,
               unsigned char *p,
               bfd_vma addr,
               bfd_vma addr,
Line 463... Line 532...
  bfd_vma base_disp;
  bfd_vma base_disp;
  bfd_vma outer_disp;
  bfd_vma outer_disp;
  char buf[40];
  char buf[40];
  char vmabuf[50];
  char vmabuf[50];
 
 
  word = NEXTWORD (p);
  NEXTWORD (p, word, NULL);
 
 
  /* Generate the text for the index register.
  /* Generate the text for the index register.
     Where this will be output is not yet determined.  */
     Where this will be output is not yet determined.  */
  sprintf (buf, "%s:%c%s",
  sprintf (buf, "%s:%c%s",
           reg_names[(word >> 12) & 0xf],
           reg_names[(word >> 12) & 0xf],
Line 501... Line 570...
    buf[0] = '\0';
    buf[0] = '\0';
  base_disp = 0;
  base_disp = 0;
  switch ((word >> 4) & 3)
  switch ((word >> 4) & 3)
    {
    {
    case 2:
    case 2:
      base_disp = NEXTWORD (p);
      NEXTWORD (p, base_disp, NULL);
      break;
      break;
    case 3:
    case 3:
      base_disp = NEXTLONG (p);
      NEXTLONG (p, base_disp, NULL);
    }
    }
  if (basereg == -1)
  if (basereg == -1)
    base_disp += addr;
    base_disp += addr;
 
 
  /* Handle single-level case (not indirect).  */
  /* Handle single-level case (not indirect).  */
Line 524... Line 593...
  /* Two level.  Compute displacement to add after indirection.  */
  /* Two level.  Compute displacement to add after indirection.  */
  outer_disp = 0;
  outer_disp = 0;
  switch (word & 3)
  switch (word & 3)
    {
    {
    case 2:
    case 2:
      outer_disp = NEXTWORD (p);
      NEXTWORD (p, outer_disp, NULL);
      break;
      break;
    case 3:
    case 3:
      outer_disp = NEXTLONG (p);
      NEXTLONG (p, outer_disp, NULL);
    }
    }
 
 
  print_base (basereg, base_disp, info);
  print_base (basereg, base_disp, info);
  if ((word & 4) == 0 && buf[0] != '\0')
  if ((word & 4) == 0 && buf[0] != '\0')
    {
    {
Line 545... Line 614...
  (*info->fprintf_func) (info->stream, ")");
  (*info->fprintf_func) (info->stream, ")");
 
 
  return p;
  return p;
}
}
 
 
 
#define FETCH_ARG(size, val)                            \
 
  do                                                    \
 
    {                                                   \
 
      val = fetch_arg (buffer, place, size, info);      \
 
      if (val < 0)                                       \
 
        return -3;                                      \
 
    }                                                   \
 
  while (0)
 
 
/* Returns number of bytes "eaten" by the operand, or
/* Returns number of bytes "eaten" by the operand, or
   return -1 if an invalid operand was found, or -2 if
   return -1 if an invalid operand was found, or -2 if
   an opcode tabe error was found.
   an opcode tabe error was found or -3 to simply abort.
   ADDR is the pc for this arg to be relative to.  */
   ADDR is the pc for this arg to be relative to.  */
 
 
static int
static int
print_insn_arg (const char *d,
print_insn_arg (const char *d,
                unsigned char *buffer,
                unsigned char *buffer,
Line 573... Line 651...
  switch (*d)
  switch (*d)
    {
    {
    case 'c':           /* Cache identifier.  */
    case 'c':           /* Cache identifier.  */
      {
      {
        static char *const cacheFieldName[] = { "nc", "dc", "ic", "bc" };
        static char *const cacheFieldName[] = { "nc", "dc", "ic", "bc" };
        val = fetch_arg (buffer, place, 2, info);
        FETCH_ARG (2, val);
        (*info->fprintf_func) (info->stream, cacheFieldName[val]);
        (*info->fprintf_func) (info->stream, cacheFieldName[val]);
        break;
        break;
      }
      }
 
 
    case 'a':           /* Address register indirect only. Cf. case '+'.  */
    case 'a':           /* Address register indirect only. Cf. case '+'.  */
      {
      {
        (*info->fprintf_func)
        FETCH_ARG (3, val);
          (info->stream,
        (*info->fprintf_func) (info->stream, "%s@", reg_names[val + 8]);
           "%s@",
 
           reg_names[fetch_arg (buffer, place, 3, info) + 8]);
 
        break;
        break;
      }
      }
 
 
    case '_':           /* 32-bit absolute address for move16.  */
    case '_':           /* 32-bit absolute address for move16.  */
      {
      {
        uval = NEXTULONG (p);
        NEXTULONG (p, uval);
        (*info->print_address_func) (uval, info);
        (*info->print_address_func) (uval, info);
        break;
        break;
      }
      }
 
 
    case 'C':
    case 'C':
Line 621... Line 697...
      break;
      break;
 
 
    case 'J':
    case 'J':
      {
      {
        /* FIXME: There's a problem here, different m68k processors call the
        /* FIXME: There's a problem here, different m68k processors call the
           same address different names. This table can't get it right
           same address different names.  The tables below try to get it right
           because it doesn't know which processor it's disassembling for.  */
           using info->mach, but only for v4e.  */
        static const struct { char *name; int value; } names[]
        struct regname { char * name; int value; };
          = {{"%sfc", 0x000}, {"%dfc", 0x001}, {"%cacr", 0x002},
        static const struct regname names[] =
 
          {
 
            {"%sfc", 0x000}, {"%dfc", 0x001}, {"%cacr", 0x002},
             {"%tc",  0x003}, {"%itt0",0x004}, {"%itt1", 0x005},
             {"%tc",  0x003}, {"%itt0",0x004}, {"%itt1", 0x005},
             {"%dtt0",0x006}, {"%dtt1",0x007}, {"%buscr",0x008},
             {"%dtt0",0x006}, {"%dtt1",0x007}, {"%buscr",0x008},
             {"%usp", 0x800}, {"%vbr", 0x801}, {"%caar", 0x802},
             {"%usp", 0x800}, {"%vbr", 0x801}, {"%caar", 0x802},
             {"%msp", 0x803}, {"%isp", 0x804},
             {"%msp", 0x803}, {"%isp", 0x804},
             /* reg c04 is sometimes called flashbar or rambar.
            {"%pc", 0x80f},
                rec c05 is also sometimes called rambar.  */
            /* Reg c04 is sometimes called flashbar or rambar.
 
               Rec c05 is also sometimes called rambar.  */
             {"%rambar0", 0xc04}, {"%rambar1", 0xc05},
             {"%rambar0", 0xc04}, {"%rambar1", 0xc05},
 
 
 
            {"%mbar", 0xc0f},
 
 
             /* Should we be calling this psr like we do in case 'Y'?  */
             /* Should we be calling this psr like we do in case 'Y'?  */
             {"%mmusr",0x805},
             {"%mmusr",0x805},
 
 
             {"%urp", 0x806}, {"%srp", 0x807}, {"%pcr", 0x808},
             {"%urp", 0x806}, {"%srp", 0x807}, {"%pcr", 0x808},
 
 
             /* Fido added these.  */
             /* Fido added these.  */
             {"%cac", 0xffe}, {"%mbo", 0xfff}};
            {"%cac", 0xffe}, {"%mbo", 0xfff}
 
        };
 
        /* Alternate names for v4e (MCF5407/5445x/MCF547x/MCF548x), at least.  */
 
        static const struct regname names_v4e[] =
 
          {
 
            {"%asid",0x003}, {"%acr0",0x004}, {"%acr1",0x005},
 
            {"%acr2",0x006}, {"%acr3",0x007}, {"%mmubar",0x008},
 
          };
 
        unsigned int arch_mask;
 
 
        val = fetch_arg (buffer, place, 12, info);
        arch_mask = bfd_m68k_mach_to_features (info->mach);
        for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--)
        FETCH_ARG (12, val);
 
        if (arch_mask & (mcfisa_b | mcfisa_c))
 
          {
 
            for (regno = ARRAY_SIZE (names_v4e); --regno >= 0;)
 
              if (names_v4e[regno].value == val)
 
                {
 
                  (*info->fprintf_func) (info->stream, "%s", names_v4e[regno].name);
 
                  break;
 
                }
 
            if (regno >= 0)
 
              break;
 
          }
 
        for (regno = ARRAY_SIZE (names) - 1; regno >= 0; regno--)
          if (names[regno].value == val)
          if (names[regno].value == val)
            {
            {
              (*info->fprintf_func) (info->stream, "%s", names[regno].name);
              (*info->fprintf_func) (info->stream, "%s", names[regno].name);
              break;
              break;
            }
            }
        if (regno < 0)
        if (regno < 0)
          (*info->fprintf_func) (info->stream, "%d", val);
          (*info->fprintf_func) (info->stream, "0x%x", val);
      }
      }
      break;
      break;
 
 
    case 'Q':
    case 'Q':
      val = fetch_arg (buffer, place, 3, info);
      FETCH_ARG (3, val);
      /* 0 means 8, except for the bkpt instruction... */
      /* 0 means 8, except for the bkpt instruction... */
      if (val == 0 && d[1] != 's')
      if (val == 0 && d[1] != 's')
        val = 8;
        val = 8;
      (*info->fprintf_func) (info->stream, "#%d", val);
      (*info->fprintf_func) (info->stream, "#%d", val);
      break;
      break;
 
 
    case 'x':
    case 'x':
      val = fetch_arg (buffer, place, 3, info);
      FETCH_ARG (3, val);
      /* 0 means -1.  */
      /* 0 means -1.  */
      if (val == 0)
      if (val == 0)
        val = -1;
        val = -1;
      (*info->fprintf_func) (info->stream, "#%d", val);
      (*info->fprintf_func) (info->stream, "#%d", val);
      break;
      break;
 
 
    case 'j':
    case 'j':
      val = fetch_arg (buffer, place, 3, info);
      FETCH_ARG (3, val);
      (*info->fprintf_func) (info->stream, "#%d", val+1);
      (*info->fprintf_func) (info->stream, "#%d", val+1);
      break;
      break;
 
 
    case 'K':
    case 'K':
      val = fetch_arg (buffer, place, 9, info);
      FETCH_ARG (9, val);
      (*info->fprintf_func) (info->stream, "#%d", val);
      (*info->fprintf_func) (info->stream, "#%d", val);
      break;
      break;
 
 
    case 'M':
    case 'M':
      if (place == 'h')
      if (place == 'h')
        {
        {
          static char *const scalefactor_name[] = { "<<", ">>" };
          static char *const scalefactor_name[] = { "<<", ">>" };
          val = fetch_arg (buffer, place, 1, info);
 
 
          FETCH_ARG (1, val);
          (*info->fprintf_func) (info->stream, scalefactor_name[val]);
          (*info->fprintf_func) (info->stream, scalefactor_name[val]);
        }
        }
      else
      else
        {
        {
          val = fetch_arg (buffer, place, 8, info);
          FETCH_ARG (8, val);
          if (val & 0x80)
          if (val & 0x80)
            val = val - 0x100;
            val = val - 0x100;
          (*info->fprintf_func) (info->stream, "#%d", val);
          (*info->fprintf_func) (info->stream, "#%d", val);
        }
        }
      break;
      break;
 
 
    case 'T':
    case 'T':
      val = fetch_arg (buffer, place, 4, info);
      FETCH_ARG (4, val);
      (*info->fprintf_func) (info->stream, "#%d", val);
      (*info->fprintf_func) (info->stream, "#%d", val);
      break;
      break;
 
 
    case 'D':
    case 'D':
      (*info->fprintf_func) (info->stream, "%s",
      FETCH_ARG (3, val);
                             reg_names[fetch_arg (buffer, place, 3, info)]);
      (*info->fprintf_func) (info->stream, "%s", reg_names[val]);
      break;
      break;
 
 
    case 'A':
    case 'A':
      (*info->fprintf_func)
      FETCH_ARG (3, val);
        (info->stream, "%s",
      (*info->fprintf_func) (info->stream, "%s", reg_names[val + 010]);
         reg_names[fetch_arg (buffer, place, 3, info) + 010]);
 
      break;
      break;
 
 
    case 'R':
    case 'R':
      (*info->fprintf_func)
      FETCH_ARG (4, val);
        (info->stream, "%s",
      (*info->fprintf_func) (info->stream, "%s", reg_names[val]);
         reg_names[fetch_arg (buffer, place, 4, info)]);
 
      break;
      break;
 
 
    case 'r':
    case 'r':
      regno = fetch_arg (buffer, place, 4, info);
      FETCH_ARG (4, regno);
      if (regno > 7)
      if (regno > 7)
        (*info->fprintf_func) (info->stream, "%s@", reg_names[regno]);
        (*info->fprintf_func) (info->stream, "%s@", reg_names[regno]);
      else
      else
        (*info->fprintf_func) (info->stream, "@(%s)", reg_names[regno]);
        (*info->fprintf_func) (info->stream, "@(%s)", reg_names[regno]);
      break;
      break;
 
 
    case 'F':
    case 'F':
      (*info->fprintf_func)
      FETCH_ARG (3, val);
        (info->stream, "%%fp%d",
      (*info->fprintf_func) (info->stream, "%%fp%d", val);
         fetch_arg (buffer, place, 3, info));
 
      break;
      break;
 
 
    case 'O':
    case 'O':
      val = fetch_arg (buffer, place, 6, info);
      FETCH_ARG (6, val);
      if (val & 0x20)
      if (val & 0x20)
        (*info->fprintf_func) (info->stream, "%s", reg_names[val & 7]);
        (*info->fprintf_func) (info->stream, "%s", reg_names[val & 7]);
      else
      else
        (*info->fprintf_func) (info->stream, "%d", val);
        (*info->fprintf_func) (info->stream, "%d", val);
      break;
      break;
 
 
    case '+':
    case '+':
      (*info->fprintf_func)
      FETCH_ARG (3, val);
        (info->stream, "%s@+",
      (*info->fprintf_func) (info->stream, "%s@+", reg_names[val + 8]);
         reg_names[fetch_arg (buffer, place, 3, info) + 8]);
 
      break;
      break;
 
 
    case '-':
    case '-':
      (*info->fprintf_func)
      FETCH_ARG (3, val);
        (info->stream, "%s@-",
      (*info->fprintf_func) (info->stream, "%s@-", reg_names[val + 8]);
         reg_names[fetch_arg (buffer, place, 3, info) + 8]);
 
      break;
      break;
 
 
    case 'k':
    case 'k':
      if (place == 'k')
      if (place == 'k')
        (*info->fprintf_func)
        {
          (info->stream, "{%s}",
          FETCH_ARG (3, val);
           reg_names[fetch_arg (buffer, place, 3, info)]);
          (*info->fprintf_func) (info->stream, "{%s}", reg_names[val]);
 
        }
      else if (place == 'C')
      else if (place == 'C')
        {
        {
          val = fetch_arg (buffer, place, 7, info);
          FETCH_ARG (7, val);
          if (val > 63)         /* This is a signed constant.  */
          if (val > 63)         /* This is a signed constant.  */
            val -= 128;
            val -= 128;
          (*info->fprintf_func) (info->stream, "{#%d}", val);
          (*info->fprintf_func) (info->stream, "{#%d}", val);
        }
        }
      else
      else
        return -2;
        return -1;
      break;
      break;
 
 
    case '#':
    case '#':
    case '^':
    case '^':
      p1 = buffer + (*d == '#' ? 2 : 4);
      p1 = buffer + (*d == '#' ? 2 : 4);
      if (place == 's')
      if (place == 's')
        val = fetch_arg (buffer, place, 4, info);
        FETCH_ARG (4, val);
      else if (place == 'C')
      else if (place == 'C')
        val = fetch_arg (buffer, place, 7, info);
        FETCH_ARG (7, val);
      else if (place == '8')
      else if (place == '8')
        val = fetch_arg (buffer, place, 3, info);
        FETCH_ARG (3, val);
      else if (place == '3')
      else if (place == '3')
        val = fetch_arg (buffer, place, 8, info);
        FETCH_ARG (8, val);
      else if (place == 'b')
      else if (place == 'b')
        val = NEXTBYTE (p1);
        NEXTBYTE (p1, val);
      else if (place == 'w' || place == 'W')
      else if (place == 'w' || place == 'W')
        val = NEXTWORD (p1);
        NEXTWORD (p1, val, -3);
      else if (place == 'l')
      else if (place == 'l')
        val = NEXTLONG (p1);
        NEXTLONG (p1, val, -3);
      else
      else
        return -2;
        return -2;
 
 
      (*info->fprintf_func) (info->stream, "#%d", val);
      (*info->fprintf_func) (info->stream, "#%d", val);
      break;
      break;
 
 
    case 'B':
    case 'B':
      if (place == 'b')
      if (place == 'b')
        disp = NEXTBYTE (p);
        NEXTBYTE (p, disp);
      else if (place == 'B')
      else if (place == 'B')
        disp = COERCE_SIGNED_CHAR (buffer[1]);
        disp = COERCE_SIGNED_CHAR (buffer[1]);
      else if (place == 'w' || place == 'W')
      else if (place == 'w' || place == 'W')
        disp = NEXTWORD (p);
        NEXTWORD (p, disp, -3);
      else if (place == 'l' || place == 'L' || place == 'C')
      else if (place == 'l' || place == 'L' || place == 'C')
        disp = NEXTLONG (p);
        NEXTLONG (p, disp, -3);
      else if (place == 'g')
      else if (place == 'g')
        {
        {
          disp = NEXTBYTE (buffer);
          NEXTBYTE (buffer, disp);
          if (disp == 0)
          if (disp == 0)
            disp = NEXTWORD (p);
            NEXTWORD (p, disp, -3);
          else if (disp == -1)
          else if (disp == -1)
            disp = NEXTLONG (p);
            NEXTLONG (p, disp, -3);
        }
        }
      else if (place == 'c')
      else if (place == 'c')
        {
        {
          if (buffer[1] & 0x40)         /* If bit six is one, long offset.  */
          if (buffer[1] & 0x40)         /* If bit six is one, long offset.  */
            disp = NEXTLONG (p);
            NEXTLONG (p, disp, -3);
          else
          else
            disp = NEXTWORD (p);
            NEXTWORD (p, disp, -3);
        }
        }
      else
      else
        return -2;
        return -2;
 
 
      (*info->print_address_func) (addr + disp, info);
      (*info->print_address_func) (addr + disp, info);
      break;
      break;
 
 
    case 'd':
    case 'd':
      val = NEXTWORD (p);
      {
      (*info->fprintf_func)
        int val1;
        (info->stream, "%s@(%d)",
 
         reg_names[fetch_arg (buffer, place, 3, info) + 8], val);
        NEXTWORD (p, val, -3);
 
        FETCH_ARG (3, val1);
 
        (*info->fprintf_func) (info->stream, "%s@(%d)", reg_names[val1 + 8], val);
      break;
      break;
 
      }
 
 
    case 's':
    case 's':
      (*info->fprintf_func) (info->stream, "%s",
      FETCH_ARG (3, val);
                             fpcr_names[fetch_arg (buffer, place, 3, info)]);
      (*info->fprintf_func) (info->stream, "%s", fpcr_names[val]);
      break;
      break;
 
 
    case 'e':
    case 'e':
      val = fetch_arg(buffer, place, 2, info);
      FETCH_ARG (2, val);
      (*info->fprintf_func) (info->stream, "%%acc%d", val);
      (*info->fprintf_func) (info->stream, "%%acc%d", val);
      break;
      break;
 
 
    case 'g':
    case 'g':
      val = fetch_arg(buffer, place, 1, info);
      FETCH_ARG (1, val);
      (*info->fprintf_func) (info->stream, "%%accext%s", val==0 ? "01" : "23");
      (*info->fprintf_func) (info->stream, "%%accext%s", val==0 ? "01" : "23");
      break;
      break;
 
 
    case 'i':
    case 'i':
      val = fetch_arg(buffer, place, 2, info);
      FETCH_ARG (2, val);
      if (val == 1)
      if (val == 1)
        (*info->fprintf_func) (info->stream, "<<");
        (*info->fprintf_func) (info->stream, "<<");
      else if (val == 3)
      else if (val == 3)
        (*info->fprintf_func) (info->stream, ">>");
        (*info->fprintf_func) (info->stream, ">>");
      else
      else
Line 854... Line 956...
      break;
      break;
 
 
    case 'I':
    case 'I':
      /* Get coprocessor ID... */
      /* Get coprocessor ID... */
      val = fetch_arg (buffer, 'd', 3, info);
      val = fetch_arg (buffer, 'd', 3, info);
 
      if (val < 0)
 
        return -3;
      if (val != 1)                             /* Unusual coprocessor ID?  */
      if (val != 1)                             /* Unusual coprocessor ID?  */
        (*info->fprintf_func) (info->stream, "(cpid=%d) ", val);
        (*info->fprintf_func) (info->stream, "(cpid=%d) ", val);
      break;
      break;
 
 
    case '4':
    case '4':
Line 886... Line 989...
    case 'y':
    case 'y':
    case 'z':
    case 'z':
      if (place == 'd')
      if (place == 'd')
        {
        {
          val = fetch_arg (buffer, 'x', 6, info);
          val = fetch_arg (buffer, 'x', 6, info);
 
          if (val < 0)
 
            return -3;
          val = ((val & 7) << 3) + ((val >> 3) & 7);
          val = ((val & 7) << 3) + ((val >> 3) & 7);
        }
        }
      else
      else
 
        {
        val = fetch_arg (buffer, 's', 6, info);
        val = fetch_arg (buffer, 's', 6, info);
 
          if (val < 0)
 
            return -3;
 
        }
 
 
      /* If the <ea> is invalid for *d, then reject this match.  */
      /* If the <ea> is invalid for *d, then reject this match.  */
      if (!m68k_valid_ea (*d, val))
      if (!m68k_valid_ea (*d, val))
        return -1;
        return -1;
 
 
Line 921... Line 1030...
        case 4:
        case 4:
          (*info->fprintf_func) (info->stream, "%s@-", regname);
          (*info->fprintf_func) (info->stream, "%s@-", regname);
          break;
          break;
 
 
        case 5:
        case 5:
          val = NEXTWORD (p);
          NEXTWORD (p, val, -3);
          (*info->fprintf_func) (info->stream, "%s@(%d)", regname, val);
          (*info->fprintf_func) (info->stream, "%s@(%d)", regname, val);
          break;
          break;
 
 
        case 6:
        case 6:
          p = print_indexed (regno, p, addr, info);
          p = print_indexed (regno, p, addr, info);
 
          if (p == NULL)
 
            return -3;
          break;
          break;
 
 
        case 7:
        case 7:
          switch (val & 7)
          switch (val & 7)
            {
            {
            case 0:
            case 0:
              val = NEXTWORD (p);
              NEXTWORD (p, val, -3);
              (*info->print_address_func) (val, info);
              (*info->print_address_func) (val, info);
              break;
              break;
 
 
            case 1:
            case 1:
              uval = NEXTULONG (p);
              NEXTULONG (p, uval);
              (*info->print_address_func) (uval, info);
              (*info->print_address_func) (uval, info);
              break;
              break;
 
 
            case 2:
            case 2:
              val = NEXTWORD (p);
              NEXTWORD (p, val, -3);
              (*info->fprintf_func) (info->stream, "%%pc@(");
              (*info->fprintf_func) (info->stream, "%%pc@(");
              (*info->print_address_func) (addr + val, info);
              (*info->print_address_func) (addr + val, info);
              (*info->fprintf_func) (info->stream, ")");
              (*info->fprintf_func) (info->stream, ")");
              break;
              break;
 
 
            case 3:
            case 3:
              p = print_indexed (-1, p, addr, info);
              p = print_indexed (-1, p, addr, info);
 
              if (p == NULL)
 
                return -3;
              break;
              break;
 
 
            case 4:
            case 4:
              flt_p = 1;        /* Assume it's a float... */
              flt_p = 1;        /* Assume it's a float... */
              switch (place)
              switch (place)
              {
              {
                case 'b':
                case 'b':
                  val = NEXTBYTE (p);
                  NEXTBYTE (p, val);
                  flt_p = 0;
                  flt_p = 0;
                  break;
                  break;
 
 
                case 'w':
                case 'w':
                  val = NEXTWORD (p);
                  NEXTWORD (p, val, -3);
                  flt_p = 0;
                  flt_p = 0;
                  break;
                  break;
 
 
                case 'l':
                case 'l':
                  val = NEXTLONG (p);
                  NEXTLONG (p, val, -3);
                  flt_p = 0;
                  flt_p = 0;
                  break;
                  break;
 
 
                case 'f':
                case 'f':
                  NEXTSINGLE (flval, p);
                  NEXTSINGLE (flval, p);
Line 985... Line 1098...
                case 'x':
                case 'x':
                  NEXTEXTEND (flval, p);
                  NEXTEXTEND (flval, p);
                  break;
                  break;
 
 
                case 'p':
                case 'p':
                  flval = NEXTPACKED (p);
                  NEXTPACKED (p, flval);
                  break;
                  break;
 
 
                default:
                default:
                  return -1;
                  return -1;
              }
              }
Line 1007... Line 1120...
      /* If place is '/', then this is the case of the mask bit for
      /* If place is '/', then this is the case of the mask bit for
         mac/emac loads. Now that the arg has been printed, grab the
         mac/emac loads. Now that the arg has been printed, grab the
         mask bit and if set, add a '&' to the arg.  */
         mask bit and if set, add a '&' to the arg.  */
      if (place == '/')
      if (place == '/')
        {
        {
          val = fetch_arg (buffer, place, 1, info);
          FETCH_ARG (1, val);
          if (val)
          if (val)
            info->fprintf_func (info->stream, "&");
            info->fprintf_func (info->stream, "&");
        }
        }
      break;
      break;
 
 
Line 1019... Line 1132...
    case 'l':
    case 'l':
        if (place == 'w')
        if (place == 'w')
          {
          {
            char doneany;
            char doneany;
            p1 = buffer + 2;
            p1 = buffer + 2;
            val = NEXTWORD (p1);
            NEXTWORD (p1, val, -3);
            /* Move the pointer ahead if this point is farther ahead
            /* Move the pointer ahead if this point is farther ahead
               than the last.  */
               than the last.  */
            p = p1 > p ? p1 : p;
            p = p1 > p ? p1 : p;
            if (val == 0)
            if (val == 0)
              {
              {
Line 1060... Line 1173...
          }
          }
        else if (place == '3')
        else if (place == '3')
          {
          {
            /* `fmovem' insn.  */
            /* `fmovem' insn.  */
            char doneany;
            char doneany;
            val = fetch_arg (buffer, place, 8, info);
 
 
            FETCH_ARG (8, val);
            if (val == 0)
            if (val == 0)
              {
              {
                (*info->fprintf_func) (info->stream, "#0");
                (*info->fprintf_func) (info->stream, "#0");
                break;
                break;
              }
              }
Line 1094... Line 1208...
                    (*info->fprintf_func) (info->stream, "-%%fp%d", regno);
                    (*info->fprintf_func) (info->stream, "-%%fp%d", regno);
                }
                }
          }
          }
        else if (place == '8')
        else if (place == '8')
          {
          {
 
            FETCH_ARG (3, val);
            /* fmoveml for FP status registers.  */
            /* fmoveml for FP status registers.  */
            (*info->fprintf_func) (info->stream, "%s",
            (*info->fprintf_func) (info->stream, "%s", fpcr_names[val]);
                                   fpcr_names[fetch_arg (buffer, place, 3,
 
                                                         info)]);
 
          }
          }
        else
        else
          return -2;
          return -2;
      break;
      break;
 
 
Line 1113... Line 1226...
    case '0':
    case '0':
    case '1':
    case '1':
    case '2':
    case '2':
    case '3':
    case '3':
      {
      {
        int val = fetch_arg (buffer, place, 5, info);
        int val;
        char *name = 0;
        char *name = 0;
 
 
 
        FETCH_ARG (5, val);
        switch (val)
        switch (val)
          {
          {
          case 2: name = "%tt0"; break;
          case 2: name = "%tt0"; break;
          case 3: name = "%tt1"; break;
          case 3: name = "%tt1"; break;
          case 0x10: name = "%tc"; break;
          case 0x10: name = "%tc"; break;
Line 1150... Line 1264...
      }
      }
      break;
      break;
 
 
    case 'f':
    case 'f':
      {
      {
        int fc = fetch_arg (buffer, place, 5, info);
        int fc;
 
 
 
        FETCH_ARG (5, fc);
        if (fc == 1)
        if (fc == 1)
          (*info->fprintf_func) (info->stream, "%%dfc");
          (*info->fprintf_func) (info->stream, "%%dfc");
        else if (fc == 0)
        else if (fc == 0)
          (*info->fprintf_func) (info->stream, "%%sfc");
          (*info->fprintf_func) (info->stream, "%%sfc");
        else
        else
Line 1168... Line 1283...
      (*info->fprintf_func) (info->stream, "%%val");
      (*info->fprintf_func) (info->stream, "%%val");
      break;
      break;
 
 
    case 't':
    case 't':
      {
      {
        int level = fetch_arg (buffer, place, 3, info);
        int level;
 
 
 
        FETCH_ARG (3, level);
        (*info->fprintf_func) (info->stream, "%d", level);
        (*info->fprintf_func) (info->stream, "%d", level);
      }
      }
      break;
      break;
 
 
    case 'u':
    case 'u':
      {
      {
        short is_upper = 0;
        short is_upper = 0;
        int reg = fetch_arg (buffer, place, 5, info);
        int reg;
 
 
 
        FETCH_ARG (5, reg);
        if (reg & 0x10)
        if (reg & 0x10)
          {
          {
            is_upper = 1;
            is_upper = 1;
            reg &= 0xf;
            reg &= 0xf;
          }
          }
Line 1301... Line 1418...
    {
    {
      int eaten = print_insn_arg (d, buffer, p, memaddr + (p - buffer), info);
      int eaten = print_insn_arg (d, buffer, p, memaddr + (p - buffer), info);
 
 
      if (eaten >= 0)
      if (eaten >= 0)
        p += eaten;
        p += eaten;
      else if (eaten == -1)
      else if (eaten == -1 || eaten == -3)
        {
        {
          info->fprintf_func = save_printer;
          info->fprintf_func = save_printer;
          info->print_address_func = save_print_address;
          info->print_address_func = save_print_address;
          return 0;
          return 0;
        }
        }
Line 1437... Line 1554...
              for (d = args; *d; d += 2)
              for (d = args; *d; d += 2)
                {
                {
                  if (d[0] == 's' && d[1] == '8')
                  if (d[0] == 's' && d[1] == '8')
                    {
                    {
                      val = fetch_arg (buffer, d[1], 3, info);
                      val = fetch_arg (buffer, d[1], 3, info);
 
                      if (val < 0)
 
                        return 0;
                      if ((val & (val - 1)) != 0)
                      if ((val & (val - 1)) != 0)
                        break;
                        break;
                    }
                    }
                }
                }
            }
            }
Line 1477... Line 1596...
  struct private priv;
  struct private priv;
  int val;
  int val;
 
 
  bfd_byte *buffer = priv.the_buffer;
  bfd_byte *buffer = priv.the_buffer;
 
 
  /* Save these printing functions in case we need to restore them
  info->private_data = & priv;
     later.  */
 
  fprintf_ftype save_printer = info->fprintf_func;
 
  void (* save_print_address) (bfd_vma, struct disassemble_info *)
 
    = info->print_address_func;
 
 
 
  info->private_data = (PTR) &priv;
 
  /* Tell objdump to use two bytes per chunk
  /* Tell objdump to use two bytes per chunk
     and six bytes per line for displaying raw data.  */
     and six bytes per line for displaying raw data.  */
  info->bytes_per_chunk = 2;
  info->bytes_per_chunk = 2;
  info->bytes_per_line = 6;
  info->bytes_per_line = 6;
  info->display_endian = BFD_ENDIAN_BIG;
  info->display_endian = BFD_ENDIAN_BIG;
  priv.max_fetched = priv.the_buffer;
  priv.max_fetched = priv.the_buffer;
  priv.insn_start = memaddr;
  priv.insn_start = memaddr;
 
 
  if (setjmp (priv.bailout) != 0)
 
    {
 
      /* longjmp may be called while these printing functions are
 
         temporarily replaced with dummy functions.  Restore them
 
         before we leave.
 
 
 
         Admittedly, this save-and-restore operation is somewhat ugly
 
         in that we are exposing the fact that match_insn_m68k
 
         temporarily replaces insn->fprintf_func and
 
         insn->print_address_func.  Perhaps, a real fix is to report a
 
         FETCH_DATA failure with a return value of some sort, without
 
         using setjmp/longjmp.  A better fix may be to teach the m68k
 
         disassembler do its job without temporarily replacing
 
         insn->fprintf_func and insn->print_address_func, but that's a
 
         task for another day.  */
 
      info->fprintf_func = save_printer;
 
      info->print_address_func = save_print_address;
 
 
 
      /* Error return.  */
 
      return -1;
 
    }
 
 
 
  arch_mask = bfd_m68k_mach_to_features (info->mach);
  arch_mask = bfd_m68k_mach_to_features (info->mach);
  if (!arch_mask)
  if (!arch_mask)
    {
    {
      /* First try printing an m680x0 instruction.  Try printing a Coldfire
      /* First try printing an m680x0 instruction.  Try printing a Coldfire
         one if that fails.  */
         one if that fails.  */
      val = m68k_scan_mask (memaddr, info, m68k_mask);
      val = m68k_scan_mask (memaddr, info, m68k_mask);
      if (val)
      if (val == 0)
        return val;
 
 
 
      val = m68k_scan_mask (memaddr, info, mcf_mask);
      val = m68k_scan_mask (memaddr, info, mcf_mask);
      if (val)
 
        return val;
 
    }
    }
  else
  else
    {
    {
      val = m68k_scan_mask (memaddr, info, arch_mask);
      val = m68k_scan_mask (memaddr, info, arch_mask);
      if (val)
 
        return val;
 
    }
    }
 
 
 
  if (val == 0)
  /* Handle undefined instructions.  */
  /* Handle undefined instructions.  */
  info->fprintf_func (info->stream, "0%o", (buffer[0] << 8) + buffer[1]);
  info->fprintf_func (info->stream, "0%o", (buffer[0] << 8) + buffer[1]);
  return 2;
 
 
  return val ? val : 2;
}
}
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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