/* Target-dependent code for the Toshiba MeP for GDB, the GNU debugger.

   Copyright (C) 2001-2022 Free Software Foundation, Inc.

   Contributed by Red Hat, Inc.

   This file is part of GDB.

   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
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "frame.h"
#include "frame-unwind.h"
#include "frame-base.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "gdbcmd.h"
#include "gdbcore.h"
#include "value.h"
#include "inferior.h"
#include "dis-asm.h"
#include "symfile.h"
#include "objfiles.h"
#include "language.h"
#include "arch-utils.h"
#include "regcache.h"
#include "remote.h"
#include "sim-regno.h"
#include "trad-frame.h"
#include "reggroups.h"
#include "elf-bfd.h"
#include "elf/mep.h"
#include "prologue-value.h"
#include "cgen/bitset.h"
#include "infcall.h"
#include "gdbarch.h"

/* Get the user's customized MeP coprocessor register names from
   libopcodes.  */
#include "opcodes/mep-desc.h"
#include "opcodes/mep-opc.h"


/* The gdbarch_tdep structure.  */

/* A quick recap for GDB hackers not familiar with the whole Toshiba
   Media Processor story:

   The MeP media engine is a configureable processor: users can design
   their own coprocessors, implement custom instructions, adjust cache
   sizes, select optional standard facilities like add-and-saturate
   instructions, and so on.  Then, they can build custom versions of
   the GNU toolchain to support their customized chips.  The
   MeP-Integrator program (see utils/mep) takes a GNU toolchain source
   tree, and a config file pointing to various files provided by the
   user describing their customizations, and edits the source tree to
   produce a compiler that can generate their custom instructions, an
   assembler that can assemble them and recognize their custom
   register names, and so on.

   Furthermore, the user can actually specify several of these custom
   configurations, called 'me_modules', and get a toolchain which can
   produce code for any of them, given a compiler/assembler switch;
   you say something like 'gcc -mconfig=mm_max' to generate code for
   the me_module named 'mm_max'.

   GDB, in particular, needs to:

   - use the coprocessor control register names provided by the user
     in their hardware description, in expressions, 'info register'
     output, and disassembly,

   - know the number, names, and types of the coprocessor's
     general-purpose registers, adjust the 'info all-registers' output
     accordingly, and print error messages if the user refers to one
     that doesn't exist

   - allow access to the control bus space only when the configuration
     actually has a control bus, and recognize which regions of the
     control bus space are actually populated,

   - disassemble using the user's provided mnemonics for their custom
     instructions, and

   - recognize whether the $hi and $lo registers are present, and
     allow access to them only when they are actually there.

   There are three sources of information about what sort of me_module
   we're actually dealing with:

   - A MeP executable file indicates which me_module it was compiled
     for, and libopcodes has tables describing each module.  So, given
     an executable file, we can find out about the processor it was
     compiled for.

   - There are SID command-line options to select a particular
     me_module, overriding the one specified in the ELF file.  SID
     provides GDB with a fake read-only register, 'module', which
     indicates which me_module GDB is communicating with an instance
     of.

   - There are SID command-line options to enable or disable certain
     optional processor features, overriding the defaults for the
     selected me_module.  The MeP $OPT register indicates which
     options are present on the current processor.  */


struct mep_gdbarch_tdep : gdbarch_tdep
{
  /* A CGEN cpu descriptor for this BFD architecture and machine.

     Note: this is *not* customized for any particular me_module; the
     MeP libopcodes machinery actually puts off module-specific
     customization until the last minute.  So this contains
     information about all supported me_modules.  */
  CGEN_CPU_DESC cpu_desc = nullptr;

  /* The me_module index from the ELF file we used to select this
     architecture, or CONFIG_NONE if there was none.

     Note that we should prefer to use the me_module number available
     via the 'module' register, whenever we're actually talking to a
     real target.

     In the absence of live information, we'd like to get the
     me_module number from the ELF file.  But which ELF file: the
     executable file, the core file, ... ?  The answer is, "the last
     ELF file we used to set the current architecture".  Thus, we
     create a separate instance of the gdbarch structure for each
     me_module value mep_gdbarch_init sees, and store the me_module
     value from the ELF file here.  */
  CONFIG_ATTR me_module {};
};



/* Getting me_module information from the CGEN tables.  */


/* Find an entry in the DESC's hardware table whose name begins with
   PREFIX, and whose ISA mask intersects COPRO_ISA_MASK, but does not
   intersect with GENERIC_ISA_MASK.  If there is no matching entry,
   return zero.  */
static const CGEN_HW_ENTRY *
find_hw_entry_by_prefix_and_isa (CGEN_CPU_DESC desc,
				 const char *prefix,
				 CGEN_BITSET *copro_isa_mask,
				 CGEN_BITSET *generic_isa_mask)
{
  int prefix_len = strlen (prefix);
  int i;

  for (i = 0; i < desc->hw_table.num_entries; i++)
    {
      const CGEN_HW_ENTRY *hw = desc->hw_table.entries[i];
      if (strncmp (prefix, hw->name, prefix_len) == 0)
	{
	  CGEN_BITSET *hw_isa_mask
	    = ((CGEN_BITSET *)
	       &CGEN_ATTR_CGEN_HW_ISA_VALUE (CGEN_HW_ATTRS (hw)));

	  if (cgen_bitset_intersect_p (hw_isa_mask, copro_isa_mask)
	      && ! cgen_bitset_intersect_p (hw_isa_mask, generic_isa_mask))
	    return hw;
	}
    }

  return 0;
}


/* Find an entry in DESC's hardware table whose type is TYPE.  Return
   zero if there is none.  */
static const CGEN_HW_ENTRY *
find_hw_entry_by_type (CGEN_CPU_DESC desc, CGEN_HW_TYPE type)
{
  int i;

  for (i = 0; i < desc->hw_table.num_entries; i++)
    {
      const CGEN_HW_ENTRY *hw = desc->hw_table.entries[i];

      if (hw->type == type)
	return hw;
    }

  return 0;
}


/* Return the CGEN hardware table entry for the coprocessor register
   set for ME_MODULE, whose name prefix is PREFIX.  If ME_MODULE has
   no such register set, return zero.  If ME_MODULE is the generic
   me_module CONFIG_NONE, return the table entry for the register set
   whose hardware type is GENERIC_TYPE.  */
static const CGEN_HW_ENTRY *
me_module_register_set (CONFIG_ATTR me_module,
			const char *prefix,
			CGEN_HW_TYPE generic_type)
{
  /* This is kind of tricky, because the hardware table is constructed
     in a way that isn't very helpful.  Perhaps we can fix that, but
     here's how it works at the moment:

     The configuration map, `mep_config_map', is indexed by me_module
     number, and indicates which coprocessor and core ISAs that
     me_module supports.  The 'core_isa' mask includes all the core
     ISAs, and the 'cop_isa' mask includes all the coprocessor ISAs.
     The entry for the generic me_module, CONFIG_NONE, has an empty
     'cop_isa', and its 'core_isa' selects only the standard MeP
     instruction set.

     The CGEN CPU descriptor's hardware table, desc->hw_table, has
     entries for all the register sets, for all me_modules.  Each
     entry has a mask indicating which ISAs use that register set.
     So, if an me_module supports some coprocessor ISA, we can find
     applicable register sets by scanning the hardware table for
     register sets whose masks include (at least some of) those ISAs.

     Each hardware table entry also has a name, whose prefix says
     whether it's a general-purpose ("h-cr") or control ("h-ccr")
     coprocessor register set.  It might be nicer to have an attribute
     indicating what sort of register set it was, that we could use
     instead of pattern-matching on the name.

     When there is no hardware table entry whose mask includes a
     particular coprocessor ISA and whose name starts with a given
     prefix, then that means that that coprocessor doesn't have any
     registers of that type.  In such cases, this function must return
     a null pointer.

     Coprocessor register sets' masks may or may not include the core
     ISA for the me_module they belong to.  Those generated by a2cgen
     do, but the sample me_module included in the unconfigured tree,
     'ccfx', does not.

     There are generic coprocessor register sets, intended only for
     use with the generic me_module.  Unfortunately, their masks
     include *all* ISAs --- even those for coprocessors that don't
     have such register sets.  This makes detecting the case where a
     coprocessor lacks a particular register set more complicated.

     So, here's the approach we take:

     - For CONFIG_NONE, we return the generic coprocessor register set.

     - For any other me_module, we search for a register set whose
       mask contains any of the me_module's coprocessor ISAs,
       specifically excluding the generic coprocessor register sets.  */

  mep_gdbarch_tdep *tdep
    = (mep_gdbarch_tdep *) gdbarch_tdep (target_gdbarch ());
  CGEN_CPU_DESC desc = tdep->cpu_desc;
  const CGEN_HW_ENTRY *hw;

  if (me_module == CONFIG_NONE)
    hw = find_hw_entry_by_type (desc, generic_type);
  else
    {
      CGEN_BITSET *cop = &mep_config_map[me_module].cop_isa;
      CGEN_BITSET *core = &mep_config_map[me_module].core_isa;
      CGEN_BITSET *generic = &mep_config_map[CONFIG_NONE].core_isa;
      CGEN_BITSET *cop_and_core;

      /* The coprocessor ISAs include the ISA for the specific core which
	 has that coprocessor.  */
      cop_and_core = cgen_bitset_copy (cop);
      cgen_bitset_union (cop, core, cop_and_core);
      hw = find_hw_entry_by_prefix_and_isa (desc, prefix, cop_and_core, generic);
    }

  return hw;
}


/* Given a hardware table entry HW representing a register set, return
   a pointer to the keyword table with all the register names.  If HW
   is NULL, return NULL, to propagate the "no such register set" info
   along.  */
static CGEN_KEYWORD *
register_set_keyword_table (const CGEN_HW_ENTRY *hw)
{
  if (! hw)
    return NULL;

  /* Check that HW is actually a keyword table.  */
  gdb_assert (hw->asm_type == CGEN_ASM_KEYWORD);

  /* The 'asm_data' field of a register set's hardware table entry
     refers to a keyword table.  */
  return (CGEN_KEYWORD *) hw->asm_data;
}


/* Given a keyword table KEYWORD and a register number REGNUM, return
   the name of the register, or "" if KEYWORD contains no register
   whose number is REGNUM.  */
static const char *
register_name_from_keyword (CGEN_KEYWORD *keyword_table, int regnum)
{
  const CGEN_KEYWORD_ENTRY *entry
    = cgen_keyword_lookup_value (keyword_table, regnum);

  if (entry)
    {
      char *name = entry->name;

      /* The CGEN keyword entries for register names include the
	 leading $, which appears in MeP assembly as well as in GDB.
	 But we don't want to return that; GDB core code adds that
	 itself.  */
      if (name[0] == '$')
	name++;

      return name;
    }
  else
    return "";
}

  
/* Masks for option bits in the OPT special-purpose register.  */
enum {
  MEP_OPT_DIV = 1 << 25,        /* 32-bit divide instruction option */
  MEP_OPT_MUL = 1 << 24,        /* 32-bit multiply instruction option */
  MEP_OPT_BIT = 1 << 23,        /* bit manipulation instruction option */
  MEP_OPT_SAT = 1 << 22,        /* saturation instruction option */
  MEP_OPT_CLP = 1 << 21,        /* clip instruction option */
  MEP_OPT_MIN = 1 << 20,        /* min/max instruction option */
  MEP_OPT_AVE = 1 << 19,        /* average instruction option */
  MEP_OPT_ABS = 1 << 18,        /* absolute difference instruction option */
  MEP_OPT_LDZ = 1 << 16,        /* leading zero instruction option */
  MEP_OPT_VL64 = 1 << 6,        /* 64-bit VLIW operation mode option */
  MEP_OPT_VL32 = 1 << 5,        /* 32-bit VLIW operation mode option */
  MEP_OPT_COP = 1 << 4,         /* coprocessor option */
  MEP_OPT_DSP = 1 << 2,         /* DSP option */
  MEP_OPT_UCI = 1 << 1,         /* UCI option */
  MEP_OPT_DBG = 1 << 0,         /* DBG function option */
};


/* Given the option_mask value for a particular entry in
   mep_config_map, produce the value the processor's OPT register
   would use to represent the same set of options.  */
static unsigned int
opt_from_option_mask (unsigned int option_mask)
{
  /* A table mapping OPT register bits onto CGEN config map option
     bits.  */
  struct {
    unsigned int opt_bit, option_mask_bit;
  } bits[] = {
    { MEP_OPT_DIV, 1 << CGEN_INSN_OPTIONAL_DIV_INSN },
    { MEP_OPT_MUL, 1 << CGEN_INSN_OPTIONAL_MUL_INSN },
    { MEP_OPT_DIV, 1 << CGEN_INSN_OPTIONAL_DIV_INSN },
    { MEP_OPT_DBG, 1 << CGEN_INSN_OPTIONAL_DEBUG_INSN },
    { MEP_OPT_LDZ, 1 << CGEN_INSN_OPTIONAL_LDZ_INSN },
    { MEP_OPT_ABS, 1 << CGEN_INSN_OPTIONAL_ABS_INSN },
    { MEP_OPT_AVE, 1 << CGEN_INSN_OPTIONAL_AVE_INSN },
    { MEP_OPT_MIN, 1 << CGEN_INSN_OPTIONAL_MINMAX_INSN },
    { MEP_OPT_CLP, 1 << CGEN_INSN_OPTIONAL_CLIP_INSN },
    { MEP_OPT_SAT, 1 << CGEN_INSN_OPTIONAL_SAT_INSN },
    { MEP_OPT_UCI, 1 << CGEN_INSN_OPTIONAL_UCI_INSN },
    { MEP_OPT_DSP, 1 << CGEN_INSN_OPTIONAL_DSP_INSN },
    { MEP_OPT_COP, 1 << CGEN_INSN_OPTIONAL_CP_INSN },
  };

  int i;
  unsigned int opt = 0;

  for (i = 0; i < (sizeof (bits) / sizeof (bits[0])); i++)
    if (option_mask & bits[i].option_mask_bit)
      opt |= bits[i].opt_bit;

  return opt;
}


/* Return the value the $OPT register would use to represent the set
   of options for ME_MODULE.  */
static unsigned int
me_module_opt (CONFIG_ATTR me_module)
{
  return opt_from_option_mask (mep_config_map[me_module].option_mask);
}


/* Return the width of ME_MODULE's coprocessor data bus, in bits.
   This is either 32 or 64.  */
static int
me_module_cop_data_bus_width (CONFIG_ATTR me_module)
{
  if (mep_config_map[me_module].option_mask
      & (1 << CGEN_INSN_OPTIONAL_CP64_INSN))
    return 64;
  else
    return 32;
}


/* Return true if ME_MODULE is big-endian, false otherwise.  */
static int
me_module_big_endian (CONFIG_ATTR me_module)
{
  return mep_config_map[me_module].big_endian;
}


/* Return the name of ME_MODULE, or NULL if it has no name.  */
static const char *
me_module_name (CONFIG_ATTR me_module)
{
  /* The default me_module has "" as its name, but it's easier for our
     callers to test for NULL.  */
  if (! mep_config_map[me_module].name
      || mep_config_map[me_module].name[0] == '\0')
    return NULL;
  else
    return mep_config_map[me_module].name;
}

/* Register set.  */


/* The MeP spec defines the following registers:
   16 general purpose registers (r0-r15) 
   32 control/special registers (csr0-csr31)
   32 coprocessor general-purpose registers (c0 -- c31)
   64 coprocessor control registers (ccr0 -- ccr63)

   For the raw registers, we assign numbers here explicitly, instead
   of letting the enum assign them for us; the numbers are a matter of
   external protocol, and shouldn't shift around as things are edited.

   We access the control/special registers via pseudoregisters, to
   enforce read-only portions that some registers have.

   We access the coprocessor general purpose and control registers via
   pseudoregisters, to make sure they appear in the proper order in
   the 'info all-registers' command (which uses the register number
   ordering), and also to allow them to be renamed and resized
   depending on the me_module in use.

   The MeP allows coprocessor general-purpose registers to be either
   32 or 64 bits long, depending on the configuration.  Since we don't
   want the format of the 'g' packet to vary from one core to another,
   the raw coprocessor GPRs are always 64 bits.  GDB doesn't allow the
   types of registers to change (see the implementation of
   register_type), so we have four banks of pseudoregisters for the
   coprocessor gprs --- 32-bit vs. 64-bit, and integer
   vs. floating-point --- and we show or hide them depending on the
   configuration.  */
enum
{
  MEP_FIRST_RAW_REGNUM = 0,

  MEP_FIRST_GPR_REGNUM = 0,
  MEP_R0_REGNUM = 0,
  MEP_R1_REGNUM = 1,
  MEP_R2_REGNUM = 2,
  MEP_R3_REGNUM = 3,
  MEP_R4_REGNUM = 4,
  MEP_R5_REGNUM = 5,
  MEP_R6_REGNUM = 6,
  MEP_R7_REGNUM = 7,
  MEP_R8_REGNUM = 8,
  MEP_R9_REGNUM = 9,
  MEP_R10_REGNUM = 10,
  MEP_R11_REGNUM = 11,
  MEP_R12_REGNUM = 12,
  MEP_FP_REGNUM = MEP_R8_REGNUM,
  MEP_R13_REGNUM = 13,
  MEP_TP_REGNUM = MEP_R13_REGNUM,	/* (r13) Tiny data pointer */
  MEP_R14_REGNUM = 14,
  MEP_GP_REGNUM = MEP_R14_REGNUM,	/* (r14) Global pointer */
  MEP_R15_REGNUM = 15,
  MEP_SP_REGNUM = MEP_R15_REGNUM,	/* (r15) Stack pointer */
  MEP_LAST_GPR_REGNUM = MEP_R15_REGNUM,

  /* The raw control registers.  These are the values as received via
     the remote protocol, directly from the target; we only let user
     code touch the via the pseudoregisters, which enforce read-only
     bits.  */
  MEP_FIRST_RAW_CSR_REGNUM = 16,
  MEP_RAW_PC_REGNUM    = 16,    /* Program counter */
  MEP_RAW_LP_REGNUM    = 17,    /* Link pointer */
  MEP_RAW_SAR_REGNUM   = 18,    /* Raw shift amount */
  MEP_RAW_CSR3_REGNUM  = 19,    /* csr3: reserved */
  MEP_RAW_RPB_REGNUM   = 20,    /* Raw repeat begin address */
  MEP_RAW_RPE_REGNUM   = 21,    /* Repeat end address */
  MEP_RAW_RPC_REGNUM   = 22,    /* Repeat count */
  MEP_RAW_HI_REGNUM    = 23, /* Upper 32 bits of result of 64 bit mult/div */
  MEP_RAW_LO_REGNUM    = 24, /* Lower 32 bits of result of 64 bit mult/div */
  MEP_RAW_CSR9_REGNUM  = 25,    /* csr3: reserved */
  MEP_RAW_CSR10_REGNUM = 26,    /* csr3: reserved */
  MEP_RAW_CSR11_REGNUM = 27,    /* csr3: reserved */
  MEP_RAW_MB0_REGNUM   = 28,    /* Raw modulo begin address 0 */
  MEP_RAW_ME0_REGNUM   = 29,    /* Raw modulo end address 0 */
  MEP_RAW_MB1_REGNUM   = 30,    /* Raw modulo begin address 1 */
  MEP_RAW_ME1_REGNUM   = 31,    /* Raw modulo end address 1 */
  MEP_RAW_PSW_REGNUM   = 32,    /* Raw program status word */
  MEP_RAW_ID_REGNUM    = 33,    /* Raw processor ID/revision */
  MEP_RAW_TMP_REGNUM   = 34,    /* Temporary */
  MEP_RAW_EPC_REGNUM   = 35,    /* Exception program counter */
  MEP_RAW_EXC_REGNUM   = 36,    /* Raw exception cause */
  MEP_RAW_CFG_REGNUM   = 37,    /* Raw processor configuration*/
  MEP_RAW_CSR22_REGNUM = 38,    /* csr3: reserved */
  MEP_RAW_NPC_REGNUM   = 39,    /* Nonmaskable interrupt PC */
  MEP_RAW_DBG_REGNUM   = 40,    /* Raw debug */
  MEP_RAW_DEPC_REGNUM  = 41,    /* Debug exception PC */
  MEP_RAW_OPT_REGNUM   = 42,    /* Raw options */
  MEP_RAW_RCFG_REGNUM  = 43,    /* Raw local ram config */
  MEP_RAW_CCFG_REGNUM  = 44,    /* Raw cache config */
  MEP_RAW_CSR29_REGNUM = 45,    /* csr3: reserved */
  MEP_RAW_CSR30_REGNUM = 46,    /* csr3: reserved */
  MEP_RAW_CSR31_REGNUM = 47,    /* csr3: reserved */
  MEP_LAST_RAW_CSR_REGNUM = MEP_RAW_CSR31_REGNUM,

  /* The raw coprocessor general-purpose registers.  These are all 64
     bits wide.  */
  MEP_FIRST_RAW_CR_REGNUM = 48,
  MEP_LAST_RAW_CR_REGNUM = MEP_FIRST_RAW_CR_REGNUM + 31,

  MEP_FIRST_RAW_CCR_REGNUM = 80,
  MEP_LAST_RAW_CCR_REGNUM = MEP_FIRST_RAW_CCR_REGNUM + 63,

  /* The module number register.  This is the index of the me_module
     of which the current target is an instance.  (This is not a real
     MeP-specified register; it's provided by SID.)  */
  MEP_MODULE_REGNUM,

  MEP_LAST_RAW_REGNUM = MEP_MODULE_REGNUM,

  MEP_NUM_RAW_REGS = MEP_LAST_RAW_REGNUM + 1,

  /* Pseudoregisters.  See mep_pseudo_register_read and
     mep_pseudo_register_write.  */
  MEP_FIRST_PSEUDO_REGNUM = MEP_NUM_RAW_REGS,

  /* We have a pseudoregister for every control/special register, to
     implement registers with read-only bits.  */
  MEP_FIRST_CSR_REGNUM = MEP_FIRST_PSEUDO_REGNUM,
  MEP_PC_REGNUM = MEP_FIRST_CSR_REGNUM, /* Program counter */
  MEP_LP_REGNUM,                /* Link pointer */
  MEP_SAR_REGNUM,               /* shift amount */
  MEP_CSR3_REGNUM,              /* csr3: reserved */
  MEP_RPB_REGNUM,               /* repeat begin address */
  MEP_RPE_REGNUM,               /* Repeat end address */
  MEP_RPC_REGNUM,               /* Repeat count */
  MEP_HI_REGNUM,  /* Upper 32 bits of the result of 64 bit mult/div */
  MEP_LO_REGNUM,  /* Lower 32 bits of the result of 64 bit mult/div */
  MEP_CSR9_REGNUM,              /* csr3: reserved */
  MEP_CSR10_REGNUM,             /* csr3: reserved */
  MEP_CSR11_REGNUM,             /* csr3: reserved */
  MEP_MB0_REGNUM,               /* modulo begin address 0 */
  MEP_ME0_REGNUM,               /* modulo end address 0 */
  MEP_MB1_REGNUM,               /* modulo begin address 1 */
  MEP_ME1_REGNUM,               /* modulo end address 1 */
  MEP_PSW_REGNUM,               /* program status word */
  MEP_ID_REGNUM,                /* processor ID/revision */
  MEP_TMP_REGNUM,               /* Temporary */
  MEP_EPC_REGNUM,               /* Exception program counter */
  MEP_EXC_REGNUM,               /* exception cause */
  MEP_CFG_REGNUM,               /* processor configuration*/
  MEP_CSR22_REGNUM,             /* csr3: reserved */
  MEP_NPC_REGNUM,               /* Nonmaskable interrupt PC */
  MEP_DBG_REGNUM,               /* debug */
  MEP_DEPC_REGNUM,              /* Debug exception PC */
  MEP_OPT_REGNUM,               /* options */
  MEP_RCFG_REGNUM,              /* local ram config */
  MEP_CCFG_REGNUM,              /* cache config */
  MEP_CSR29_REGNUM,             /* csr3: reserved */
  MEP_CSR30_REGNUM,             /* csr3: reserved */
  MEP_CSR31_REGNUM,             /* csr3: reserved */
  MEP_LAST_CSR_REGNUM = MEP_CSR31_REGNUM,

  /* The 32-bit integer view of the coprocessor GPR's.  */
  MEP_FIRST_CR32_REGNUM,
  MEP_LAST_CR32_REGNUM = MEP_FIRST_CR32_REGNUM + 31,

  /* The 32-bit floating-point view of the coprocessor GPR's.  */
  MEP_FIRST_FP_CR32_REGNUM,
  MEP_LAST_FP_CR32_REGNUM = MEP_FIRST_FP_CR32_REGNUM + 31,

  /* The 64-bit integer view of the coprocessor GPR's.  */
  MEP_FIRST_CR64_REGNUM,
  MEP_LAST_CR64_REGNUM = MEP_FIRST_CR64_REGNUM + 31,

  /* The 64-bit floating-point view of the coprocessor GPR's.  */
  MEP_FIRST_FP_CR64_REGNUM,
  MEP_LAST_FP_CR64_REGNUM = MEP_FIRST_FP_CR64_REGNUM + 31,

  MEP_FIRST_CCR_REGNUM,
  MEP_LAST_CCR_REGNUM = MEP_FIRST_CCR_REGNUM + 63,

  MEP_LAST_PSEUDO_REGNUM = MEP_LAST_CCR_REGNUM,

  MEP_NUM_PSEUDO_REGS = (MEP_LAST_PSEUDO_REGNUM - MEP_LAST_RAW_REGNUM),

  MEP_NUM_REGS = MEP_NUM_RAW_REGS + MEP_NUM_PSEUDO_REGS
};


#define IN_SET(set, n) \
  (MEP_FIRST_ ## set ## _REGNUM <= (n) && (n) <= MEP_LAST_ ## set ## _REGNUM)

#define IS_GPR_REGNUM(n)     (IN_SET (GPR,     (n)))
#define IS_RAW_CSR_REGNUM(n) (IN_SET (RAW_CSR, (n)))
#define IS_RAW_CR_REGNUM(n)  (IN_SET (RAW_CR,  (n)))
#define IS_RAW_CCR_REGNUM(n) (IN_SET (RAW_CCR, (n)))

#define IS_CSR_REGNUM(n)     (IN_SET (CSR,     (n)))
#define IS_CR32_REGNUM(n)    (IN_SET (CR32,    (n)))
#define IS_FP_CR32_REGNUM(n) (IN_SET (FP_CR32, (n)))
#define IS_CR64_REGNUM(n)    (IN_SET (CR64,    (n)))
#define IS_FP_CR64_REGNUM(n) (IN_SET (FP_CR64, (n)))
#define IS_CR_REGNUM(n)      (IS_CR32_REGNUM (n) || IS_FP_CR32_REGNUM (n) \
			      || IS_CR64_REGNUM (n) || IS_FP_CR64_REGNUM (n))
#define IS_CCR_REGNUM(n)     (IN_SET (CCR,     (n)))

#define IS_RAW_REGNUM(n)     (IN_SET (RAW,     (n)))
#define IS_PSEUDO_REGNUM(n)  (IN_SET (PSEUDO,  (n)))

#define NUM_REGS_IN_SET(set) \
  (MEP_LAST_ ## set ## _REGNUM - MEP_FIRST_ ## set ## _REGNUM + 1)

#define MEP_GPR_SIZE (4)        /* Size of a MeP general-purpose register.  */
#define MEP_PSW_SIZE (4)        /* Size of the PSW register.  */
#define MEP_LP_SIZE (4)         /* Size of the LP register.  */


/* Many of the control/special registers contain bits that cannot be
   written to; some are entirely read-only.  So we present them all as
   pseudoregisters.

   The following table describes the special properties of each CSR.  */
struct mep_csr_register
{
  /* The number of this CSR's raw register.  */
  int raw;

  /* The number of this CSR's pseudoregister.  */
  int pseudo;

  /* A mask of the bits that are writeable: if a bit is set here, then
     it can be modified; if the bit is clear, then it cannot.  */
  LONGEST writeable_bits;
};


/* mep_csr_registers[i] describes the i'th CSR.
   We just list the register numbers here explicitly to help catch
   typos.  */
#define CSR(name) MEP_RAW_ ## name ## _REGNUM, MEP_ ## name ## _REGNUM
static mep_csr_register mep_csr_registers[] = {
  { CSR(PC),    0xffffffff },   /* manual says r/o, but we can write it */
  { CSR(LP),    0xffffffff },
  { CSR(SAR),   0x0000003f },
  { CSR(CSR3),  0xffffffff },
  { CSR(RPB),   0xfffffffe },
  { CSR(RPE),   0xffffffff },
  { CSR(RPC),   0xffffffff },
  { CSR(HI),    0xffffffff },
  { CSR(LO),    0xffffffff },
  { CSR(CSR9),  0xffffffff },
  { CSR(CSR10), 0xffffffff },
  { CSR(CSR11), 0xffffffff },
  { CSR(MB0),   0x0000ffff },
  { CSR(ME0),   0x0000ffff },
  { CSR(MB1),   0x0000ffff },
  { CSR(ME1),   0x0000ffff },
  { CSR(PSW),   0x000003ff },
  { CSR(ID),    0x00000000 },
  { CSR(TMP),   0xffffffff },
  { CSR(EPC),   0xffffffff },
  { CSR(EXC),   0x000030f0 },
  { CSR(CFG),   0x00c0001b },
  { CSR(CSR22), 0xffffffff },
  { CSR(NPC),   0xffffffff },
  { CSR(DBG),   0x00000580 },
  { CSR(DEPC),  0xffffffff },
  { CSR(OPT),   0x00000000 },
  { CSR(RCFG),  0x00000000 },
  { CSR(CCFG),  0x00000000 },
  { CSR(CSR29), 0xffffffff },
  { CSR(CSR30), 0xffffffff },
  { CSR(CSR31), 0xffffffff },
};


/* If R is the number of a raw register, then mep_raw_to_pseudo[R] is
   the number of the corresponding pseudoregister.  Otherwise,
   mep_raw_to_pseudo[R] == R.  */
static int mep_raw_to_pseudo[MEP_NUM_REGS];

/* If R is the number of a pseudoregister, then mep_pseudo_to_raw[R]
   is the number of the underlying raw register.  Otherwise
   mep_pseudo_to_raw[R] == R.  */
static int mep_pseudo_to_raw[MEP_NUM_REGS];

static void
mep_init_pseudoregister_maps (void)
{
  int i;

  /* Verify that mep_csr_registers covers all the CSRs, in order.  */
  gdb_assert (ARRAY_SIZE (mep_csr_registers) == NUM_REGS_IN_SET (CSR));
  gdb_assert (ARRAY_SIZE (mep_csr_registers) == NUM_REGS_IN_SET (RAW_CSR));

  /* Verify that the raw and pseudo ranges have matching sizes.  */
  gdb_assert (NUM_REGS_IN_SET (RAW_CSR) == NUM_REGS_IN_SET (CSR));
  gdb_assert (NUM_REGS_IN_SET (RAW_CR)  == NUM_REGS_IN_SET (CR32));
  gdb_assert (NUM_REGS_IN_SET (RAW_CR)  == NUM_REGS_IN_SET (CR64));
  gdb_assert (NUM_REGS_IN_SET (RAW_CCR) == NUM_REGS_IN_SET (CCR));

  for (i = 0; i < ARRAY_SIZE (mep_csr_registers); i++)
    {
      struct mep_csr_register *r = &mep_csr_registers[i];

      gdb_assert (r->pseudo == MEP_FIRST_CSR_REGNUM + i);
      gdb_assert (r->raw    == MEP_FIRST_RAW_CSR_REGNUM + i);
    }

  /* Set up the initial  raw<->pseudo mappings.  */
  for (i = 0; i < MEP_NUM_REGS; i++)
    {
      mep_raw_to_pseudo[i] = i;
      mep_pseudo_to_raw[i] = i;
    }

  /* Add the CSR raw<->pseudo mappings.  */
  for (i = 0; i < ARRAY_SIZE (mep_csr_registers); i++)
    {
      struct mep_csr_register *r = &mep_csr_registers[i];

      mep_raw_to_pseudo[r->raw] = r->pseudo;
      mep_pseudo_to_raw[r->pseudo] = r->raw;
    }

  /* Add the CR raw<->pseudo mappings.  */
  for (i = 0; i < NUM_REGS_IN_SET (RAW_CR); i++)
    {
      int raw = MEP_FIRST_RAW_CR_REGNUM + i;
      int pseudo32 = MEP_FIRST_CR32_REGNUM + i;
      int pseudofp32 = MEP_FIRST_FP_CR32_REGNUM + i;
      int pseudo64 = MEP_FIRST_CR64_REGNUM + i;
      int pseudofp64 = MEP_FIRST_FP_CR64_REGNUM + i;

      /* Truly, the raw->pseudo mapping depends on the current module.
	 But we use the raw->pseudo mapping when we read the debugging
	 info; at that point, we don't know what module we'll actually
	 be running yet.  So, we always supply the 64-bit register
	 numbers; GDB knows how to pick a smaller value out of a
	 larger register properly.  */
      mep_raw_to_pseudo[raw] = pseudo64;
      mep_pseudo_to_raw[pseudo32] = raw;
      mep_pseudo_to_raw[pseudofp32] = raw;
      mep_pseudo_to_raw[pseudo64] = raw;
      mep_pseudo_to_raw[pseudofp64] = raw;
    }

  /* Add the CCR raw<->pseudo mappings.  */
  for (i = 0; i < NUM_REGS_IN_SET (CCR); i++)
    {
      int raw = MEP_FIRST_RAW_CCR_REGNUM + i;
      int pseudo = MEP_FIRST_CCR_REGNUM + i;
      mep_raw_to_pseudo[raw] = pseudo;
      mep_pseudo_to_raw[pseudo] = raw;
    }
}


static int
mep_debug_reg_to_regnum (struct gdbarch *gdbarch, int debug_reg)
{
  /* The debug info uses the raw register numbers.  */
  if (debug_reg >= 0 && debug_reg < ARRAY_SIZE (mep_raw_to_pseudo))
    return mep_raw_to_pseudo[debug_reg];
  return -1;
}


/* Return the size, in bits, of the coprocessor pseudoregister
   numbered PSEUDO.  */
static int
mep_pseudo_cr_size (int pseudo)
{
  if (IS_CR32_REGNUM (pseudo)
      || IS_FP_CR32_REGNUM (pseudo))
    return 32;
  else if (IS_CR64_REGNUM (pseudo)
	   || IS_FP_CR64_REGNUM (pseudo))
    return 64;
  else
    gdb_assert_not_reached ("unexpected coprocessor pseudo register");
}


/* If the coprocessor pseudoregister numbered PSEUDO is a
   floating-point register, return non-zero; if it is an integer
   register, return zero.  */
static int
mep_pseudo_cr_is_float (int pseudo)
{
  return (IS_FP_CR32_REGNUM (pseudo)
	  || IS_FP_CR64_REGNUM (pseudo));
}


/* Given a coprocessor GPR pseudoregister number, return its index
   within that register bank.  */
static int
mep_pseudo_cr_index (int pseudo)
{
  if (IS_CR32_REGNUM (pseudo))
    return pseudo - MEP_FIRST_CR32_REGNUM;
  else if (IS_FP_CR32_REGNUM (pseudo))
      return pseudo - MEP_FIRST_FP_CR32_REGNUM;
  else if (IS_CR64_REGNUM (pseudo))
      return pseudo - MEP_FIRST_CR64_REGNUM;
  else if (IS_FP_CR64_REGNUM (pseudo))
      return pseudo - MEP_FIRST_FP_CR64_REGNUM;
  else
    gdb_assert_not_reached ("unexpected coprocessor pseudo register");
}


/* Return the me_module index describing the current target.

   If the current target has registers (e.g., simulator, remote
   target), then this uses the value of the 'module' register, raw
   register MEP_MODULE_REGNUM.  Otherwise, this retrieves the value
   from the ELF header's e_flags field of the current executable
   file.  */
static CONFIG_ATTR
current_me_module (void)
{
  if (target_has_registers ())
    {
      ULONGEST regval;
      regcache_cooked_read_unsigned (get_current_regcache (),
				     MEP_MODULE_REGNUM, &regval);
      return (CONFIG_ATTR) regval;
    }
  else
    {
      mep_gdbarch_tdep *tdep
	= (mep_gdbarch_tdep *) gdbarch_tdep (target_gdbarch ());
      return tdep->me_module;
    }
}


/* Return the set of options for the current target, in the form that
   the OPT register would use.

   If the current target has registers (e.g., simulator, remote
   target), then this is the actual value of the OPT register.  If the
   current target does not have registers (e.g., an executable file),
   then use the 'module_opt' field we computed when we build the
   gdbarch object for this module.  */
static unsigned int
current_options (void)
{
  if (target_has_registers ())
    {
      ULONGEST regval;
      regcache_cooked_read_unsigned (get_current_regcache (),
				     MEP_OPT_REGNUM, &regval);
      return regval;
    }
  else
    return me_module_opt (current_me_module ());
}


/* Return the width of the current me_module's coprocessor data bus,
   in bits.  This is either 32 or 64.  */
static int
current_cop_data_bus_width (void)
{
  return me_module_cop_data_bus_width (current_me_module ());
}


/* Return the keyword table of coprocessor general-purpose register
   names appropriate for the me_module we're dealing with.  */
static CGEN_KEYWORD *
current_cr_names (void)
{
  const CGEN_HW_ENTRY *hw
    = me_module_register_set (current_me_module (), "h-cr-", HW_H_CR);

  return register_set_keyword_table (hw);
}


/* Return non-zero if the coprocessor general-purpose registers are
   floating-point values, zero otherwise.  */
static int
current_cr_is_float (void)
{
  const CGEN_HW_ENTRY *hw
    = me_module_register_set (current_me_module (), "h-cr-", HW_H_CR);

  return CGEN_ATTR_CGEN_HW_IS_FLOAT_VALUE (CGEN_HW_ATTRS (hw));
}


/* Return the keyword table of coprocessor control register names
   appropriate for the me_module we're dealing with.  */
static CGEN_KEYWORD *
current_ccr_names (void)
{
  const CGEN_HW_ENTRY *hw
    = me_module_register_set (current_me_module (), "h-ccr-", HW_H_CCR);

  return register_set_keyword_table (hw);
}


static const char *
mep_register_name (struct gdbarch *gdbarch, int regnr)
{
  /* General-purpose registers.  */
  static const char *gpr_names[] = {
    "r0",   "r1",   "r2",   "r3",   /* 0 */
    "r4",   "r5",   "r6",   "r7",   /* 4 */
    "fp",   "r9",   "r10",  "r11",  /* 8 */
    "r12",  "tp",   "gp",   "sp"    /* 12 */
  };

  /* Special-purpose registers.  */
  static const char *csr_names[] = {
    "pc",   "lp",   "sar",  "",     /* 0  csr3: reserved */ 
    "rpb",  "rpe",  "rpc",  "hi",   /* 4 */
    "lo",   "",     "",     "",     /* 8  csr9-csr11: reserved */
    "mb0",  "me0",  "mb1",  "me1",  /* 12 */

    "psw",  "id",   "tmp",  "epc",  /* 16 */
    "exc",  "cfg",  "",     "npc",  /* 20  csr22: reserved */
    "dbg",  "depc", "opt",  "rcfg", /* 24 */
    "ccfg", "",     "",     ""      /* 28  csr29-csr31: reserved */
  };

  if (IS_GPR_REGNUM (regnr))
    return gpr_names[regnr - MEP_R0_REGNUM];
  else if (IS_CSR_REGNUM (regnr))
    {
      /* The 'hi' and 'lo' registers are only present on processors
	 that have the 'MUL' or 'DIV' instructions enabled.  */
      if ((regnr == MEP_HI_REGNUM || regnr == MEP_LO_REGNUM)
	  && (! (current_options () & (MEP_OPT_MUL | MEP_OPT_DIV))))
	return "";

      return csr_names[regnr - MEP_FIRST_CSR_REGNUM];
    }
  else if (IS_CR_REGNUM (regnr))
    {
      CGEN_KEYWORD *names;
      int cr_size;
      int cr_is_float;

      /* Does this module have a coprocessor at all?  */
      if (! (current_options () & MEP_OPT_COP))
	return "";

      names = current_cr_names ();
      if (! names)
	/* This module's coprocessor has no general-purpose registers.  */
	return "";

      cr_size = current_cop_data_bus_width ();
      if (cr_size != mep_pseudo_cr_size (regnr))
	/* This module's coprocessor's GPR's are of a different size.  */
	return "";

      cr_is_float = current_cr_is_float ();
      /* The extra ! operators ensure we get boolean equality, not
	 numeric equality.  */
      if (! cr_is_float != ! mep_pseudo_cr_is_float (regnr))
	/* This module's coprocessor's GPR's are of a different type.  */
	return "";

      return register_name_from_keyword (names, mep_pseudo_cr_index (regnr));
    }
  else if (IS_CCR_REGNUM (regnr))
    {
      /* Does this module have a coprocessor at all?  */
      if (! (current_options () & MEP_OPT_COP))
	return "";

      {
	CGEN_KEYWORD *names = current_ccr_names ();

	if (! names)
	  /* This me_module's coprocessor has no control registers.  */
	  return "";

	return register_name_from_keyword (names, regnr-MEP_FIRST_CCR_REGNUM);
      }
    }

  /* It might be nice to give the 'module' register a name, but that
     would affect the output of 'info all-registers', which would
     disturb the test suites.  So we leave it invisible.  */
  else
    return NULL;
}


/* Custom register groups for the MeP.  */
static struct reggroup *mep_csr_reggroup; /* control/special */
static struct reggroup *mep_cr_reggroup;  /* coprocessor general-purpose */
static struct reggroup *mep_ccr_reggroup; /* coprocessor control */


static int
mep_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
			 const struct reggroup *group)
{
  /* Filter reserved or unused register numbers.  */
  {
    const char *name = mep_register_name (gdbarch, regnum);

    if (! name || name[0] == '\0')
      return 0;
  }

  /* We could separate the GPRs and the CSRs.  Toshiba has approved of
     the existing behavior, so we'd want to run that by them.  */
  if (group == general_reggroup)
    return (IS_GPR_REGNUM (regnum)
	    || IS_CSR_REGNUM (regnum));

  /* Everything is in the 'all' reggroup, except for the raw CSR's.  */
  else if (group == all_reggroup)
    return (IS_GPR_REGNUM (regnum)
	    || IS_CSR_REGNUM (regnum)
	    || IS_CR_REGNUM (regnum)
	    || IS_CCR_REGNUM (regnum));

  /* All registers should be saved and restored, except for the raw
     CSR's.

     This is probably right if the coprocessor is something like a
     floating-point unit, but would be wrong if the coprocessor is
     something that does I/O, where register accesses actually cause
     externally-visible actions.  But I get the impression that the
     coprocessor isn't supposed to do things like that --- you'd use a
     hardware engine, perhaps.  */
  else if (group == save_reggroup || group == restore_reggroup)
    return (IS_GPR_REGNUM (regnum)
	    || IS_CSR_REGNUM (regnum)
	    || IS_CR_REGNUM (regnum)
	    || IS_CCR_REGNUM (regnum));

  else if (group == mep_csr_reggroup)
    return IS_CSR_REGNUM (regnum);
  else if (group == mep_cr_reggroup)
    return IS_CR_REGNUM (regnum);
  else if (group == mep_ccr_reggroup)
    return IS_CCR_REGNUM (regnum);
  else
    return 0;
}


static struct type *
mep_register_type (struct gdbarch *gdbarch, int reg_nr)
{
  /* Coprocessor general-purpose registers may be either 32 or 64 bits
     long.  So for them, the raw registers are always 64 bits long (to
     keep the 'g' packet format fixed), and the pseudoregisters vary
     in length.  */
  if (IS_RAW_CR_REGNUM (reg_nr))
    return builtin_type (gdbarch)->builtin_uint64;

  /* Since GDB doesn't allow registers to change type, we have two
     banks of pseudoregisters for the coprocessor general-purpose
     registers: one that gives a 32-bit view, and one that gives a
     64-bit view.  We hide or show one or the other depending on the
     current module.  */
  if (IS_CR_REGNUM (reg_nr))
    {
      int size = mep_pseudo_cr_size (reg_nr);
      if (size == 32)
	{
	  if (mep_pseudo_cr_is_float (reg_nr))
	    return builtin_type (gdbarch)->builtin_float;
	  else
	    return builtin_type (gdbarch)->builtin_uint32;
	}
      else if (size == 64)
	{
	  if (mep_pseudo_cr_is_float (reg_nr))
	    return builtin_type (gdbarch)->builtin_double;
	  else
	    return builtin_type (gdbarch)->builtin_uint64;
	}
      else
	gdb_assert_not_reached ("unexpected cr size");
    }

  /* All other registers are 32 bits long.  */
  else
    return builtin_type (gdbarch)->builtin_uint32;
}

static enum register_status
mep_pseudo_cr32_read (struct gdbarch *gdbarch,
		      readable_regcache *regcache,
		      int cookednum,
		      gdb_byte *buf)
{
  enum register_status status;
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  /* Read the raw register into a 64-bit buffer, and then return the
     appropriate end of that buffer.  */
  int rawnum = mep_pseudo_to_raw[cookednum];
  gdb_byte buf64[8];

  gdb_assert (TYPE_LENGTH (register_type (gdbarch, rawnum)) == sizeof (buf64));
  gdb_assert (TYPE_LENGTH (register_type (gdbarch, cookednum)) == 4);
  status = regcache->raw_read (rawnum, buf64);
  if (status == REG_VALID)
    {
      /* Slow, but legible.  */
      store_unsigned_integer (buf, 4, byte_order,
			      extract_unsigned_integer (buf64, 8, byte_order));
    }
  return status;
}


static enum register_status
mep_pseudo_cr64_read (struct gdbarch *gdbarch,
		      readable_regcache *regcache,
		      int cookednum,
		      gdb_byte *buf)
{
  return regcache->raw_read (mep_pseudo_to_raw[cookednum], buf);
}


static enum register_status
mep_pseudo_register_read (struct gdbarch *gdbarch,
			  readable_regcache *regcache,
			  int cookednum,
			  gdb_byte *buf)
{
  if (IS_CSR_REGNUM (cookednum)
      || IS_CCR_REGNUM (cookednum))
    return regcache->raw_read (mep_pseudo_to_raw[cookednum], buf);
  else if (IS_CR32_REGNUM (cookednum)
	   || IS_FP_CR32_REGNUM (cookednum))
    return mep_pseudo_cr32_read (gdbarch, regcache, cookednum, buf);
  else if (IS_CR64_REGNUM (cookednum)
	   || IS_FP_CR64_REGNUM (cookednum))
    return mep_pseudo_cr64_read (gdbarch, regcache, cookednum, buf);
  else
    gdb_assert_not_reached ("unexpected pseudo register");
}


static void
mep_pseudo_csr_write (struct gdbarch *gdbarch,
		      struct regcache *regcache,
		      int cookednum,
		      const gdb_byte *buf)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int size = register_size (gdbarch, cookednum);
  struct mep_csr_register *r
    = &mep_csr_registers[cookednum - MEP_FIRST_CSR_REGNUM];

  if (r->writeable_bits == 0)
    /* A completely read-only register; avoid the read-modify-
       write cycle, and juts ignore the entire write.  */
    ;
  else
    {
      /* A partially writeable register; do a read-modify-write cycle.  */
      ULONGEST old_bits;
      ULONGEST new_bits;
      ULONGEST mixed_bits;
	  
      regcache_raw_read_unsigned (regcache, r->raw, &old_bits);
      new_bits = extract_unsigned_integer (buf, size, byte_order);
      mixed_bits = ((r->writeable_bits & new_bits)
		    | (~r->writeable_bits & old_bits));
      regcache_raw_write_unsigned (regcache, r->raw, mixed_bits);
    }
}
		      

static void
mep_pseudo_cr32_write (struct gdbarch *gdbarch,
		       struct regcache *regcache,
		       int cookednum,
		       const gdb_byte *buf)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  /* Expand the 32-bit value into a 64-bit value, and write that to
     the pseudoregister.  */
  int rawnum = mep_pseudo_to_raw[cookednum];
  gdb_byte buf64[8];
  
  gdb_assert (TYPE_LENGTH (register_type (gdbarch, rawnum)) == sizeof (buf64));
  gdb_assert (TYPE_LENGTH (register_type (gdbarch, cookednum)) == 4);
  /* Slow, but legible.  */
  store_unsigned_integer (buf64, 8, byte_order,
			  extract_unsigned_integer (buf, 4, byte_order));
  regcache->raw_write (rawnum, buf64);
}


static void
mep_pseudo_cr64_write (struct gdbarch *gdbarch,
		     struct regcache *regcache,
		     int cookednum,
		     const gdb_byte *buf)
{
  regcache->raw_write (mep_pseudo_to_raw[cookednum], buf);
}


static void
mep_pseudo_register_write (struct gdbarch *gdbarch,
			   struct regcache *regcache,
			   int cookednum,
			   const gdb_byte *buf)
{
  if (IS_CSR_REGNUM (cookednum))
    mep_pseudo_csr_write (gdbarch, regcache, cookednum, buf);
  else if (IS_CR32_REGNUM (cookednum)
	   || IS_FP_CR32_REGNUM (cookednum))
    mep_pseudo_cr32_write (gdbarch, regcache, cookednum, buf);
  else if (IS_CR64_REGNUM (cookednum)
	   || IS_FP_CR64_REGNUM (cookednum))
    mep_pseudo_cr64_write (gdbarch, regcache, cookednum, buf);
  else if (IS_CCR_REGNUM (cookednum))
    regcache->raw_write (mep_pseudo_to_raw[cookednum], buf);
  else
    gdb_assert_not_reached ("unexpected pseudo register");
}



/* Disassembly.  */

static int
mep_gdb_print_insn (bfd_vma pc, disassemble_info * info)
{
  struct obj_section * s = find_pc_section (pc);

  info->arch = bfd_arch_mep;
  if (s)
    {
      /* The libopcodes disassembly code uses the section to find the
	 BFD, the BFD to find the ELF header, the ELF header to find
	 the me_module index, and the me_module index to select the
	 right instructions to print.  */
      info->section = s->the_bfd_section;
    }

  return print_insn_mep (pc, info);
}


/* Prologue analysis.  */


/* The MeP has two classes of instructions: "core" instructions, which
   are pretty normal RISC chip stuff, and "coprocessor" instructions,
   which are mostly concerned with moving data in and out of
   coprocessor registers, and branching on coprocessor condition
   codes.  There's space in the instruction set for custom coprocessor
   instructions, too.

   Instructions can be 16 or 32 bits long; the top two bits of the
   first byte indicate the length.  The coprocessor instructions are
   mixed in with the core instructions, and there's no easy way to
   distinguish them; you have to completely decode them to tell one
   from the other.

   The MeP also supports a "VLIW" operation mode, where instructions
   always occur in fixed-width bundles.  The bundles are either 32
   bits or 64 bits long, depending on a fixed configuration flag.  You
   decode the first part of the bundle as normal; if it's a core
   instruction, and there's any space left in the bundle, the
   remainder of the bundle is a coprocessor instruction, which will
   execute in parallel with the core instruction.  If the first part
   of the bundle is a coprocessor instruction, it occupies the entire
   bundle.

   So, here are all the cases:

   - 32-bit VLIW mode:
     Every bundle is four bytes long, and naturally aligned, and can hold
     one or two instructions:
     - 16-bit core instruction; 16-bit coprocessor instruction
       These execute in parallel.
     - 32-bit core instruction
     - 32-bit coprocessor instruction

   - 64-bit VLIW mode:
     Every bundle is eight bytes long, and naturally aligned, and can hold
     one or two instructions:
     - 16-bit core instruction; 48-bit (!) coprocessor instruction
       These execute in parallel.
     - 32-bit core instruction; 32-bit coprocessor instruction
       These execute in parallel.
     - 64-bit coprocessor instruction

   Now, the MeP manual doesn't define any 48- or 64-bit coprocessor
   instruction, so I don't really know what's up there; perhaps these
   are always the user-defined coprocessor instructions.  */


/* Return non-zero if PC is in a VLIW code section, zero
   otherwise.  */
static int
mep_pc_in_vliw_section (CORE_ADDR pc)
{
  struct obj_section *s = find_pc_section (pc);
  if (s)
    return (s->the_bfd_section->flags & SEC_MEP_VLIW);
  return 0;
}


/* Set *INSN to the next core instruction at PC, and return the
   address of the next instruction.

   The MeP instruction encoding is endian-dependent.  16- and 32-bit
   instructions are encoded as one or two two-byte parts, and each
   part is byte-swapped independently.  Thus:

      void
      foo (void)
      {
	asm ("movu $1, 0x123456");
	asm ("sb $1,0x5678($2)");
	asm ("clip $1, 19");
      }

   compiles to this big-endian code:

       0:	d1 56 12 34 	movu $1,0x123456
       4:	c1 28 56 78 	sb $1,22136($2)
       8:	f1 01 10 98 	clip $1,0x13
       c:	70 02       	ret

   and this little-endian code:

       0:	56 d1 34 12 	movu $1,0x123456
       4:	28 c1 78 56 	sb $1,22136($2)
       8:	01 f1 98 10 	clip $1,0x13
       c:	02 70       	ret

   Instructions are returned in *INSN in an endian-independent form: a
   given instruction always appears in *INSN the same way, regardless
   of whether the instruction stream is big-endian or little-endian.

   *INSN's most significant 16 bits are the first (i.e., at lower
   addresses) 16 bit part of the instruction.  Its least significant
   16 bits are the second (i.e., higher-addressed) 16 bit part of the
   instruction, or zero for a 16-bit instruction.  Both 16-bit parts
   are fetched using the current endianness.

   So, the *INSN values for the instruction sequence above would be
   the following, in either endianness:

       0xd1561234       movu $1,0x123456     
       0xc1285678 	sb $1,22136($2)
       0xf1011098 	clip $1,0x13
       0x70020000      	ret

   (In a sense, it would be more natural to return 16-bit instructions
   in the least significant 16 bits of *INSN, but that would be
   ambiguous.  In order to tell whether you're looking at a 16- or a
   32-bit instruction, you have to consult the major opcode field ---
   the most significant four bits of the instruction's first 16-bit
   part.  But if we put 16-bit instructions at the least significant
   end of *INSN, then you don't know where to find the major opcode
   field until you know if it's a 16- or a 32-bit instruction ---
   which is where we started.)

   If PC points to a core / coprocessor bundle in a VLIW section, set
   *INSN to the core instruction, and return the address of the next
   bundle.  This has the effect of skipping the bundled coprocessor
   instruction.  That's okay, since coprocessor instructions aren't
   significant to prologue analysis --- for the time being,
   anyway.  */

static CORE_ADDR 
mep_get_insn (struct gdbarch *gdbarch, CORE_ADDR pc, unsigned long *insn)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int pc_in_vliw_section;
  int vliw_mode;
  int insn_len;
  gdb_byte buf[2];

  *insn = 0;

  /* Are we in a VLIW section?  */
  pc_in_vliw_section = mep_pc_in_vliw_section (pc);
  if (pc_in_vliw_section)
    {
      /* Yes, find out which bundle size.  */
      vliw_mode = current_options () & (MEP_OPT_VL32 | MEP_OPT_VL64);

      /* If PC is in a VLIW section, but the current core doesn't say
	 that it supports either VLIW mode, then we don't have enough
	 information to parse the instruction stream it contains.
	 Since the "undifferentiated" standard core doesn't have
	 either VLIW mode bit set, this could happen.

	 But it shouldn't be an error to (say) set a breakpoint in a
	 VLIW section, if you know you'll never reach it.  (Perhaps
	 you have a script that sets a bunch of standard breakpoints.)

	 So we'll just return zero here, and hope for the best.  */
      if (! (vliw_mode & (MEP_OPT_VL32 | MEP_OPT_VL64)))
	return 0;

      /* If both VL32 and VL64 are set, that's bogus, too.  */
      if (vliw_mode == (MEP_OPT_VL32 | MEP_OPT_VL64))
	return 0;
    }
  else
    vliw_mode = 0;

  read_memory (pc, buf, sizeof (buf));
  *insn = extract_unsigned_integer (buf, 2, byte_order) << 16;

  /* The major opcode --- the top four bits of the first 16-bit
     part --- indicates whether this instruction is 16 or 32 bits
     long.  All 32-bit instructions have a major opcode whose top
     two bits are 11; all the rest are 16-bit instructions.  */
  if ((*insn & 0xc0000000) == 0xc0000000)
    {
      /* Fetch the second 16-bit part of the instruction.  */
      read_memory (pc + 2, buf, sizeof (buf));
      *insn = *insn | extract_unsigned_integer (buf, 2, byte_order);
    }

  /* If we're in VLIW code, then the VLIW width determines the address
     of the next instruction.  */
  if (vliw_mode)
    {
      /* In 32-bit VLIW code, all bundles are 32 bits long.  We ignore the
	 coprocessor half of a core / copro bundle.  */
      if (vliw_mode == MEP_OPT_VL32)
	insn_len = 4;

      /* In 64-bit VLIW code, all bundles are 64 bits long.  We ignore the
	 coprocessor half of a core / copro bundle.  */
      else if (vliw_mode == MEP_OPT_VL64)
	insn_len = 8;

      /* We'd better be in either core, 32-bit VLIW, or 64-bit VLIW mode.  */
      else
	gdb_assert_not_reached ("unexpected vliw mode");
    }
  
  /* Otherwise, the top two bits of the major opcode are (again) what
     we need to check.  */
  else if ((*insn & 0xc0000000) == 0xc0000000)
    insn_len = 4;
  else
    insn_len = 2;

  return pc + insn_len;
}


/* Sign-extend the LEN-bit value N.  */
#define SEXT(n, len) ((((int) (n)) ^ (1 << ((len) - 1))) - (1 << ((len) - 1)))

/* Return the LEN-bit field at POS from I.  */
#define FIELD(i, pos, len) (((i) >> (pos)) & ((1 << (len)) - 1))

/* Like FIELD, but sign-extend the field's value.  */
#define SFIELD(i, pos, len) (SEXT (FIELD ((i), (pos), (len)), (len)))


/* Macros for decoding instructions.

   Remember that 16-bit instructions are placed in bits 16..31 of i,
   not at the least significant end; this means that the major opcode
   field is always in the same place, regardless of the width of the
   instruction.  As a reminder of this, we show the lower 16 bits of a
   16-bit instruction as xxxx_xxxx_xxxx_xxxx.  */

/* SB Rn,(Rm)		      0000_nnnn_mmmm_1000 */
/* SH Rn,(Rm)		      0000_nnnn_mmmm_1001 */
/* SW Rn,(Rm)		      0000_nnnn_mmmm_1010 */

/* SW Rn,disp16(Rm)	      1100_nnnn_mmmm_1010 dddd_dddd_dddd_dddd */
#define IS_SW(i)	      (((i) & 0xf00f0000) == 0xc00a0000)
/* SB Rn,disp16(Rm)	      1100_nnnn_mmmm_1000 dddd_dddd_dddd_dddd */
#define IS_SB(i)	      (((i) & 0xf00f0000) == 0xc0080000)
/* SH Rn,disp16(Rm)	      1100_nnnn_mmmm_1001 dddd_dddd_dddd_dddd */
#define IS_SH(i)	      (((i) & 0xf00f0000) == 0xc0090000)
#define SWBH_32_BASE(i)       (FIELD (i, 20, 4))
#define SWBH_32_SOURCE(i)     (FIELD (i, 24, 4))
#define SWBH_32_OFFSET(i)     (SFIELD (i, 0, 16))

/* SW Rn,disp7.align4(SP)     0100_nnnn_0ddd_dd10 xxxx_xxxx_xxxx_xxxx */
#define IS_SW_IMMD(i)	      (((i) & 0xf0830000) == 0x40020000)
#define SW_IMMD_SOURCE(i)     (FIELD (i, 24, 4))
#define SW_IMMD_OFFSET(i)     (FIELD (i, 18, 5) << 2)

/* SW Rn,(Rm)                 0000_nnnn_mmmm_1010 xxxx_xxxx_xxxx_xxxx */
#define IS_SW_REG(i)	      (((i) & 0xf00f0000) == 0x000a0000)
#define SW_REG_SOURCE(i)      (FIELD (i, 24, 4))
#define SW_REG_BASE(i)        (FIELD (i, 20, 4))

/* ADD3 Rl,Rn,Rm              1001_nnnn_mmmm_llll xxxx_xxxx_xxxx_xxxx */
#define IS_ADD3_16_REG(i)     (((i) & 0xf0000000) == 0x90000000)
#define ADD3_16_REG_SRC1(i)   (FIELD (i, 20, 4))               /* n */
#define ADD3_16_REG_SRC2(i)   (FIELD (i, 24, 4))               /* m */

/* ADD3 Rn,Rm,imm16           1100_nnnn_mmmm_0000 iiii_iiii_iiii_iiii */
#define IS_ADD3_32(i)	      (((i) & 0xf00f0000) == 0xc0000000)
#define ADD3_32_TARGET(i)     (FIELD (i, 24, 4))
#define ADD3_32_SOURCE(i)     (FIELD (i, 20, 4))
#define ADD3_32_OFFSET(i)     (SFIELD (i, 0, 16))

/* ADD3 Rn,SP,imm7.align4     0100_nnnn_0iii_ii00 xxxx_xxxx_xxxx_xxxx */
#define IS_ADD3_16(i)  	      (((i) & 0xf0830000) == 0x40000000)
#define ADD3_16_TARGET(i)     (FIELD (i, 24, 4))
#define ADD3_16_OFFSET(i)     (FIELD (i, 18, 5) << 2)

/* ADD Rn,imm6		      0110_nnnn_iiii_ii00 xxxx_xxxx_xxxx_xxxx */
#define IS_ADD(i) 	      (((i) & 0xf0030000) == 0x60000000)
#define ADD_TARGET(i)	      (FIELD (i, 24, 4))
#define ADD_OFFSET(i)         (SFIELD (i, 18, 6))

/* LDC Rn,imm5		      0111_nnnn_iiii_101I xxxx_xxxx_xxxx_xxxx
			      imm5 = I||i[7:4] */
#define IS_LDC(i)	      (((i) & 0xf00e0000) == 0x700a0000)
#define LDC_IMM(i)            ((FIELD (i, 16, 1) << 4) | FIELD (i, 20, 4))
#define LDC_TARGET(i)         (FIELD (i, 24, 4))

/* LW Rn,disp16(Rm)           1100_nnnn_mmmm_1110 dddd_dddd_dddd_dddd  */
#define IS_LW(i)              (((i) & 0xf00f0000) == 0xc00e0000)
#define LW_TARGET(i)          (FIELD (i, 24, 4))
#define LW_BASE(i)            (FIELD (i, 20, 4))
#define LW_OFFSET(i)          (SFIELD (i, 0, 16))

/* MOV Rn,Rm		      0000_nnnn_mmmm_0000 xxxx_xxxx_xxxx_xxxx */
#define IS_MOV(i)	      (((i) & 0xf00f0000) == 0x00000000)
#define MOV_TARGET(i)	      (FIELD (i, 24, 4))
#define MOV_SOURCE(i)	      (FIELD (i, 20, 4))

/* BRA disp12.align2	      1011_dddd_dddd_ddd0 xxxx_xxxx_xxxx_xxxx */
#define IS_BRA(i)	      (((i) & 0xf0010000) == 0xb0000000)
#define BRA_DISP(i)           (SFIELD (i, 17, 11) << 1)


/* This structure holds the results of a prologue analysis.  */
struct mep_prologue
{
  /* The architecture for which we generated this prologue info.  */
  struct gdbarch *gdbarch;

  /* The offset from the frame base to the stack pointer --- always
     zero or negative.

     Calling this a "size" is a bit misleading, but given that the
     stack grows downwards, using offsets for everything keeps one
     from going completely sign-crazy: you never change anything's
     sign for an ADD instruction; always change the second operand's
     sign for a SUB instruction; and everything takes care of
     itself.  */
  int frame_size;

  /* Non-zero if this function has initialized the frame pointer from
     the stack pointer, zero otherwise.  */
  int has_frame_ptr;

  /* If has_frame_ptr is non-zero, this is the offset from the frame
     base to where the frame pointer points.  This is always zero or
     negative.  */
  int frame_ptr_offset;

  /* The address of the first instruction at which the frame has been
     set up and the arguments are where the debug info says they are
     --- as best as we can tell.  */
  CORE_ADDR prologue_end;

  /* reg_offset[R] is the offset from the CFA at which register R is
     saved, or 1 if register R has not been saved.  (Real values are
     always zero or negative.)  */
  int reg_offset[MEP_NUM_REGS];
};

/* Return non-zero if VALUE is an incoming argument register.  */

static int
is_arg_reg (pv_t value)
{
  return (value.kind == pvk_register
	  && MEP_R1_REGNUM <= value.reg && value.reg <= MEP_R4_REGNUM
	  && value.k == 0);
}

/* Return non-zero if a store of REG's current value VALUE to ADDR is
   probably spilling an argument register to its stack slot in STACK.
   Such instructions should be included in the prologue, if possible.

   The store is a spill if:
   - the value being stored is REG's original value;
   - the value has not already been stored somewhere in STACK; and
   - ADDR is a stack slot's address (e.g., relative to the original
     value of the SP).  */
static int
is_arg_spill (struct gdbarch *gdbarch, pv_t value, pv_t addr,
	      struct pv_area *stack)
{
  return (is_arg_reg (value)
	  && pv_is_register (addr, MEP_SP_REGNUM)
	  && ! stack->find_reg (gdbarch, value.reg, 0));
}


/* Function for finding saved registers in a 'struct pv_area'; we pass
   this to pv_area::scan.

   If VALUE is a saved register, ADDR says it was saved at a constant
   offset from the frame base, and SIZE indicates that the whole
   register was saved, record its offset in RESULT_UNTYPED.  */
static void
check_for_saved (void *result_untyped, pv_t addr, CORE_ADDR size, pv_t value)
{
  struct mep_prologue *result = (struct mep_prologue *) result_untyped;

  if (value.kind == pvk_register
      && value.k == 0
      && pv_is_register (addr, MEP_SP_REGNUM)
      && size == register_size (result->gdbarch, value.reg))
    result->reg_offset[value.reg] = addr.k;
}


/* Analyze a prologue starting at START_PC, going no further than
   LIMIT_PC.  Fill in RESULT as appropriate.  */
static void
mep_analyze_prologue (struct gdbarch *gdbarch,
		      CORE_ADDR start_pc, CORE_ADDR limit_pc,
		      struct mep_prologue *result)
{
  CORE_ADDR pc;
  unsigned long insn;
  pv_t reg[MEP_NUM_REGS];
  CORE_ADDR after_last_frame_setup_insn = start_pc;

  memset (result, 0, sizeof (*result));
  result->gdbarch = gdbarch;

  for (int rn = 0; rn < MEP_NUM_REGS; rn++)
    {
      reg[rn] = pv_register (rn, 0);
      result->reg_offset[rn] = 1;
    }

  pv_area stack (MEP_SP_REGNUM, gdbarch_addr_bit (gdbarch));

  pc = start_pc;
  while (pc < limit_pc)
    {
      CORE_ADDR next_pc;
      pv_t pre_insn_fp, pre_insn_sp;

      next_pc = mep_get_insn (gdbarch, pc, &insn);

      /* A zero return from mep_get_insn means that either we weren't
	 able to read the instruction from memory, or that we don't
	 have enough information to be able to reliably decode it.  So
	 we'll store here and hope for the best.  */
      if (! next_pc)
	break;

      /* Note the current values of the SP and FP, so we can tell if
	 this instruction changed them, below.  */
      pre_insn_fp = reg[MEP_FP_REGNUM];
      pre_insn_sp = reg[MEP_SP_REGNUM];

      if (IS_ADD (insn))
	{
	  int rn = ADD_TARGET (insn);
	  CORE_ADDR imm6 = ADD_OFFSET (insn);

	  reg[rn] = pv_add_constant (reg[rn], imm6);
	}
      else if (IS_ADD3_16 (insn))
	{
	  int rn = ADD3_16_TARGET (insn);
	  int imm7 = ADD3_16_OFFSET (insn);

	  reg[rn] = pv_add_constant (reg[MEP_SP_REGNUM], imm7);
	}
      else if (IS_ADD3_32 (insn))
	{
	  int rn = ADD3_32_TARGET (insn);
	  int rm = ADD3_32_SOURCE (insn);
	  int imm16 = ADD3_32_OFFSET (insn);

	  reg[rn] = pv_add_constant (reg[rm], imm16);
	}
      else if (IS_SW_REG (insn))
	{
	  int rn = SW_REG_SOURCE (insn);
	  int rm = SW_REG_BASE (insn);

	  /* If simulating this store would require us to forget
	     everything we know about the stack frame in the name of
	     accuracy, it would be better to just quit now.  */
	  if (stack.store_would_trash (reg[rm]))
	    break;
	  
	  if (is_arg_spill (gdbarch, reg[rn], reg[rm], &stack))
	    after_last_frame_setup_insn = next_pc;

	  stack.store (reg[rm], 4, reg[rn]);
	}
      else if (IS_SW_IMMD (insn))
	{
	  int rn = SW_IMMD_SOURCE (insn);
	  int offset = SW_IMMD_OFFSET (insn);
	  pv_t addr = pv_add_constant (reg[MEP_SP_REGNUM], offset);

	  /* If simulating this store would require us to forget
	     everything we know about the stack frame in the name of
	     accuracy, it would be better to just quit now.  */
	  if (stack.store_would_trash (addr))
	    break;

	  if (is_arg_spill (gdbarch, reg[rn], addr, &stack))
	    after_last_frame_setup_insn = next_pc;

	  stack.store (addr, 4, reg[rn]);
	}
      else if (IS_MOV (insn))
	{
	  int rn = MOV_TARGET (insn);
	  int rm = MOV_SOURCE (insn);

	  reg[rn] = reg[rm];

	  if (pv_is_register (reg[rm], rm) && is_arg_reg (reg[rm]))
	    after_last_frame_setup_insn = next_pc;
	}
      else if (IS_SB (insn) || IS_SH (insn) || IS_SW (insn))
	{
	  int rn = SWBH_32_SOURCE (insn);
	  int rm = SWBH_32_BASE (insn);
	  int disp = SWBH_32_OFFSET (insn);
	  int size = (IS_SB (insn) ? 1
		      : IS_SH (insn) ? 2
		      : (gdb_assert (IS_SW (insn)), 4));
	  pv_t addr = pv_add_constant (reg[rm], disp);

	  if (stack.store_would_trash (addr))
	    break;

	  if (is_arg_spill (gdbarch, reg[rn], addr, &stack))
	    after_last_frame_setup_insn = next_pc;

	  stack.store (addr, size, reg[rn]);
	}
      else if (IS_LDC (insn))
	{
	  int rn = LDC_TARGET (insn);
	  int cr = LDC_IMM (insn) + MEP_FIRST_CSR_REGNUM;

	  reg[rn] = reg[cr];
	}
      else if (IS_LW (insn))
	{
	  int rn = LW_TARGET (insn);
	  int rm = LW_BASE (insn);
	  int offset = LW_OFFSET (insn);
	  pv_t addr = pv_add_constant (reg[rm], offset);

	  reg[rn] = stack.fetch (addr, 4);
	}
      else if (IS_BRA (insn) && BRA_DISP (insn) > 0)
	{
	  /* When a loop appears as the first statement of a function
	     body, gcc 4.x will use a BRA instruction to branch to the
	     loop condition checking code.  This BRA instruction is
	     marked as part of the prologue.  We therefore set next_pc
	     to this branch target and also stop the prologue scan.
	     The instructions at and beyond the branch target should
	     no longer be associated with the prologue.
	     
	     Note that we only consider forward branches here.  We
	     presume that a forward branch is being used to skip over
	     a loop body.
	     
	     A backwards branch is covered by the default case below.
	     If we were to encounter a backwards branch, that would
	     most likely mean that we've scanned through a loop body.
	     We definitely want to stop the prologue scan when this
	     happens and that is precisely what is done by the default
	     case below.  */
	  next_pc = pc + BRA_DISP (insn);
	  after_last_frame_setup_insn = next_pc;
	  break;
	}
      else
	/* We've hit some instruction we don't know how to simulate.
	   Strictly speaking, we should set every value we're
	   tracking to "unknown".  But we'll be optimistic, assume
	   that we have enough information already, and stop
	   analysis here.  */
	break;

      /* If this instruction changed the FP or decreased the SP (i.e.,
	 allocated more stack space), then this may be a good place to
	 declare the prologue finished.  However, there are some
	 exceptions:

	 - If the instruction just changed the FP back to its original
	   value, then that's probably a restore instruction.  The
	   prologue should definitely end before that.  

	 - If the instruction increased the value of the SP (that is,
	   shrunk the frame), then it's probably part of a frame
	   teardown sequence, and the prologue should end before that.  */

      if (! pv_is_identical (reg[MEP_FP_REGNUM], pre_insn_fp))
	{
	  if (! pv_is_register_k (reg[MEP_FP_REGNUM], MEP_FP_REGNUM, 0))
	    after_last_frame_setup_insn = next_pc;
	}
      else if (! pv_is_identical (reg[MEP_SP_REGNUM], pre_insn_sp))
	{
	  /* The comparison of constants looks odd, there, because .k
	     is unsigned.  All it really means is that the new value
	     is lower than it was before the instruction.  */
	  if (pv_is_register (pre_insn_sp, MEP_SP_REGNUM)
	      && pv_is_register (reg[MEP_SP_REGNUM], MEP_SP_REGNUM)
	      && ((pre_insn_sp.k - reg[MEP_SP_REGNUM].k)
		  < (reg[MEP_SP_REGNUM].k - pre_insn_sp.k)))
	    after_last_frame_setup_insn = next_pc;
	}

      pc = next_pc;
    }

  /* Is the frame size (offset, really) a known constant?  */
  if (pv_is_register (reg[MEP_SP_REGNUM], MEP_SP_REGNUM))
    result->frame_size = reg[MEP_SP_REGNUM].k;

  /* Was the frame pointer initialized?  */
  if (pv_is_register (reg[MEP_FP_REGNUM], MEP_SP_REGNUM))
    {
      result->has_frame_ptr = 1;
      result->frame_ptr_offset = reg[MEP_FP_REGNUM].k;
    }

  /* Record where all the registers were saved.  */
  stack.scan (check_for_saved, (void *) result);

  result->prologue_end = after_last_frame_setup_insn;
}


static CORE_ADDR
mep_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  const char *name;
  CORE_ADDR func_addr, func_end;
  struct mep_prologue p;

  /* Try to find the extent of the function that contains PC.  */
  if (! find_pc_partial_function (pc, &name, &func_addr, &func_end))
    return pc;

  mep_analyze_prologue (gdbarch, pc, func_end, &p);
  return p.prologue_end;
}



/* Breakpoints.  */
constexpr gdb_byte mep_break_insn[] = { 0x70, 0x32 };

typedef BP_MANIPULATION (mep_break_insn) mep_breakpoint;


/* Frames and frame unwinding.  */


static struct mep_prologue *
mep_analyze_frame_prologue (struct frame_info *this_frame,
			    void **this_prologue_cache)
{
  if (! *this_prologue_cache)
    {
      CORE_ADDR func_start, stop_addr;

      *this_prologue_cache 
	= FRAME_OBSTACK_ZALLOC (struct mep_prologue);

      func_start = get_frame_func (this_frame);
      stop_addr = get_frame_pc (this_frame);

      /* If we couldn't find any function containing the PC, then
	 just initialize the prologue cache, but don't do anything.  */
      if (! func_start)
	stop_addr = func_start;

      mep_analyze_prologue (get_frame_arch (this_frame),
			    func_start, stop_addr,
			    (struct mep_prologue *) *this_prologue_cache);
    }

  return (struct mep_prologue *) *this_prologue_cache;
}


/* Given the next frame and a prologue cache, return this frame's
   base.  */
static CORE_ADDR
mep_frame_base (struct frame_info *this_frame,
		void **this_prologue_cache)
{
  struct mep_prologue *p
    = mep_analyze_frame_prologue (this_frame, this_prologue_cache);

  /* In functions that use alloca, the distance between the stack
     pointer and the frame base varies dynamically, so we can't use
     the SP plus static information like prologue analysis to find the
     frame base.  However, such functions must have a frame pointer,
     to be able to restore the SP on exit.  So whenever we do have a
     frame pointer, use that to find the base.  */
  if (p->has_frame_ptr)
    {
      CORE_ADDR fp
	= get_frame_register_unsigned (this_frame, MEP_FP_REGNUM);
      return fp - p->frame_ptr_offset;
    }
  else
    {
      CORE_ADDR sp
	= get_frame_register_unsigned (this_frame, MEP_SP_REGNUM);
      return sp - p->frame_size;
    }
}


static void
mep_frame_this_id (struct frame_info *this_frame,
		   void **this_prologue_cache,
		   struct frame_id *this_id)
{
  *this_id = frame_id_build (mep_frame_base (this_frame, this_prologue_cache),
			     get_frame_func (this_frame));
}


static struct value *
mep_frame_prev_register (struct frame_info *this_frame,
			 void **this_prologue_cache, int regnum)
{
  struct mep_prologue *p
    = mep_analyze_frame_prologue (this_frame, this_prologue_cache);

  /* There are a number of complications in unwinding registers on the
     MeP, having to do with core functions calling VLIW functions and
     vice versa.

     The least significant bit of the link register, LP.LTOM, is the
     VLIW mode toggle bit: it's set if a core function called a VLIW
     function, or vice versa, and clear when the caller and callee
     were both in the same mode.

     So, if we're asked to unwind the PC, then we really want to
     unwind the LP and clear the least significant bit.  (Real return
     addresses are always even.)  And if we want to unwind the program
     status word (PSW), we need to toggle PSW.OM if LP.LTOM is set.

     Tweaking the register values we return in this way means that the
     bits in BUFFERP[] are not the same as the bits you'd find at
     ADDRP in the inferior, so we make sure lvalp is not_lval when we
     do this.  */
  if (regnum == MEP_PC_REGNUM)
    {
      struct value *value;
      CORE_ADDR lp;
      value = mep_frame_prev_register (this_frame, this_prologue_cache,
				       MEP_LP_REGNUM);
      lp = value_as_long (value);
      release_value (value);

      return frame_unwind_got_constant (this_frame, regnum, lp & ~1);
    }
  else
    {
      CORE_ADDR frame_base = mep_frame_base (this_frame, this_prologue_cache);
      struct value *value;

      /* Our caller's SP is our frame base.  */
      if (regnum == MEP_SP_REGNUM)
	return frame_unwind_got_constant (this_frame, regnum, frame_base);

      /* If prologue analysis says we saved this register somewhere,
	 return a description of the stack slot holding it.  */
      if (p->reg_offset[regnum] != 1)
	value = frame_unwind_got_memory (this_frame, regnum,
					 frame_base + p->reg_offset[regnum]);

      /* Otherwise, presume we haven't changed the value of this
	 register, and get it from the next frame.  */
      else
	value = frame_unwind_got_register (this_frame, regnum, regnum);

      /* If we need to toggle the operating mode, do so.  */
      if (regnum == MEP_PSW_REGNUM)
	{
	  CORE_ADDR psw, lp;

	  psw = value_as_long (value);
	  release_value (value);

	  /* Get the LP's value, too.  */
	  value = get_frame_register_value (this_frame, MEP_LP_REGNUM);
	  lp = value_as_long (value);
	  release_value (value);

	  /* If LP.LTOM is set, then toggle PSW.OM.  */
	  if (lp & 0x1)
	    psw ^= 0x1000;

	  return frame_unwind_got_constant (this_frame, regnum, psw);
	}

      return value;
    }
}


static const struct frame_unwind mep_frame_unwind = {
  "mep prologue",
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  mep_frame_this_id,
  mep_frame_prev_register,
  NULL,
  default_frame_sniffer
};


/* Return values.  */


static int
mep_use_struct_convention (struct type *type)
{
  return (TYPE_LENGTH (type) > MEP_GPR_SIZE);
}


static void
mep_extract_return_value (struct gdbarch *arch,
			  struct type *type,
			  struct regcache *regcache,
			  gdb_byte *valbuf)
{
  int byte_order = gdbarch_byte_order (arch);

  /* Values that don't occupy a full register appear at the less
     significant end of the value.  This is the offset to where the
     value starts.  */
  int offset;

  /* Return values > MEP_GPR_SIZE bytes are returned in memory,
     pointed to by R0.  */
  gdb_assert (TYPE_LENGTH (type) <= MEP_GPR_SIZE);

  if (byte_order == BFD_ENDIAN_BIG)
    offset = MEP_GPR_SIZE - TYPE_LENGTH (type);
  else
    offset = 0;

  /* Return values that do fit in a single register are returned in R0.  */
  regcache->cooked_read_part (MEP_R0_REGNUM, offset, TYPE_LENGTH (type),
			      valbuf);
}


static void
mep_store_return_value (struct gdbarch *arch,
			struct type *type,
			struct regcache *regcache,
			const gdb_byte *valbuf)
{
  int byte_order = gdbarch_byte_order (arch);

  /* Values that fit in a single register go in R0.  */
  if (TYPE_LENGTH (type) <= MEP_GPR_SIZE)
    {
      /* Values that don't occupy a full register appear at the least
	 significant end of the value.  This is the offset to where the
	 value starts.  */
      int offset;

      if (byte_order == BFD_ENDIAN_BIG)
	offset = MEP_GPR_SIZE - TYPE_LENGTH (type);
      else
	offset = 0;

      regcache->cooked_write_part (MEP_R0_REGNUM, offset, TYPE_LENGTH (type),
				   valbuf);
    }

  /* Return values larger than a single register are returned in
     memory, pointed to by R0.  Unfortunately, we can't count on R0
     pointing to the return buffer, so we raise an error here.  */
  else
    error (_("\
GDB cannot set return values larger than four bytes; the Media Processor's\n\
calling conventions do not provide enough information to do this.\n\
Try using the 'return' command with no argument."));
}

static enum return_value_convention
mep_return_value (struct gdbarch *gdbarch, struct value *function,
		  struct type *type, struct regcache *regcache,
		  gdb_byte *readbuf, const gdb_byte *writebuf)
{
  if (mep_use_struct_convention (type))
    {
      if (readbuf)
	{
	  ULONGEST addr;
	  /* Although the address of the struct buffer gets passed in R1, it's
	     returned in R0.  Fetch R0's value and then read the memory
	     at that address.  */
	  regcache_raw_read_unsigned (regcache, MEP_R0_REGNUM, &addr);
	  read_memory (addr, readbuf, TYPE_LENGTH (type));
	}
      if (writebuf)
	{
	  /* Return values larger than a single register are returned in
	     memory, pointed to by R0.  Unfortunately, we can't count on R0
	     pointing to the return buffer, so we raise an error here.  */
	  error (_("\
GDB cannot set return values larger than four bytes; the Media Processor's\n\
calling conventions do not provide enough information to do this.\n\
Try using the 'return' command with no argument."));
	}
      return RETURN_VALUE_ABI_RETURNS_ADDRESS;
    }

  if (readbuf)
    mep_extract_return_value (gdbarch, type, regcache, readbuf);
  if (writebuf)
    mep_store_return_value (gdbarch, type, regcache, writebuf);

  return RETURN_VALUE_REGISTER_CONVENTION;
}


/* Inferior calls.  */


static CORE_ADDR
mep_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
{
  /* Require word alignment.  */
  return sp & -4;
}


/* From "lang_spec2.txt":

   4.2 Calling conventions

   4.2.1 Core register conventions

   - Parameters should be evaluated from left to right, and they
     should be held in $1,$2,$3,$4 in order.  The fifth parameter or
     after should be held in the stack.  If the size is larger than 4
     bytes in the first four parameters, the pointer should be held in
     the registers instead.  If the size is larger than 4 bytes in the
     fifth parameter or after, the pointer should be held in the stack.

   - Return value of a function should be held in register $0.  If the
     size of return value is larger than 4 bytes, $1 should hold the
     pointer pointing memory that would hold the return value.  In this
     case, the first parameter should be held in $2, the second one in
     $3, and the third one in $4, and the forth parameter or after
     should be held in the stack.

   [This doesn't say so, but arguments shorter than four bytes are
   passed in the least significant end of a four-byte word when
   they're passed on the stack.]  */


/* Traverse the list of ARGC arguments ARGV; for every ARGV[i] too
   large to fit in a register, save it on the stack, and place its
   address in COPY[i].  SP is the initial stack pointer; return the
   new stack pointer.  */
static CORE_ADDR
push_large_arguments (CORE_ADDR sp, int argc, struct value **argv,
		      CORE_ADDR copy[])
{
  int i;

  for (i = 0; i < argc; i++)
    {
      unsigned arg_len = TYPE_LENGTH (value_type (argv[i]));

      if (arg_len > MEP_GPR_SIZE)
	{
	  /* Reserve space for the copy, and then round the SP down, to
	     make sure it's all aligned properly.  */
	  sp = (sp - arg_len) & -4;
	  write_memory (sp, value_contents (argv[i]).data (), arg_len);
	  copy[i] = sp;
	}
    }

  return sp;
}


static CORE_ADDR
mep_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
		     struct regcache *regcache, CORE_ADDR bp_addr,
		     int argc, struct value **argv, CORE_ADDR sp,
		     function_call_return_method return_method,
		     CORE_ADDR struct_addr)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR *copy = (CORE_ADDR *) alloca (argc * sizeof (copy[0]));
  int i;

  /* The number of the next register available to hold an argument.  */
  int arg_reg;

  /* The address of the next stack slot available to hold an argument.  */
  CORE_ADDR arg_stack;

  /* The address of the end of the stack area for arguments.  This is
     just for error checking.  */
  CORE_ADDR arg_stack_end;
  
  sp = push_large_arguments (sp, argc, argv, copy);

  /* Reserve space for the stack arguments, if any.  */
  arg_stack_end = sp;
  if (argc + (struct_addr ? 1 : 0) > 4)
    sp -= ((argc + (struct_addr ? 1 : 0)) - 4) * MEP_GPR_SIZE;

  arg_reg = MEP_R1_REGNUM;
  arg_stack = sp;

  /* If we're returning a structure by value, push the pointer to the
     buffer as the first argument.  */
  if (return_method == return_method_struct)
    {
      regcache_cooked_write_unsigned (regcache, arg_reg, struct_addr);
      arg_reg++;
    }

  for (i = 0; i < argc; i++)
    {
      ULONGEST value;

      /* Arguments that fit in a GPR get expanded to fill the GPR.  */
      if (TYPE_LENGTH (value_type (argv[i])) <= MEP_GPR_SIZE)
	value = extract_unsigned_integer (value_contents (argv[i]).data (),
					  TYPE_LENGTH (value_type (argv[i])),
					  byte_order);

      /* Arguments too large to fit in a GPR get copied to the stack,
	 and we pass a pointer to the copy.  */
      else
	value = copy[i];

      /* We use $1 -- $4 for passing arguments, then use the stack.  */
      if (arg_reg <= MEP_R4_REGNUM)
	{
	  regcache_cooked_write_unsigned (regcache, arg_reg, value);
	  arg_reg++;
	}
      else
	{
	  gdb_byte buf[MEP_GPR_SIZE];
	  store_unsigned_integer (buf, MEP_GPR_SIZE, byte_order, value);
	  write_memory (arg_stack, buf, MEP_GPR_SIZE);
	  arg_stack += MEP_GPR_SIZE;
	}
    }

  gdb_assert (arg_stack <= arg_stack_end);

  /* Set the return address.  */
  regcache_cooked_write_unsigned (regcache, MEP_LP_REGNUM, bp_addr);

  /* Update the stack pointer.  */
  regcache_cooked_write_unsigned (regcache, MEP_SP_REGNUM, sp);
  
  return sp;
}


/* Initialization.  */


static struct gdbarch *
mep_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  struct gdbarch *gdbarch;

  /* Which me_module are we building a gdbarch object for?  */
  CONFIG_ATTR me_module;

  /* If we have a BFD in hand, figure out which me_module it was built
     for.  Otherwise, use the no-particular-me_module code.  */
  if (info.abfd)
    {
      /* The way to get the me_module code depends on the object file
	 format.  At the moment, we only know how to handle ELF.  */
      if (bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
	{
	  int flag = elf_elfheader (info.abfd)->e_flags & EF_MEP_INDEX_MASK;
	  me_module = (CONFIG_ATTR) flag;
	}
      else
	me_module = CONFIG_NONE;
    }
  else
    me_module = CONFIG_NONE;

  /* If we're setting the architecture from a file, check the
     endianness of the file against that of the me_module.  */
  if (info.abfd)
    {
      /* The negations on either side make the comparison treat all
	 non-zero (true) values as equal.  */
      if (! bfd_big_endian (info.abfd) != ! me_module_big_endian (me_module))
	{
	  const char *module_name = me_module_name (me_module);
	  const char *module_endianness
	    = me_module_big_endian (me_module) ? "big" : "little";
	  const char *file_name = bfd_get_filename (info.abfd);
	  const char *file_endianness
	    = bfd_big_endian (info.abfd) ? "big" : "little";
	  
	  gdb_putc ('\n', gdb_stderr);
	  if (module_name)
	    warning (_("the MeP module '%s' is %s-endian, but the executable\n"
		       "%s is %s-endian."),
		     module_name, module_endianness,
		     file_name, file_endianness);
	  else
	    warning (_("the selected MeP module is %s-endian, but the "
		       "executable\n"
		       "%s is %s-endian."),
		     module_endianness, file_name, file_endianness);
	}
    }

  /* Find a candidate among the list of architectures we've created
     already.  info->bfd_arch_info needs to match, but we also want
     the right me_module: the ELF header's e_flags field needs to
     match as well.  */
  for (arches = gdbarch_list_lookup_by_info (arches, &info); 
       arches != NULL;
       arches = gdbarch_list_lookup_by_info (arches->next, &info))
    {
      mep_gdbarch_tdep *tdep
	= (mep_gdbarch_tdep *) gdbarch_tdep (arches->gdbarch);

      if (tdep->me_module == me_module)
	return arches->gdbarch;
    }

  mep_gdbarch_tdep *tdep = new mep_gdbarch_tdep;
  gdbarch = gdbarch_alloc (&info, tdep);

  /* Get a CGEN CPU descriptor for this architecture.  */
  {
    const char *mach_name = info.bfd_arch_info->printable_name;
    enum cgen_endian endian = (info.byte_order == BFD_ENDIAN_BIG
			       ? CGEN_ENDIAN_BIG
			       : CGEN_ENDIAN_LITTLE);

    tdep->cpu_desc = mep_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
					CGEN_CPU_OPEN_ENDIAN, endian,
					CGEN_CPU_OPEN_END);
  }

  tdep->me_module = me_module;

  /* Register set.  */
  set_gdbarch_num_regs (gdbarch, MEP_NUM_RAW_REGS);
  set_gdbarch_pc_regnum (gdbarch, MEP_PC_REGNUM);
  set_gdbarch_sp_regnum (gdbarch, MEP_SP_REGNUM);
  set_gdbarch_register_name (gdbarch, mep_register_name);
  set_gdbarch_register_type (gdbarch, mep_register_type);
  set_gdbarch_num_pseudo_regs (gdbarch, MEP_NUM_PSEUDO_REGS);
  set_gdbarch_pseudo_register_read (gdbarch, mep_pseudo_register_read);
  set_gdbarch_pseudo_register_write (gdbarch, mep_pseudo_register_write);
  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, mep_debug_reg_to_regnum);
  set_gdbarch_stab_reg_to_regnum (gdbarch, mep_debug_reg_to_regnum);

  set_gdbarch_register_reggroup_p (gdbarch, mep_register_reggroup_p);
  reggroup_add (gdbarch, all_reggroup);
  reggroup_add (gdbarch, general_reggroup);
  reggroup_add (gdbarch, save_reggroup);
  reggroup_add (gdbarch, restore_reggroup);
  reggroup_add (gdbarch, mep_csr_reggroup);
  reggroup_add (gdbarch, mep_cr_reggroup);
  reggroup_add (gdbarch, mep_ccr_reggroup);

  /* Disassembly.  */
  set_gdbarch_print_insn (gdbarch, mep_gdb_print_insn); 

  /* Breakpoints.  */
  set_gdbarch_breakpoint_kind_from_pc (gdbarch, mep_breakpoint::kind_from_pc);
  set_gdbarch_sw_breakpoint_from_kind (gdbarch, mep_breakpoint::bp_from_kind);
  set_gdbarch_decr_pc_after_break (gdbarch, 0);
  set_gdbarch_skip_prologue (gdbarch, mep_skip_prologue);

  /* Frames and frame unwinding.  */
  frame_unwind_append_unwinder (gdbarch, &mep_frame_unwind);
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
  set_gdbarch_frame_args_skip (gdbarch, 0);

  /* Return values.  */
  set_gdbarch_return_value (gdbarch, mep_return_value);
  
  /* Inferior function calls.  */
  set_gdbarch_frame_align (gdbarch, mep_frame_align);
  set_gdbarch_push_dummy_call (gdbarch, mep_push_dummy_call);

  return gdbarch;
}

void _initialize_mep_tdep ();
void
_initialize_mep_tdep ()
{
  mep_csr_reggroup = reggroup_new ("csr", USER_REGGROUP);
  mep_cr_reggroup  = reggroup_new ("cr", USER_REGGROUP); 
  mep_ccr_reggroup = reggroup_new ("ccr", USER_REGGROUP);

  register_gdbarch_init (bfd_arch_mep, mep_gdbarch_init);

  mep_init_pseudoregister_maps ();
}
