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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [vax-tdep.c] - Diff between revs 105 and 1765

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

Rev 105 Rev 1765
/* Print VAX instructions for GDB, the GNU debugger.
/* Print VAX instructions for GDB, the GNU debugger.
   Copyright 1986, 1989, 1991, 1992, 1996 Free Software Foundation, Inc.
   Copyright 1986, 1989, 1991, 1992, 1996 Free Software Foundation, Inc.
 
 
   This file is part of GDB.
   This file is part of GDB.
 
 
   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,
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */
   Boston, MA 02111-1307, USA.  */
 
 
#include "defs.h"
#include "defs.h"
#include "symtab.h"
#include "symtab.h"
#include "opcode/vax.h"
#include "opcode/vax.h"
 
 
/* Vax instructions are never longer than this.  */
/* Vax instructions are never longer than this.  */
#define MAXLEN 62
#define MAXLEN 62
 
 
/* Number of elements in the opcode table.  */
/* Number of elements in the opcode table.  */
#define NOPCODES (sizeof votstrs / sizeof votstrs[0])
#define NOPCODES (sizeof votstrs / sizeof votstrs[0])
 
 
static unsigned char *print_insn_arg ();
static unsigned char *print_insn_arg ();


/* Advance PC across any function entry prologue instructions
/* Advance PC across any function entry prologue instructions
   to reach some "real" code.  */
   to reach some "real" code.  */
 
 
CORE_ADDR
CORE_ADDR
vax_skip_prologue (pc)
vax_skip_prologue (pc)
     CORE_ADDR pc;
     CORE_ADDR pc;
{
{
  register int op = (unsigned char) read_memory_integer (pc, 1);
  register int op = (unsigned char) read_memory_integer (pc, 1);
  if (op == 0x11)
  if (op == 0x11)
    pc += 2;                    /* skip brb */
    pc += 2;                    /* skip brb */
  if (op == 0x31)
  if (op == 0x31)
    pc += 3;                    /* skip brw */
    pc += 3;                    /* skip brw */
  if (op == 0xC2
  if (op == 0xC2
      && ((unsigned char) read_memory_integer (pc + 2, 1)) == 0x5E)
      && ((unsigned char) read_memory_integer (pc + 2, 1)) == 0x5E)
    pc += 3;                    /* skip subl2 */
    pc += 3;                    /* skip subl2 */
  if (op == 0x9E
  if (op == 0x9E
      && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xAE
      && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xAE
      && ((unsigned char) read_memory_integer (pc + 3, 1)) == 0x5E)
      && ((unsigned char) read_memory_integer (pc + 3, 1)) == 0x5E)
    pc += 4;                    /* skip movab */
    pc += 4;                    /* skip movab */
  if (op == 0x9E
  if (op == 0x9E
      && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xCE
      && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xCE
      && ((unsigned char) read_memory_integer (pc + 4, 1)) == 0x5E)
      && ((unsigned char) read_memory_integer (pc + 4, 1)) == 0x5E)
    pc += 5;                    /* skip movab */
    pc += 5;                    /* skip movab */
  if (op == 0x9E
  if (op == 0x9E
      && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xEE
      && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xEE
      && ((unsigned char) read_memory_integer (pc + 6, 1)) == 0x5E)
      && ((unsigned char) read_memory_integer (pc + 6, 1)) == 0x5E)
    pc += 7;                    /* skip movab */
    pc += 7;                    /* skip movab */
  return pc;
  return pc;
}
}
 
 
/* Return number of args passed to a frame.
/* Return number of args passed to a frame.
   Can return -1, meaning no way to tell.  */
   Can return -1, meaning no way to tell.  */
 
 
int
int
vax_frame_num_args (fi)
vax_frame_num_args (fi)
     struct frame_info *fi;
     struct frame_info *fi;
{
{
  return (0xff & read_memory_integer (FRAME_ARGS_ADDRESS (fi), 1));
  return (0xff & read_memory_integer (FRAME_ARGS_ADDRESS (fi), 1));
}
}
 
 
 
 
 
 
/* Print the vax instruction at address MEMADDR in debugged memory,
/* Print the vax instruction at address MEMADDR in debugged memory,
   from disassembler info INFO.
   from disassembler info INFO.
   Returns length of the instruction, in bytes.  */
   Returns length of the instruction, in bytes.  */
 
 
static int
static int
vax_print_insn (memaddr, info)
vax_print_insn (memaddr, info)
     CORE_ADDR memaddr;
     CORE_ADDR memaddr;
     disassemble_info *info;
     disassemble_info *info;
{
{
  unsigned char buffer[MAXLEN];
  unsigned char buffer[MAXLEN];
  register int i;
  register int i;
  register unsigned char *p;
  register unsigned char *p;
  register char *d;
  register char *d;
 
 
  int status = (*info->read_memory_func) (memaddr, buffer, MAXLEN, info);
  int status = (*info->read_memory_func) (memaddr, buffer, MAXLEN, info);
  if (status != 0)
  if (status != 0)
    {
    {
      (*info->memory_error_func) (status, memaddr, info);
      (*info->memory_error_func) (status, memaddr, info);
      return -1;
      return -1;
    }
    }
 
 
  for (i = 0; i < NOPCODES; i++)
  for (i = 0; i < NOPCODES; i++)
    if (votstrs[i].detail.code == buffer[0]
    if (votstrs[i].detail.code == buffer[0]
        || votstrs[i].detail.code == *(unsigned short *) buffer)
        || votstrs[i].detail.code == *(unsigned short *) buffer)
      break;
      break;
 
 
  /* Handle undefined instructions.  */
  /* Handle undefined instructions.  */
  if (i == NOPCODES)
  if (i == NOPCODES)
    {
    {
      (*info->fprintf_func) (info->stream, "0%o", buffer[0]);
      (*info->fprintf_func) (info->stream, "0%o", buffer[0]);
      return 1;
      return 1;
    }
    }
 
 
  (*info->fprintf_func) (info->stream, "%s", votstrs[i].name);
  (*info->fprintf_func) (info->stream, "%s", votstrs[i].name);
 
 
  /* Point at first byte of argument data,
  /* Point at first byte of argument data,
     and at descriptor for first argument.  */
     and at descriptor for first argument.  */
  p = buffer + 1 + (votstrs[i].detail.code >= 0x100);
  p = buffer + 1 + (votstrs[i].detail.code >= 0x100);
  d = votstrs[i].detail.args;
  d = votstrs[i].detail.args;
 
 
  if (*d)
  if (*d)
    (*info->fprintf_func) (info->stream, " ");
    (*info->fprintf_func) (info->stream, " ");
 
 
  while (*d)
  while (*d)
    {
    {
      p = print_insn_arg (d, p, memaddr + (p - buffer), info);
      p = print_insn_arg (d, p, memaddr + (p - buffer), info);
      d += 2;
      d += 2;
      if (*d)
      if (*d)
        (*info->fprintf_func) (info->stream, ",");
        (*info->fprintf_func) (info->stream, ",");
    }
    }
  return p - buffer;
  return p - buffer;
}
}
 
 
static unsigned char *
static unsigned char *
print_insn_arg (d, p, addr, info)
print_insn_arg (d, p, addr, info)
     char *d;
     char *d;
     register char *p;
     register char *p;
     CORE_ADDR addr;
     CORE_ADDR addr;
     disassemble_info *info;
     disassemble_info *info;
{
{
  register int regnum = *p & 0xf;
  register int regnum = *p & 0xf;
  float floatlitbuf;
  float floatlitbuf;
 
 
  if (*d == 'b')
  if (*d == 'b')
    {
    {
      if (d[1] == 'b')
      if (d[1] == 'b')
        (*info->fprintf_func) (info->stream, "0x%x", addr + *p++ + 1);
        (*info->fprintf_func) (info->stream, "0x%x", addr + *p++ + 1);
      else
      else
        {
        {
          (*info->fprintf_func) (info->stream, "0x%x", addr + *(short *) p + 2);
          (*info->fprintf_func) (info->stream, "0x%x", addr + *(short *) p + 2);
          p += 2;
          p += 2;
        }
        }
    }
    }
  else
  else
    switch ((*p++ >> 4) & 0xf)
    switch ((*p++ >> 4) & 0xf)
      {
      {
      case 0:
      case 0:
      case 1:
      case 1:
      case 2:
      case 2:
      case 3:                   /* Literal mode */
      case 3:                   /* Literal mode */
        if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
        if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
          {
          {
            *(int *) &floatlitbuf = 0x4000 + ((p[-1] & 0x3f) << 4);
            *(int *) &floatlitbuf = 0x4000 + ((p[-1] & 0x3f) << 4);
            (*info->fprintf_func) (info->stream, "$%f", floatlitbuf);
            (*info->fprintf_func) (info->stream, "$%f", floatlitbuf);
          }
          }
        else
        else
          (*info->fprintf_func) (info->stream, "$%d", p[-1] & 0x3f);
          (*info->fprintf_func) (info->stream, "$%d", p[-1] & 0x3f);
        break;
        break;
 
 
      case 4:                   /* Indexed */
      case 4:                   /* Indexed */
        p = (char *) print_insn_arg (d, p, addr + 1, info);
        p = (char *) print_insn_arg (d, p, addr + 1, info);
        (*info->fprintf_func) (info->stream, "[%s]", REGISTER_NAME (regnum));
        (*info->fprintf_func) (info->stream, "[%s]", REGISTER_NAME (regnum));
        break;
        break;
 
 
      case 5:                   /* Register */
      case 5:                   /* Register */
        (*info->fprintf_func) (info->stream, REGISTER_NAME (regnum));
        (*info->fprintf_func) (info->stream, REGISTER_NAME (regnum));
        break;
        break;
 
 
      case 7:                   /* Autodecrement */
      case 7:                   /* Autodecrement */
        (*info->fprintf_func) (info->stream, "-");
        (*info->fprintf_func) (info->stream, "-");
      case 6:                   /* Register deferred */
      case 6:                   /* Register deferred */
        (*info->fprintf_func) (info->stream, "(%s)", REGISTER_NAME (regnum));
        (*info->fprintf_func) (info->stream, "(%s)", REGISTER_NAME (regnum));
        break;
        break;
 
 
      case 9:                   /* Autoincrement deferred */
      case 9:                   /* Autoincrement deferred */
        (*info->fprintf_func) (info->stream, "@");
        (*info->fprintf_func) (info->stream, "@");
        if (regnum == PC_REGNUM)
        if (regnum == PC_REGNUM)
          {
          {
            (*info->fprintf_func) (info->stream, "#");
            (*info->fprintf_func) (info->stream, "#");
            info->target = *(long *) p;
            info->target = *(long *) p;
            (*info->print_address_func) (info->target, info);
            (*info->print_address_func) (info->target, info);
            p += 4;
            p += 4;
            break;
            break;
          }
          }
      case 8:                   /* Autoincrement */
      case 8:                   /* Autoincrement */
        if (regnum == PC_REGNUM)
        if (regnum == PC_REGNUM)
          {
          {
            (*info->fprintf_func) (info->stream, "#");
            (*info->fprintf_func) (info->stream, "#");
            switch (d[1])
            switch (d[1])
              {
              {
              case 'b':
              case 'b':
                (*info->fprintf_func) (info->stream, "%d", *p++);
                (*info->fprintf_func) (info->stream, "%d", *p++);
                break;
                break;
 
 
              case 'w':
              case 'w':
                (*info->fprintf_func) (info->stream, "%d", *(short *) p);
                (*info->fprintf_func) (info->stream, "%d", *(short *) p);
                p += 2;
                p += 2;
                break;
                break;
 
 
              case 'l':
              case 'l':
                (*info->fprintf_func) (info->stream, "%d", *(long *) p);
                (*info->fprintf_func) (info->stream, "%d", *(long *) p);
                p += 4;
                p += 4;
                break;
                break;
 
 
              case 'q':
              case 'q':
                (*info->fprintf_func) (info->stream, "0x%x%08x",
                (*info->fprintf_func) (info->stream, "0x%x%08x",
                                       ((long *) p)[1], ((long *) p)[0]);
                                       ((long *) p)[1], ((long *) p)[0]);
                p += 8;
                p += 8;
                break;
                break;
 
 
              case 'o':
              case 'o':
                (*info->fprintf_func) (info->stream, "0x%x%08x%08x%08x",
                (*info->fprintf_func) (info->stream, "0x%x%08x%08x%08x",
                                       ((long *) p)[3], ((long *) p)[2],
                                       ((long *) p)[3], ((long *) p)[2],
                                       ((long *) p)[1], ((long *) p)[0]);
                                       ((long *) p)[1], ((long *) p)[0]);
                p += 16;
                p += 16;
                break;
                break;
 
 
              case 'f':
              case 'f':
                if (INVALID_FLOAT (p, 4))
                if (INVALID_FLOAT (p, 4))
                  (*info->fprintf_func) (info->stream,
                  (*info->fprintf_func) (info->stream,
                                         "<<invalid float 0x%x>>",
                                         "<<invalid float 0x%x>>",
                                         *(int *) p);
                                         *(int *) p);
                else
                else
                  (*info->fprintf_func) (info->stream, "%f", *(float *) p);
                  (*info->fprintf_func) (info->stream, "%f", *(float *) p);
                p += 4;
                p += 4;
                break;
                break;
 
 
              case 'd':
              case 'd':
                if (INVALID_FLOAT (p, 8))
                if (INVALID_FLOAT (p, 8))
                  (*info->fprintf_func) (info->stream,
                  (*info->fprintf_func) (info->stream,
                                         "<<invalid float 0x%x%08x>>",
                                         "<<invalid float 0x%x%08x>>",
                                         ((long *) p)[1], ((long *) p)[0]);
                                         ((long *) p)[1], ((long *) p)[0]);
                else
                else
                  (*info->fprintf_func) (info->stream, "%f", *(double *) p);
                  (*info->fprintf_func) (info->stream, "%f", *(double *) p);
                p += 8;
                p += 8;
                break;
                break;
 
 
              case 'g':
              case 'g':
                (*info->fprintf_func) (info->stream, "g-float");
                (*info->fprintf_func) (info->stream, "g-float");
                p += 8;
                p += 8;
                break;
                break;
 
 
              case 'h':
              case 'h':
                (*info->fprintf_func) (info->stream, "h-float");
                (*info->fprintf_func) (info->stream, "h-float");
                p += 16;
                p += 16;
                break;
                break;
 
 
              }
              }
          }
          }
        else
        else
          (*info->fprintf_func) (info->stream, "(%s)+", REGISTER_NAME (regnum));
          (*info->fprintf_func) (info->stream, "(%s)+", REGISTER_NAME (regnum));
        break;
        break;
 
 
      case 11:                  /* Byte displacement deferred */
      case 11:                  /* Byte displacement deferred */
        (*info->fprintf_func) (info->stream, "@");
        (*info->fprintf_func) (info->stream, "@");
      case 10:                  /* Byte displacement */
      case 10:                  /* Byte displacement */
        if (regnum == PC_REGNUM)
        if (regnum == PC_REGNUM)
          {
          {
            info->target = addr + *p + 2;
            info->target = addr + *p + 2;
            (*info->print_address_func) (info->target, info);
            (*info->print_address_func) (info->target, info);
          }
          }
        else
        else
          (*info->fprintf_func) (info->stream, "%d(%s)", *p, REGISTER_NAME (regnum));
          (*info->fprintf_func) (info->stream, "%d(%s)", *p, REGISTER_NAME (regnum));
        p += 1;
        p += 1;
        break;
        break;
 
 
      case 13:                  /* Word displacement deferred */
      case 13:                  /* Word displacement deferred */
        (*info->fprintf_func) (info->stream, "@");
        (*info->fprintf_func) (info->stream, "@");
      case 12:                  /* Word displacement */
      case 12:                  /* Word displacement */
        if (regnum == PC_REGNUM)
        if (regnum == PC_REGNUM)
          {
          {
            info->target = addr + *(short *) p + 3;
            info->target = addr + *(short *) p + 3;
            (*info->print_address_func) (info->target, info);
            (*info->print_address_func) (info->target, info);
          }
          }
        else
        else
          (*info->fprintf_func) (info->stream, "%d(%s)",
          (*info->fprintf_func) (info->stream, "%d(%s)",
                                 *(short *) p, REGISTER_NAME (regnum));
                                 *(short *) p, REGISTER_NAME (regnum));
        p += 2;
        p += 2;
        break;
        break;
 
 
      case 15:                  /* Long displacement deferred */
      case 15:                  /* Long displacement deferred */
        (*info->fprintf_func) (info->stream, "@");
        (*info->fprintf_func) (info->stream, "@");
      case 14:                  /* Long displacement */
      case 14:                  /* Long displacement */
        if (regnum == PC_REGNUM)
        if (regnum == PC_REGNUM)
          {
          {
            info->target = addr + *(short *) p + 5;
            info->target = addr + *(short *) p + 5;
            (*info->print_address_func) (info->target, info);
            (*info->print_address_func) (info->target, info);
          }
          }
        else
        else
          (*info->fprintf_func) (info->stream, "%d(%s)",
          (*info->fprintf_func) (info->stream, "%d(%s)",
                                 *(long *) p, REGISTER_NAME (regnum));
                                 *(long *) p, REGISTER_NAME (regnum));
        p += 4;
        p += 4;
      }
      }
 
 
  return (unsigned char *) p;
  return (unsigned char *) p;
}
}
 
 
void
void
_initialize_vax_tdep ()
_initialize_vax_tdep ()
{
{
  tm_print_insn = vax_print_insn;
  tm_print_insn = vax_print_insn;
}
}
 
 

powered by: WebSVN 2.1.0

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