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

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [gdb/] [ns32k-tdep.c] - Diff between revs 579 and 1765

Only display areas with differences | Details | Blame | View Log

Rev 579 Rev 1765
/* Print NS 32000 instructions for GDB, the GNU debugger.
/* Print NS 32000 instructions for GDB, the GNU debugger.
   Copyright 1986, 1988, 1991, 1992, 1994, 1995, 1998, 1999, 2000, 2001
   Copyright 1986, 1988, 1991, 1992, 1994, 1995, 1998, 1999, 2000, 2001
   Free Software Foundation, Inc.
   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 "frame.h"
#include "frame.h"
#include "gdbcore.h"
#include "gdbcore.h"
 
 
static int sign_extend (int value, int bits);
static int sign_extend (int value, int bits);
 
 
void
void
_initialize_ns32k_tdep (void)
_initialize_ns32k_tdep (void)
{
{
  tm_print_insn = print_insn_ns32k;
  tm_print_insn = print_insn_ns32k;
}
}
 
 
/* 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.  */
 
 
/* OBSOLETE CORE_ADDR */
/* OBSOLETE CORE_ADDR */
/* OBSOLETE merlin_skip_prologue (CORE_ADDR pc) */
/* OBSOLETE merlin_skip_prologue (CORE_ADDR pc) */
/* OBSOLETE { */
/* OBSOLETE { */
/* OBSOLETE   register int op = read_memory_integer (pc, 1); */
/* OBSOLETE   register int op = read_memory_integer (pc, 1); */
/* OBSOLETE   if (op == 0x82) */
/* OBSOLETE   if (op == 0x82) */
/* OBSOLETE     { */
/* OBSOLETE     { */
/* OBSOLETE       op = read_memory_integer (pc + 2, 1); */
/* OBSOLETE       op = read_memory_integer (pc + 2, 1); */
/* OBSOLETE       if ((op & 0x80) == 0) */
/* OBSOLETE       if ((op & 0x80) == 0) */
/* OBSOLETE     pc += 3; */
/* OBSOLETE     pc += 3; */
/* OBSOLETE       else if ((op & 0xc0) == 0x80) */
/* OBSOLETE       else if ((op & 0xc0) == 0x80) */
/* OBSOLETE     pc += 4; */
/* OBSOLETE     pc += 4; */
/* OBSOLETE       else */
/* OBSOLETE       else */
/* OBSOLETE     pc += 6; */
/* OBSOLETE     pc += 6; */
/* OBSOLETE     } */
/* OBSOLETE     } */
/* OBSOLETE   return pc; */
/* OBSOLETE   return pc; */
/* OBSOLETE } */
/* OBSOLETE } */
 
 
CORE_ADDR
CORE_ADDR
umax_skip_prologue (CORE_ADDR pc)
umax_skip_prologue (CORE_ADDR pc)
{
{
  register unsigned char op = read_memory_integer (pc, 1);
  register unsigned char op = read_memory_integer (pc, 1);
  if (op == 0x82)
  if (op == 0x82)
    {
    {
      op = read_memory_integer (pc + 2, 1);
      op = read_memory_integer (pc + 2, 1);
      if ((op & 0x80) == 0)
      if ((op & 0x80) == 0)
        pc += 3;
        pc += 3;
      else if ((op & 0xc0) == 0x80)
      else if ((op & 0xc0) == 0x80)
        pc += 4;
        pc += 4;
      else
      else
        pc += 6;
        pc += 6;
    }
    }
  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.  */
 
 
/* OBSOLETE int */
/* OBSOLETE int */
/* OBSOLETE merlin_frame_num_args (struct frame_info *fi) */
/* OBSOLETE merlin_frame_num_args (struct frame_info *fi) */
/* OBSOLETE { */
/* OBSOLETE { */
/* OBSOLETE   int numargs; */
/* OBSOLETE   int numargs; */
/* OBSOLETE   CORE_ADDR pc; */
/* OBSOLETE   CORE_ADDR pc; */
/* OBSOLETE   int insn; */
/* OBSOLETE   int insn; */
/* OBSOLETE   int addr_mode; */
/* OBSOLETE   int addr_mode; */
/* OBSOLETE   int width; */
/* OBSOLETE   int width; */
/* OBSOLETE  */
/* OBSOLETE  */
/* OBSOLETE   pc = FRAME_SAVED_PC (fi); */
/* OBSOLETE   pc = FRAME_SAVED_PC (fi); */
/* OBSOLETE   insn = read_memory_integer (pc, 2); */
/* OBSOLETE   insn = read_memory_integer (pc, 2); */
/* OBSOLETE   addr_mode = (insn >> 11) & 0x1f; */
/* OBSOLETE   addr_mode = (insn >> 11) & 0x1f; */
/* OBSOLETE   insn = insn & 0x7ff; */
/* OBSOLETE   insn = insn & 0x7ff; */
/* OBSOLETE   if ((insn & 0x7fc) == 0x57c */
/* OBSOLETE   if ((insn & 0x7fc) == 0x57c */
/* OBSOLETE       && addr_mode == 0x14)  *//* immediate */
/* OBSOLETE       && addr_mode == 0x14)  *//* immediate */
/* OBSOLETE     { */
/* OBSOLETE     { */
/* OBSOLETE       if (insn == 0x57c)     *//* adjspb */
/* OBSOLETE       if (insn == 0x57c)     *//* adjspb */
/* OBSOLETE     width = 1; */
/* OBSOLETE     width = 1; */
/* OBSOLETE       else if (insn == 0x57d)        *//* adjspw */
/* OBSOLETE       else if (insn == 0x57d)        *//* adjspw */
/* OBSOLETE     width = 2; */
/* OBSOLETE     width = 2; */
/* OBSOLETE       else if (insn == 0x57f)        *//* adjspd */
/* OBSOLETE       else if (insn == 0x57f)        *//* adjspd */
/* OBSOLETE     width = 4; */
/* OBSOLETE     width = 4; */
/* OBSOLETE       else */
/* OBSOLETE       else */
/* OBSOLETE     internal_error (__FILE__, __LINE__, "bad else"); */
/* OBSOLETE     internal_error (__FILE__, __LINE__, "bad else"); */
/* OBSOLETE       numargs = read_memory_integer (pc + 2, width); */
/* OBSOLETE       numargs = read_memory_integer (pc + 2, width); */
/* OBSOLETE       if (width > 1) */
/* OBSOLETE       if (width > 1) */
/* OBSOLETE     flip_bytes (&numargs, width); */
/* OBSOLETE     flip_bytes (&numargs, width); */
/* OBSOLETE       numargs = -sign_extend (numargs, width * 8) / 4; */
/* OBSOLETE       numargs = -sign_extend (numargs, width * 8) / 4; */
/* OBSOLETE     } */
/* OBSOLETE     } */
/* OBSOLETE   else */
/* OBSOLETE   else */
/* OBSOLETE     numargs = -1; */
/* OBSOLETE     numargs = -1; */
/* OBSOLETE   return numargs; */
/* OBSOLETE   return numargs; */
/* OBSOLETE } */
/* OBSOLETE } */
 
 
/* 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.
   Encore's C compiler often reuses same area on stack for args,
   Encore's C compiler often reuses same area on stack for args,
   so this will often not work properly.  If the arg names
   so this will often not work properly.  If the arg names
   are known, it's likely most of them will be printed. */
   are known, it's likely most of them will be printed. */
 
 
int
int
umax_frame_num_args (struct frame_info *fi)
umax_frame_num_args (struct frame_info *fi)
{
{
  int numargs;
  int numargs;
  CORE_ADDR pc;
  CORE_ADDR pc;
  CORE_ADDR enter_addr;
  CORE_ADDR enter_addr;
  unsigned int insn;
  unsigned int insn;
  unsigned int addr_mode;
  unsigned int addr_mode;
  int width;
  int width;
 
 
  numargs = -1;
  numargs = -1;
  enter_addr = ns32k_get_enter_addr ((fi)->pc);
  enter_addr = ns32k_get_enter_addr ((fi)->pc);
  if (enter_addr > 0)
  if (enter_addr > 0)
    {
    {
      pc = ((enter_addr == 1)
      pc = ((enter_addr == 1)
            ? SAVED_PC_AFTER_CALL (fi)
            ? SAVED_PC_AFTER_CALL (fi)
            : FRAME_SAVED_PC (fi));
            : FRAME_SAVED_PC (fi));
      insn = read_memory_integer (pc, 2);
      insn = read_memory_integer (pc, 2);
      addr_mode = (insn >> 11) & 0x1f;
      addr_mode = (insn >> 11) & 0x1f;
      insn = insn & 0x7ff;
      insn = insn & 0x7ff;
      if ((insn & 0x7fc) == 0x57c
      if ((insn & 0x7fc) == 0x57c
          && addr_mode == 0x14) /* immediate */
          && addr_mode == 0x14) /* immediate */
        {
        {
          if (insn == 0x57c)    /* adjspb */
          if (insn == 0x57c)    /* adjspb */
            width = 1;
            width = 1;
          else if (insn == 0x57d)       /* adjspw */
          else if (insn == 0x57d)       /* adjspw */
            width = 2;
            width = 2;
          else if (insn == 0x57f)       /* adjspd */
          else if (insn == 0x57f)       /* adjspd */
            width = 4;
            width = 4;
          else
          else
            internal_error (__FILE__, __LINE__, "bad else");
            internal_error (__FILE__, __LINE__, "bad else");
          numargs = read_memory_integer (pc + 2, width);
          numargs = read_memory_integer (pc + 2, width);
          if (width > 1)
          if (width > 1)
            flip_bytes (&numargs, width);
            flip_bytes (&numargs, width);
          numargs = -sign_extend (numargs, width * 8) / 4;
          numargs = -sign_extend (numargs, width * 8) / 4;
        }
        }
    }
    }
  return numargs;
  return numargs;
}
}
 
 
static int
static int
sign_extend (int value, int bits)
sign_extend (int value, int bits)
{
{
  value = value & ((1 << bits) - 1);
  value = value & ((1 << bits) - 1);
  return (value & (1 << (bits - 1))
  return (value & (1 << (bits - 1))
          ? value | (~((1 << bits) - 1))
          ? value | (~((1 << bits) - 1))
          : value);
          : value);
}
}
 
 
void
void
flip_bytes (void *p, int count)
flip_bytes (void *p, int count)
{
{
  char tmp;
  char tmp;
  char *ptr = 0;
  char *ptr = 0;
 
 
  while (count > 0)
  while (count > 0)
    {
    {
      tmp = *ptr;
      tmp = *ptr;
      ptr[0] = ptr[count - 1];
      ptr[0] = ptr[count - 1];
      ptr[count - 1] = tmp;
      ptr[count - 1] = tmp;
      ptr++;
      ptr++;
      count -= 2;
      count -= 2;
    }
    }
}
}
 
 
/* Return the number of locals in the current frame given a pc
/* Return the number of locals in the current frame given a pc
   pointing to the enter instruction.  This is used in the macro
   pointing to the enter instruction.  This is used in the macro
   FRAME_FIND_SAVED_REGS.  */
   FRAME_FIND_SAVED_REGS.  */
 
 
int
int
ns32k_localcount (CORE_ADDR enter_pc)
ns32k_localcount (CORE_ADDR enter_pc)
{
{
  unsigned char localtype;
  unsigned char localtype;
  int localcount;
  int localcount;
 
 
  localtype = read_memory_integer (enter_pc + 2, 1);
  localtype = read_memory_integer (enter_pc + 2, 1);
  if ((localtype & 0x80) == 0)
  if ((localtype & 0x80) == 0)
    localcount = localtype;
    localcount = localtype;
  else if ((localtype & 0xc0) == 0x80)
  else if ((localtype & 0xc0) == 0x80)
    localcount = (((localtype & 0x3f) << 8)
    localcount = (((localtype & 0x3f) << 8)
                  | (read_memory_integer (enter_pc + 3, 1) & 0xff));
                  | (read_memory_integer (enter_pc + 3, 1) & 0xff));
  else
  else
    localcount = (((localtype & 0x3f) << 24)
    localcount = (((localtype & 0x3f) << 24)
                  | ((read_memory_integer (enter_pc + 3, 1) & 0xff) << 16)
                  | ((read_memory_integer (enter_pc + 3, 1) & 0xff) << 16)
                  | ((read_memory_integer (enter_pc + 4, 1) & 0xff) << 8)
                  | ((read_memory_integer (enter_pc + 4, 1) & 0xff) << 8)
                  | (read_memory_integer (enter_pc + 5, 1) & 0xff));
                  | (read_memory_integer (enter_pc + 5, 1) & 0xff));
  return localcount;
  return localcount;
}
}
 
 
 
 
/* Nonzero if instruction at PC is a return instruction.  */
/* Nonzero if instruction at PC is a return instruction.  */
 
 
static int
static int
ns32k_about_to_return (CORE_ADDR pc)
ns32k_about_to_return (CORE_ADDR pc)
{
{
  return (read_memory_integer (pc, 1) == 0x12);
  return (read_memory_integer (pc, 1) == 0x12);
}
}
 
 
 
 
/*
/*
 * Get the address of the enter opcode for the function
 * Get the address of the enter opcode for the function
 * containing PC, if there is an enter for the function,
 * containing PC, if there is an enter for the function,
 * and if the pc is between the enter and exit.
 * and if the pc is between the enter and exit.
 * Returns positive address if pc is between enter/exit,
 * Returns positive address if pc is between enter/exit,
 * 1 if pc before enter or after exit, 0 otherwise.
 * 1 if pc before enter or after exit, 0 otherwise.
 */
 */
 
 
CORE_ADDR
CORE_ADDR
ns32k_get_enter_addr (CORE_ADDR pc)
ns32k_get_enter_addr (CORE_ADDR pc)
{
{
  CORE_ADDR enter_addr;
  CORE_ADDR enter_addr;
  unsigned char op;
  unsigned char op;
 
 
  if (pc == 0)
  if (pc == 0)
    return 0;
    return 0;
 
 
  if (ns32k_about_to_return (pc))
  if (ns32k_about_to_return (pc))
    return 1;                   /* after exit */
    return 1;                   /* after exit */
 
 
  enter_addr = get_pc_function_start (pc);
  enter_addr = get_pc_function_start (pc);
 
 
  if (pc == enter_addr)
  if (pc == enter_addr)
    return 1;                   /* before enter */
    return 1;                   /* before enter */
 
 
  op = read_memory_integer (enter_addr, 1);
  op = read_memory_integer (enter_addr, 1);
 
 
  if (op != 0x82)
  if (op != 0x82)
    return 0;                    /* function has no enter/exit */
    return 0;                    /* function has no enter/exit */
 
 
  return enter_addr;            /* pc is between enter and exit */
  return enter_addr;            /* pc is between enter and exit */
}
}
 
 

powered by: WebSVN 2.1.0

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