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

Subversion Repositories or1k

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

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

Rev 115 Rev 116
/* 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.
 
 
   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 "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"
#include "value.h"
#include "value.h"
#include "gdbcmd.h"
#include "gdbcmd.h"
#include "language.h"
#include "language.h"
#include "gdbcore.h"
#include "gdbcore.h"
#include "symfile.h"
#include "symfile.h"
#include "objfiles.h"
#include "objfiles.h"
#include "gdbtypes.h"
#include "gdbtypes.h"
#include "target.h"
#include "target.h"
 
 
#include "opcode/or32.h"
#include "opcode/or32.h"
 
 
/* *INDENT-OFF* */
/* *INDENT-OFF* */
 
 
/* Group reg name size.  See or1k_reg_names.  */
/* Group reg name size.  See or1k_reg_names.  */
int or1k_group_name_sizes[OR1K_NUM_SPR_GROUPS] = {
int or1k_group_name_sizes[OR1K_NUM_SPR_GROUPS] = {
  80,   0,   0, 6, 4, 2,
  80,   0,   0, 6, 4, 2,
  23, 16, 1, 3, 2, 8};
  23, 16, 1, 3, 2, 8};
 
 
int or1k_group_name_start[OR1K_NUM_SPR_GROUPS] = {
int or1k_group_name_start[OR1K_NUM_SPR_GROUPS] = {
  0,   0,   0, 253, 254, 256,
  0,   0,   0, 253, 254, 256,
  32, 248, 16, 16, 255, 0};
  32, 248, 16, 16, 255, 0};
 
 
/* Generated reg names (max valid alias index).
/* Generated reg names (max valid alias index).
   See or1k_spr_reg_name.  */
   See or1k_spr_reg_name.  */
int or1k_spr_valid_aliases[OR1K_NUM_SPR_GROUPS] = {
int or1k_spr_valid_aliases[OR1K_NUM_SPR_GROUPS] = {
  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",
 
 
  /* group 7 - performance counters unit */
  /* group 7 - performance counters unit */
  "PCCM0", "PCMR1", "PCMR2", "PCMR3", "PCMR4", "PCMR5", "PCMR6", "PCMR7",
  "PCCM0", "PCMR1", "PCMR2", "PCMR3", "PCMR4", "PCMR5", "PCMR6", "PCMR7",
  "PCCR0", "PCCR1", "PCCR2", "PCCR3", "PCCR4", "PCCR5", "PCCR6", "PCCR7",
  "PCCR0", "PCCR1", "PCCR2", "PCCR3", "PCCR4", "PCCR5", "PCCR6", "PCCR7",
 
 
  /* group 8 - power management */
  /* group 8 - power management */
  "PMR",
  "PMR",
 
 
  /* group 9 - PIC */
  /* group 9 - PIC */
  "PICMR", "PICPR",
  "PICMR", "PICPR",
 
 
  /* group 10 - tick timer */
  /* group 10 - tick timer */
  "TTMR", "TTCR",
  "TTMR", "TTCR",
 
 
  /* 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",
  "PC",    "SR",    "EPCR"
  "PC",    "SR",    "EPCR"
};
};
 
 
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"},
  {"DFPE", "Data Page Fault Exception"},
  {"DFPE", "Data Page Fault Exception"},
  {"IFPE", "Instruction Page Fault Exception"},
  {"IFPE", "Instruction Page Fault Exception"},
  {"LPINTE", "Low Priority Interrupt Exception"},
  {"LPINTE", "Low Priority Interrupt Exception"},
  {"AE", "Alignment Exception"},
  {"AE", "Alignment Exception"},
  {"HPINTE", "High Priority Interrupt Exception"},
  {"HPINTE", "High Priority Interrupt Exception"},
  {"DME", "DTLB Miss Exception"},
  {"DME", "DTLB Miss Exception"},
  {"IME", "ITLB Miss Exception"},
  {"IME", "ITLB Miss Exception"},
  {"RE", "Range Exception"},
  {"RE", "Range Exception"},
  {"SCE", "SCE Exception"}, //!!!
  {"SCE", "SCE Exception"}, //!!!
  {NULL, NULL}
  {NULL, NULL}
};
};
 
 
/* *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 *setor1kcmdlist = NULL;
static struct cmd_list_element *showor1kcmdlist = NULL;
static struct cmd_list_element *showor1kcmdlist = 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];
 
 
 
 
/* 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);
  if (regno < MAX_GPR_REGS + MAX_VF_REGS)
  if (regno < MAX_GPR_REGS + MAX_VF_REGS)
    return SPR_REG(SPR_SYSTEM_GROUP, regno - MAX_GPR_REGS
    return SPR_REG(SPR_SYSTEM_GROUP, regno - MAX_GPR_REGS
                   + CURRENT_CID * MAX_GPR_REGS + SPR_VFPR_START);
                   + CURRENT_CID * MAX_GPR_REGS + SPR_VFPR_START);
  if (regno == PS_REGNUM)
  if (regno == PS_REGNUM)
    return SR_SPRNUM;
    return SR_SPRNUM;
  if (regno == PC_REGNUM)
  if (regno == PC_REGNUM)
    return PC_SPRNUM;
    return PC_SPRNUM;
  if (regno == CCR_REGNUM)
  if (regno == CCR_REGNUM)
    return CCR_SPRNUM(CURRENT_CID);
    return CCR_SPRNUM(CURRENT_CID);
  error ("Invalid register number!");
  error ("Invalid register number!");
}
}
 
 
/* Builds and returns register name.  */
/* Builds and returns register name.  */
 
 
static char tmp_name[16];
static char tmp_name[16];
static char *
static char *
or1k_spr_register_name (i)
or1k_spr_register_name (i)
     int i;
     int i;
{
{
  int group = i >> SPR_GROUP_SIZE_BITS;
  int group = i >> SPR_GROUP_SIZE_BITS;
  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);
          else
          else
            sprintf (tmp_name, "VFR%i", index - SPR_VFPR_START);
            sprintf (tmp_name, "VFR%i", index - SPR_VFPR_START);
          return (char *)&tmp_name;
          return (char *)&tmp_name;
        }
        }
    case 3:
    case 3:
    case 4:
    case 4:
    case 5:
    case 5:
    case 6:
    case 6:
    case 7:
    case 7:
    case 8:
    case 8:
    case 9:
    case 9:
    case 10:
    case 10:
      {
      {
        int group_start = 0;
        int group_start = 0;
        for (i = 0; i < group; i++)
        for (i = 0; i < group; i++)
          group_start += or1k_group_name_sizes[i];
          group_start += or1k_group_name_sizes[i];
 
 
        if (index >= or1k_group_name_sizes[group])
        if (index >= or1k_group_name_sizes[group])
          {
          {
            sprintf (tmp_name, "SPR%i_%i", group, index);
            sprintf (tmp_name, "SPR%i_%i", group, index);
            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)
        {
        {
        case 16:
        case 16:
          return strcat (tmp_name, "MMUCR");
          return strcat (tmp_name, "MMUCR");
        case 17:
        case 17:
          return strcat (tmp_name, "MMUPR");
          return strcat (tmp_name, "MMUPR");
        case 18:
        case 18:
          return strcat (tmp_name, "TLBEIR");
          return strcat (tmp_name, "TLBEIR");
        case 24:
        case 24:
          return strcat (tmp_name, "ATBMR0");
          return strcat (tmp_name, "ATBMR0");
        case 25:
        case 25:
          return strcat (tmp_name, "ATBMR1");
          return strcat (tmp_name, "ATBMR1");
        case 26:
        case 26:
          return strcat (tmp_name, "ATBMR2");
          return strcat (tmp_name, "ATBMR2");
        case 27:
        case 27:
          return strcat (tmp_name, "ATBMR3");
          return strcat (tmp_name, "ATBMR3");
        case 28:
        case 28:
          return strcat (tmp_name, "ATBTR0");
          return strcat (tmp_name, "ATBTR0");
        case 29:
        case 29:
          return strcat (tmp_name, "ATBTR0");
          return strcat (tmp_name, "ATBTR0");
        case 30:
        case 30:
          return strcat (tmp_name, "ATBTR0");
          return strcat (tmp_name, "ATBTR0");
        case 31:
        case 31:
          return strcat (tmp_name, "ATBTR0");
          return strcat (tmp_name, "ATBTR0");
        default:
        default:
          if (index >= 1024) {
          if (index >= 1024) {
            index -= 1024;
            index -= 1024;
            sprintf (tmp_name, "%sTLBW%iMR%i", (group == 1)?"D":"I", index / 128, index % 128);
            sprintf (tmp_name, "%sTLBW%iMR%i", (group == 1)?"D":"I", index / 128, index % 128);
            return (char *)&tmp_name;
            return (char *)&tmp_name;
          }
          }
          sprintf (tmp_name, "SPR%i_%i", group, index);
          sprintf (tmp_name, "SPR%i_%i", group, index);
          return (char *)&tmp_name;
          return (char *)&tmp_name;
      }
      }
    default:
    default:
      sprintf (tmp_name, "SPR%i_%i", group, index);
      sprintf (tmp_name, "SPR%i_%i", group, index);
      return (char *)&tmp_name;
      return (char *)&tmp_name;
    }
    }
}
}
 
 
/* Get register index in group from name.  Negative if no match.  */
/* Get register index in group from name.  Negative if no match.  */
 
 
static int
static int
or1k_regno_from_name (group, name)
or1k_regno_from_name (group, name)
     int group;
     int group;
     char *name;
     char *name;
{
{
  int i;
  int i;
  if (toupper(name[0]) == 'S' && toupper(name[1]) == 'P' && toupper(name[2]) == 'R')
  if (toupper(name[0]) == 'S' && toupper(name[1]) == 'P' && toupper(name[2]) == 'R')
    {
    {
      char *ptr_c;
      char *ptr_c;
      name += 3;
      name += 3;
      i = (int) strtoul (name, &ptr_c, 10);
      i = (int) strtoul (name, &ptr_c, 10);
      if (*ptr_c != '_' || i != group)
      if (*ptr_c != '_' || i != group)
        return -1;
        return -1;
      ptr_c++;
      ptr_c++;
      i = (int) strtoul (name, &ptr_c, 10);
      i = (int) strtoul (name, &ptr_c, 10);
      if (*ptr_c)
      if (*ptr_c)
        return -1;
        return -1;
      else return i;
      else return i;
    }
    }
  for (i = 0; i < or1k_spr_valid_aliases[group]; i++)
  for (i = 0; i < or1k_spr_valid_aliases[group]; i++)
    {
    {
      char *s;
      char *s;
      s = or1k_spr_register_name (SPR_REG(group, i));
      s = or1k_spr_register_name (SPR_REG(group, i));
      if (strcasecmp (name, s) == 0)
      if (strcasecmp (name, s) == 0)
        return i;
        return i;
    }
    }
  return -1;
  return -1;
}
}
 
 
/* Resturs gdb register name.  */
/* Resturs 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];
}
}
 
 
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 */
  double doub, flt;             /* doubles extracted from raw hex data */
  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.  */
  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));
 
 
  flt = unpack_double (builtin_type_float, raw_buffer, &inv1);
  flt = unpack_double (builtin_type_float, raw_buffer, &inv1);
  doub = unpack_double (builtin_type_double, raw_buffer, &inv3);
  doub = unpack_double (builtin_type_double, raw_buffer, &inv3);
 
 
  printf_filtered (inv1 ? " %-5s flt: <invalid float>" :
  if (inv1)
                       " %-5s flt:%-17.9g", REGISTER_NAME (regnum), flt);
    printf_filtered (" %-5s flt: <invalid float>", REGISTER_NAME (regnum));
 
  else
 
    printf_filtered (" %-5s flt:%-17.9g", REGISTER_NAME (regnum), flt);
  printf_filtered (inv3 ? " dbl: <invalid double> " :
  printf_filtered (inv3 ? " dbl: <invalid double> " :
                   " 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++)
      printf_filtered ("%02x", (unsigned char) raw_buffer[byte]);
      printf_filtered ("%02x", (unsigned char) raw_buffer[byte]);
  else
  else
    for (byte = REGISTER_VIRTUAL_SIZE (regnum) - 1;
    for (byte = REGISTER_VIRTUAL_SIZE (regnum) - 1;
         byte >= 0;
         byte >= 0;
         byte--)
         byte--)
      printf_filtered ("%02x", (unsigned char) raw_buffer[byte]);
      printf_filtered ("%02x", (unsigned char) raw_buffer[byte]);
  printf_filtered ("\n");
  printf_filtered ("\n");
 
 
  regnum++;
  regnum++;
  return regnum;
  return regnum;
}
}
 
 
/* Print a row's worth of GP (int) registers, with name labels above */
/* Print a row's worth of GP (int) registers, with name labels above */
 
 
static int
static int
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 */
  int ncols = (OR1K_64BIT_IMPLEMENTATION ? 4 : 8);      /* display cols per row */
  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')
        continue;               /* unused register */
        continue;               /* unused register */
      if (OR1K_IS_VF(regnum))
      if (OR1K_IS_VF(regnum))
        break;                  /* end the row: reached VF register */
        break;                  /* end the row: reached VF register */
      printf_filtered (OR1K_64BIT_IMPLEMENTATION ? "%17s" : "%9s",
      printf_filtered (OR1K_64BIT_IMPLEMENTATION ? "%17s" : "%9s",
                       REGISTER_NAME (regnum));
                       REGISTER_NAME (regnum));
      col++;
      col++;
    }
    }
  printf_filtered ("\n      ");
  printf_filtered ("\n      ");
 
 
  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++)
    {
    {
      if (*REGISTER_NAME (regnum) == '\0')
      if (*REGISTER_NAME (regnum) == '\0')
        continue;               /* unused register */
        continue;               /* unused register */
      if (OR1K_IS_VF(regnum))
      if (OR1K_IS_VF(regnum))
        break;                  /* end row: reached VF register */
        break;                  /* end row: reached VF register */
      /* 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++)
          printf_filtered ("%02x", (unsigned char) raw_buffer[byte]);
          printf_filtered ("%02x", (unsigned char) raw_buffer[byte]);
      else
      else
        for (byte = REGISTER_VIRTUAL_SIZE (regnum) - 1;
        for (byte = REGISTER_VIRTUAL_SIZE (regnum) - 1;
             byte >= 0;
             byte >= 0;
             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... */
  if (col > 0)                   /* ie. if we actually printed anything... */
    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;
  char raw_buffer[MAX_REGISTER_RAW_SIZE];
  char raw_buffer[MAX_REGISTER_RAW_SIZE];
 
 
  /* Get the data in raw format.  */
  /* Get the data in raw format.  */
  if (read_relative_register_raw_bytes (regnum, raw_buffer))
  if (read_relative_register_raw_bytes (regnum, raw_buffer))
    {
    {
      printf_filtered ("%s: [Invalid]", REGISTER_NAME (regnum));
      printf_filtered ("%s: [Invalid]", REGISTER_NAME (regnum));
      return;
      return;
    }
    }
 
 
  /* If virtual format is floating, print it that way.  */
  /* If virtual format is floating, print it that way.  */
  if (OR1K_IS_VF (regnum))
  if (OR1K_IS_VF (regnum))
    do_vf_register (regnum);
    do_vf_register (regnum);
  else
  else
    {
    {
      int byte;
      int byte;
      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++)
          printf_filtered ("%02x", (unsigned char) raw_buffer[byte]);
          printf_filtered ("%02x", (unsigned char) raw_buffer[byte]);
      else
      else
        for (byte = REGISTER_VIRTUAL_SIZE (regnum) - 1;
        for (byte = REGISTER_VIRTUAL_SIZE (regnum) - 1;
             byte >= 0;
             byte >= 0;
             byte--)
             byte--)
          printf_filtered ("%02x", (unsigned char) raw_buffer[byte]);
          printf_filtered ("%02x", (unsigned char) raw_buffer[byte]);
      printf_filtered (" ");
      printf_filtered (" ");
    }
    }
}
}
 
 
/* DO_REGISTERS_INFO: called by "info register" command */
/* DO_REGISTERS_INFO: called by "info register" command */
 
 
void
void
or1k_do_registers_info (regnum, fpregs)
or1k_do_registers_info (regnum, fpregs)
     int regnum;
     int regnum;
     int fpregs;
     int fpregs;
{
{
  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");
    }
    }
  else
  else
    /* do all (or most) registers */
    /* do all (or most) registers */
    {
    {
      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 */
            if (fpregs)         /* true for "INFO ALL-REGISTERS" command */
              regnum = do_vf_register (regnum); /* FP regs */
              regnum = do_vf_register (regnum); /* FP regs */
            else
            else
              regnum++;         /* skip floating point regs */
              regnum++;         /* skip floating point regs */
          else
          else
            regnum = do_gp_register_row (regnum);       /* GP (int) regs */
            regnum = do_gp_register_row (regnum);       /* GP (int) regs */
        }
        }
    }
    }
}
}
 
 
/* Given the address at which to insert a breakpoint (BP_ADDR),
/* Given the address at which to insert a breakpoint (BP_ADDR),
   what will that breakpoint be?
   what will that breakpoint be?
 
 
   For or1k, we have a breakpoint instruction. Since all or1k
   For or1k, we have a breakpoint instruction. Since all or1k
   instructions are 32 bits, this is all we need, regardless of
   instructions are 32 bits, this is all we need, regardless of
   address. K is not used.  */
   address. K is not used.  */
 
 
unsigned char *
unsigned char *
or1k_breakpoint_from_pc (bp_addr, bp_size)
or1k_breakpoint_from_pc (bp_addr, bp_size)
     CORE_ADDR * bp_addr;
     CORE_ADDR * bp_addr;
     int *bp_size;
     int *bp_size;
{
{
  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).  */
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/* signals[TARGET_SIGNAL_UNKNOWN].string*/;
}
}
 
 
/* 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/*!!!signals[sig].name*/;
}
}
 
 
/* Given a name, return its signal.  */
/* Given a name, return its signal.  */
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;
 
 
  /* It's possible we also should allow "SIGCLD" as well as "SIGCHLD"
  /* It's possible we also should allow "SIGCLD" as well as "SIGCHLD"
     for TARGET_SIGNAL_SIGCHLD.  SIGIOT, on the other hand, is more
     for TARGET_SIGNAL_SIGCHLD.  SIGIOT, on the other hand, is more
     questionable; seems like by now people should call it SIGABRT
     questionable; seems like by now people should call it SIGABRT
     instead.  */
     instead.  */
 
 
  /* This ugly cast brought to you by the native VAX compiler.  */
  /* This ugly cast brought to you by the native VAX compiler.  */
  for (sig = TARGET_SIGNAL_FIRST;
  for (sig = TARGET_SIGNAL_FIRST;
       or1k_signal_to_name (sig) != NULL;
       or1k_signal_to_name (sig) != NULL;
       sig = (enum target_signal) ((int) sig + 1))
       sig = (enum target_signal) ((int) sig + 1))
    if (STREQ (name, or1k_signal_to_name (sig)))
    if (STREQ (name, or1k_signal_to_name (sig)))
      return sig;
      return sig;
  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;
{
{
  if (TYPE_CODE_FLT == TYPE_CODE (valtype))
  if (TYPE_CODE_FLT == TYPE_CODE (valtype))
    memcpy (valbuf, &regbuf[REGISTER_BYTE (VFRV_REGNUM)], TYPE_LENGTH (valtype));
    memcpy (valbuf, &regbuf[REGISTER_BYTE (VFRV_REGNUM)], TYPE_LENGTH (valtype));
  else
  else
    memcpy (valbuf, &regbuf[REGISTER_BYTE (RV_REGNUM)], TYPE_LENGTH (valtype));
    memcpy (valbuf, &regbuf[REGISTER_BYTE (RV_REGNUM)], TYPE_LENGTH (valtype));
}
}
 
 
/* The or1k cc defines the following
/* The or1k cc defines the following
   prologue:
   prologue:
00000000 <_proc1>:
00000000 <_proc1>:
   0:   d7 e1 17 e4     l.sw 0xffffffe4(r1),r2
   0:   d7 e1 17 e4     l.sw 0xffffffe4(r1),r2
   4:   9c 41 00 00     l.addi r2,r1,0x0
   4:   9c 41 00 00     l.addi r2,r1,0x0
   8:   9c 21 ff e8     l.addi r1,r1,0xffffffe8
   8:   9c 21 ff e8     l.addi r1,r1,0xffffffe8
   c:   d7 e2 1f f8     l.sw 0xfffffff8(r2),r3
   c:   d7 e2 1f f8     l.sw 0xfffffff8(r2),r3
  10:   d7 e2 27 f4     l.sw 0xfffffff4(r2),r4
  10:   d7 e2 27 f4     l.sw 0xfffffff4(r2),r4
  14:   84 82 ff f8     l.lwz r4,0xfffffff8(r2)
  14:   84 82 ff f8     l.lwz r4,0xfffffff8(r2)
  18:   9d 24 00 00     l.addi r9,r4,0x0
  18:   9d 24 00 00     l.addi r9,r4,0x0
  1c:   00 00 00 02     l.j 0x2
  1c:   00 00 00 02     l.j 0x2
  20:   15 00 00 00     l.nop
  20:   15 00 00 00     l.nop
 
 
00000024 <_L2>:
00000024 <_L2>:
  24:   84 41 ff fc     l.lwz r2,0xfffffffc(r1)
  24:   84 41 ff fc     l.lwz r2,0xfffffffc(r1)
  28:   48 00 58 00     l.jalr r11
  28:   48 00 58 00     l.jalr r11
  2c:   9c 21 00 18     l.addi r1,r1,0x18 */
  2c:   9c 21 00 18     l.addi r1,r1,0x18 */
 
 
CORE_ADDR
CORE_ADDR
or1k_skip_prologue (CORE_ADDR pc)
or1k_skip_prologue (CORE_ADDR pc)
{
{
  unsigned long inst;
  unsigned long inst;
  CORE_ADDR skip_pc;
  CORE_ADDR skip_pc;
  CORE_ADDR func_addr, func_end;
  CORE_ADDR func_addr, func_end;
  struct symtab_and_line sal;
  struct symtab_and_line sal;
  int i;
  int i;
  int offset = 0;
  int offset = 0;
 
 
  for (i = 0; i < MAX_GPR_REGS; i++)
  for (i = 0; i < MAX_GPR_REGS; i++)
    or1k_saved_reg_addr[i] = -1;
    or1k_saved_reg_addr[i] = -1;
 
 
  /* Is there a prologue?  */
  /* Is there a prologue?  */
  inst = or1k_fetch_instruction (pc);
  inst = or1k_fetch_instruction (pc);
  if (inst & 0xfc1ff800 != 0xd4011000) return pc; /* l.sw I(r1),r2 */
  if (inst & 0xfc1ff800 != 0xd4011000) return pc; /* l.sw I(r1),r2 */
  or1k_saved_reg_addr[2] = offset++;
  or1k_saved_reg_addr[2] = offset++;
  inst = or1k_fetch_instruction (pc + OR1K_INSTLEN);
  inst = or1k_fetch_instruction (pc + OR1K_INSTLEN);
  if (inst & 0xFFFF0000 != 0x9c410000) return pc; /* l.addi r2,r1,I */
  if (inst & 0xFFFF0000 != 0x9c410000) return pc; /* l.addi r2,r1,I */
  pc += 2 * OR1K_INSTLEN;
  pc += 2 * OR1K_INSTLEN;
  inst = or1k_fetch_instruction (pc);
  inst = or1k_fetch_instruction (pc);
  if (inst & 0xFFFF0000 != 0x9c210000) return pc; /* l.addi r1,r1,I */
  if (inst & 0xFFFF0000 != 0x9c210000) return pc; /* l.addi r1,r1,I */
  pc += OR1K_INSTLEN;
  pc += OR1K_INSTLEN;
 
 
  /* Skip stored registers.  */
  /* Skip stored registers.  */
  inst = or1k_fetch_instruction (pc);
  inst = or1k_fetch_instruction (pc);
  while (inst & 0xfc1ff800 != 0xd4020000)         /* l.sw 0x0(r2),rx */
  while (inst & 0xfc1ff800 != 0xd4020000)         /* l.sw 0x0(r2),rx */
    {
    {
      /* get saved reg. */
      /* get saved reg. */
      or1k_saved_reg_addr[(inst >> 11) & 0x1f] = offset++;
      or1k_saved_reg_addr[(inst >> 11) & 0x1f] = offset++;
      pc += OR1K_INSTLEN;
      pc += OR1K_INSTLEN;
      inst = or1k_fetch_instruction (pc);
      inst = or1k_fetch_instruction (pc);
    }
    }
  return pc;
  return pc;
}
}
 
 
/* Determines whether this function has frame.  */
/* Determines whether this function has frame.  */
 
 
int
int
or1k_frameless_function_invocation (struct frame_info *fi)
or1k_frameless_function_invocation (struct frame_info *fi)
{
{
  CORE_ADDR func_start, after_prologue;
  CORE_ADDR func_start, after_prologue;
  int frameless;
  int frameless;
  func_start = (get_pc_function_start ((fi)->pc) + FUNCTION_START_OFFSET);
  func_start = (get_pc_function_start ((fi)->pc) + FUNCTION_START_OFFSET);
  after_prologue = SKIP_PROLOGUE (func_start);
  after_prologue = SKIP_PROLOGUE (func_start);
 
 
  /* If we don't skip pc, we don't have even shortest possible  prologue.  */
  /* If we don't skip pc, we don't have even shortest possible  prologue.  */
  frameless = (after_prologue <= func_start);
  frameless = (after_prologue <= func_start);
  return frameless;
  return frameless;
}
}
 
 
/* Given a GDB frame, determine the address of the calling function's frame.
/* Given a GDB frame, determine the address of the calling function's frame.
   This will be used to create a new GDB frame struct, and then
   This will be used to create a new GDB frame struct, and then
   INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame. */
   INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame. */
 
 
CORE_ADDR
CORE_ADDR
or1k_frame_chain (frame)
or1k_frame_chain (frame)
     struct frame_info *frame;
     struct frame_info *frame;
{
{
  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 */
        return frame->frame;    /* dummy frame same as caller's 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;
 
 
  if (frame->signal_handler_caller)
  if (frame->signal_handler_caller)
    fp = read_memory_integer (frame->frame, 4);
    fp = read_memory_integer (frame->frame, 4);
  else if (frame->next != NULL
  else if (frame->next != NULL
           && frame->next->signal_handler_caller
           && frame->next->signal_handler_caller
           && FRAMELESS_FUNCTION_INVOCATION (frame))
           && FRAMELESS_FUNCTION_INVOCATION (frame))
    /* A frameless function interrupted by a signal did not change the
    /* A frameless function interrupted by a signal did not change the
       frame pointer.  */
       frame pointer.  */
    fp = FRAME_FP (frame);
    fp = FRAME_FP (frame);
  else
  else
    fp = read_memory_integer (frame->frame, 4);
    fp = read_memory_integer (frame->frame, 4);
 
 
  if (USE_GENERIC_DUMMY_FRAMES)
  if (USE_GENERIC_DUMMY_FRAMES)
    {
    {
      CORE_ADDR fpp, lr;
      CORE_ADDR fpp, lr;
 
 
      lr = read_register (LR_REGNUM);
      lr = read_register (LR_REGNUM);
      if (lr == entry_point_address ())
      if (lr == entry_point_address ())
        if (fp != 0 && (fpp = read_memory_integer (fp, 4)) != 0)
        if (fp != 0 && (fpp = read_memory_integer (fp, 4)) != 0)
          if (PC_IN_CALL_DUMMY (lr, fpp, fpp))
          if (PC_IN_CALL_DUMMY (lr, fpp, fpp))
            return fpp;
            return fpp;
    }
    }
 
 
  return fp;
  return fp;
}
}
 
 
/* The code to store, into a struct frame_saved_regs,
/* The code to store, into a struct frame_saved_regs,
   the addresses of the saved registers of frame described by FRAME_INFO.
   the addresses of the saved registers of frame described by FRAME_INFO.
   This includes special registers such as pc and fp saved in special
   This includes special registers such as pc and fp saved in special
   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;
  CORE_ADDR frame_addr;
  int i;
  int i;
  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);
 
 
  for (i = 0; i < NUM_GPR_REGS+NUM_VF_REGS; i++)
  for (i = 0; i < NUM_GPR_REGS + NUM_VF_REGS; i++)
    if (or1k_saved_reg_addr[i] >= 0)
    if (or1k_saved_reg_addr[i] >= 0)
      fi->saved_regs[i] = fi->frame + or1k_saved_reg_addr[i];
      fi->saved_regs[i] = fi->frame + or1k_saved_reg_addr[i];
}
}
 
 
 
 
static CORE_ADDR
static CORE_ADDR
read_next_frame_reg (fi, regno)
read_next_frame_reg (fi, regno)
     struct frame_info *fi;
     struct frame_info *fi;
     int regno;
     int regno;
{
{
  for (; fi; fi = fi->next)
  for (; fi; fi = fi->next)
    {
    {
      /* We have to get the saved sp from the sigcontext
      /* We have to get the saved sp from the sigcontext
         if it is a signal handler frame.  */
         if it is a signal handler frame.  */
      if (regno == SP_REGNUM && !fi->signal_handler_caller)
      if (regno == SP_REGNUM && !fi->signal_handler_caller)
        return fi->frame;
        return fi->frame;
      else
      else
        {
        {
          if (fi->saved_regs == NULL)
          if (fi->saved_regs == NULL)
            or1k_init_saved_regs (fi);
            or1k_init_saved_regs (fi);
          if (fi->saved_regs[regno])
          if (fi->saved_regs[regno])
            return read_memory_integer (ADDR_BITS_REMOVE (fi->saved_regs[regno]), OR1K_GPR_REGSIZE);
            return read_memory_integer (ADDR_BITS_REMOVE (fi->saved_regs[regno]), OR1K_GPR_REGSIZE);
        }
        }
    }
    }
  return read_register (regno);
  return read_register (regno);
}
}
 
 
/* Find the caller of this frame.  We do this by seeing if LR_REGNUM
/* Find the caller of this frame.  We do this by seeing if LR_REGNUM
   is saved in the stack anywhere, otherwise we get it from the
   is saved in the stack anywhere, otherwise we get it from the
   registers.  */
   registers.  */
 
 
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
    saved_pc = read_next_frame_reg (fi, PC_REGNUM);
    saved_pc = read_next_frame_reg (fi, PC_REGNUM);
 
 
  return ADDR_BITS_REMOVE (saved_pc);
  return ADDR_BITS_REMOVE (saved_pc);
}
}
 
 
/* Discard from the stack the innermost frame, restoring all registers.  */
/* Discard from the stack the innermost frame, restoring all registers.  */
 
 
void
void
or1k_pop_frame ()
or1k_pop_frame ()
{
{
  register int regnum;
  register int regnum;
  struct frame_info *frame = get_current_frame ();
  struct frame_info *frame = get_current_frame ();
  CORE_ADDR new_sp = FRAME_FP (frame);
  CORE_ADDR new_sp = FRAME_FP (frame);
 
 
  write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
  write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
  if (frame->saved_regs == NULL)
  if (frame->saved_regs == NULL)
    or1k_init_saved_regs (frame);
    or1k_init_saved_regs (frame);
  for (regnum = 0; regnum < NUM_REGS; regnum++)    {
  for (regnum = 0; regnum < NUM_REGS; regnum++)    {
      if (regnum != SP_REGNUM && regnum != PC_REGNUM
      if (regnum != SP_REGNUM && regnum != PC_REGNUM
          && frame->saved_regs[regnum] >= 0)
          && frame->saved_regs[regnum] >= 0)
        write_register (regnum,
        write_register (regnum,
                        read_memory_integer (frame->saved_regs[regnum],
                        read_memory_integer (frame->saved_regs[regnum],
                                             OR1K_GPR_REGSIZE));
                                             OR1K_GPR_REGSIZE));
    }
    }
  write_register (SP_REGNUM, new_sp);
  write_register (SP_REGNUM, new_sp);
  flush_cached_frames ();
  flush_cached_frames ();
}
}
 
 
CORE_ADDR
CORE_ADDR
or1k_push_arguments (nargs, args, sp, struct_return, struct_addr)
or1k_push_arguments (nargs, args, sp, struct_return, struct_addr)
     int nargs;
     int nargs;
     value_ptr *args;
     value_ptr *args;
     CORE_ADDR sp;
     CORE_ADDR sp;
     int struct_return;
     int struct_return;
     CORE_ADDR struct_addr;
     CORE_ADDR struct_addr;
{
{
  int argreg;
  int argreg;
  int float_argreg;
  int float_argreg;
  int argnum;
  int argnum;
  int len = 0;
  int len = 0;
  int stack_offset = 0;
  int stack_offset = 0;
 
 
  /* Initialize the integer and float register pointers.  */
  /* Initialize the integer and float register pointers.  */
  argreg = A0_REGNUM;
  argreg = A0_REGNUM;
  float_argreg = VFA0_REGNUM;
  float_argreg = VFA0_REGNUM;
 
 
  /* The struct_return pointer occupies the RV value register.  */
  /* The struct_return pointer occupies the RV value register.  */
  if (struct_return)
  if (struct_return)
    write_register (RV_REGNUM, struct_addr);
    write_register (RV_REGNUM, struct_addr);
 
 
  /* Now load as many as possible of the first arguments into
  /* Now load as many as possible of the first arguments into
     registers, and push the rest onto the stack.  Loop thru args
     registers, and push the rest onto the stack.  Loop thru args
     from first to last.  */
     from first to last.  */
  for (argnum = 0; argnum < nargs; argnum++)
  for (argnum = 0; argnum < nargs; argnum++)
    {
    {
      char *val;
      char *val;
      char valbuf[MAX_REGISTER_RAW_SIZE];
      char valbuf[MAX_REGISTER_RAW_SIZE];
      value_ptr arg = args[argnum];
      value_ptr arg = args[argnum];
      struct type *arg_type = check_typedef (VALUE_TYPE (arg));
      struct type *arg_type = check_typedef (VALUE_TYPE (arg));
      int len = TYPE_LENGTH (arg_type);
      int len = TYPE_LENGTH (arg_type);
      enum type_code typecode = TYPE_CODE (arg_type);
      enum type_code typecode = TYPE_CODE (arg_type);
 
 
      /* The EABI passes structures that do not fit in a register by
      /* The EABI passes structures that do not fit in a register by
         reference. In all other cases, pass the structure by value.  */
         reference. In all other cases, pass the structure by value.  */
      if (len > OR1K_GPR_REGSIZE &&
      if (len > OR1K_GPR_REGSIZE &&
          (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
          (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
        {
        {
          store_address (valbuf, OR1K_GPR_REGSIZE, VALUE_ADDRESS (arg));
          store_address (valbuf, OR1K_GPR_REGSIZE, VALUE_ADDRESS (arg));
          typecode = TYPE_CODE_PTR;
          typecode = TYPE_CODE_PTR;
          len = OR1K_GPR_REGSIZE;
          len = OR1K_GPR_REGSIZE;
          val = valbuf;
          val = valbuf;
        }
        }
      else
      else
        {
        {
          val = (char *) VALUE_CONTENTS (arg);
          val = (char *) VALUE_CONTENTS (arg);
 
 
          if (typecode == TYPE_CODE_FLT
          if (typecode == TYPE_CODE_FLT
              /* Doubles are not stored in regs on 32b target.  */
              /* Doubles are not stored in regs on 32b target.  */
              && len <= OR1K_VF_REGSIZE
              && len <= OR1K_VF_REGSIZE
              && OR1K_VF_PRESENT)
              && OR1K_VF_PRESENT)
            {
            {
              if (float_argreg <= OR1K_LAST_FP_ARG_REGNUM)
              if (float_argreg <= OR1K_LAST_FP_ARG_REGNUM)
                {
                {
                  CORE_ADDR regval = extract_address (val, len);
                  CORE_ADDR regval = extract_address (val, len);
                  write_register (float_argreg++, regval);
                  write_register (float_argreg++, regval);
                }
                }
              else
              else
                {
                {
                  write_memory ((CORE_ADDR) sp, val, OR1K_VF_REGSIZE);
                  write_memory ((CORE_ADDR) sp, val, OR1K_VF_REGSIZE);
                  sp -= OR1K_STACK_ALIGN;
                  sp -= OR1K_STACK_ALIGN;
                }
                }
            }
            }
          else
          else
            {
            {
              if (argreg <= OR1K_LAST_ARG_REGNUM)
              if (argreg <= OR1K_LAST_ARG_REGNUM)
                {
                {
                  CORE_ADDR regval = extract_address (val, len);
                  CORE_ADDR regval = extract_address (val, len);
                  write_register (argreg++, regval);
                  write_register (argreg++, regval);
                }
                }
              else
              else
                {
                {
                  write_memory ((CORE_ADDR) sp, val, OR1K_GPR_REGSIZE);
                  write_memory ((CORE_ADDR) sp, val, OR1K_GPR_REGSIZE);
                  sp -= OR1K_STACK_ALIGN;
                  sp -= OR1K_STACK_ALIGN;
                }
                }
            }
            }
        }
        }
    }
    }
 
 
  /* Return adjusted stack pointer.  */
  /* Return adjusted stack pointer.  */
  return sp;
  return sp;
}
}
 
 
/* Return nonzero when instruction has delay slot.  */
/* Return nonzero when instruction has delay slot.  */
static int
static int
is_delayed (insn)
is_delayed (insn)
     unsigned long insn;
     unsigned long insn;
{
{
  int i;
  int i;
  for (i = 0; i < num_opcodes; ++i)
  for (i = 0; i < num_opcodes; ++i)
    if ((or32_opcodes[i].flags & OR32_IF_DELAY)
    if ((or32_opcodes[i].flags & OR32_IF_DELAY)
        && (or32_opcode_match (insn, or32_opcodes[i].encoding)))
        && (or32_opcode_match (insn, or32_opcodes[i].encoding)))
      break;
      break;
  return (i < num_opcodes);
  return (i < num_opcodes);
}
}
 
 
int
int
or1k_step_skips_delay (pc)
or1k_step_skips_delay (pc)
     CORE_ADDR pc;
     CORE_ADDR pc;
{
{
  char buf[OR1K_INSTLEN];
  char buf[OR1K_INSTLEN];
 
 
  if (target_read_memory (pc, buf, OR1K_INSTLEN) != 0)
  if (target_read_memory (pc, buf, OR1K_INSTLEN) != 0)
    /* If error reading memory, guess that it is not a delayed branch.  */
    /* If error reading memory, guess that it is not a delayed branch.  */
    return 0;
    return 0;
  return is_delayed ((unsigned long) extract_unsigned_integer (buf, OR1K_INSTLEN));
  return is_delayed ((unsigned long) extract_unsigned_integer (buf, OR1K_INSTLEN));
}
}
 
 
CORE_ADDR
CORE_ADDR
or1k_push_return_address (pc, sp)
or1k_push_return_address (pc, sp)
     CORE_ADDR pc;
     CORE_ADDR pc;
     CORE_ADDR sp;
     CORE_ADDR sp;
{
{
  /* Set the return address register to point to the entry
  /* Set the return address register to point to the entry
     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
/* Root of all "set or1k "/"show or1k " commands. This will eventually be
   used for all OR1K-specific commands.  */
   used for all OR1K-specific commands.  */
 
 
static void show_or1k_command PARAMS ((char *, int));
static void show_or1k_command PARAMS ((char *, int));
static void
static void
show_or1k_command (args, from_tty)
show_or1k_command (args, from_tty)
     char *args;
     char *args;
     int from_tty;
     int from_tty;
{
{
  help_list (showor1kcmdlist, "show or1k ", all_commands, gdb_stdout);
  help_list (showor1kcmdlist, "show or1k ", all_commands, gdb_stdout);
}
}
 
 
static void set_or1k_command PARAMS ((char *, int));
static void set_or1k_command PARAMS ((char *, int));
static void
static void
set_or1k_command (args, from_tty)
set_or1k_command (args, from_tty)
     char *args;
     char *args;
     int from_tty;
     int from_tty;
{
{
  printf_unfiltered ("\"set or1k\" must be followed by an appropriate subcommand.\n");
  printf_unfiltered ("\"set or1k\" must be followed by an appropriate subcommand.\n");
  help_list (setor1kcmdlist, "set or1k ", all_commands, gdb_stdout);
  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;
                  int *group, *index;
                  int *group, *index;
{
{
  *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++)
                {
                {
                  int regno;
                  int regno;
                  regno = or1k_regno_from_name (i, args);
                  regno = or1k_regno_from_name (i, args);
                  if (regno >= 0)
                  if (regno >= 0)
                    {
                    {
                      *group = i;
                      *group = i;
                      *index = regno;
                      *index = regno;
                    }
                    }
                }
                }
            }
            }
        }
        }
      if (*group < 0 || *group >= OR1K_NUM_SPR_GROUPS)
      if (*group < 0 || *group >= OR1K_NUM_SPR_GROUPS)
        error ("Invalid group or register.\n");
        error ("Invalid group or register.\n");
 
 
      if (*index < 0)
      if (*index < 0)
        {
        {
          args += strlen(args) + 1;
          args += strlen(args) + 1;
          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;
          *index = (int) strtoul (args, &ptr_c, 0);
          *index = (int) strtoul (args, &ptr_c, 0);
          if (*ptr_c != 0)
          if (*ptr_c != 0)
            *index = or1k_regno_from_name (*group, args);
            *index = or1k_regno_from_name (*group, args);
          else *index = -1;
          else *index = -1;
 
 
          if (*index < 0)
          if (*index < 0)
            {
            {
              printf_filtered ("No register supplied. Valid registers are:\n");
              printf_filtered ("No register supplied. Valid registers are:\n");
              for (i = 0; i < or1k_spr_valid_aliases[*group]; i++)
              for (i = 0; i < or1k_spr_valid_aliases[*group]; i++)
                {
                {
                  char reg_name[16];
                  char reg_name[16];
                  char *gen_name = or1k_spr_register_name (SPR_REG(*group, i));
                  char *gen_name = or1k_spr_register_name (SPR_REG(*group, i));
                  sprintf (reg_name, "SPR%i_%i", *group, i);
                  sprintf (reg_name, "SPR%i_%i", *group, i);
                  if (strcmp (reg_name, gen_name) != 0)
                  if (strcmp (reg_name, gen_name) != 0)
                    printf_filtered ("%s\t", gen_name);
                    printf_filtered ("%s\t", gen_name);
                }
                }
              printf_filtered ("\n");
              printf_filtered ("\n");
              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");
      return args;
      return args;
    }
    }
  return args + strlen(args) + 1;
  return args + strlen(args) + 1;
}
}
 
 
/* SPR register info.  */
/* SPR register info.  */
 
 
void
void
info_spr_command (char *args, int from_tty)
info_spr_command (args, from_tty)
 
     char *args;
 
     int from_tty;
{
{
  int group, index;
  int group, index;
  parse_spr_params (args, &group, &index);
  parse_spr_params (args, &group, &index);
  if (index >= 0)
  if (index >= 0)
    {
    {
      printf_unfiltered ("%s.%s (SPR%i_%i) set to %i(%X), was:%i(%X)\n", or1k_group_names[group],
      printf_unfiltered ("%s.%s (SPR%i_%i) set to %i(%X), was:%i(%X)\n", or1k_group_names[group],
                         or1k_spr_register_name (SPR_REG(group, index)), group, index,
                         or1k_spr_register_name (SPR_REG(group, index)), group, index,
                         or1k_read_spr_reg (SPR_REG(group, index)));
                         or1k_read_spr_reg (SPR_REG(group, index)));
    }
    }
}
}
 
 
/* Set SPR register.  */
/* Set SPR register.  */
 
 
void
void
spr_command (char *args, int from_tty)
spr_command (args, from_tty)
 
     char *args;
 
     int from_tty;
{
{
  int group, index;
  int group, index;
  char *nargs = parse_spr_params (args, &group, &index);
  char *nargs = parse_spr_params (args, &group, &index);
  if (index >= 0)
  if (index >= 0)
    {
    {
      unsigned long prev;
      unsigned long prev;
      unsigned long value;
      unsigned long value;
      char *ptr_c;
      char *ptr_c;
 
 
      /* Any arguments left?  */
      /* Any arguments left?  */
      if (args + strlen(args) >= nargs)
      if (args + strlen(args) >= nargs)
        error ("Invalid register value.");
        error ("Invalid register value.");
 
 
      prev = or1k_read_spr_reg (SPR_REG(group, index));
      prev = or1k_read_spr_reg (SPR_REG(group, index));
 
 
      ptr_c = nargs;
      ptr_c = nargs;
      while (*ptr_c != ' ' && *ptr_c != 0)
      while (*ptr_c != ' ' && *ptr_c != 0)
        ptr_c++;
        ptr_c++;
      *ptr_c = 0;
      *ptr_c = 0;
      value = strtoul (nargs, &ptr_c, 0);
      value = strtoul (nargs, &ptr_c, 0);
      if (*ptr_c != 0)
      if (*ptr_c != 0)
        error ("Invalid register value.");
        error ("Invalid register value.");
      printf_unfiltered ("%s.%s (SPR%i_%i) set to %i(%X), was:%i(%X)\n", or1k_group_names[group],
      printf_unfiltered ("%s.%s (SPR%i_%i) set to %i(%X), was:%i(%X)\n", or1k_group_names[group],
                         or1k_spr_register_name (SPR_REG(group, index)), group, index,
                         or1k_spr_register_name (SPR_REG(group, index)), group, index,
                         value, value, prev, prev);
                         value, value, prev, prev);
    }
    }
}
}
 
 
/* Calls extended command on target.  */
/* Calls extended command on target.  */
 
 
void
void
sim_command (char *args, int from_tty)
sim_command (args, from_tty)
 
     char *args;
 
     int from_tty;
{
{
  or1k_sim_cmd (args, from_tty);
  or1k_sim_cmd (args, from_tty);
}
}
 
 
 
int
 
or1k_parse_any (exp)
 
     union exp_element *exp;
 
{
 
  if (exp->opcode == BINOP_LOGICAL_AND)
 
    {
 
      //!!!
 
    }
 
}
 
 
/* ARGSUSED */
/* ARGSUSED */
/* accessflag:  hw_write:  watch write,
/* accessflag:  hw_write:  watch write,
                hw_read:   watch read,
                hw_read:   watch read,
                hw_access: watch access (read or write) */
                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;
  int nfree;
  int nfree;
  /* Parse arguments.  */
  /* Parse arguments.  */
  exp = parse_exp_1 (&arg, 0, 0);
  exp = parse_exp_1 (&arg, 0, 0);
 
 
  dump_prefix_expression (exp, gdb_stdout, "expr1");
  dump_prefix_expression (exp, gdb_stdout, "expr1");
 
 
 
  if (or1k_parse_any (&exp->elts[0]))
 
    {
 
      //!!!
 
      printf_unfiltered ("Watchpoint successfully allocated.");
 
    }
 
  else
 
    printf_unfiltered ("Not enough resources to set specified watchpoint.");
  /* 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);
  //printf_unfiltered ("%s\n", exp->elts[1].internalvar->name);
  free (exp);
  free (exp);
}
}
 
 
void
void
_initialize_or1k_tdep ()
_initialize_or1k_tdep ()
{
{
  struct cmd_list_element *c;
  struct cmd_list_element *c;
  /* Add root prefix command for all "set or1k"/"show or1k" commands */
  /* Add root prefix command for all "set or1k"/"show or1k" commands */
  add_prefix_cmd ("or1k", no_class, set_or1k_command,
  add_prefix_cmd ("or1k", no_class, set_or1k_command,
                  "Various OR1K specific commands.",
                  "Various OR1K specific commands.",
                  &setor1kcmdlist, "set or1k ", 0, &setlist);
                  &setor1kcmdlist, "set or1k ", 0, &setlist);
 
 
  add_prefix_cmd ("or1k", no_class, show_or1k_command,
  add_prefix_cmd ("or1k", no_class, show_or1k_command,
                  "Various OR1K specific commands.",
                  "Various OR1K specific commands.",
                  &showor1kcmdlist, "show or1k ", 0, &showlist);
                  &showor1kcmdlist, "show or1k ", 0, &showlist);
 
 
  /* Commands to show information about the sprs.  */
  /* 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 ("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.");
  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.");
}
}
 
 

powered by: WebSVN 2.1.0

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