Back to index

cell-binutils  2.17cvs20070401
Classes | Defines | Functions | Variables
vax-dis.c File Reference
#include <setjmp.h>
#include <string.h>
#include "sysdep.h"
#include "opcode/vax.h"
#include "dis-asm.h"

Go to the source code of this file.

Classes

struct  private

Defines

#define COERCE_SIGNED_CHAR(ch)   ((signed char)(ch))
#define NEXTBYTE(p)
#define COERCE16(x)   ((int) (((x) ^ 0x8000) - 0x8000))
#define NEXTWORD(p)
#define COERCE32(x)   ((int) (((x) ^ 0x80000000) - 0x80000000))
#define NEXTLONG(p)
#define MAXLEN   25
#define FETCH_DATA(info, addr)

Functions

static int fetch_data (struct disassemble_info *info, bfd_byte *addr)
static bfd_boolean parse_disassembler_options (char *options)
static bfd_boolean is_function_entry (struct disassemble_info *info, bfd_vma addr)
static int print_insn_mode (const char *d, int size, unsigned char *p0, bfd_vma addr, disassemble_info *info)
static int print_insn_arg (const char *d, unsigned char *p0, bfd_vma addr, disassemble_info *info)
int print_insn_vax (bfd_vma memaddr, disassemble_info *info)

Variables

static char * reg_names []
static char * entry_mask_bit []
static unsigned int entry_addr_occupied_slots = 0
static unsigned int entry_addr_total_slots = 0
static bfd_vmaentry_addr = NULL

Class Documentation

struct private

Definition at line 35 of file h8500-dis.c.

Class Members
jmp_buf bailout
bfd_vma insn_start
bfd_byte * max_fetched
bfd_byte the_buffer

Define Documentation

#define COERCE16 (   x)    ((int) (((x) ^ 0x8000) - 0x8000))

Definition at line 57 of file vax-dis.c.

#define COERCE32 (   x)    ((int) (((x) ^ 0x80000000) - 0x80000000))

Definition at line 63 of file vax-dis.c.

#define COERCE_SIGNED_CHAR (   ch)    ((signed char)(ch))

Definition at line 49 of file vax-dis.c.

#define FETCH_DATA (   info,
  addr 
)
Value:
((addr) <= ((struct private *)(info->private_data))->max_fetched \
   ? 1 : fetch_data ((info), (addr)))

Definition at line 83 of file vax-dis.c.

#define MAXLEN   25

Definition at line 69 of file vax-dis.c.

#define NEXTBYTE (   p)
Value:
(p += 1, FETCH_DATA (info, p), \
  COERCE_SIGNED_CHAR(p[-1]))

Definition at line 52 of file vax-dis.c.

#define NEXTLONG (   p)
Value:
(p += 4, FETCH_DATA (info, p), \
   (COERCE32 ((((((p[-1] << 8) + p[-2]) << 8) + p[-3]) << 8) + p[-4])))

Definition at line 64 of file vax-dis.c.

#define NEXTWORD (   p)
Value:
(p += 2, FETCH_DATA (info, p), \
   COERCE16 ((p[-1] << 8) + p[-2]))

Definition at line 58 of file vax-dis.c.


Function Documentation

static int fetch_data ( struct disassemble_info info,
bfd_byte addr 
) [static]

Definition at line 88 of file vax-dis.c.

{
  int status;
  struct private *priv = (struct private *) info->private_data;
  bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);

  status = (*info->read_memory_func) (start,
                                  priv->max_fetched,
                                  addr - priv->max_fetched,
                                  info);
  if (status != 0)
    {
      (*info->memory_error_func) (status, start, info);
      longjmp (priv->bailout, 1);
    }
  else
    priv->max_fetched = addr;

  return 1;
}
static bfd_boolean is_function_entry ( struct disassemble_info info,
bfd_vma  addr 
) [static]

Definition at line 179 of file vax-dis.c.

{
  unsigned int i;

  /* Check if there's a BSF_FUNCTION symbol at our address.  */
  if (info->symbols
      && info->symbols[0]
      && (info->symbols[0]->flags & BSF_FUNCTION)
      && addr == bfd_asymbol_value (info->symbols[0]))
    return TRUE;

  /* Check for forced function entry address.  */
  for (i = entry_addr_occupied_slots; i--;)
    if (entry_addr[i] == addr)
      return TRUE;

  return FALSE;
}

Here is the caller graph for this function:

static bfd_boolean parse_disassembler_options ( char *  options) [static]

Definition at line 119 of file vax-dis.c.

{
  const char * entry_switch = "entry:";

  while ((options = strstr (options, entry_switch)))
    {
      options += strlen (entry_switch);

      /* The greater-than part of the test below is paranoia.  */
      if (entry_addr_occupied_slots >= entry_addr_total_slots)
       {
         /* A guesstimate of the number of entries we will have to create.  */
         entry_addr_total_slots +=
           strlen (options) / (strlen (entry_switch) + 5);
         
         entry_addr = realloc (entry_addr, sizeof (bfd_vma)
                            * entry_addr_total_slots);
       }

      if (entry_addr == NULL)
       return FALSE;
         
      entry_addr[entry_addr_occupied_slots] = bfd_scan_vma (options, NULL, 0);
      entry_addr_occupied_slots ++;
    }

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int print_insn_arg ( const char *  d,
unsigned char *  p0,
bfd_vma  addr,
disassemble_info info 
) [static]

Definition at line 314 of file vax-dis.c.

{
  int arg_len;

  /* Check validity of addressing length.  */
  switch (d[1])
    {
    case 'b' : arg_len = 1; break;
    case 'd' : arg_len = 8; break;
    case 'f' : arg_len = 4; break;
    case 'g' : arg_len = 8; break;
    case 'h' : arg_len = 16;       break;
    case 'l' : arg_len = 4; break;
    case 'o' : arg_len = 16;       break;
    case 'w' : arg_len = 2; break;
    case 'q' : arg_len = 8; break;
    default  : abort ();
    }

  /* Branches have no mode byte.  */
  if (d[0] == 'b')
    {
      unsigned char *p = p0;

      if (arg_len == 1)
       (*info->print_address_func) (addr + 1 + NEXTBYTE (p), info);
      else
       (*info->print_address_func) (addr + 2 + NEXTWORD (p), info);

      return p - p0;
    }

  return print_insn_mode (d, arg_len, p0, addr, info);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int print_insn_mode ( const char *  d,
int  size,
unsigned char *  p0,
bfd_vma  addr,
disassemble_info info 
) [static]

Definition at line 199 of file vax-dis.c.

{
  unsigned char *p = p0;
  unsigned char mode, reg;

  /* Fetch and interpret mode byte.  */
  mode = (unsigned char) NEXTBYTE (p);
  reg = mode & 0xF;
  switch (mode & 0xF0)
    {
    case 0x00:
    case 0x10:
    case 0x20:
    case 0x30: /* Literal mode                   $number.  */
      if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
       (*info->fprintf_func) (info->stream, "$0x%x [%c-float]", mode, d[1]);
      else
        (*info->fprintf_func) (info->stream, "$0x%x", mode);
      break;
    case 0x40: /* Index:                  base-addr[Rn] */
      p += print_insn_mode (d, size, p0 + 1, addr + 1, info);
      (*info->fprintf_func) (info->stream, "[%s]", reg_names[reg]);
      break;
    case 0x50: /* Register:               Rn */
      (*info->fprintf_func) (info->stream, "%s", reg_names[reg]);
      break;
    case 0x60: /* Register deferred:             (Rn) */
      (*info->fprintf_func) (info->stream, "(%s)", reg_names[reg]);
      break;
    case 0x70: /* Autodecrement:          -(Rn) */
      (*info->fprintf_func) (info->stream, "-(%s)", reg_names[reg]);
      break;
    case 0x80: /* Autoincrement:          (Rn)+ */
      if (reg == 0xF)
       {      /* Immediate?  */
         int i;

         FETCH_DATA (info, p + size);
         (*info->fprintf_func) (info->stream, "$0x");
         if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
           {
             int float_word;

             float_word = p[0] | (p[1] << 8);
             if ((d[1] == 'd' || d[1] == 'f')
                && (float_word & 0xff80) == 0x8000)
              {
                (*info->fprintf_func) (info->stream, "[invalid %c-float]",
                                    d[1]);
              }
             else
              {
                 for (i = 0; i < size; i++)
                  (*info->fprintf_func) (info->stream, "%02x",
                                         p[size - i - 1]);
                 (*info->fprintf_func) (info->stream, " [%c-float]", d[1]);
              }
           }
         else
           {
             for (i = 0; i < size; i++)
               (*info->fprintf_func) (info->stream, "%02x", p[size - i - 1]);
           }
         p += size;
       }
      else
       (*info->fprintf_func) (info->stream, "(%s)+", reg_names[reg]);
      break;
    case 0x90: /* Autoincrement deferred: @(Rn)+ */
      if (reg == 0xF)
       (*info->fprintf_func) (info->stream, "*0x%x", NEXTLONG (p));
      else
       (*info->fprintf_func) (info->stream, "@(%s)+", reg_names[reg]);
      break;
    case 0xB0: /* Displacement byte deferred:    *displ(Rn).  */
      (*info->fprintf_func) (info->stream, "*");
    case 0xA0: /* Displacement byte:             displ(Rn).  */
      if (reg == 0xF)
       (*info->print_address_func) (addr + 2 + NEXTBYTE (p), info);
      else
       (*info->fprintf_func) (info->stream, "0x%x(%s)", NEXTBYTE (p),
                            reg_names[reg]);
      break;
    case 0xD0: /* Displacement word deferred:    *displ(Rn).  */
      (*info->fprintf_func) (info->stream, "*");
    case 0xC0: /* Displacement word:             displ(Rn).  */
      if (reg == 0xF)
       (*info->print_address_func) (addr + 3 + NEXTWORD (p), info);
      else
       (*info->fprintf_func) (info->stream, "0x%x(%s)", NEXTWORD (p),
                            reg_names[reg]);
      break;
    case 0xF0: /* Displacement long deferred:    *displ(Rn).  */
      (*info->fprintf_func) (info->stream, "*");
    case 0xE0: /* Displacement long:             displ(Rn).  */
      if (reg == 0xF)
       (*info->print_address_func) (addr + 5 + NEXTLONG (p), info);
      else
       (*info->fprintf_func) (info->stream, "0x%x(%s)", NEXTLONG (p),
                            reg_names[reg]);
      break;
    }

  return p - p0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int print_insn_vax ( bfd_vma  memaddr,
disassemble_info info 
)

Definition at line 356 of file vax-dis.c.

{
  static bfd_boolean parsed_disassembler_options = FALSE;
  const struct vot *votp;
  const char *argp;
  unsigned char *arg;
  struct private priv;
  bfd_byte *buffer = priv.the_buffer;

  info->private_data = & priv;
  priv.max_fetched = priv.the_buffer;
  priv.insn_start = memaddr;

  if (! parsed_disassembler_options
      && info->disassembler_options != NULL)
    {
      parse_disassembler_options (info->disassembler_options);

      /* To avoid repeated parsing of these options.  */
      parsed_disassembler_options = TRUE;
    }

  if (setjmp (priv.bailout) != 0)
    /* Error return.  */
    return -1;

  argp = NULL;
  /* Check if the info buffer has more than one byte left since
     the last opcode might be a single byte with no argument data.  */
  if (info->buffer_length - (memaddr - info->buffer_vma) > 1)
    {
      FETCH_DATA (info, buffer + 2);
    }
  else
    {
      FETCH_DATA (info, buffer + 1);
      buffer[1] = 0;
    }

  /* Decode function entry mask.  */
  if (is_function_entry (info, memaddr))
    {
      int i = 0;
      int register_mask = buffer[1] << 8 | buffer[0];

      (*info->fprintf_func) (info->stream, ".word 0x%04x # Entry mask: <",
                          register_mask);

      for (i = 15; i >= 0; i--)
       if (register_mask & (1 << i))
          (*info->fprintf_func) (info->stream, " %s", entry_mask_bit[i]);

      (*info->fprintf_func) (info->stream, " >");

      return 2;
    }

  for (votp = &votstrs[0]; votp->name[0]; votp++)
    {
      vax_opcodeT opcode = votp->detail.code;

      /* 2 byte codes match 2 buffer pos. */
      if ((bfd_byte) opcode == buffer[0]
         && (opcode >> 8 == 0 || opcode >> 8 == buffer[1]))
       {
         argp = votp->detail.args;
         break;
       }
    }
  if (argp == NULL)
    {
      /* Handle undefined instructions. */
      (*info->fprintf_func) (info->stream, ".word 0x%x",
                          (buffer[0] << 8) + buffer[1]);
      return 2;
    }

  /* Point at first byte of argument data, and at descriptor for first
     argument.  */
  arg = buffer + ((votp->detail.code >> 8) ? 2 : 1);

  /* Make sure we have it in mem */
  FETCH_DATA (info, arg);

  (*info->fprintf_func) (info->stream, "%s", votp->name);
  if (*argp)
    (*info->fprintf_func) (info->stream, " ");

  while (*argp)
    {
      arg += print_insn_arg (argp, arg, memaddr + arg - buffer, info);
      argp += 2;
      if (*argp)
       (*info->fprintf_func) (info->stream, ",");
    }

  return arg - buffer;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

bfd_vma* entry_addr = NULL [static]

Definition at line 112 of file vax-dis.c.

Definition at line 110 of file vax-dis.c.

Definition at line 111 of file vax-dis.c.

char* entry_mask_bit[] [static]
Initial value:
{
  
  "~r0~", "~r1~",
  
  "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
  
  "~ap~", "~fp~",
  
  "IntOvfl", "DecOvfl",
}

Definition at line 34 of file vax-dis.c.

char* reg_names[] [static]
Initial value:
{
  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
  "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc"
}

Definition at line 27 of file vax-dis.c.