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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [or1k-tdep.c] - Diff between revs 116 and 118

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

Rev 116 Rev 118
Line 1... Line 1...
/* Target-dependent code for the or1k architecture, for GDB, the GNU Debugger.
/* Target-dependent code for the or1k architecture, for GDB, the GNU Debugger.
 
 
   Copyright 1988-1999, Free Software Foundation, Inc.
   Copyright 1988-1999, Free Software Foundation, Inc.
   Contributed by Alessandro Forin(af@cs.cmu.edu at CMU
   Contributed by Alessandro Forin(af@cs.cmu.edu at CMU
   and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
   and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
 
 
   This file is part of GDB.
   This file is part of GDB.
Line 18... Line 19...
   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 "demangle.h"
#include "defs.h"
#include "defs.h"
#include "gdb_string.h"
#include "gdb_string.h"
#include "frame.h"
#include "frame.h"
#include "inferior.h"
#include "inferior.h"
#include "symtab.h"
#include "symtab.h"
Line 53... Line 55...
  2047+1, 2047+1, 2047+1, 258+1, 257+1, 257+1,
  2047+1, 2047+1, 2047+1, 258+1, 257+1, 257+1,
  79+1, 263+1, 16+1, 18+1, 256+1, 7+1};
  79+1, 263+1, 16+1, 18+1, 256+1, 7+1};
 
 
/* Register names.  */
/* Register names.  */
char *or1k_reg_names[] = {
char *or1k_reg_names[] = {
 
 
  /* group 0 - general*/
  /* group 0 - general*/
  "VR", "UPR", "CPUCFGR", "DMMUCFGR", "IMMUCFGR", "DCCFGR", "ICCFGR", "DCFGR",
  "VR", "UPR", "CPUCFGR", "DMMUCFGR", "IMMUCFGR", "DCCFGR", "ICCFGR", "DCFGR",
  "PCCFGR", "SPR0_9", "SPR0_10", "SPR0_11", "SPR0_12", "SPR0_13", "SPR0_14", "SPR0_15",
  "PCCFGR", "SPR0_9", "SPR0_10", "SPR0_11", "SPR0_12", "SPR0_13", "SPR0_14", "SPR0_15",
  "PC", "SR", "SPR0_18", "SPR0_19", "SPR0_20", "SPR0_21", "SPR0_22", "SPR0_23",
  "PC", "SR", "SPR0_18", "SPR0_19", "SPR0_20", "SPR0_21", "SPR0_22", "SPR0_23",
  "EPCR0", "EPCR1", "EPCR2", "EPCR3", "EPCR4", "EPCR5", "EPCR6", "EPCR7",
  "EPCR0", "EPCR1", "EPCR2", "EPCR3", "EPCR4", "EPCR5", "EPCR6", "EPCR7",
  "EPCR8", "EPCR9", "EPCR10", "EPCR11", "EPCR12", "EPCR13", "EPCR14", "EPCR15",
  "EPCR8", "EPCR9", "EPCR10", "EPCR11", "EPCR12", "EPCR13", "EPCR14", "EPCR15",
  "EEAR0","EEAR1", "EEAR2", "EEAR3", "EEAR4", "EEAR5", "EEAR6", "EEAR7",
  "EEAR0","EEAR1", "EEAR2", "EEAR3", "EEAR4", "EEAR5", "EEAR6", "EEAR7",
  "EEAR8", "EEAR9", "EEAR10", "EEAR11", "EEAR12", "EEAR13", "EEAR14", "EEAR15",
  "EEAR8", "EEAR9", "EEAR10", "EEAR11", "EEAR12", "EEAR13", "EEAR14", "EEAR15",
  "ESR0", "ESR1", "ESR2", "ESR3", "ESR4", "ESR5", "ESR6", "ESR7",
  "ESR0", "ESR1", "ESR2", "ESR3", "ESR4", "ESR5", "ESR6", "ESR7",
  "ESR8", "ESR9", "ESR10", "ESR11", "ESR12", "ESR13", "ESR14", "ESR15",
  "ESR8", "ESR9", "ESR10", "ESR11", "ESR12", "ESR13", "ESR14", "ESR15",
 
 
  /* gpr+vf registers generated */
  /* gpr+vf registers generated */
  /* group 1 - Data MMU - not listed, generated */
  /* group 1 - Data MMU - not listed, generated */
  /* group 2 - Instruction MMU - not listed, generated */
  /* group 2 - Instruction MMU - not listed, generated */
 
 
  /* group 3 - Data cache */
  /* group 3 - Data cache */
  "DCCR", "DCBIR", "DCBPR", "DCBFR", "DCBWR", "DCBLR",
  "DCCR", "DCBIR", "DCBPR", "DCBFR", "DCBWR", "DCBLR",
 
 
  /* group 4 - Instruction cache */
  /* group 4 - Instruction cache */
  "ICCR", "ICBLR", "ICBIR", "ICBPR",
  "ICCR", "ICBLR", "ICBIR", "ICBPR",
 
 
  /* group 5 - MAC */
  /* group 5 - MAC */
  "MACLO", "MACHI",
  "MACLO", "MACHI",
 
 
  /* group 6 - debug */
  /* group 6 - debug */
  "DVR0", "DVR1", "DVR2", "DVR3", "DVR4", "DVR5", "DVR6", "DVR7",
  "DVR0", "DVR1", "DVR2", "DVR3", "DVR4", "DVR5", "DVR6", "DVR7",
  "DCR0", "DCR1", "DCR2", "DCR3", "DCR4", "DCR5", "DCR6", "DCR7",
  "DCR0", "DCR1", "DCR2", "DCR3", "DCR4", "DCR5", "DCR6", "DCR7",
  "DMR1", "DMR2", "DCWR0","DCWR1","DSR",  "DRR",  "DIR",
  "DMR1", "DMR2", "DCWR0","DCWR1","DSR",  "DRR",  "DIR",
 
 
Line 95... Line 103...
  /* group 11 - configureation */
  /* group 11 - configureation */
  "CPUCFGR", "DMMUCFGR", "IMMUCFGR", "DCCFGR", "ICCFGR", "SPR11_5", "DCFGR", "PCCFGR"
  "CPUCFGR", "DMMUCFGR", "IMMUCFGR", "DCCFGR", "ICCFGR", "SPR11_5", "DCFGR", "PCCFGR"
};
};
 
 
static char *or1k_gdb_reg_names[] = {
static char *or1k_gdb_reg_names[] = {
 
 
  /* general purpose registers */
  /* general purpose registers */
  "ZERO", "SP", "FP", "A0", "A1", "A2", "A3", "A4",
  "ZERO", "SP", "FP", "A0", "A1", "A2", "A3", "A4",
  "A5", "LR", "R10", "RV", "R12", "R13", "R14", "R15",
  "A5", "LR", "R10", "RV", "R12", "R13", "R14", "R15",
  "R16", "R17", "R18", "R19", "R20", "R21", "R22", "R23",
  "R16", "R17", "R18", "R19", "R20", "R21", "R22", "R23",
  "R24", "R25", "R26", "R27", "R28", "R29", "R30", "R31",
  "R24", "R25", "R26", "R27", "R28", "R29", "R30", "R31",
 
 
  /* vector/floating point registers */
  /* vector/floating point registers */
  "VFA0",  "VFA1",  "VFA2",  "VFA3",  "VFA4",  "VFA5",  "VFRV ", "VFR7",
  "VFA0",  "VFA1",  "VFA2",  "VFA3",  "VFA4",  "VFA5",  "VFRV ", "VFR7",
  "VFR8",  "VFR9",  "VFR10", "VFR11", "VFR12", "VFR13", "VFR14", "VFR15",
  "VFR8",  "VFR9",  "VFR10", "VFR11", "VFR12", "VFR13", "VFR14", "VFR15",
  "VFR16", "VFR17", "VFR18", "VFR19", "VFR20", "VFR21", "VFR22", "VFR23",
  "VFR16", "VFR17", "VFR18", "VFR19", "VFR20", "VFR21", "VFR22", "VFR23",
  "VFR24", "VFR25", "VFR26", "VFR27", "VFR28", "VFR29", "VFR30", "VFR31",
  "VFR24", "VFR25", "VFR26", "VFR27", "VFR28", "VFR29", "VFR30", "VFR31",
Line 112... Line 122...
 
 
static char *or1k_group_names[] = {
static char *or1k_group_names[] = {
  "SYS", "DMMU", "IMMU", "DCACHE", "ICACHE", "MAC", "DEBUG", "PERF", "POWER",
  "SYS", "DMMU", "IMMU", "DCACHE", "ICACHE", "MAC", "DEBUG", "PERF", "POWER",
  "PIC", "TIMER"
  "PIC", "TIMER"
};
};
 
 
/* Table of or1k signals.  */
/* Table of or1k signals.  */
static struct {
static struct
 
  {
  char *name;
  char *name;
  char *string;
  char *string;
  } or1k_signals [NUM_OR1K_SIGNALS + 1] =
  } or1k_signals [NUM_OR1K_SIGNALS + 1] =
{
{
  {"RSTE", "Reset Exception"},
  {"RSTE", "Reset Exception"},
Line 131... Line 143...
  {"RE", "Range Exception"},
  {"RE", "Range Exception"},
  {"SCE", "SCE Exception"}, //!!!
  {"SCE", "SCE Exception"}, //!!!
  {NULL, NULL}
  {NULL, NULL}
};
};
 
 
 
const char *compare_to_names[NUM_CT_NAMES] =
 
  {
 
    "ERR", "FETCH", "LEA", "SEA", "AEA", "LDATA", "SDATA", "ADATA"
 
  };
 
 
 
const char *or1k_record_names[MAX_RECORD_NAMES] =
 
  {
 
    "PC", "LSEA", "LDATA", "SDATA", "READSPR", "WRITESPR", "INSTR"
 
  };
 
 
 
const char *or1k_is_names[MAX_IS_NAMES] =
 
  {
 
    "IF_NONE", "IF_NORMAL", "IF_BRANCH", "IF_DELAY"
 
  };
 
 
 
const char *or1k_ls_names[MAX_LS_NAMES] =
 
  {
 
    "LS_NONE", " ", "LBZ", "LBS", "LHZ", "LHS", "LWZ", "LWS",
 
    " ", " ", "SB", " ", "SH", " ", "SW", " "
 
  };
 
 
/* *INDENT-ON* */
/* *INDENT-ON* */
 
 
/* The list of available "set or1k " and "show or1k " commands */
/* The list of available "set or1k " and "show or1k " commands */
static struct cmd_list_element *setor1kcmdlist = NULL;
static struct cmd_list_element *htrace_cmdlist = NULL;
static struct cmd_list_element *showor1kcmdlist = NULL;
static struct cmd_list_element *htrace_mode_cmdlist = NULL;
 
 
/* List of all saved register addresses, produced by skip_prologue.
/* List of all saved register addresses, produced by skip_prologue.
   Relative address to sp, not used if 0.  */
   Relative address to sp, not used if 0.  */
static int or1k_saved_reg_addr[NUM_REGS];
static int or1k_saved_reg_addr[NUM_REGS];
 
 
 
struct htrace_struct or1k_htrace;
 
struct hwatch_struct or1k_hwatch[MAX_HW_WATCHES];
 
int num_hw_watches = 0;
 
 
 
/* Trace data.  */
 
char trace_filename[TRACE_FILENAME_SIZE] = "trace.dat";
 
 
 
/* Size of trace file in records.  */
 
int trace_size = 0;
 
 
 
/* Previous values for buffer display.  */
 
static int prev_length = 10;
 
static int prev_from = 0;
 
 
/* Converts regno to sprno.  or1k debug unit has GPRs mapped to SPRs,
/* Converts regno to sprno.  or1k debug unit has GPRs mapped to SPRs,
   which are not compact, so we are mapping them for GDB.  */
   which are not compact, so we are mapping them for GDB.  */
 
 
int
int
or1k_regnum_to_sprnum (int regno)
or1k_regnum_to_sprnum (int regno)
{
{
  if (regno < MAX_GPR_REGS)
  if (regno < MAX_GPR_REGS)
    return SPR_REG(SPR_SYSTEM_GROUP, regno + CURRENT_CID * MAX_GPR_REGS + SPR_GPR_START);
    return SPR_REG(SPR_SYSTEM_GROUP, regno + CURRENT_CID * MAX_GPR_REGS + SPR_GPR_START);
Line 174... Line 221...
  int index = i & (SPR_GROUP_SIZE - 1);
  int index = i & (SPR_GROUP_SIZE - 1);
  switch (group)
  switch (group)
    {
    {
      /* Names covered in or1k_reg_names.  */
      /* Names covered in or1k_reg_names.  */
    case 0:
    case 0:
 
 
      /* Generate upper names.  */
      /* Generate upper names.  */
      if (index >= SPR_GPR_START)
      if (index >= SPR_GPR_START)
        {
        {
          if (index < SPR_VFPR_START)
          if (index < SPR_VFPR_START)
            sprintf (tmp_name, "GPR%i", index - SPR_GPR_START);
            sprintf (tmp_name, "GPR%i", index - SPR_GPR_START);
Line 204... Line 252...
            return (char *)&tmp_name;
            return (char *)&tmp_name;
          }
          }
        else
        else
          return or1k_reg_names[group_start + index - or1k_group_name_start[group]];
          return or1k_reg_names[group_start + index - or1k_group_name_start[group]];
      }
      }
 
 
      /* Build names for DMMU group.  */
      /* Build names for DMMU group.  */
    case 1:
    case 1:
    case 2:
    case 2:
      strcpy (tmp_name, (group == 1)?"D":"I");
      strcpy (tmp_name, (group == 1)?"D":"I");
      switch (index)
      switch (index)
Line 278... Line 327...
        return i;
        return i;
    }
    }
  return -1;
  return -1;
}
}
 
 
/* Resturs gdb register name.  */
/* Returns gdb register name.  */
 
 
char *
char *
or1k_register_name (regno)
or1k_register_name (regno)
     int regno;
     int regno;
{
{
  return or1k_gdb_reg_names[regno];
  return or1k_gdb_reg_names[regno];
}
}
 
 
 
/* Utility function to display vf regs.  */
 
 
static int
static int
do_vf_register (regnum)
do_vf_register (regnum)
     int regnum;
     int regnum;
{                               /* do values for FP (float) regs */
{
 
  /* do values for FP (float) regs */
  char *raw_buffer;
  char *raw_buffer;
  double doub, flt;             /* doubles extracted from raw hex data */
 
 
   /* doubles extracted from raw hex data */
 
  double doub, flt;
  int inv1, inv3, byte;
  int inv1, inv3, byte;
 
 
  raw_buffer = (char *) alloca (OR1K_VF_REGSIZE);
  raw_buffer = (char *) alloca (OR1K_VF_REGSIZE);
 
 
  /* Get the data in raw format.  */
  /* Get the data in raw format.  */
Line 313... Line 368...
                   " dbl: %-24.17g ", doub);
                   " dbl: %-24.17g ", doub);
 
 
  /* pad small registers */
  /* pad small registers */
  for (byte = 0; byte < (OR1K_GPR_REGSIZE - REGISTER_VIRTUAL_SIZE (regnum)); byte++)
  for (byte = 0; byte < (OR1K_GPR_REGSIZE - REGISTER_VIRTUAL_SIZE (regnum)); byte++)
    printf_filtered ("  ");
    printf_filtered ("  ");
 
 
  /* Now print the register value in hex, endian order. */
  /* Now print the register value in hex, endian order. */
  if (TARGET_BYTE_ORDER == BIG_ENDIAN)
  if (TARGET_BYTE_ORDER == BIG_ENDIAN)
    for (byte = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum);
    for (byte = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum);
         byte < REGISTER_RAW_SIZE (regnum);
         byte < REGISTER_RAW_SIZE (regnum);
         byte++)
         byte++)
Line 338... Line 394...
do_gp_register_row (regnum)
do_gp_register_row (regnum)
     int regnum;
     int regnum;
{
{
  /* do values for GP (int) regs */
  /* do values for GP (int) regs */
  char raw_buffer[MAX_REGISTER_RAW_SIZE];
  char raw_buffer[MAX_REGISTER_RAW_SIZE];
  int ncols = (OR1K_64BIT_IMPLEMENTATION ? 4 : 8);      /* display cols per row */
 
 
  /* display cols per row */
 
  int ncols = (OR1K_64BIT_IMPLEMENTATION ? 4 : 8);
  int col, byte;
  int col, byte;
  int start_regnum = regnum;
  int start_regnum = regnum;
  int numregs = NUM_REGS;
  int numregs = NUM_REGS;
 
 
 
 
  /* For GP registers, we print a separate row of names above the vals */
  /* For GP registers, we print a separate row of names above the vals */
  printf_filtered ("     ");
  printf_filtered ("     ");
  for (col = 0; col < ncols && regnum < numregs; regnum++)
  for (col = 0; col < ncols && regnum < numregs; regnum++)
    {
    {
      if (*REGISTER_NAME (regnum) == '\0')
      if (*REGISTER_NAME (regnum) == '\0')
Line 363... Line 420...
  regnum = start_regnum;        /* go back to start of row */
  regnum = start_regnum;        /* go back to start of row */
 
 
  /* now print the values in hex, 4 or 8 to the row */
  /* now print the values in hex, 4 or 8 to the row */
  for (col = 0; col < ncols && regnum < numregs; regnum++)
  for (col = 0; col < ncols && regnum < numregs; regnum++)
    {
    {
 
      /* unused register? */
      if (*REGISTER_NAME (regnum) == '\0')
      if (*REGISTER_NAME (regnum) == '\0')
        continue;               /* unused register */
        continue;
 
 
 
      /* end row: reached VF register? */
      if (OR1K_IS_VF(regnum))
      if (OR1K_IS_VF(regnum))
        break;                  /* end row: reached VF register */
        break;
 
 
      /* OK: get the data in raw format.  */
      /* OK: get the data in raw format.  */
      if (read_relative_register_raw_bytes (regnum, raw_buffer))
      if (read_relative_register_raw_bytes (regnum, raw_buffer))
        error ("can't read register %d (%s)", regnum, REGISTER_NAME (regnum));
        error ("can't read register %d (%s)", regnum, REGISTER_NAME (regnum));
 
 
      /* pad small registers */
      /* pad small registers */
      for (byte = 0; byte < (OR1K_GPR_REGSIZE - REGISTER_VIRTUAL_SIZE (regnum)); byte++)
      for (byte = 0; byte < (OR1K_GPR_REGSIZE - REGISTER_VIRTUAL_SIZE (regnum)); byte++)
        printf_filtered ("  ");
        printf_filtered ("  ");
 
 
      /* Now print the register value in hex, endian order. */
      /* Now print the register value in hex, endian order. */
      if (TARGET_BYTE_ORDER == BIG_ENDIAN)
      if (TARGET_BYTE_ORDER == BIG_ENDIAN)
        for (byte = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum);
        for (byte = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum);
             byte < REGISTER_RAW_SIZE (regnum);
             byte < REGISTER_RAW_SIZE (regnum);
             byte++)
             byte++)
Line 387... Line 450...
             byte--)
             byte--)
          printf_filtered ("%02x", (unsigned char) raw_buffer[byte]);
          printf_filtered ("%02x", (unsigned char) raw_buffer[byte]);
      printf_filtered (" ");
      printf_filtered (" ");
      col++;
      col++;
    }
    }
  if (col > 0)                   /* ie. if we actually printed anything... */
 
 
  /* ie. if we actually printed anything... */
 
  if (col > 0)
    printf_filtered ("\n");
    printf_filtered ("\n");
 
 
  return regnum;
  return regnum;
}
}
 
 
/* Replacement for generic do_registers_info.
/* Replacement for generic do_registers_info.
   Print regs in pretty columns.  */
   Print regs in pretty columns.  */
 
 
static void
static void
print_register (regnum, all)
print_register (regnum, all)
     int regnum, all;
     int regnum, all;
{
{
  int offset;
  int offset;
Line 420... Line 486...
      printf_filtered ("%-16s\t", REGISTER_NAME (regnum));
      printf_filtered ("%-16s\t", REGISTER_NAME (regnum));
 
 
      /* pad small registers */
      /* pad small registers */
      for (byte = 0; byte < (OR1K_GPR_REGSIZE - REGISTER_VIRTUAL_SIZE (regnum)); byte++)
      for (byte = 0; byte < (OR1K_GPR_REGSIZE - REGISTER_VIRTUAL_SIZE (regnum)); byte++)
        printf_filtered ("  ");
        printf_filtered ("  ");
 
 
      /* Now print the register value in hex, endian order. */
      /* Now print the register value in hex, endian order. */
      if (TARGET_BYTE_ORDER == BIG_ENDIAN)
      if (TARGET_BYTE_ORDER == BIG_ENDIAN)
        for (byte = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum);
        for (byte = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum);
             byte < REGISTER_RAW_SIZE (regnum);
             byte < REGISTER_RAW_SIZE (regnum);
             byte++)
             byte++)
Line 447... Line 514...
  if (fpregs && !or1k_implementation.vf_present)
  if (fpregs && !or1k_implementation.vf_present)
    {
    {
      warning ("VF register set not present in this implementation.");
      warning ("VF register set not present in this implementation.");
      fpregs = 0;
      fpregs = 0;
    }
    }
  if (regnum != -1)             /* do one specified register */
  if (regnum != -1)
    {
    {
 
      /* do one specified register */
      if (*(REGISTER_NAME (regnum)) == '\0')
      if (*(REGISTER_NAME (regnum)) == '\0')
        error ("Not a valid register for the current processor type");
        error ("Not a valid register for the current processor type");
 
 
      print_register (regnum, 0);
      print_register (regnum, 0);
      printf_filtered ("\n");
      printf_filtered ("\n");
Line 462... Line 530...
    {
    {
      regnum = 0;
      regnum = 0;
      while (regnum < NUM_REGS)
      while (regnum < NUM_REGS)
        {
        {
          if (OR1K_IS_VF (regnum))
          if (OR1K_IS_VF (regnum))
            if (fpregs)         /* true for "INFO ALL-REGISTERS" command */
            /* true for "INFO ALL-REGISTERS" command */
              regnum = do_vf_register (regnum); /* FP regs */
            if (fpregs)
 
              /* FP regs */
 
              regnum = do_vf_register (regnum);
            else
            else
              regnum++;         /* skip floating point regs */
              /* skip floating point regs */
 
              regnum++;
          else
          else
            regnum = do_gp_register_row (regnum);       /* GP (int) regs */
            /* GP (int) regs */
 
            regnum = do_gp_register_row (regnum);
        }
        }
    }
    }
}
}
 
 
/* Given the address at which to insert a breakpoint (BP_ADDR),
/* Given the address at which to insert a breakpoint (BP_ADDR),
Line 489... Line 561...
  static char breakpoint[] = BRK_INSTR_STRUCT;
  static char breakpoint[] = BRK_INSTR_STRUCT;
  *bp_size = OR1K_INSTLEN;
  *bp_size = OR1K_INSTLEN;
  return breakpoint;
  return breakpoint;
}
}
 
 
/* Return the string for a signal.  Replacement for target_signal_to_string (sig).  */
/* Return the string for a signal.
 
   Replacement for target_signal_to_string (sig).  NOT USED.  */
 
 
char
char
*or1k_signal_to_string (sig)
*or1k_signal_to_string (sig)
     enum target_signal sig;
     enum target_signal sig;
{
{
  if ((sig >= TARGET_SIGNAL_FIRST) && (sig <= TARGET_SIGNAL_LAST))
  if ((sig >= TARGET_SIGNAL_FIRST) && (sig <= TARGET_SIGNAL_LAST))
    return or1k_signals[sig].string;
    return or1k_signals[sig].string;
  else
  else
    if (sig <= TARGET_SIGNAL_LAST + NUM_OR1K_SIGNALS)
    if (sig <= TARGET_SIGNAL_LAST + NUM_OR1K_SIGNALS)
      return or1k_signals[sig - TARGET_SIGNAL_LAST].string;
      return or1k_signals[sig - TARGET_SIGNAL_LAST].string;
    else
    else
      return 0/* signals[TARGET_SIGNAL_UNKNOWN].string*/;
      return 0;
}
}
 
 
/* Return the name for a signal.  */
/* Return the name for a signal.  */
 
 
char *
char *
or1k_signal_to_name (sig)
or1k_signal_to_name (sig)
     enum target_signal sig;
     enum target_signal sig;
{
{
  if (sig >= TARGET_SIGNAL_LAST)
  if (sig >= TARGET_SIGNAL_LAST)
    if (sig <= TARGET_SIGNAL_LAST + NUM_OR1K_SIGNALS)
    if (sig <= TARGET_SIGNAL_LAST + NUM_OR1K_SIGNALS)
      return or1k_signals[sig - TARGET_SIGNAL_LAST].name;
      return or1k_signals[sig - TARGET_SIGNAL_LAST].name;
    else
    else
 
 
    /* I think the code which prints this will always print it along with
    /* I think the code which prints this will always print it along with
       the string, so no need to be verbose.  */
       the string, so no need to be verbose.  */
      return "?";
      return "?";
  if (sig == TARGET_SIGNAL_UNKNOWN)
  if (sig == TARGET_SIGNAL_UNKNOWN)
    return "?";
    return "?";
  return 0/*!!!signals[sig].name*/;
  return 0;
}
}
 
 
/* Given a name, return its signal.  */
/* Given a name, return its signal.  NOT USED.  */
enum target_signal
enum target_signal
or1k_signal_from_name (name)
or1k_signal_from_name (name)
     char *name;
     char *name;
{
{
  enum target_signal sig;
  enum target_signal sig;
Line 543... Line 619...
  return TARGET_SIGNAL_UNKNOWN;
  return TARGET_SIGNAL_UNKNOWN;
}
}
 
 
/* Given a return value in `regbuf' with a type `valtype', extract and
/* Given a return value in `regbuf' with a type `valtype', extract and
   copy its value into `valbuf'. */
   copy its value into `valbuf'. */
 
 
void
void
or1k_extract_return_value (valtype, regbuf, valbuf)
or1k_extract_return_value (valtype, regbuf, valbuf)
     struct type *valtype;
     struct type *valtype;
     char regbuf[REGISTER_BYTES];
     char regbuf[REGISTER_BYTES];
     char *valbuf;
     char *valbuf;
Line 636... Line 713...
{
{
  CORE_ADDR fp;
  CORE_ADDR fp;
  if (USE_GENERIC_DUMMY_FRAMES)
  if (USE_GENERIC_DUMMY_FRAMES)
    {
    {
      if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
      if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
        return frame->frame;    /* dummy frame same as caller's frame */
        /* dummy frame same as caller's frame */
 
        return frame->frame;
    }
    }
 
 
  if (inside_entry_file (frame->pc) ||
  if (inside_entry_file (frame->pc) ||
      frame->pc == entry_point_address ())
      frame->pc == entry_point_address ())
    return 0;
    return 0;
Line 676... Line 754...
   ways in the stack frame.  sp is even more special:
   ways in the stack frame.  sp is even more special:
   the address we return for it IS the sp for the next frame.  */
   the address we return for it IS the sp for the next frame.  */
void
void
or1k_init_saved_regs (struct frame_info *fi)
or1k_init_saved_regs (struct frame_info *fi)
{
{
  CORE_ADDR frame_addr;
 
  int i;
  int i;
 
  CORE_ADDR frame_addr;
  frame_saved_regs_zalloc (fi);
  frame_saved_regs_zalloc (fi);
 
 
  /* Skip prologue sets or1k_saved_reg_addr[], we will use it later.  */
  /* Skip prologue sets or1k_saved_reg_addr[], we will use it later.  */
  or1k_skip_prologue (get_pc_function_start ((fi)->pc) + FUNCTION_START_OFFSET);
  or1k_skip_prologue (get_pc_function_start ((fi)->pc) + FUNCTION_START_OFFSET);
 
 
Line 720... Line 798...
CORE_ADDR
CORE_ADDR
or1k_frame_saved_pc (fi)
or1k_frame_saved_pc (fi)
     struct frame_info *fi;
     struct frame_info *fi;
{
{
  CORE_ADDR saved_pc;
  CORE_ADDR saved_pc;
 
 
  /* We have to get the saved pc from the sigcontext
  /* We have to get the saved pc from the sigcontext
     if it is a signal handler frame.  */
     if it is a signal handler frame.  */
  if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
  if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
    saved_pc = read_memory_integer (fi->frame, OR1K_GPR_REGSIZE);
    saved_pc = read_memory_integer (fi->frame, OR1K_GPR_REGSIZE);
  else
  else
Line 873... Line 952...
     point of the program, where a breakpoint lies in wait.  */
     point of the program, where a breakpoint lies in wait.  */
  write_register (LR_REGNUM, CALL_DUMMY_ADDRESS ());
  write_register (LR_REGNUM, CALL_DUMMY_ADDRESS ());
  return sp;
  return sp;
}
}
 
 
/* Root of all "set or1k "/"show or1k " commands. This will eventually be
 
   used for all OR1K-specific commands.  */
 
 
 
static void show_or1k_command PARAMS ((char *, int));
 
static void
 
show_or1k_command (args, from_tty)
 
     char *args;
 
     int from_tty;
 
{
 
  help_list (showor1kcmdlist, "show or1k ", all_commands, gdb_stdout);
 
}
 
 
 
static void set_or1k_command PARAMS ((char *, int));
 
static void
 
set_or1k_command (args, from_tty)
 
     char *args;
 
     int from_tty;
 
{
 
  printf_unfiltered ("\"set or1k\" must be followed by an appropriate subcommand.\n");
 
  help_list (setor1kcmdlist, "set or1k ", all_commands, gdb_stdout);
 
}
 
 
 
/* Parses args for spr name and puts result into group and index.  */
/* Parses args for spr name and puts result into group and index.  */
 
 
static char *
static char *
parse_spr_params (args, group, index)
parse_spr_params (args, group, index)
                  char *args;
                  char *args;
Line 907... Line 964...
  *index = -1;
  *index = -1;
  if (args)
  if (args)
    {
    {
      int i;
      int i;
      char *ptr_c;
      char *ptr_c;
 
 
      /* Check if group number was supplied.  */
      /* Check if group number was supplied.  */
      ptr_c = args;
      ptr_c = args;
      while (*ptr_c != ' ' && *ptr_c != 0)
      while (*ptr_c != ' ' && *ptr_c != 0)
        ptr_c++;
        ptr_c++;
      *ptr_c = 0;
      *ptr_c = 0;
 
 
      *group = (int) strtoul (args, &ptr_c, 0);
      *group = (int) strtoul (args, &ptr_c, 0);
      if (*ptr_c != 0)
      if (*ptr_c != 0)
        {
        {
          *group = OR1K_NUM_SPR_GROUPS;
          *group = OR1K_NUM_SPR_GROUPS;
 
 
          /* check for group name */
          /* check for group name */
          for (i = 0; i < OR1K_NUM_SPR_GROUPS; i++)
          for (i = 0; i < OR1K_NUM_SPR_GROUPS; i++)
            if (strcasecmp (or1k_group_names[i], args) == 0)
            if (strcasecmp (or1k_group_names[i], args) == 0)
              {
              {
                *group = i;
                *group = i;
                break;
                break;
              }
              }
 
 
          /* Invalid group => check all register names in all groups.  */
          /* Invalid group => check all register names in all groups.  */
          if (*group >= OR1K_NUM_SPR_GROUPS)
          if (*group >= OR1K_NUM_SPR_GROUPS)
            {
            {
              for (i = 0; i < OR1K_NUM_SPR_GROUPS; i++)
              for (i = 0; i < OR1K_NUM_SPR_GROUPS; i++)
                {
                {
Line 971... Line 1031...
              return args + strlen(args) + 1;
              return args + strlen(args) + 1;
            }
            }
        }
        }
    }
    }
  else
  else
  /* No parameters - print groups */
 
    {
    {
 
      /* No parameters - print groups */
      int i;
      int i;
      printf_filtered ("No parameter supplied. Valid groups are:\n");
      printf_filtered ("No parameter supplied. Valid groups are:\n");
      for (i = 0; i < OR1K_NUM_SPR_GROUPS; i++)
      for (i = 0; i < OR1K_NUM_SPR_GROUPS; i++)
        printf_filtered ("%s\t", or1k_group_names[i]);
        printf_filtered ("%s\t", or1k_group_names[i]);
      printf_filtered ("\nSingle register name or register name or number after the group can be also supplied.\n");
      printf_filtered ("\nSingle register name or register name or number after the group can be also supplied.\n");
Line 1044... Line 1104...
     int from_tty;
     int from_tty;
{
{
  or1k_sim_cmd (args, from_tty);
  or1k_sim_cmd (args, from_tty);
}
}
 
 
int
 
or1k_parse_any (exp)
static union exp_element exp_error;
 
 
 
/* Parses compare variable and returns it into ct.  */
 
 
 
union exp_element * or1k_parse_ct (exp, ct)
 
     union exp_element *exp;
 
     int *ct;
 
{
 
  int i;
 
  if (exp->opcode != OP_INTERNALVAR)
 
    error ("Valid lvalue expected.");
 
  exp++;
 
 
 
  for (i = 1; i < NUM_CT_NAMES; i++)
 
    if (strcasecmp (compare_to_names[i], exp->internalvar->name) == 0) break;
 
 
 
  if (i >= NUM_CT_NAMES)
 
    error ("Invalid compare to operand.");
 
  *ct = i;
 
  exp++;
 
 
 
  if (exp->opcode != OP_INTERNALVAR)
 
    return &exp_error;
 
  exp++;
 
  return exp;
 
}
 
 
 
/* Parses compare value and returns it into cv.  */
 
 
 
union exp_element * or1k_parse_cv (exp, cv)
 
     union exp_element *exp;
 
     unsigned int *cv;
 
{
 
  switch (exp->opcode)
 
    {
 
    case UNOP_IND:
 
      exp++;
 
      exp = or1k_parse_cv (exp, cv);
 
      *cv = or1k_fetch_word (*cv);
 
      break;
 
    case OP_LONG:
 
      exp += 2;
 
      *cv = exp->longconst;
 
      exp += 2;
 
      break;
 
    case OP_REGISTER:
 
      exp++;
 
      *cv = read_register (exp->longconst);
 
      exp += 2;
 
      break;
 
    default:
 
      error ("Value expected.");
 
    }
 
  return exp;
 
}
 
 
 
/* Parse conditional.
 
   Puts freshly allocated array of matchpoints into match.  */
 
 
 
union exp_element *
 
or1k_parse_cond (exp, match, nmatch)
 
     union exp_element *exp;
 
     struct matchpoint **match;
 
     int *nmatch;
 
{
 
  unsigned int ct;
 
  *match = (struct matchpoint *) malloc (sizeof (struct matchpoint));
 
  *nmatch = 1;
 
  switch (exp->opcode)
 
    {
 
    case BINOP_EQUAL:
 
      (*match)->dcr.cc = CC_EQUAL;
 
      break;
 
    case BINOP_NOTEQUAL:
 
      (*match)->dcr.cc = CC_NEQUAL;
 
      break;
 
    case BINOP_LESS:
 
      (*match)->dcr.cc = CC_LESS;
 
      break;
 
    case BINOP_GTR:
 
      (*match)->dcr.cc = CC_GREAT;
 
      break;
 
    case BINOP_LEQ:
 
      (*match)->dcr.cc = CC_LESSE;
 
      break;
 
    case BINOP_GEQ:
 
      (*match)->dcr.cc = CC_GREATE;
 
      break;
 
    case BINOP_BITWISE_AND:
 
      (*match)->dcr.cc = CC_MASKED;
 
      break;
 
    default:
 
      return &exp_error;
 
    }
 
 
 
  exp++;
 
  (*match)->dcr.dp = 1;
 
  (*match)->dcr.sc = 0;
 
  if (exp->opcode == OP_INTERNALVAR)
 
    {
 
      exp = or1k_parse_ct (exp, &ct);
 
      exp = or1k_parse_cv (exp, &(*match)->dvr);
 
    }
 
  else
 
    {
 
      exp = or1k_parse_cv (exp, &(*match)->dvr);
 
      exp = or1k_parse_ct (exp, &ct);
 
    }
 
 
 
  (*match)->dcr.ct = ct;
 
  (*match)->chain_type = CHAINING_NONE;
 
  (*match)->cause_breakpoint = 0;
 
  return exp;
 
}
 
 
 
/* Parses expression with && or || operators.
 
   Puts freshly allocated array of matchpoints into match.
 
   valid & 1: && is allowed,
 
   valid & 2: || is allowed.  */
 
 
 
union exp_element *
 
or1k_parse_any (exp, match, nmatch, valid)
     union exp_element *exp;
     union exp_element *exp;
 
     struct matchpoint **match;
 
     int *nmatch;
 
     int valid;
 
{
 
  union exp_element *tmp;
 
  int first_and_only = 0, first_or_only = 0;
 
  struct matchpoint *tmp_match1, *tmp_match2, *tmpm;
 
  int tmp_nmatch1, tmp_nmatch2, tmpn;
 
 
 
  switch (exp->opcode)
 
    {
 
    case BINOP_LOGICAL_AND:
 
      if (!(valid & 1))
 
        return &exp_error;
 
      exp++;
 
 
 
      /* Parse first argument.  */
 
      tmp = or1k_parse_any (exp, &tmp_match1, &tmp_nmatch1, 1);
 
      if (tmp == &exp_error)
 
        exp = or1k_parse_any (exp, &tmp_match1, &tmp_nmatch1, valid);
 
      else
 
        {
 
          /* and_only successful */
 
          exp = tmp;
 
          first_and_only = 1;
 
        }
 
      if (exp == &exp_error)
 
        return &exp_error;
 
 
 
      /* Parse second argument.  */
 
      if (first_and_only)
 
        exp = or1k_parse_any (exp, &tmp_match2, &tmp_nmatch2, valid);
 
      else
 
        exp = or1k_parse_any (exp, &tmp_match2, &tmp_nmatch2, 1);
 
 
 
      if (exp == &exp_error)
 
        return &exp_error;
 
 
 
      if (first_and_only)
 
        {
 
          /* Exchange structures, so that and_only is listed last.  */
 
          struct matchpoint *tmpm = tmp_match1;
 
          int tmpn = tmp_nmatch1;
 
          tmp_match1 = tmp_match2;
 
          tmp_nmatch1 = tmp_nmatch2;
 
          tmp_match2 = tmpm;
 
          tmp_nmatch2 = tmpn;
 
        }
 
 
 
      *nmatch = tmp_nmatch1 + tmp_nmatch2;
 
      *match = (struct matchpoint *)malloc (*nmatch * sizeof (struct matchpoint));
 
      memcpy (*match, tmp_match1, tmp_nmatch1 * sizeof (struct matchpoint));
 
      free (tmp_match1);
 
      tmp_match2[0].chain_type = CHAINING_AND;
 
      memcpy (*match + tmp_nmatch1, tmp_match2, tmp_nmatch2 * sizeof (struct matchpoint));
 
      free (tmp_match2);
 
      return exp;
 
 
 
    case BINOP_LOGICAL_OR:
 
      if (!(valid & 2))
 
        return &exp_error;
 
      exp++;
 
 
 
      /* Parse first argument.  */
 
      tmp = or1k_parse_any (exp, &tmp_match1, &tmp_nmatch1, 2);
 
      if (tmp == &exp_error)
 
        exp = or1k_parse_any (exp, &tmp_match1, &tmp_nmatch1, valid);
 
      else
 
        {
 
          /* and_only successful */
 
          exp = tmp;
 
          first_or_only = 1;
 
        }
 
      if (exp == &exp_error)
 
        return &exp_error;
 
 
 
      /* Parse second argument.  */
 
      if (first_or_only)
 
        exp = or1k_parse_any (exp, &tmp_match2, &tmp_nmatch2, valid);
 
      else
 
        exp = or1k_parse_any (exp, &tmp_match2, &tmp_nmatch2, 2);
 
 
 
      if (exp == &exp_error)
 
        return &exp_error;
 
 
 
      if (first_or_only)
 
        {
 
          /* Exchange structures, so that and_only is listed first.  */
 
          struct matchpoint *tmpm = tmp_match1;
 
          int tmpn = tmp_nmatch1;
 
          tmp_match1 = tmp_match2;
 
          tmp_nmatch1 = tmp_nmatch2;
 
          tmp_match2 = tmpm;
 
          tmp_nmatch2 = tmpn;
 
        }
 
 
 
      *nmatch = tmp_nmatch1 + tmp_nmatch2;
 
      *match = (struct matchpoint *)malloc (*nmatch * sizeof (struct matchpoint));
 
      memcpy (*match, tmp_match1, tmp_nmatch1 * sizeof (struct matchpoint));
 
      free (tmp_match1);
 
      tmp_match2[0].chain_type = CHAINING_OR;
 
      memcpy (*match + tmp_nmatch1, tmp_match2, tmp_nmatch2 * sizeof (struct matchpoint));
 
      free (tmp_match2);
 
      return exp;
 
 
 
    default:
 
      return or1k_parse_cond (exp, match, nmatch);
 
    }
 
}
 
 
 
/* Parses sequence of ||s.
 
   Puts freshly allocated array of matchpoints into match.  */
 
 
 
union exp_element *
 
or1k_parse_or (exp, match, nmatch, set_break)
 
     union exp_element *exp;
 
     struct matchpoint **match;
 
     int *nmatch;
 
     int set_break;
 
{
 
  struct matchpoint *tmp_match1, *tmp_match2;
 
  int tmp_nmatch1, tmp_nmatch2;
 
 
 
  switch (exp->opcode)
 
    {
 
    case BINOP_LOGICAL_OR:
 
      exp++;
 
      exp = or1k_parse_or (exp, &tmp_match1, &tmp_nmatch1);
 
      if (exp == &exp_error)
 
        return &exp_error;
 
 
 
      exp = or1k_parse_any (exp, &tmp_match2, &tmp_nmatch2, 3);
 
      if (set_break)
 
        {
 
          tmp_match1[tmp_nmatch1 - 1].cause_breakpoint = 1;
 
          tmp_match2[tmp_nmatch2 - 1].cause_breakpoint = 1;
 
        }
 
      *nmatch = tmp_nmatch1 + tmp_nmatch2;
 
      *match = (struct matchpoint *)malloc (*nmatch * sizeof (struct matchpoint));
 
      memcpy (*match, tmp_match1, tmp_nmatch1 * sizeof (struct matchpoint));
 
      free (tmp_match1);
 
      memcpy (*match + tmp_nmatch1, tmp_match2, tmp_nmatch2 * sizeof (struct matchpoint));
 
      free (tmp_match2);
 
      return exp;
 
 
 
    default:
 
      return or1k_parse_any (exp, match, nmatch, 3);
 
      if (set_break)
 
        (*match)[*nmatch - 1].cause_breakpoint = 1;
 
    }
 
}
 
 
 
/* Prints single matchpoint from specified struct.  */
 
 
 
static void
 
print_matchpoint_struct (mp)
 
     struct matchpoint *mp;
{
{
  if (exp->opcode == BINOP_LOGICAL_AND)
  printf_filtered ("%-6s (%i) %u, ON=%i, chain_type=%i, cause break=%i\n", compare_to_names[mp->dcr.ct],
 
                   mp->dcr.cc, mp->dvr, mp->dcr.dp, mp->chain_type, mp->cause_breakpoint);
 
}
 
 
 
/* Build watchpoint(s) based on given structure.  */
 
 
 
static void
 
set_matchpoints (match, nmatch)
 
     struct matchpoint *match;
 
     int nmatch;
 
{
 
  int i;
 
  debug_regs_changed = 1;
 
  sift_matchpoints ();
 
  for (i = 0; i < nmatch; i++)
 
    {
 
      int num = or1k_implementation.num_used_matchpoints;
 
      dcr[num] = match[i].dcr;
 
      dvr[num] = match[i].dvr;
 
 
 
      /* Set chaining bits.  */
 
      dmr1 &= ~(3 << (2 * num));
 
      dmr1 |= match[i].chain_type << (2 * num);
 
 
 
      /* Set watchpoint bits */
 
      dmr2 &= 1 << num;
 
      dmr2 |= match[i].cause_breakpoint << num;
 
      matchpoint_user_count[i]++;
 
      or1k_implementation.num_used_matchpoints++;
 
    }
 
}
 
 
 
/* Returns nonzero, if matchpoints [start .. start+nmatch-1] are
 
   equal to match record. */
 
 
 
static int
 
matchpoint_matches (start, match, nmatch)
 
     int start;
 
     struct matchpoint *match;
 
     int nmatch;
 
{
 
  int i;
 
  if (nmatch + start >= or1k_implementation.num_matchpoints)
 
    return 0;
 
 
 
  for (i = 0; i < nmatch; i++)
    {
    {
      //!!!
      int j = i + start;
 
 
 
      /* Everything exept cause breakpoint must match.  */
 
      if (dcr[j].dp != match[i].dcr.dp
 
          || dcr[j].ct != match[i].dcr.ct
 
          || dcr[j].cc != match[i].dcr.cc
 
          || dcr[j].sc != match[i].dcr.sc
 
          || dvr[j] != match[i].dvr
 
          || match[i].chain_type != (dmr1 >> (2 * j)) & 3)
 
        return 0;
    }
    }
 
  return 1;
}
}
 
 
/* ARGSUSED */
 
/* accessflag:  hw_write:  watch write,
 
                hw_read:   watch read,
 
                hw_access: watch access (read or write) */
 
static void
static void
hwatch_command (arg, from_tty)
hwatch_command (arg, from_tty)
     char *arg;
     char *arg;
     int from_tty;
     int from_tty;
{
{
  struct expression *exp;
  struct expression *exp;
  int i;
  int i, nfree, nmatch, remove = 0;
  int nfree;
  struct matchpoint *match;
 
 
 
  if (arg == NULL)
 
    arg = "";
 
  if (strncasecmp ("remove ", arg, 7) == 0)
 
    {
 
      arg += 7;
 
      remove = 1;
 
    }
 
 
  /* Parse arguments.  */
  /* Parse arguments.  */
  exp = parse_exp_1 (&arg, 0, 0);
  exp = parse_exp_1 (&arg, 0, 0);
 
 
 
#ifdef DEBUG
  dump_prefix_expression (exp, gdb_stdout, "expr1");
  dump_prefix_expression (exp, gdb_stdout, "expr1");
 
#endif  
 
 
 
  if (or1k_parse_or (&exp->elts[0], &match, &nmatch, 1) == &exp_error)
 
    error ("Watchpoint too complex.");
 
 
 
  for (i = 0; i < nmatch; i++)
 
    print_matchpoint_struct (&match[i]);
 
 
 
  if (remove)
 
    {
 
      int start = -1;
 
      int cleared = 0;
 
 
 
      if (num_hw_watches <= 0)
 
        error ("No extended hardware supported watchpoints present.");
 
 
 
      for (i = 0; i < num_hw_watches; i++)
 
        if (matchpoint_matches (or1k_hwatch[i].matchpoint_start, match, nmatch))
 
          {
 
            start = or1k_hwatch[i].matchpoint_start;
 
            break;
 
          }
 
 
 
      if (start < 0)
 
        error ("Watchpoint not found.");
 
 
 
      for (i = 0; i < nmatch; i++)
 
        {
 
          int j = start + i;
 
          if (--matchpoint_user_count[j] <= 0)
 
            {
 
              debug_regs_changed = 1;
 
              memset (&dcr[j], 0, sizeof (dcr[j]));
 
              or1k_implementation.num_used_matchpoints--;
 
              cleared = 1;
 
            }
 
        }
 
      if (!cleared)
 
        warning ("No matchpoint(s) freed. Resources are busy.");
 
    }
 
  else
 
    {
 
      if (num_hw_watches >= MAX_HW_WATCHES)
 
        error ("Number of watchpoints too large.");
 
 
 
      /* Now we have to find out if given prefix expression matches
 
         our HW based support. It may take up to
 
         or1k_implementation.num_matchpoints - or1k_implementation.num_used_matchpoints. */
 
      nfree = or1k_implementation.num_matchpoints - or1k_implementation.num_used_matchpoints;
 
 
 
      if (nmatch > nfree)
 
        error ("Not enough free matchpoint resources.");
 
 
 
      /* Build watchpoint(s) based on just built structure.  */
 
      or1k_hwatch[num_hw_watches].matchpoint_start = or1k_implementation.num_used_matchpoints;
 
      set_matchpoints (match, nmatch);
 
      num_hw_watches++;
 
      printf_unfiltered ("Watchpoint successfully allocated.\n");
 
    }
 
  free (match);
 
  free (exp);
 
}
 
 
 
static void
 
htrace_command (args, from_tty)
 
     char *args;
 
     int from_tty;
 
{
 
  help_list (htrace_cmdlist, "htrace ", all_commands, gdb_stdout);
 
}
 
 
 
static void
 
htrace_mode_command (args, from_tty)
 
     char *args;
 
     int from_tty;
 
{
 
  help_list (htrace_mode_cmdlist, "htrace mode ", all_commands, gdb_stdout);
 
}
 
 
 
static void
 
htrace_mode_contin_command (args, from_tty)
 
     char *args;
 
     int from_tty;
 
{
 
  or1k_htrace.moder.contin = 1;
 
  printf_unfiltered ("Continuous trace mode set.\n");
 
}
 
 
 
static void
 
htrace_mode_suspend_command (args, from_tty)
 
     char *args;
 
     int from_tty;
 
{
 
  or1k_htrace.moder.contin = 0;
 
  printf_unfiltered ("Suspend trace mode set.\n");
 
}
 
 
 
static void print_event_struct (event, stop)
 
     struct htrace_event_struct *event;
 
     int stop;
 
{
 
  int i;
 
  if (event->operation == TRIGOP_ANY)
 
    if (stop)
 
      printf_filtered ("not active");
 
    else
 
      printf_filtered ("always active");
 
  else
 
    {
 
      char *comma;
 
      if (event->operation == TRIGOP_AND)
 
        comma = "&(";
 
      else
 
        comma = "|(";
 
 
  if (or1k_parse_any (&exp->elts[0]))
      if (event->is_valid)
 
        {
 
          printf_filtered ("%s%s", comma, or1k_is_names[event->is_trig]);
 
          comma = ", ";
 
        }
 
      if (event->ls_valid)
 
        {
 
          printf_filtered ("%s%s", comma, or1k_ls_names[event->ls_trig]);
 
          comma = ", ";
 
        }
 
      if (event->bp_valid)
 
        {
 
          printf_filtered ("%sbreak", comma);
 
          comma = ", ";
 
        }
 
      if (event->wp_valid)
 
        for (i = 0; i < 11; i++)
 
          if ((event->wp_trig >> i) & 1)
    {
    {
      //!!!
              printf_filtered ("%sWP%i", comma, i);
      printf_unfiltered ("Watchpoint successfully allocated.");
              comma = ", ";
    }
    }
 
      if (comma[0] == ',')
 
        printf_filtered (")");
  else
  else
    printf_unfiltered ("Not enough resources to set specified watchpoint.");
        printf_filtered ("not active");
 
    }
 
}
 
 
 
static void
 
print_record_struct (record)
 
     struct htrace_record_struct *record;
 
{
 
  int i;
 
  char *comma = "";
 
  for (i = 0; i < MAX_RECORD_NAMES; i++)
 
    {
 
      if ((record->rec >> i)&1)
 
        {
 
          printf_filtered ("%s%s", comma, or1k_record_names[i]);
 
          comma = ", ";
 
        }
 
    }
 
  if (!*comma)
 
    printf_unfiltered ("none");
 
}
 
 
 
static void
 
htrace_info_command (args, from_tty)
 
     char *args;
 
     int from_tty;
 
{
 
  int i;
 
  printf_filtered ("Trace trigger: ");
 
  print_event_struct (&or1k_htrace.trig, 0);
 
  printf_filtered ("\nTrace qualifier: ");
 
  print_event_struct (&or1k_htrace.qual, 0);
 
  for (i = 0; i < MAX_MATCHPOINTS; i++)
 
    {
 
      printf_filtered ("\n WP%i records: ", i);
 
      print_record_struct (&or1k_htrace.recwp[i]);
 
    }
 
  printf_filtered ("\n BP records: ");
 
  print_record_struct (&or1k_htrace.recbp);
 
  printf_filtered ("\nTrace stop: ");
 
  print_event_struct (&or1k_htrace.stop, 1);
 
  printf_filtered ("\n");
 
}
 
 
 
/* Parses event from given string.
 
   Result is placed into event structure, and previously allocated
 
   resources are freed.  Parameter stop is nonzero, when we are parsing
 
   for stop criteria.  */
 
 
 
static void
 
parse_event (args, event, stop)
 
     char *args;
 
     struct htrace_event_struct *event;
 
     int stop;
 
{
 
  int i, op_type = 0, was_last_op = 1, any = 0;
 
 
 
  /* Release previous resources.  */
 
  for (i = 0; i < MAX_MATCHPOINTS; i++)
 
    {
 
      if ((event->wp_trig << i) & 1)
 
        if (--matchpoint_user_count[i] <= 0)
 
          {
 
            memset (&dcr[i], 0, sizeof (dcr[i]));
 
            debug_regs_changed = 1;
 
            or1k_implementation.num_used_matchpoints--;
 
          }
 
    }
 
 
 
  event->is_valid = event->is_trig = 0;
 
  event->ls_valid = event->ls_trig = 0;
 
  event->bp_valid = event->bp_trig = 0;
 
  event->wp_valid = event->wp_trig = 0;
 
 
 
  if (args == NULL)
 
    args = "";
 
  while (*args == ' ')
 
    args++;
 
 
 
  while (*args != '\0')
 
    {
 
      if (strncasecmp ("breakpoint", args, 10) == 0)
 
        {
 
          if (!was_last_op)
 
            error ("Syntax error.");
 
          was_last_op = 0;
 
          event->bp_valid = event->bp_trig = 1;
 
        }
 
      else if (!stop && strncasecmp ("any", args, 3) == 0
 
               || stop && strncasecmp ("none", args, 4) == 0)
 
        {
 
          if (!was_last_op)
 
            error ("Syntax error.");
 
          was_last_op = 0;
 
          any = 1;
 
        }
 
      else if (strncasecmp ("||", args, 2) == 0)
 
        {
 
          if (op_type == TRIGOP_AND)
 
            error ("Only one type of logical operator allowed at a time.");
 
          op_type = TRIGOP_OR;
 
          if (was_last_op)
 
            error ("Syntax error.");
 
          was_last_op = 1;
 
          args += 2;
 
        }
 
      else if (strncasecmp ("&&", args, 2) == 0)
 
        {
 
          if (op_type == TRIGOP_OR)
 
            error ("Only one type of logical operator allowed at a time.");
 
          op_type = TRIGOP_AND;
 
          if (was_last_op)
 
            error ("Syntax error.");
 
          was_last_op = 1;
 
          args += 2;
 
        }
 
      else
 
        {
 
          int found = 0;
 
          if (!was_last_op)
 
            error ("Syntax error.");
 
          was_last_op = 0;
 
 
 
          /* Search through is and ls tables for a match.  */
 
          for (i = 0; i < MAX_IS_NAMES; i++)
 
            if (strncasecmp (args, or1k_is_names[i], strlen (or1k_is_names[i])) == 0)
 
              {
 
                event->is_valid = 1;
 
                event->is_trig = i;
 
                args +=  strlen (or1k_is_names[i]);
 
                found = 1;
 
                break;
 
              }
 
          if (!found)
 
            {
 
              for (i = 0; i < MAX_LS_NAMES; i++)
 
                if (strncasecmp (args, or1k_ls_names[i], strlen (or1k_ls_names[i])) == 0)
 
                  {
 
                    event->ls_valid = 1;
 
                    event->ls_trig = i;
 
                    args +=  strlen (or1k_ls_names[i]);
 
                    found = 1;
 
                    break;
 
                  }
 
            }
 
          if (!found)
 
            {
 
              /* No special name was found => parse expression.  */
 
              struct expression *exp;
 
              struct matchpoint *match;
 
              int nmatch, nfree;
 
 
 
              exp = parse_exp_1 (&args, 0, 0);
 
 
 
              if (or1k_parse_any (&exp->elts[0], &match, &nmatch, 3) == &exp_error)
 
                error ("Expression too complex.");
 
              for (i = 0; i < nmatch; i++)
 
                print_matchpoint_struct (&match[i]);
 
 
  /* Now we have to find out if given prefix expression matches
  /* Now we have to find out if given prefix expression matches
     our HW based support. It may take up to
     our HW based support. It may take up to
     or1k_implementation.num_matchpoints - or1k_implementation.num_used_matchpoints. */
     or1k_implementation.num_matchpoints - or1k_implementation.num_used_matchpoints. */
  nfree = or1k_implementation.num_matchpoints - or1k_implementation.num_used_matchpoints;
  nfree = or1k_implementation.num_matchpoints - or1k_implementation.num_used_matchpoints;
  //printf_unfiltered ("%s\n", exp->elts[1].internalvar->name);
 
 
              if (nmatch > nfree)
 
                error ("Not enough free matchpoint resources.");
 
 
 
              /* Build matchpoint(s) based on just built structure.  */
 
              set_matchpoints (match, nmatch);
 
              event->wp_valid = 1;
 
              event->wp_trig |= 1 << (or1k_implementation.num_used_matchpoints - 1);
 
              printf_unfiltered ("Watchpoint successfully allocated.\n");
 
              free (match);
  free (exp);
  free (exp);
 
              found = 1;
 
            }
 
          if (!found)
 
            warning ("Invalid event at '%s'", args);
 
        }
 
      while (*args == ' ') args++;
 
    }
 
  if (any)
 
    event->operation = TRIGOP_ANY;
 
  else
 
    {
 
      if (op_type == 0)
 
        op_type = TRIGOP_AND;
 
      event->operation = op_type;
 
    }
 
}
 
 
 
static void
 
htrace_trigger_command (args, from_tty)
 
     char *args;
 
     int from_tty;
 
{
 
  parse_event (args, &or1k_htrace.trig, 0);
 
  printf_filtered ("Trace starts, when:\n");
 
  print_event_struct (&or1k_htrace.trig, 0);
 
  printf_filtered ("\n");
 
}
 
 
 
static void
 
htrace_qualifier_command (args, from_tty)
 
     char *args;
 
     int from_tty;
 
{
 
  parse_event (args, &or1k_htrace.qual, 0);
 
  printf_filtered ("Trace records, when:\n");
 
  print_event_struct (&or1k_htrace.qual, 0);
 
  printf_filtered ("\n");
 
}
 
 
 
static void
 
htrace_stop_command (args, from_tty)
 
     char *args;
 
     int from_tty;
 
{
 
  parse_event (args, &or1k_htrace.stop, 1);
 
  printf_filtered ("Trace stops, when:\n");
 
  print_event_struct (&or1k_htrace.stop, 1);
 
  printf_filtered ("\n");
 
}
 
 
 
static void
 
htrace_clear_records_command (args, from_tty)
 
     char *args;
 
     int from_tty;
 
{
 
  int i, j, cleared = 0;
 
 
 
  /* Clear all. */
 
  for (i = 0; i < MAX_MATCHPOINTS; i++)
 
    {
 
      for (j = 0; j < MAX_MATCHPOINTS; j++)
 
        {
 
          if ((or1k_htrace.wp_record_uses[i] << j) & 1)
 
            if (--matchpoint_user_count[j] <= 0)
 
            {
 
              memset (&dcr[j], 0, sizeof (dcr[j]));
 
              debug_regs_changed = 1;
 
              cleared = 1;
 
              or1k_implementation.num_used_matchpoints--;
 
            }
 
        }
 
      or1k_htrace.wp_record_uses[i] = 0;
 
    }
 
  if (!cleared)
 
    warning ("No matchpoints freed. Resources are busy.");
 
}
 
 
 
/* Syntax: htrace record {data}* when {expr} */
 
 
 
static void
 
htrace_record_command (args, from_tty)
 
     char *args;
 
     int from_tty;
 
{
 
  struct expression *exp;
 
  int i, nfree, nmatch, wp;
 
  struct matchpoint *match;
 
  unsigned int recdata = 0;
 
  char *c;
 
 
 
  if (args == '\0')
 
    error ( "Please specify data to record, e.g.:\n"
 
            "htrace record PC WRITESPR SDATA when $SEA == 100\n"
 
            "htrace record when $SEA == 100 to remove record");
 
 
 
  for (i = 0; *args != '\0' && strncasecmp ("when ", args, 5); i++)
 
    {
 
      int j, found = 0;
 
      for (j = 0; j < MAX_RECORD_NAMES; j++)
 
        if (strncasecmp (args, or1k_record_names[j], strlen (or1k_record_names[j])) == 0)
 
          {
 
            recdata |= 1 << j;
 
            found = 1;
 
            break;
 
          }
 
      if (!found)
 
        warning ("Invalid record data name at '%s'.", args);
 
      while (*args != ' ' && *args != '\0') args++;
 
      while (*args == ' ') args++;
 
    }
 
 
 
  if (strncasecmp ("when ", args, 5) != 0)
 
    if (*args == '\0')
 
      {
 
        warning ("Condition not set. Assuming breakpoint.");
 
        wp = -1;
 
      }
 
    else
 
      error ("Syntax error.");
 
  else
 
    {
 
      args += 5;
 
      if (strcasecmp ("breakpoint", args) == 0)
 
        wp = -1;
 
      else
 
        {
 
          /* Parse arguments.  */
 
          exp = parse_exp_1 (&args, 0, 0);
 
 
 
#ifdef DEBUG
 
          dump_prefix_expression (exp, gdb_stdout, "expr1");
 
#endif
 
          if (or1k_parse_any (&exp->elts[0], &match, &nmatch, 3) == &exp_error)
 
            error ("Expression too complex.");
 
 
 
          for (i = 0; i < nmatch; i++)
 
            print_matchpoint_struct (&match[i]);
 
 
 
          if (recdata)
 
            {
 
              /* Now we have to find out if given prefix expression matches
 
                 our HW based support. It may take up to
 
                 or1k_implementation.num_matchpoints - or1k_implementation.num_used_matchpoints. */
 
              nfree = or1k_implementation.num_matchpoints - or1k_implementation.num_used_matchpoints;
 
 
 
              if (nmatch > nfree)
 
                error ("Not enough free matchpoint resources.");
 
 
 
              wp = or1k_implementation.num_used_matchpoints - 1;
 
              or1k_htrace.wp_record_uses[wp] = 0;
 
              for (i = or1k_implementation.num_used_matchpoints; i <= wp; i++)
 
                or1k_htrace.wp_record_uses[wp] |= 1 << i;
 
              set_matchpoints (match, nmatch);
 
            }
 
          else
 
            {
 
              /* Remove record. */
 
              int start = -1, cleared = 0;
 
 
 
              for (i = 0; i < MAX_MATCHPOINTS; i++)
 
                {
 
                  int mp_start = 0, j;
 
                  j = or1k_htrace.wp_record_uses[i];
 
                  while (j > 0 && j & 1 == 0)
 
                    mp_start++;
 
 
 
                  if (matchpoint_matches (mp_start, match, nmatch))
 
                    {
 
                      start = mp_start;
 
                      or1k_htrace.wp_record_uses[i] = 0;
 
                      break;
 
                    }
 
                }
 
              if (start < 0)
 
                error ("Record with such expression not found.");
 
 
 
              for (i = 0; i < nmatch; i++)
 
                {
 
                  int j = i + start;
 
                  if (--matchpoint_user_count[j] <= 0)
 
                    {
 
                      memset (&dcr[j], 0, sizeof (dcr[j]));
 
                      debug_regs_changed = 1;
 
                      cleared = 1;
 
                    }
 
                }
 
              if (!cleared)
 
                warning ("No matchpoint(s) freed.");
 
            }
 
        }
 
    }
 
 
 
  /* If we reached this point we have matchpoints set, and wp
 
     holds the value of that watchpoint.  wp == -1, if breakpoint
 
     was specified.  */
 
  if (wp < 0)
 
    or1k_htrace.recbp.rec = recdata;
 
  else
 
    or1k_htrace.recwp[wp].rec = recdata;
 
 
 
  if (recdata)
 
    {
 
      printf_unfiltered ("Data");
 
      for (i = 0; i < MAX_RECORD_NAMES; i++)
 
        if ((recdata >> i) & 1)
 
          printf_unfiltered (" %s,", or1k_record_names[i]);
 
    }
 
  else
 
    printf_unfiltered ("No data");
 
  if (wp < 0)
 
    printf_unfiltered (" will be recorded when breakpoint occurs\n");
 
  else
 
    printf_unfiltered (" will be recorded when watchpoint #%i occurs\n", wp);
 
}
 
 
 
static void
 
htrace_enable_command (args, from_tty)
 
     char *args;
 
     int from_tty;
 
{
 
  or1k_htrace.moder.trace_enable = 1;
 
  printf_unfiltered ("HW Trace enabled.\n");
 
}
 
 
 
static void
 
htrace_disable_command (args, from_tty)
 
     char *args;
 
     int from_tty;
 
{
 
  or1k_htrace.moder.trace_enable = 0;
 
  printf_unfiltered ("HW Trace disabled.\n");
 
}
 
 
 
static void
 
htrace_rewind_command (args, from_tty)
 
     char *args;
 
     int from_tty;
 
{
 
  FILE *f;
 
  if (args != NULL && *args != '\0')
 
    strncpy (TRACE_FILENAME, args, TRACE_FILENAME_SIZE);
 
 
 
  /* Just empty it.  */
 
  if ((f = fopen (TRACE_FILENAME, "wb+")) == NULL)
 
    error ("Cannot open trace file.");
 
  fclose (f);
 
  printf_unfiltered ("Trace data cleared.\n");
 
}
 
 
 
static void
 
print_data_struct (pos, data)
 
     unsigned int pos;
 
     struct htrace_data_struct *data;
 
{
 
  struct symbol *func;
 
  char *funname = NULL;
 
 
 
  if (data->type < 4)
 
    {
 
      /* Determine function name - copied from stack.c  */
 
      func = find_pc_function (data->data);
 
      if (func)
 
        {
 
          struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (data->data);
 
          if (msymbol != NULL
 
              && (SYMBOL_VALUE_ADDRESS (msymbol)
 
                  > BLOCK_START (SYMBOL_BLOCK_VALUE (func))))
 
            funname = SYMBOL_NAME (msymbol);
 
          else
 
            {
 
              char *demangled;
 
              funname = SYMBOL_NAME (func);
 
              if (SYMBOL_LANGUAGE (func) == language_cplus)
 
                {
 
                  demangled = cplus_demangle (funname, DMGL_ANSI);
 
                  if (demangled == NULL)
 
                    funname = SYMBOL_SOURCE_NAME (func);
 
                }
 
            }
 
        }
 
      else
 
        {
 
          struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (data->data);
 
          if (msymbol != NULL)
 
            funname = SYMBOL_NAME (msymbol);
 
        }
 
    }
 
 
 
  printf_filtered ("%06X%c %-8s %08X", pos, data->valid ? '>' : ':',
 
                   or1k_record_names[data->type], data->data);
 
  if (funname)
 
    printf_filtered (" (%s)\n", funname);
 
  else
 
    printf_filtered ("\n");
 
}
 
 
 
/* Prints out trace buffer.  */
 
 
 
static void
 
htrace_print_command (args, from_tty)
 
     char *args;
 
     int from_tty;
 
{
 
  int i, from = 0, length = prev_length;
 
  FILE *f;
 
  struct htrace_data_struct *td;
 
 
 
  if (args == NULL) args = "";
 
  while (*args == ' ') args++;
 
  if (*args == '\0')
 
    {
 
      /* We will display buffer further. */
 
      from = prev_from + prev_length;
 
    }
 
  else
 
    {
 
      /* Display buffer range.  */
 
      int numbers = 0;
 
      char *cnum = args;
 
      while (*args != ' ' && *args != '\0')
 
        args++;
 
 
 
      /* Any arguments?  */
 
      if (*args == '\0')
 
        numbers = 1;
 
      else
 
        {
 
          *args = 0;
 
          args++;
 
          numbers = 2;
 
        }
 
      from = strtoul (cnum, &cnum, 0);
 
      if (*cnum != 0)
 
        error ("Invalid from value.");
 
      if (from < 0) from += trace_size;
 
      if (numbers == 2)
 
        {
 
          while (*args == ' ') args++;
 
          length = strtoul (cnum, &cnum, 0);
 
          if (*args != 0)
 
            error ("Invalid length value.");
 
          if (length < 0)
 
            {
 
              from += length;
 
              length = -length;
 
            }
 
        }
 
    }
 
 
 
  if (from >= trace_size)
 
    from = trace_size - 1;
 
  if (from < 0)
 
    from = 0;
 
  if (from + length >= trace_size)
 
    length = trace_size - from;
 
 
 
  prev_length = length;
 
  prev_from = from;
 
  if (length == 0)
 
    error ("Nothing to print.");
 
 
 
  printf_filtered ("Trace buffer %06x:%06x (size = %i)\n", from, from + length - 1, length);
 
  if ((f = fopen (TRACE_FILENAME, "rb")) == NULL)
 
    error ("Cannot open trace file.");
 
  if (fseek (f, TRACE_DATA_SIZE * from, SEEK_SET))
 
    error ("Error reading trace file.");
 
  td = (struct htrace_data_struct *) malloc (TRACE_DATA_SIZE * length);
 
  length = fread (td, TRACE_DATA_SIZE, length, f);
 
  for (i = 0; i < length; i++)
 
    print_data_struct (from + i, td[i]);
 
  fclose (f);
}
}
 
 
void
void
_initialize_or1k_tdep ()
_initialize_or1k_tdep ()
{
{
  struct cmd_list_element *c;
  /* Commands to show and set sprs.  */
  /* Add root prefix command for all "set or1k"/"show or1k" commands */
 
  add_prefix_cmd ("or1k", no_class, set_or1k_command,
 
                  "Various OR1K specific commands.",
 
                  &setor1kcmdlist, "set or1k ", 0, &setlist);
 
 
 
  add_prefix_cmd ("or1k", no_class, show_or1k_command,
 
                  "Various OR1K specific commands.",
 
                  &showor1kcmdlist, "show or1k ", 0, &showlist);
 
 
 
  /* Commands to show information about the sprs.  */
 
  add_info ("spr", info_spr_command, "Show information about the spr registers.");
  add_info ("spr", info_spr_command, "Show information about the spr registers.");
  add_com ("hwatch", class_breakpoint, hwatch_command, "Set hardware watchpoint.");
 
  add_com ("spr", class_support, spr_command, "Set specified SPR register.");
  add_com ("spr", class_support, spr_command, "Set specified SPR register.");
 
 
 
  /* hwatch command.  */
 
  add_com ("hwatch", class_breakpoint, hwatch_command, "Set hardware watchpoint.\n\
 
Example: ($LEA == my_var)&&($LDATA < 50)||($SEA == my_var)&&($SDATA >= 50).\n\
 
See OR1k Architecture document for more info.");
 
 
 
  /* htrace commands.  */
 
  add_prefix_cmd ("htrace", class_breakpoint, htrace_command,
 
                  "Set hardware trace.\nExamples:\n"
 
                  "  htrace info\n"
 
                  "  htrace trigger <expr>\n"
 
                  "  htrace qualifier <expr>\n"
 
                  "  htrace stop <expr>\n"
 
                  "  htrace record <data> when [<expr>|breakpoint]\n"
 
                  "  htrace clear recors\n"
 
                  "  htrace enable\n"
 
                  "  htrace disable\n"
 
                  "  htrace control\n\n"
 
                  "See OR1k Architecture and gdb for or1k documents for more info.",
 
                  &htrace_cmdlist, "htrace ", 0, &cmdlist);
 
  add_cmd ("info", class_breakpoint, htrace_info_command, "Display information about HW trace.",
 
           &htrace_cmdlist);
 
  add_alias_cmd ("i", "info", class_breakpoint, 1, &htrace_cmdlist);
 
  add_cmd ("trigger", class_breakpoint, htrace_trigger_command, "Set starting criteria for trace.",
 
           &htrace_cmdlist);
 
  add_alias_cmd ("t", "trigger", class_breakpoint, 1, &htrace_cmdlist);
 
  add_cmd ("qualifier", class_breakpoint, htrace_qualifier_command, "Set acquisition qualifier for HW trace.",
 
           &htrace_cmdlist);
 
  add_alias_cmd ("q", "qualifier", class_breakpoint, 1, &htrace_cmdlist);
 
  add_cmd ("stop", class_breakpoint, htrace_stop_command, "Set HW trace stopping criteria.",
 
           &htrace_cmdlist);
 
  add_alias_cmd ("s", "stop", class_breakpoint, 1, &htrace_cmdlist);
 
  add_cmd ("record", class_breakpoint, htrace_record_command, "Sets data to be recorded when expression occurs.",
 
           &htrace_cmdlist);
 
  add_alias_cmd ("r", "record", class_breakpoint, 1, &htrace_cmdlist);
 
  add_cmd ("clear records", class_breakpoint, htrace_clear_records_command,
 
           "Disposes all matchpoints used by records.", &htrace_cmdlist);
 
  add_cmd ("enable", class_breakpoint, htrace_enable_command, "Enables the HW trace.", &htrace_cmdlist);
 
  add_alias_cmd ("e", "enable", class_breakpoint, 1, &htrace_cmdlist);
 
  add_cmd ("disable", class_breakpoint, htrace_disable_command, "Disables the HW trace.", &htrace_cmdlist);
 
  add_alias_cmd ("d", "disable", class_breakpoint, 1, &htrace_cmdlist);
 
  add_cmd ("rewind", class_breakpoint, htrace_rewind_command, "Clears currently recorded trace data.\n"
 
           "If filename is specified, new trace file is made and any newly collected data\n"
 
           "will be written there.", &htrace_cmdlist);
 
  add_cmd ("print", class_breakpoint, htrace_print_command,
 
           "Prints trace buffer, using current record configuration.\n"
 
           "htrace print [<start> [<len>]]\n"
 
           "htrace print"
 
           , &htrace_cmdlist);
 
  add_alias_cmd ("p", "print", class_breakpoint, 1, &htrace_cmdlist);
 
  add_prefix_cmd ("mode", class_breakpoint, htrace_mode_command,
 
           "Configures the HW trace.\n"
 
           "htrace mode [continuous|suspend]"
 
           , &htrace_mode_cmdlist, "htrace mode ", 0, &htrace_cmdlist);
 
  add_alias_cmd ("m", "mode", class_breakpoint, 1, &htrace_cmdlist);
 
  add_cmd ("continuous", class_breakpoint, htrace_mode_contin_command,
 
           "Set continuous trace mode.\n", &htrace_mode_cmdlist);
 
  add_cmd ("suspend", class_breakpoint, htrace_mode_suspend_command,
 
           "Set suspend trace mode.\n", &htrace_mode_cmdlist);
 
 
 
  /* Extra functions supported by simulator.  */
  add_com ("sim", class_obscure, sim_command,
  add_com ("sim", class_obscure, sim_command,
           "Send a extended command to the simulator.");
           "Send a extended command to the simulator.");
}
}
 
 
 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.