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

   Copyright (C) 2001-2023 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_base
{
  /* 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 = gdbarch_tdep<mep_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
	= gdbarch_tdep<mep_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 "";
}

/* Custom register groups for the MeP.  */
static const reggroup *mep_csr_reggroup; /* control/special */
static const reggroup *mep_cr_reggroup;	 /* coprocessor general-purpose */
static const 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 (register_type (gdbarch, rawnum)->length () == sizeof (buf64));
  gdb_assert (register_type (gdbarch, cookednum)->length () == 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 (register_type (gdbarch, rawnum)->length () == sizeof (buf64));
  gdb_assert (register_type (gdbarch, cookednum)->length () == 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 (frame_info_ptr 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 (frame_info_ptr 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 (frame_info_ptr 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 (frame_info_ptr 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 () > 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 () <= MEP_GPR_SIZE);

  if (byte_order == BFD_ENDIAN_BIG)
    offset = MEP_GPR_SIZE - type->length ();
  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 (), 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 () <= 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 ();
      else
	offset = 0;

      regcache->cooked_write_part (MEP_R0_REGNUM, offset, type->length (),
				   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 ());
	}
      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 = value_type (argv[i])->length ();

      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 (value_type (argv[i])->length () <= MEP_GPR_SIZE)
	value = extract_unsigned_integer (value_contents (argv[i]).data (),
					  value_type (argv[i])->length (),
					  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)
{
  /* 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
	= gdbarch_tdep<mep_gdbarch_tdep> (arches->gdbarch);

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

  gdbarch *gdbarch
    = gdbarch_alloc (&info, gdbarch_tdep_up (new mep_gdbarch_tdep));
  mep_gdbarch_tdep *tdep = gdbarch_tdep<mep_gdbarch_tdep> (gdbarch);

  /* 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, 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);

  gdbarch_register (bfd_arch_mep, mep_gdbarch_init);

  mep_init_pseudoregister_maps ();
}
