/* Renesas M32C target-dependent code for GDB, the GNU debugger.

   Copyright (C) 2004-2022 Free Software Foundation, 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 "gdb/sim-m32c.h"
#include "gdbtypes.h"
#include "regcache.h"
#include "arch-utils.h"
#include "frame.h"
#include "frame-unwind.h"
#include "symtab.h"
#include "gdbcore.h"
#include "value.h"
#include "reggroups.h"
#include "prologue-value.h"
#include "objfiles.h"
#include "gdbarch.h"


/* The m32c tdep structure.  */

static const reggroup *m32c_dma_reggroup;

/* The type of a function that moves the value of REG between CACHE or
   BUF --- in either direction.  */
typedef enum register_status (m32c_write_reg_t) (struct m32c_reg *reg,
						 struct regcache *cache,
						 const gdb_byte *buf);

typedef enum register_status (m32c_read_reg_t) (struct m32c_reg *reg,
						readable_regcache *cache,
						gdb_byte *buf);

struct m32c_reg
{
  /* The name of this register.  */
  const char *name;

  /* Its type.  */
  struct type *type;

  /* The architecture this register belongs to.  */
  struct gdbarch *arch;

  /* Its GDB register number.  */
  int num;

  /* Its sim register number.  */
  int sim_num;

  /* Its DWARF register number, or -1 if it doesn't have one.  */
  int dwarf_num;

  /* Register group memberships.  */
  unsigned int general_p : 1;
  unsigned int dma_p : 1;
  unsigned int system_p : 1;
  unsigned int save_restore_p : 1;

  /* Functions to read its value from a regcache, and write its value
     to a regcache.  */
  m32c_read_reg_t *read;
  m32c_write_reg_t *write;

  /* Data for READ and WRITE functions.  The exact meaning depends on
     the specific functions selected; see the comments for those
     functions.  */
  struct m32c_reg *rx, *ry;
  int n;
};


/* An overestimate of the number of raw and pseudoregisters we will
   have.  The exact answer depends on the variant of the architecture
   at hand, but we can use this to declare statically allocated
   arrays, and bump it up when needed.  */
#define M32C_MAX_NUM_REGS (75)

/* The largest assigned DWARF register number.  */
#define M32C_MAX_DWARF_REGNUM (40)


struct m32c_gdbarch_tdep : gdbarch_tdep
{
  /* All the registers for this variant, indexed by GDB register
     number, and the number of registers present.  */
  struct m32c_reg regs[M32C_MAX_NUM_REGS] {};

  /* The number of valid registers.  */
  int num_regs = 0;

  /* Interesting registers.  These are pointers into REGS.  */
  struct m32c_reg *pc = nullptr, *flg = nullptr;
  struct m32c_reg *r0 = nullptr, *r1 = nullptr, *r2 = nullptr, *r3 = nullptr,
    *a0 = nullptr, *a1 = nullptr;
  struct m32c_reg *r2r0 = nullptr, *r3r2r1r0 = nullptr, *r3r1r2r0 = nullptr;
  struct m32c_reg *sb = nullptr, *fb = nullptr, *sp = nullptr;

  /* A table indexed by DWARF register numbers, pointing into
     REGS.  */
  struct m32c_reg *dwarf_regs[M32C_MAX_DWARF_REGNUM + 1] {};

  /* Types for this architecture.  We can't use the builtin_type_foo
     types, because they're not initialized when building a gdbarch
     structure.  */
  struct type *voyd = nullptr, *ptr_voyd = nullptr, *func_voyd = nullptr;
  struct type *uint8 = nullptr, *uint16 = nullptr;
  struct type *int8 = nullptr, *int16 = nullptr, *int32 = nullptr,
    *int64 = nullptr;

  /* The types for data address and code address registers.  */
  struct type *data_addr_reg_type = nullptr, *code_addr_reg_type = nullptr;

  /* The number of bytes a return address pushed by a 'jsr' instruction
     occupies on the stack.  */
  int ret_addr_bytes = 0;

  /* The number of bytes an address register occupies on the stack
     when saved by an 'enter' or 'pushm' instruction.  */
  int push_addr_bytes = 0;
};


/* Types.  */

static void
make_types (struct gdbarch *arch)
{
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (arch);
  unsigned long mach = gdbarch_bfd_arch_info (arch)->mach;
  int data_addr_reg_bits, code_addr_reg_bits;
  char type_name[50];

#if 0
  /* This is used to clip CORE_ADDR values, so this value is
     appropriate both on the m32c, where pointers are 32 bits long,
     and on the m16c, where pointers are sixteen bits long, but there
     may be code above the 64k boundary.  */
  set_gdbarch_addr_bit (arch, 24);
#else
  /* GCC uses 32 bits for addrs in the dwarf info, even though
     only 16/24 bits are used.  Setting addr_bit to 24 causes
     errors in reading the dwarf addresses.  */
  set_gdbarch_addr_bit (arch, 32);
#endif

  set_gdbarch_int_bit (arch, 16);
  switch (mach)
    {
    case bfd_mach_m16c:
      data_addr_reg_bits = 16;
      code_addr_reg_bits = 24;
      set_gdbarch_ptr_bit (arch, 16);
      tdep->ret_addr_bytes = 3;
      tdep->push_addr_bytes = 2;
      break;

    case bfd_mach_m32c:
      data_addr_reg_bits = 24;
      code_addr_reg_bits = 24;
      set_gdbarch_ptr_bit (arch, 32);
      tdep->ret_addr_bytes = 4;
      tdep->push_addr_bytes = 4;
      break;

    default:
      gdb_assert_not_reached ("unexpected mach");
    }

  /* The builtin_type_mumble variables are sometimes uninitialized when
     this is called, so we avoid using them.  */
  tdep->voyd = arch_type (arch, TYPE_CODE_VOID, TARGET_CHAR_BIT, "void");
  tdep->ptr_voyd
    = arch_pointer_type (arch, gdbarch_ptr_bit (arch), NULL, tdep->voyd);
  tdep->func_voyd = lookup_function_type (tdep->voyd);

  xsnprintf (type_name, sizeof (type_name), "%s_data_addr_t",
	     gdbarch_bfd_arch_info (arch)->printable_name);
  tdep->data_addr_reg_type
    = arch_pointer_type (arch, data_addr_reg_bits, type_name, tdep->voyd);

  xsnprintf (type_name, sizeof (type_name), "%s_code_addr_t",
	     gdbarch_bfd_arch_info (arch)->printable_name);
  tdep->code_addr_reg_type
    = arch_pointer_type (arch, code_addr_reg_bits, type_name, tdep->func_voyd);

  tdep->uint8  = arch_integer_type (arch,  8, 1, "uint8_t");
  tdep->uint16 = arch_integer_type (arch, 16, 1, "uint16_t");
  tdep->int8   = arch_integer_type (arch,  8, 0, "int8_t");
  tdep->int16  = arch_integer_type (arch, 16, 0, "int16_t");
  tdep->int32  = arch_integer_type (arch, 32, 0, "int32_t");
  tdep->int64  = arch_integer_type (arch, 64, 0, "int64_t");
}



/* Register set.  */

static const char *
m32c_register_name (struct gdbarch *gdbarch, int num)
{
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  return tdep->regs[num].name;
}


static struct type *
m32c_register_type (struct gdbarch *arch, int reg_nr)
{
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (arch);
  return tdep->regs[reg_nr].type;
}


static int
m32c_register_sim_regno (struct gdbarch *gdbarch, int reg_nr)
{
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  return tdep->regs[reg_nr].sim_num;
}


static int
m32c_debug_info_reg_to_regnum (struct gdbarch *gdbarch, int reg_nr)
{
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  if (0 <= reg_nr && reg_nr <= M32C_MAX_DWARF_REGNUM
      && tdep->dwarf_regs[reg_nr])
    return tdep->dwarf_regs[reg_nr]->num;
  else
    /* The DWARF CFI code expects to see -1 for invalid register
       numbers.  */
    return -1;
}


static int
m32c_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
			  const struct reggroup *group)
{
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  struct m32c_reg *reg = &tdep->regs[regnum];

  /* The anonymous raw registers aren't in any groups.  */
  if (! reg->name)
    return 0;

  if (group == all_reggroup)
    return 1;

  if (group == general_reggroup
      && reg->general_p)
    return 1;

  if (group == m32c_dma_reggroup
      && reg->dma_p)
    return 1;

  if (group == system_reggroup
      && reg->system_p)
    return 1;

  /* Since the m32c DWARF register numbers refer to cooked registers, not
     raw registers, and frame_pop depends on the save and restore groups
     containing registers the DWARF CFI will actually mention, our save
     and restore groups are cooked registers, not raw registers.  (This is
     why we can't use the default reggroup function.)  */
  if ((group == save_reggroup
       || group == restore_reggroup)
      && reg->save_restore_p)
    return 1;

  return 0;
}


/* Register move functions.  We declare them here using
   m32c_{read,write}_reg_t to check the types.  */
static m32c_read_reg_t m32c_raw_read;
static m32c_read_reg_t m32c_banked_read;
static m32c_read_reg_t m32c_sb_read;
static m32c_read_reg_t m32c_part_read;
static m32c_read_reg_t m32c_cat_read;
static m32c_read_reg_t m32c_r3r2r1r0_read;

static m32c_write_reg_t m32c_raw_write;
static m32c_write_reg_t m32c_banked_write;
static m32c_write_reg_t m32c_sb_write;
static m32c_write_reg_t m32c_part_write;
static m32c_write_reg_t m32c_cat_write;
static m32c_write_reg_t m32c_r3r2r1r0_write;

/* Copy the value of the raw register REG from CACHE to BUF.  */
static enum register_status
m32c_raw_read (struct m32c_reg *reg, readable_regcache *cache, gdb_byte *buf)
{
  return cache->raw_read (reg->num, buf);
}


/* Copy the value of the raw register REG from BUF to CACHE.  */
static enum register_status
m32c_raw_write (struct m32c_reg *reg, struct regcache *cache,
		const gdb_byte *buf)
{
  cache->raw_write (reg->num, buf);

  return REG_VALID;
}


/* Return the value of the 'flg' register in CACHE.  */
static int
m32c_read_flg (readable_regcache *cache)
{
  gdbarch *arch = cache->arch ();
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (arch);
  ULONGEST flg;

  cache->raw_read (tdep->flg->num, &flg);
  return flg & 0xffff;
}


/* Evaluate the real register number of a banked register.  */
static struct m32c_reg *
m32c_banked_register (struct m32c_reg *reg, readable_regcache *cache)
{
  return ((m32c_read_flg (cache) & reg->n) ? reg->ry : reg->rx);
}


/* Move the value of a banked register from CACHE to BUF.
   If the value of the 'flg' register in CACHE has any of the bits
   masked in REG->n set, then read REG->ry.  Otherwise, read
   REG->rx.  */
static enum register_status
m32c_banked_read (struct m32c_reg *reg, readable_regcache *cache, gdb_byte *buf)
{
  struct m32c_reg *bank_reg = m32c_banked_register (reg, cache);
  return cache->raw_read (bank_reg->num, buf);
}


/* Move the value of a banked register from BUF to CACHE.
   If the value of the 'flg' register in CACHE has any of the bits
   masked in REG->n set, then write REG->ry.  Otherwise, write
   REG->rx.  */
static enum register_status
m32c_banked_write (struct m32c_reg *reg, struct regcache *cache,
		   const gdb_byte *buf)
{
  struct m32c_reg *bank_reg = m32c_banked_register (reg, cache);
  cache->raw_write (bank_reg->num, buf);

  return REG_VALID;
}


/* Move the value of SB from CACHE to BUF.  On bfd_mach_m32c, SB is a
   banked register; on bfd_mach_m16c, it's not.  */
static enum register_status
m32c_sb_read (struct m32c_reg *reg, readable_regcache *cache, gdb_byte *buf)
{
  if (gdbarch_bfd_arch_info (reg->arch)->mach == bfd_mach_m16c)
    return m32c_raw_read (reg->rx, cache, buf);
  else
    return m32c_banked_read (reg, cache, buf);
}


/* Move the value of SB from BUF to CACHE.  On bfd_mach_m32c, SB is a
   banked register; on bfd_mach_m16c, it's not.  */
static enum register_status
m32c_sb_write (struct m32c_reg *reg, struct regcache *cache, const gdb_byte *buf)
{
  if (gdbarch_bfd_arch_info (reg->arch)->mach == bfd_mach_m16c)
    m32c_raw_write (reg->rx, cache, buf);
  else
    m32c_banked_write (reg, cache, buf);

  return REG_VALID;
}


/* Assuming REG uses m32c_part_read and m32c_part_write, set *OFFSET_P
   and *LEN_P to the offset and length, in bytes, of the part REG
   occupies in its underlying register.  The offset is from the
   lower-addressed end, regardless of the architecture's endianness.
   (The M32C family is always little-endian, but let's keep those
   assumptions out of here.)  */
static void
m32c_find_part (struct m32c_reg *reg, int *offset_p, int *len_p)
{
  /* The length of the containing register, of which REG is one part.  */
  int containing_len = TYPE_LENGTH (reg->rx->type);

  /* The length of one "element" in our imaginary array.  */
  int elt_len = TYPE_LENGTH (reg->type);

  /* The offset of REG's "element" from the least significant end of
     the containing register.  */
  int elt_offset = reg->n * elt_len;

  /* If we extend off the end, trim the length of the element.  */
  if (elt_offset + elt_len > containing_len)
    {
      elt_len = containing_len - elt_offset;
      /* We shouldn't be declaring partial registers that go off the
	 end of their containing registers.  */
      gdb_assert (elt_len > 0);
    }

  /* Flip the offset around if we're big-endian.  */
  if (gdbarch_byte_order (reg->arch) == BFD_ENDIAN_BIG)
    elt_offset = TYPE_LENGTH (reg->rx->type) - elt_offset - elt_len;

  *offset_p = elt_offset;
  *len_p = elt_len;
}


/* Move the value of a partial register (r0h, intbl, etc.) from CACHE
   to BUF.  Treating the value of the register REG->rx as an array of
   REG->type values, where higher indices refer to more significant
   bits, read the value of the REG->n'th element.  */
static enum register_status
m32c_part_read (struct m32c_reg *reg, readable_regcache *cache, gdb_byte *buf)
{
  int offset, len;

  memset (buf, 0, TYPE_LENGTH (reg->type));
  m32c_find_part (reg, &offset, &len);
  return cache->cooked_read_part (reg->rx->num, offset, len, buf);
}


/* Move the value of a banked register from BUF to CACHE.
   Treating the value of the register REG->rx as an array of REG->type
   values, where higher indices refer to more significant bits, write
   the value of the REG->n'th element.  */
static enum register_status
m32c_part_write (struct m32c_reg *reg, struct regcache *cache,
		 const gdb_byte *buf)
{
  int offset, len;

  m32c_find_part (reg, &offset, &len);
  cache->cooked_write_part (reg->rx->num, offset, len, buf);

  return REG_VALID;
}


/* Move the value of REG from CACHE to BUF.  REG's value is the
   concatenation of the values of the registers REG->rx and REG->ry,
   with REG->rx contributing the more significant bits.  */
static enum register_status
m32c_cat_read (struct m32c_reg *reg, readable_regcache *cache, gdb_byte *buf)
{
  int high_bytes = TYPE_LENGTH (reg->rx->type);
  int low_bytes  = TYPE_LENGTH (reg->ry->type);
  enum register_status status;

  gdb_assert (TYPE_LENGTH (reg->type) == high_bytes + low_bytes);

  if (gdbarch_byte_order (reg->arch) == BFD_ENDIAN_BIG)
    {
      status = cache->cooked_read (reg->rx->num, buf);
      if (status == REG_VALID)
	status = cache->cooked_read (reg->ry->num, buf + high_bytes);
    }
  else
    {
      status = cache->cooked_read (reg->rx->num, buf + low_bytes);
      if (status == REG_VALID)
	status = cache->cooked_read (reg->ry->num, buf);
    }
  return status;
}


/* Move the value of REG from CACHE to BUF.  REG's value is the
   concatenation of the values of the registers REG->rx and REG->ry,
   with REG->rx contributing the more significant bits.  */
static enum register_status
m32c_cat_write (struct m32c_reg *reg, struct regcache *cache,
		const gdb_byte *buf)
{
  int high_bytes = TYPE_LENGTH (reg->rx->type);
  int low_bytes  = TYPE_LENGTH (reg->ry->type);

  gdb_assert (TYPE_LENGTH (reg->type) == high_bytes + low_bytes);

  if (gdbarch_byte_order (reg->arch) == BFD_ENDIAN_BIG)
    {
      cache->cooked_write (reg->rx->num, buf);
      cache->cooked_write (reg->ry->num, buf + high_bytes);
    }
  else
    {
      cache->cooked_write (reg->rx->num, buf + low_bytes);
      cache->cooked_write (reg->ry->num, buf);
    }

  return REG_VALID;
}


/* Copy the value of the raw register REG from CACHE to BUF.  REG is
   the concatenation (from most significant to least) of r3, r2, r1,
   and r0.  */
static enum register_status
m32c_r3r2r1r0_read (struct m32c_reg *reg, readable_regcache *cache, gdb_byte *buf)
{
  gdbarch *arch = reg->arch;
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (arch);
  int len = TYPE_LENGTH (tdep->r0->type);
  enum register_status status;

  if (gdbarch_byte_order (reg->arch) == BFD_ENDIAN_BIG)
    {
      status = cache->cooked_read (tdep->r0->num, buf + len * 3);
      if (status == REG_VALID)
	status = cache->cooked_read (tdep->r1->num, buf + len * 2);
      if (status == REG_VALID)
	status = cache->cooked_read (tdep->r2->num, buf + len * 1);
      if (status == REG_VALID)
	status = cache->cooked_read (tdep->r3->num, buf);
    }
  else
    {
      status = cache->cooked_read (tdep->r0->num, buf);
      if (status == REG_VALID)
	status = cache->cooked_read (tdep->r1->num, buf + len * 1);
      if (status == REG_VALID)
	status = cache->cooked_read (tdep->r2->num, buf + len * 2);
      if (status == REG_VALID)
	status = cache->cooked_read (tdep->r3->num, buf + len * 3);
    }

  return status;
}


/* Copy the value of the raw register REG from BUF to CACHE.  REG is
   the concatenation (from most significant to least) of r3, r2, r1,
   and r0.  */
static enum register_status
m32c_r3r2r1r0_write (struct m32c_reg *reg, struct regcache *cache,
		     const gdb_byte *buf)
{
  gdbarch *arch = reg->arch;
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (arch);
  int len = TYPE_LENGTH (tdep->r0->type);

  if (gdbarch_byte_order (reg->arch) == BFD_ENDIAN_BIG)
    {
      cache->cooked_write (tdep->r0->num, buf + len * 3);
      cache->cooked_write (tdep->r1->num, buf + len * 2);
      cache->cooked_write (tdep->r2->num, buf + len * 1);
      cache->cooked_write (tdep->r3->num, buf);
    }
  else
    {
      cache->cooked_write (tdep->r0->num, buf);
      cache->cooked_write (tdep->r1->num, buf + len * 1);
      cache->cooked_write (tdep->r2->num, buf + len * 2);
      cache->cooked_write (tdep->r3->num, buf + len * 3);
    }

  return REG_VALID;
}


static enum register_status
m32c_pseudo_register_read (struct gdbarch *arch,
			   readable_regcache *cache,
			   int cookednum,
			   gdb_byte *buf)
{
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (arch);
  struct m32c_reg *reg;

  gdb_assert (0 <= cookednum && cookednum < tdep->num_regs);
  gdb_assert (arch == cache->arch ());
  gdb_assert (arch == tdep->regs[cookednum].arch);
  reg = &tdep->regs[cookednum];

  return reg->read (reg, cache, buf);
}


static void
m32c_pseudo_register_write (struct gdbarch *arch,
			    struct regcache *cache,
			    int cookednum,
			    const gdb_byte *buf)
{
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (arch);
  struct m32c_reg *reg;

  gdb_assert (0 <= cookednum && cookednum < tdep->num_regs);
  gdb_assert (arch == cache->arch ());
  gdb_assert (arch == tdep->regs[cookednum].arch);
  reg = &tdep->regs[cookednum];

  reg->write (reg, cache, buf);
}


/* Add a register with the given fields to the end of ARCH's table.
   Return a pointer to the newly added register.  */
static struct m32c_reg *
add_reg (struct gdbarch *arch,
	 const char *name,
	 struct type *type,
	 int sim_num,
	 m32c_read_reg_t *read,
	 m32c_write_reg_t *write,
	 struct m32c_reg *rx,
	 struct m32c_reg *ry,
	 int n)
{
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (arch);
  struct m32c_reg *r = &tdep->regs[tdep->num_regs];

  gdb_assert (tdep->num_regs < M32C_MAX_NUM_REGS);

  r->name           = name;
  r->type           = type;
  r->arch           = arch;
  r->num            = tdep->num_regs;
  r->sim_num        = sim_num;
  r->dwarf_num      = -1;
  r->general_p      = 0;
  r->dma_p          = 0;
  r->system_p       = 0;
  r->save_restore_p = 0;
  r->read           = read;
  r->write          = write;
  r->rx             = rx;
  r->ry             = ry;
  r->n              = n;

  tdep->num_regs++;

  return r;
}


/* Record NUM as REG's DWARF register number.  */
static void
set_dwarf_regnum (struct m32c_reg *reg, int num)
{
  gdb_assert (num < M32C_MAX_NUM_REGS);

  /* Update the reg->DWARF mapping.  Only count the first number
     assigned to this register.  */
  if (reg->dwarf_num == -1)
    reg->dwarf_num = num;

  /* Update the DWARF->reg mapping.  */
  gdbarch *arch = reg->arch;
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (arch);
  tdep->dwarf_regs[num] = reg;
}


/* Mark REG as a general-purpose register, and return it.  */
static struct m32c_reg *
mark_general (struct m32c_reg *reg)
{
  reg->general_p = 1;
  return reg;
}


/* Mark REG as a DMA register.  */
static void
mark_dma (struct m32c_reg *reg)
{
  reg->dma_p = 1;
}


/* Mark REG as a SYSTEM register, and return it.  */
static struct m32c_reg *
mark_system (struct m32c_reg *reg)
{
  reg->system_p = 1;
  return reg;
}


/* Mark REG as a save-restore register, and return it.  */
static struct m32c_reg *
mark_save_restore (struct m32c_reg *reg)
{
  reg->save_restore_p = 1;
  return reg;
}


#define FLAGBIT_B	0x0010
#define FLAGBIT_U	0x0080

/* Handy macros for declaring registers.  These all evaluate to
   pointers to the register declared.  Macros that define two
   registers evaluate to a pointer to the first.  */

/* A raw register named NAME, with type TYPE and sim number SIM_NUM.  */
#define R(name, type, sim_num)					\
  (add_reg (arch, (name), (type), (sim_num),			\
	    m32c_raw_read, m32c_raw_write, NULL, NULL, 0))

/* The simulator register number for a raw register named NAME.  */
#define SIM(name) (m32c_sim_reg_ ## name)

/* A raw unsigned 16-bit data register named NAME.
   NAME should be an identifier, not a string.  */
#define R16U(name)						\
  (R(#name, tdep->uint16, SIM (name)))

/* A raw data address register named NAME.
   NAME should be an identifier, not a string.  */
#define RA(name)						\
  (R(#name, tdep->data_addr_reg_type, SIM (name)))

/* A raw code address register named NAME.  NAME should
   be an identifier, not a string.  */
#define RC(name)						\
  (R(#name, tdep->code_addr_reg_type, SIM (name)))

/* A pair of raw registers named NAME0 and NAME1, with type TYPE.
   NAME should be an identifier, not a string.  */
#define RP(name, type)				\
  (R(#name "0", (type), SIM (name ## 0)),	\
   R(#name "1", (type), SIM (name ## 1)) - 1)

/* A raw banked general-purpose data register named NAME.
   NAME should be an identifier, not a string.  */
#define RBD(name)						\
  (R(NULL, tdep->int16, SIM (name ## _bank0)),		\
   R(NULL, tdep->int16, SIM (name ## _bank1)) - 1)

/* A raw banked data address register named NAME.
   NAME should be an identifier, not a string.  */
#define RBA(name)						\
  (R(NULL, tdep->data_addr_reg_type, SIM (name ## _bank0)),	\
   R(NULL, tdep->data_addr_reg_type, SIM (name ## _bank1)) - 1)

/* A cooked register named NAME referring to a raw banked register
   from the bank selected by the current value of FLG.  RAW_PAIR
   should be a pointer to the first register in the banked pair.
   NAME must be an identifier, not a string.  */
#define CB(name, raw_pair)				\
  (add_reg (arch, #name, (raw_pair)->type, 0,		\
	    m32c_banked_read, m32c_banked_write,	\
	    (raw_pair), (raw_pair + 1), FLAGBIT_B))

/* A pair of registers named NAMEH and NAMEL, of type TYPE, that
   access the top and bottom halves of the register pointed to by
   NAME.  NAME should be an identifier.  */
#define CHL(name, type)							\
  (add_reg (arch, #name "h", (type), 0,					\
	    m32c_part_read, m32c_part_write, name, NULL, 1),		\
   add_reg (arch, #name "l", (type), 0,					\
	    m32c_part_read, m32c_part_write, name, NULL, 0) - 1)

/* A register constructed by concatenating the two registers HIGH and
   LOW, whose name is HIGHLOW and whose type is TYPE.  */
#define CCAT(high, low, type)					\
  (add_reg (arch, #high #low, (type), 0,			\
	    m32c_cat_read, m32c_cat_write, (high), (low), 0))

/* Abbreviations for marking register group membership.  */
#define G(reg)   (mark_general (reg))
#define S(reg)   (mark_system  (reg))
#define DMA(reg) (mark_dma     (reg))


/* Construct the register set for ARCH.  */
static void
make_regs (struct gdbarch *arch)
{
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (arch);
  int mach = gdbarch_bfd_arch_info (arch)->mach;
  int num_raw_regs;
  int num_cooked_regs;

  struct m32c_reg *r0;
  struct m32c_reg *r1;
  struct m32c_reg *r2;
  struct m32c_reg *r3;
  struct m32c_reg *a0;
  struct m32c_reg *a1;
  struct m32c_reg *fb;
  struct m32c_reg *sb;
  struct m32c_reg *sp;
  struct m32c_reg *r0hl;
  struct m32c_reg *r1hl;
  struct m32c_reg *r2r0;
  struct m32c_reg *r3r1;
  struct m32c_reg *r3r1r2r0;
  struct m32c_reg *r3r2r1r0;
  struct m32c_reg *a1a0;

  struct m32c_reg *raw_r0_pair = RBD (r0);
  struct m32c_reg *raw_r1_pair = RBD (r1);
  struct m32c_reg *raw_r2_pair = RBD (r2);
  struct m32c_reg *raw_r3_pair = RBD (r3);
  struct m32c_reg *raw_a0_pair = RBA (a0);
  struct m32c_reg *raw_a1_pair = RBA (a1);
  struct m32c_reg *raw_fb_pair = RBA (fb);

  /* sb is banked on the bfd_mach_m32c, but not on bfd_mach_m16c.
     We always declare both raw registers, and deal with the distinction
     in the pseudoregister.  */
  struct m32c_reg *raw_sb_pair = RBA (sb);

  struct m32c_reg *usp         = S (RA (usp));
  struct m32c_reg *isp         = S (RA (isp));
  struct m32c_reg *intb        = S (RC (intb));
  struct m32c_reg *pc          = G (RC (pc));
  struct m32c_reg *flg         = G (R16U (flg));

  if (mach == bfd_mach_m32c)
    {
      S (R16U (svf));
      S (RC (svp));
      S (RC (vct));

      DMA (RP (dmd, tdep->uint8));
      DMA (RP (dct, tdep->uint16));
      DMA (RP (drc, tdep->uint16));
      DMA (RP (dma, tdep->data_addr_reg_type));
      DMA (RP (dsa, tdep->data_addr_reg_type));
      DMA (RP (dra, tdep->data_addr_reg_type));
    }

  num_raw_regs = tdep->num_regs;

  r0 	      = G (CB (r0, raw_r0_pair));
  r1 	      = G (CB (r1, raw_r1_pair));
  r2          = G (CB (r2, raw_r2_pair));
  r3          = G (CB (r3, raw_r3_pair));
  a0          = G (CB (a0, raw_a0_pair));
  a1          = G (CB (a1, raw_a1_pair));
  fb          = G (CB (fb, raw_fb_pair));

  /* sb is banked on the bfd_mach_m32c, but not on bfd_mach_m16c.
     Specify custom read/write functions that do the right thing.  */
  sb          = G (add_reg (arch, "sb", raw_sb_pair->type, 0,
			    m32c_sb_read, m32c_sb_write,
			    raw_sb_pair, raw_sb_pair + 1, 0));

  /* The current sp is either usp or isp, depending on the value of
     the FLG register's U bit.  */
  sp          = G (add_reg (arch, "sp", usp->type, 0,
			    m32c_banked_read, m32c_banked_write,
			    isp, usp, FLAGBIT_U));

  r0hl        = CHL (r0, tdep->int8);
  r1hl        = CHL (r1, tdep->int8);
  CHL (r2, tdep->int8);
  CHL (r3, tdep->int8);
  CHL (intb, tdep->int16);

  r2r0        = CCAT (r2,   r0,   tdep->int32);
  r3r1        = CCAT (r3,   r1,   tdep->int32);
  r3r1r2r0    = CCAT (r3r1, r2r0, tdep->int64);

  r3r2r1r0
    = add_reg (arch, "r3r2r1r0", tdep->int64, 0,
	       m32c_r3r2r1r0_read, m32c_r3r2r1r0_write, NULL, NULL, 0);

  if (mach == bfd_mach_m16c)
    a1a0 = CCAT (a1, a0, tdep->int32);
  else
    a1a0 = NULL;

  num_cooked_regs = tdep->num_regs - num_raw_regs;

  tdep->pc   	 = pc;
  tdep->flg  	 = flg;
  tdep->r0   	 = r0;
  tdep->r1   	 = r1;
  tdep->r2   	 = r2;
  tdep->r3   	 = r3;
  tdep->r2r0 	 = r2r0;
  tdep->r3r2r1r0 = r3r2r1r0;
  tdep->r3r1r2r0 = r3r1r2r0;
  tdep->a0       = a0;
  tdep->a1       = a1;
  tdep->sb       = sb;
  tdep->fb   	 = fb;
  tdep->sp   	 = sp;

  /* Set up the DWARF register table.  */
  memset (tdep->dwarf_regs, 0, sizeof (tdep->dwarf_regs));
  set_dwarf_regnum (r0hl + 1, 0x01);
  set_dwarf_regnum (r0hl + 0, 0x02);
  set_dwarf_regnum (r1hl + 1, 0x03);
  set_dwarf_regnum (r1hl + 0, 0x04);
  set_dwarf_regnum (r0,       0x05);
  set_dwarf_regnum (r1,       0x06);
  set_dwarf_regnum (r2,       0x07);
  set_dwarf_regnum (r3,       0x08);
  set_dwarf_regnum (a0,       0x09);
  set_dwarf_regnum (a1,       0x0a);
  set_dwarf_regnum (fb,       0x0b);
  set_dwarf_regnum (sp,       0x0c);
  set_dwarf_regnum (pc,       0x0d); /* GCC's invention */
  set_dwarf_regnum (sb,       0x13);
  set_dwarf_regnum (r2r0,     0x15);
  set_dwarf_regnum (r3r1,     0x16);
  if (a1a0)
    set_dwarf_regnum (a1a0,   0x17);

  /* Enumerate the save/restore register group.

     The regcache_save and regcache_restore functions apply their read
     function to each register in this group.

     Since frame_pop supplies frame_unwind_register as its read
     function, the registers meaningful to the Dwarf unwinder need to
     be in this group.

     On the other hand, when we make inferior calls, save_inferior_status
     and restore_inferior_status use them to preserve the current register
     values across the inferior call.  For this, you'd kind of like to
     preserve all the raw registers, to protect the interrupted code from
     any sort of bank switching the callee might have done.  But we handle
     those cases so badly anyway --- for example, it matters whether we
     restore FLG before or after we restore the general-purpose registers,
     but there's no way to express that --- that it isn't worth worrying
     about.

     We omit control registers like inthl: if you call a function that
     changes those, it's probably because you wanted that change to be
     visible to the interrupted code.  */
  mark_save_restore (r0);
  mark_save_restore (r1);
  mark_save_restore (r2);
  mark_save_restore (r3);
  mark_save_restore (a0);
  mark_save_restore (a1);
  mark_save_restore (sb);
  mark_save_restore (fb);
  mark_save_restore (sp);
  mark_save_restore (pc);
  mark_save_restore (flg);

  set_gdbarch_num_regs (arch, num_raw_regs);
  set_gdbarch_num_pseudo_regs (arch, num_cooked_regs);
  set_gdbarch_pc_regnum (arch, pc->num);
  set_gdbarch_sp_regnum (arch, sp->num);
  set_gdbarch_register_name (arch, m32c_register_name);
  set_gdbarch_register_type (arch, m32c_register_type);
  set_gdbarch_pseudo_register_read (arch, m32c_pseudo_register_read);
  set_gdbarch_pseudo_register_write (arch, m32c_pseudo_register_write);
  set_gdbarch_register_sim_regno (arch, m32c_register_sim_regno);
  set_gdbarch_stab_reg_to_regnum (arch, m32c_debug_info_reg_to_regnum);
  set_gdbarch_dwarf2_reg_to_regnum (arch, m32c_debug_info_reg_to_regnum);
  set_gdbarch_register_reggroup_p (arch, m32c_register_reggroup_p);

  reggroup_add (arch, m32c_dma_reggroup);
}



/* Breakpoints.  */
constexpr gdb_byte m32c_break_insn[] = { 0x00 };	/* brk */

typedef BP_MANIPULATION (m32c_break_insn) m32c_breakpoint;


/* Prologue analysis.  */

enum m32c_prologue_kind
{
  /* This function uses a frame pointer.  */
  prologue_with_frame_ptr,

  /* This function has no frame pointer.  */
  prologue_sans_frame_ptr,

  /* This function sets up the stack, so its frame is the first
     frame on the stack.  */
  prologue_first_frame
};

struct m32c_prologue
{
  /* For consistency with the DWARF 2 .debug_frame info generated by
     GCC, a frame's CFA is the address immediately after the saved
     return address.  */

  /* The architecture for which we generated this prologue info.  */
  struct gdbarch *arch;

  enum m32c_prologue_kind kind;

  /* If KIND is prologue_with_frame_ptr, this is the offset from the
     CFA to where the frame pointer points.  This is always zero or
     negative.  */
  LONGEST frame_ptr_offset;

  /* If KIND is prologue_sans_frame_ptr, the offset from the CFA 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.

     Functions that use alloca don't have a constant frame size.  But
     they always have frame pointers, so we must use that to find the
     CFA (and perhaps to unwind the stack pointer).  */
  LONGEST frame_size;

  /* 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.)  */
  LONGEST reg_offset[M32C_MAX_NUM_REGS];
};


/* The longest I've seen, anyway.  */
#define M32C_MAX_INSN_LEN (9)

/* Processor state, for the prologue analyzer.  */
struct m32c_pv_state
{
  struct gdbarch *arch;
  pv_t r0, r1, r2, r3;
  pv_t a0, a1;
  pv_t sb, fb, sp;
  pv_t pc;
  struct pv_area *stack;

  /* Bytes from the current PC, the address they were read from,
     and the address of the next unconsumed byte.  */
  gdb_byte insn[M32C_MAX_INSN_LEN];
  CORE_ADDR scan_pc, next_addr;
};


/* Push VALUE on STATE's stack, occupying SIZE bytes.  Return zero if
   all went well, or non-zero if simulating the action would trash our
   state.  */
static int
m32c_pv_push (struct m32c_pv_state *state, pv_t value, int size)
{
  if (state->stack->store_would_trash (state->sp))
    return 1;

  state->sp = pv_add_constant (state->sp, -size);
  state->stack->store (state->sp, size, value);

  return 0;
}


enum srcdest_kind
{
  srcdest_reg,
  srcdest_partial_reg,
  srcdest_mem
};

/* A source or destination location for an m16c or m32c
   instruction.  */
struct srcdest
{
  /* If srcdest_reg, the location is a register pointed to by REG.
     If srcdest_partial_reg, the location is part of a register pointed
     to by REG.  We don't try to handle this too well.
     If srcdest_mem, the location is memory whose address is ADDR.  */
  enum srcdest_kind kind;
  pv_t *reg, addr;
};


/* Return the SIZE-byte value at LOC in STATE.  */
static pv_t
m32c_srcdest_fetch (struct m32c_pv_state *state, struct srcdest loc, int size)
{
  if (loc.kind == srcdest_mem)
    return state->stack->fetch (loc.addr, size);
  else if (loc.kind == srcdest_partial_reg)
    return pv_unknown ();
  else
    return *loc.reg;
}


/* Write VALUE, a SIZE-byte value, to LOC in STATE.  Return zero if
   all went well, or non-zero if simulating the store would trash our
   state.  */
static int
m32c_srcdest_store (struct m32c_pv_state *state, struct srcdest loc,
		    pv_t value, int size)
{
  if (loc.kind == srcdest_mem)
    {
      if (state->stack->store_would_trash (loc.addr))
	return 1;
      state->stack->store (loc.addr, size, value);
    }
  else if (loc.kind == srcdest_partial_reg)
    *loc.reg = pv_unknown ();
  else
    *loc.reg = value;

  return 0;
}


static int
m32c_sign_ext (int v, int bits)
{
  int mask = 1 << (bits - 1);
  return (v ^ mask) - mask;
}

static unsigned int
m32c_next_byte (struct m32c_pv_state *st)
{
  gdb_assert (st->next_addr - st->scan_pc < sizeof (st->insn));
  return st->insn[st->next_addr++ - st->scan_pc];
}

static int
m32c_udisp8 (struct m32c_pv_state *st)
{
  return m32c_next_byte (st);
}


static int
m32c_sdisp8 (struct m32c_pv_state *st)
{
  return m32c_sign_ext (m32c_next_byte (st), 8);
}


static int
m32c_udisp16 (struct m32c_pv_state *st)
{
  int low  = m32c_next_byte (st);
  int high = m32c_next_byte (st);

  return low + (high << 8);
}


static int
m32c_sdisp16 (struct m32c_pv_state *st)
{
  int low  = m32c_next_byte (st);
  int high = m32c_next_byte (st);

  return m32c_sign_ext (low + (high << 8), 16);
}


static int
m32c_udisp24 (struct m32c_pv_state *st)
{
  int low  = m32c_next_byte (st);
  int mid  = m32c_next_byte (st);
  int high = m32c_next_byte (st);

  return low + (mid << 8) + (high << 16);
}


/* Extract the 'source' field from an m32c MOV.size:G-format instruction.  */
static int
m32c_get_src23 (unsigned char *i)
{
  return (((i[0] & 0x70) >> 2)
	  | ((i[1] & 0x30) >> 4));
}


/* Extract the 'dest' field from an m32c MOV.size:G-format instruction.  */
static int
m32c_get_dest23 (unsigned char *i)
{
  return (((i[0] & 0x0e) << 1)
	  | ((i[1] & 0xc0) >> 6));
}


static struct srcdest
m32c_decode_srcdest4 (struct m32c_pv_state *st,
		      int code, int size)
{
  struct srcdest sd;

  if (code < 6)
    sd.kind = (size == 2 ? srcdest_reg : srcdest_partial_reg);
  else
    sd.kind = srcdest_mem;

  sd.addr = pv_unknown ();
  sd.reg = 0;

  switch (code)
    {
    case 0x0: sd.reg = &st->r0; break;
    case 0x1: sd.reg = (size == 1 ? &st->r0 : &st->r1); break;
    case 0x2: sd.reg = (size == 1 ? &st->r1 : &st->r2); break;
    case 0x3: sd.reg = (size == 1 ? &st->r1 : &st->r3); break;

    case 0x4: sd.reg = &st->a0; break;
    case 0x5: sd.reg = &st->a1; break;

    case 0x6: sd.addr = st->a0; break;
    case 0x7: sd.addr = st->a1; break;

    case 0x8: sd.addr = pv_add_constant (st->a0, m32c_udisp8 (st)); break;
    case 0x9: sd.addr = pv_add_constant (st->a1, m32c_udisp8 (st)); break;
    case 0xa: sd.addr = pv_add_constant (st->sb, m32c_udisp8 (st)); break;
    case 0xb: sd.addr = pv_add_constant (st->fb, m32c_sdisp8 (st)); break;

    case 0xc: sd.addr = pv_add_constant (st->a0, m32c_udisp16 (st)); break;
    case 0xd: sd.addr = pv_add_constant (st->a1, m32c_udisp16 (st)); break;
    case 0xe: sd.addr = pv_add_constant (st->sb, m32c_udisp16 (st)); break;
    case 0xf: sd.addr = pv_constant (m32c_udisp16 (st)); break;

    default:
      gdb_assert_not_reached ("unexpected srcdest4");
    }

  return sd;
}


static struct srcdest
m32c_decode_sd23 (struct m32c_pv_state *st, int code, int size, int ind)
{
  struct srcdest sd;

  sd.addr = pv_unknown ();
  sd.reg = 0;

  switch (code)
    {
    case 0x12:
    case 0x13:
    case 0x10:
    case 0x11:
      sd.kind = (size == 1) ? srcdest_partial_reg : srcdest_reg;
      break;

    case 0x02:
    case 0x03:
      sd.kind = (size == 4) ? srcdest_reg : srcdest_partial_reg;
      break;

    default:
      sd.kind = srcdest_mem;
      break;

    }

  switch (code)
    {
    case 0x12: sd.reg = &st->r0; break;
    case 0x13: sd.reg = &st->r1; break;
    case 0x10: sd.reg = ((size == 1) ? &st->r0 : &st->r2); break;
    case 0x11: sd.reg = ((size == 1) ? &st->r1 : &st->r3); break;
    case 0x02: sd.reg = &st->a0; break;
    case 0x03: sd.reg = &st->a1; break;

    case 0x00: sd.addr = st->a0; break;
    case 0x01: sd.addr = st->a1; break;
    case 0x04: sd.addr = pv_add_constant (st->a0, m32c_udisp8 (st)); break;
    case 0x05: sd.addr = pv_add_constant (st->a1, m32c_udisp8 (st)); break;
    case 0x06: sd.addr = pv_add_constant (st->sb, m32c_udisp8 (st)); break;
    case 0x07: sd.addr = pv_add_constant (st->fb, m32c_sdisp8 (st)); break;
    case 0x08: sd.addr = pv_add_constant (st->a0, m32c_udisp16 (st)); break;
    case 0x09: sd.addr = pv_add_constant (st->a1, m32c_udisp16 (st)); break;
    case 0x0a: sd.addr = pv_add_constant (st->sb, m32c_udisp16 (st)); break;
    case 0x0b: sd.addr = pv_add_constant (st->fb, m32c_sdisp16 (st)); break;
    case 0x0c: sd.addr = pv_add_constant (st->a0, m32c_udisp24 (st)); break;
    case 0x0d: sd.addr = pv_add_constant (st->a1, m32c_udisp24 (st)); break;
    case 0x0f: sd.addr = pv_constant (m32c_udisp16 (st)); break;
    case 0x0e: sd.addr = pv_constant (m32c_udisp24 (st)); break;
    default:
      gdb_assert_not_reached ("unexpected sd23");
    }

  if (ind)
    {
      sd.addr = m32c_srcdest_fetch (st, sd, 4);
      sd.kind = srcdest_mem;
    }

  return sd;
}


/* The r16c and r32c machines have instructions with similar
   semantics, but completely different machine language encodings.  So
   we break out the semantics into their own functions, and leave
   machine-specific decoding in m32c_analyze_prologue.

   The following functions all expect their arguments already decoded,
   and they all return zero if analysis should continue past this
   instruction, or non-zero if analysis should stop.  */


/* Simulate an 'enter SIZE' instruction in STATE.  */
static int
m32c_pv_enter (struct m32c_pv_state *state, int size)
{
  /* 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 (state->stack->store_would_trash (state->sp))
    return 1;

  gdbarch *arch = state->arch;
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (arch);
  if (m32c_pv_push (state, state->fb, tdep->push_addr_bytes))
    return 1;

  state->fb = state->sp;
  state->sp = pv_add_constant (state->sp, -size);

  return 0;
}


static int
m32c_pv_pushm_one (struct m32c_pv_state *state, pv_t reg,
		   int bit, int src, int size)
{
  if (bit & src)
    {
      if (m32c_pv_push (state, reg, size))
	return 1;
    }

  return 0;
}


/* Simulate a 'pushm SRC' instruction in STATE.  */
static int
m32c_pv_pushm (struct m32c_pv_state *state, int src)
{
  gdbarch *arch = state->arch;
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (arch);

  /* The bits in SRC indicating which registers to save are:
     r0 r1 r2 r3 a0 a1 sb fb */
  return
    (   m32c_pv_pushm_one (state, state->fb, 0x01, src, tdep->push_addr_bytes)
     || m32c_pv_pushm_one (state, state->sb, 0x02, src, tdep->push_addr_bytes)
     || m32c_pv_pushm_one (state, state->a1, 0x04, src, tdep->push_addr_bytes)
     || m32c_pv_pushm_one (state, state->a0, 0x08, src, tdep->push_addr_bytes)
     || m32c_pv_pushm_one (state, state->r3, 0x10, src, 2)
     || m32c_pv_pushm_one (state, state->r2, 0x20, src, 2)
     || m32c_pv_pushm_one (state, state->r1, 0x40, src, 2)
     || m32c_pv_pushm_one (state, state->r0, 0x80, src, 2));
}

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

static int
m32c_is_1st_arg_reg (struct m32c_pv_state *state, pv_t value)
{
  gdbarch *arch = state->arch;
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (arch);

  return (value.kind == pvk_register
	  && (gdbarch_bfd_arch_info (state->arch)->mach == bfd_mach_m16c
	      ? (value.reg == tdep->r1->num)
	      : (value.reg == tdep->r0->num))
	  && value.k == 0);
}

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

static int
m32c_is_arg_reg (struct m32c_pv_state *state, pv_t value)
{
  gdbarch *arch = state->arch;
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (arch);

  return (value.kind == pvk_register
	  && (gdbarch_bfd_arch_info (state->arch)->mach == bfd_mach_m16c
	      ? (value.reg == tdep->r1->num || value.reg == tdep->r2->num)
	      : (value.reg == tdep->r0->num))
	  && value.k == 0);
}

/* Return non-zero if a store of VALUE to LOC is probably spilling an
   argument register to its stack slot in STATE.  Such instructions
   should be included in the prologue, if possible.

   The store is a spill if:
   - the value being stored is the original value of an argument register;
   - the value has not already been stored somewhere in STACK; and
   - LOC is a stack slot (e.g., a memory location whose address is
     relative to the original value of the SP).  */

static int
m32c_is_arg_spill (struct m32c_pv_state *st, 
		   struct srcdest loc, 
		   pv_t value)
{
  gdbarch *arch = st->arch;
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (arch);

  return (m32c_is_arg_reg (st, value)
	  && loc.kind == srcdest_mem
	  && pv_is_register (loc.addr, tdep->sp->num)
	  && ! st->stack->find_reg (st->arch, value.reg, 0));
}

/* Return non-zero if a store of VALUE to LOC is probably 
   copying the struct return address into an address register
   for immediate use.  This is basically a "spill" into the
   address register, instead of onto the stack. 

   The prerequisites are:
   - value being stored is original value of the FIRST arg register;
   - value has not already been stored on stack; and
   - LOC is an address register (a0 or a1).  */

static int
m32c_is_struct_return (struct m32c_pv_state *st,
		       struct srcdest loc, 
		       pv_t value)
{
  gdbarch *arch = st->arch;
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (arch);

  return (m32c_is_1st_arg_reg (st, value)
	  && !st->stack->find_reg (st->arch, value.reg, 0)
	  && loc.kind == srcdest_reg
	  && (pv_is_register (*loc.reg, tdep->a0->num)
	      || pv_is_register (*loc.reg, tdep->a1->num)));
}

/* Return non-zero if a 'pushm' saving the registers indicated by SRC
   was a register save:
   - all the named registers should have their original values, and
   - the stack pointer should be at a constant offset from the
     original stack pointer.  */
static int
m32c_pushm_is_reg_save (struct m32c_pv_state *st, int src)
{
  gdbarch *arch = st->arch;
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (arch);

  /* The bits in SRC indicating which registers to save are:
     r0 r1 r2 r3 a0 a1 sb fb */
  return
    (pv_is_register (st->sp, tdep->sp->num)
     && (! (src & 0x01) || pv_is_register_k (st->fb, tdep->fb->num, 0))
     && (! (src & 0x02) || pv_is_register_k (st->sb, tdep->sb->num, 0))
     && (! (src & 0x04) || pv_is_register_k (st->a1, tdep->a1->num, 0))
     && (! (src & 0x08) || pv_is_register_k (st->a0, tdep->a0->num, 0))
     && (! (src & 0x10) || pv_is_register_k (st->r3, tdep->r3->num, 0))
     && (! (src & 0x20) || pv_is_register_k (st->r2, tdep->r2->num, 0))
     && (! (src & 0x40) || pv_is_register_k (st->r1, tdep->r1->num, 0))
     && (! (src & 0x80) || pv_is_register_k (st->r0, tdep->r0->num, 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 *prologue_untyped, pv_t addr, CORE_ADDR size, pv_t value)
{
  struct m32c_prologue *prologue = (struct m32c_prologue *) prologue_untyped;
  struct gdbarch *arch = prologue->arch;
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (arch);

  /* Is this the unchanged value of some register being saved on the
     stack?  */
  if (value.kind == pvk_register
      && value.k == 0
      && pv_is_register (addr, tdep->sp->num))
    {
      /* Some registers require special handling: they're saved as a
	 larger value than the register itself.  */
      CORE_ADDR saved_size = register_size (arch, value.reg);

      if (value.reg == tdep->pc->num)
	saved_size = tdep->ret_addr_bytes;
      else if (register_type (arch, value.reg)
	       == tdep->data_addr_reg_type)
	saved_size = tdep->push_addr_bytes;

      if (size == saved_size)
	{
	  /* Find which end of the saved value corresponds to our
	     register.  */
	  if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG)
	    prologue->reg_offset[value.reg]
	      = (addr.k + saved_size - register_size (arch, value.reg));
	  else
	    prologue->reg_offset[value.reg] = addr.k;
	}
    }
}


/* Analyze the function prologue for ARCH at START, going no further
   than LIMIT, and place a description of what we found in
   PROLOGUE.  */
static void
m32c_analyze_prologue (struct gdbarch *arch,
		       CORE_ADDR start, CORE_ADDR limit,
		       struct m32c_prologue *prologue)
{
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (arch);
  unsigned long mach = gdbarch_bfd_arch_info (arch)->mach;
  CORE_ADDR after_last_frame_related_insn;
  struct m32c_pv_state st;

  st.arch = arch;
  st.r0 = pv_register (tdep->r0->num, 0);
  st.r1 = pv_register (tdep->r1->num, 0);
  st.r2 = pv_register (tdep->r2->num, 0);
  st.r3 = pv_register (tdep->r3->num, 0);
  st.a0 = pv_register (tdep->a0->num, 0);
  st.a1 = pv_register (tdep->a1->num, 0);
  st.sb = pv_register (tdep->sb->num, 0);
  st.fb = pv_register (tdep->fb->num, 0);
  st.sp = pv_register (tdep->sp->num, 0);
  st.pc = pv_register (tdep->pc->num, 0);
  pv_area stack (tdep->sp->num, gdbarch_addr_bit (arch));
  st.stack = &stack;

  /* Record that the call instruction has saved the return address on
     the stack.  */
  m32c_pv_push (&st, st.pc, tdep->ret_addr_bytes);

  memset (prologue, 0, sizeof (*prologue));
  prologue->arch = arch;
  {
    int i;
    for (i = 0; i < M32C_MAX_NUM_REGS; i++)
      prologue->reg_offset[i] = 1;
  }

  st.scan_pc = after_last_frame_related_insn = start;

  while (st.scan_pc < limit)
    {
      pv_t pre_insn_fb = st.fb;
      pv_t pre_insn_sp = st.sp;

      /* In theory we could get in trouble by trying to read ahead
	 here, when we only know we're expecting one byte.  In
	 practice I doubt anyone will care, and it makes the rest of
	 the code easier.  */
      if (target_read_memory (st.scan_pc, st.insn, sizeof (st.insn)))
	/* If we can't fetch the instruction from memory, stop here
	   and hope for the best.  */
	break;
      st.next_addr = st.scan_pc;

      /* The assembly instructions are written as they appear in the
	 section of the processor manuals that describe the
	 instruction encodings.

	 When a single assembly language instruction has several
	 different machine-language encodings, the manual
	 distinguishes them by a number in parens, before the
	 mnemonic.  Those numbers are included, as well.

	 The srcdest decoding instructions have the same names as the
	 analogous functions in the simulator.  */
      if (mach == bfd_mach_m16c)
	{
	  /* (1) ENTER #imm8 */
	  if (st.insn[0] == 0x7c && st.insn[1] == 0xf2)
	    {
	      if (m32c_pv_enter (&st, st.insn[2]))
		break;
	      st.next_addr += 3;
	    }
	  /* (1) PUSHM src */
	  else if (st.insn[0] == 0xec)
	    {
	      int src = st.insn[1];
	      if (m32c_pv_pushm (&st, src))
		break;
	      st.next_addr += 2;

	      if (m32c_pushm_is_reg_save (&st, src))
		after_last_frame_related_insn = st.next_addr;
	    }

	  /* (6) MOV.size:G src, dest */
	  else if ((st.insn[0] & 0xfe) == 0x72)
	    {
	      int size = (st.insn[0] & 0x01) ? 2 : 1;
	      struct srcdest src;
	      struct srcdest dest;
	      pv_t src_value;
	      st.next_addr += 2;

	      src
		= m32c_decode_srcdest4 (&st, (st.insn[1] >> 4) & 0xf, size);
	      dest
		= m32c_decode_srcdest4 (&st, st.insn[1] & 0xf, size);
	      src_value = m32c_srcdest_fetch (&st, src, size);

	      if (m32c_is_arg_spill (&st, dest, src_value))
		after_last_frame_related_insn = st.next_addr;
	      else if (m32c_is_struct_return (&st, dest, src_value))
		after_last_frame_related_insn = st.next_addr;

	      if (m32c_srcdest_store (&st, dest, src_value, size))
		break;
	    }

	  /* (1) LDC #IMM16, sp */
	  else if (st.insn[0] == 0xeb
		   && st.insn[1] == 0x50)
	    {
	      st.next_addr += 2;
	      st.sp = pv_constant (m32c_udisp16 (&st));
	    }

	  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;
	}
      else
	{
	  int src_indirect = 0;
	  int dest_indirect = 0;
	  int i = 0;

	  gdb_assert (mach == bfd_mach_m32c);

	  /* Check for prefix bytes indicating indirect addressing.  */
	  if (st.insn[0] == 0x41)
	    {
	      src_indirect = 1;
	      i++;
	    }
	  else if (st.insn[0] == 0x09)
	    {
	      dest_indirect = 1;
	      i++;
	    }
	  else if (st.insn[0] == 0x49)
	    {
	      src_indirect = dest_indirect = 1;
	      i++;
	    }

	  /* (1) ENTER #imm8 */
	  if (st.insn[i] == 0xec)
	    {
	      if (m32c_pv_enter (&st, st.insn[i + 1]))
		break;
	      st.next_addr += 2;
	    }

	  /* (1) PUSHM src */
	  else if (st.insn[i] == 0x8f)
	    {
	      int src = st.insn[i + 1];
	      if (m32c_pv_pushm (&st, src))
		break;
	      st.next_addr += 2;

	      if (m32c_pushm_is_reg_save (&st, src))
		after_last_frame_related_insn = st.next_addr;
	    }

	  /* (7) MOV.size:G src, dest */
	  else if ((st.insn[i] & 0x80) == 0x80
		   && (st.insn[i + 1] & 0x0f) == 0x0b
		   && m32c_get_src23 (&st.insn[i]) < 20
		   && m32c_get_dest23 (&st.insn[i]) < 20)
	    {
	      struct srcdest src;
	      struct srcdest dest;
	      pv_t src_value;
	      int bw = st.insn[i] & 0x01;
	      int size = bw ? 2 : 1;
	      st.next_addr += 2;

	      src
		= m32c_decode_sd23 (&st, m32c_get_src23 (&st.insn[i]),
				    size, src_indirect);
	      dest
		= m32c_decode_sd23 (&st, m32c_get_dest23 (&st.insn[i]),
				    size, dest_indirect);
	      src_value = m32c_srcdest_fetch (&st, src, size);

	      if (m32c_is_arg_spill (&st, dest, src_value))
		after_last_frame_related_insn = st.next_addr;

	      if (m32c_srcdest_store (&st, dest, src_value, size))
		break;
	    }
	  /* (2) LDC #IMM24, sp */
	  else if (st.insn[i] == 0xd5
		   && st.insn[i + 1] == 0x29)
	    {
	      st.next_addr += 2;
	      st.sp = pv_constant (m32c_udisp24 (&st));
	    }
	  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 FB 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 FB 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 (st.fb, pre_insn_fb))
	{
	  if (! pv_is_register_k (st.fb, tdep->fb->num, 0))
	    after_last_frame_related_insn = st.next_addr;
	}
      else if (! pv_is_identical (st.sp, pre_insn_sp))
	{
	  /* The comparison of the constants looks odd, there, because
	     .k is unsigned.  All it really means is that the SP is
	     lower than it was before the instruction.  */
	  if (   pv_is_register (pre_insn_sp, tdep->sp->num)
	      && pv_is_register (st.sp,       tdep->sp->num)
	      && ((pre_insn_sp.k - st.sp.k) < (st.sp.k - pre_insn_sp.k)))
	    after_last_frame_related_insn = st.next_addr;
	}

      st.scan_pc = st.next_addr;
    }

  /* Did we load a constant value into the stack pointer?  */
  if (pv_is_constant (st.sp))
    prologue->kind = prologue_first_frame;

  /* Alternatively, did we initialize the frame pointer?  Remember
     that the CFA is the address after the return address.  */
  if (pv_is_register (st.fb, tdep->sp->num))
    {
      prologue->kind = prologue_with_frame_ptr;
      prologue->frame_ptr_offset = st.fb.k;
    }

  /* Is the frame size a known constant?  Remember that frame_size is
     actually the offset from the CFA to the SP (i.e., a negative
     value).  */
  else if (pv_is_register (st.sp, tdep->sp->num))
    {
      prologue->kind = prologue_sans_frame_ptr;
      prologue->frame_size = st.sp.k;
    }

  /* We haven't been able to make sense of this function's frame.  Treat
     it as the first frame.  */
  else
    prologue->kind = prologue_first_frame;

  /* Record where all the registers were saved.  */
  st.stack->scan (check_for_saved, (void *) prologue);

  prologue->prologue_end = after_last_frame_related_insn;
}


static CORE_ADDR
m32c_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR ip)
{
  const char *name;
  CORE_ADDR func_addr, func_end, sal_end;
  struct m32c_prologue p;

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

  /* Find end by prologue analysis.  */
  m32c_analyze_prologue (gdbarch, ip, func_end, &p);
  /* Find end by line info.  */
  sal_end = skip_prologue_using_sal (gdbarch, ip);
  /* Return whichever is lower.  */
  if (sal_end != 0 && sal_end != ip && sal_end < p.prologue_end)
    return sal_end;
  else
    return p.prologue_end;
}



/* Stack unwinding.  */

static struct m32c_prologue *
m32c_analyze_frame_prologue (struct frame_info *this_frame,
			     void **this_prologue_cache)
{
  if (! *this_prologue_cache)
    {
      CORE_ADDR func_start = get_frame_func (this_frame);
      CORE_ADDR 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;

      *this_prologue_cache = FRAME_OBSTACK_ZALLOC (struct m32c_prologue);
      m32c_analyze_prologue (get_frame_arch (this_frame),
			     func_start, stop_addr,
			     (struct m32c_prologue *) *this_prologue_cache);
    }

  return (struct m32c_prologue *) *this_prologue_cache;
}


static CORE_ADDR
m32c_frame_base (struct frame_info *this_frame,
		void **this_prologue_cache)
{
  struct m32c_prologue *p
    = m32c_analyze_frame_prologue (this_frame, this_prologue_cache);
  gdbarch *arch = get_frame_arch (this_frame);
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (arch);

  /* 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.  */
  switch (p->kind)
    {
    case prologue_with_frame_ptr:
      {
	CORE_ADDR fb
	  = get_frame_register_unsigned (this_frame, tdep->fb->num);
	return fb - p->frame_ptr_offset;
      }

    case prologue_sans_frame_ptr:
      {
	CORE_ADDR sp
	  = get_frame_register_unsigned (this_frame, tdep->sp->num);
	return sp - p->frame_size;
      }

    case prologue_first_frame:
      return 0;

    default:
      gdb_assert_not_reached ("unexpected prologue kind");
    }
}


static void
m32c_this_id (struct frame_info *this_frame,
	      void **this_prologue_cache,
	      struct frame_id *this_id)
{
  CORE_ADDR base = m32c_frame_base (this_frame, this_prologue_cache);

  if (base)
    *this_id = frame_id_build (base, get_frame_func (this_frame));
  /* Otherwise, leave it unset, and that will terminate the backtrace.  */
}


static struct value *
m32c_prev_register (struct frame_info *this_frame,
		    void **this_prologue_cache, int regnum)
{
  gdbarch *arch = get_frame_arch (this_frame);
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (arch);
  struct m32c_prologue *p
    = m32c_analyze_frame_prologue (this_frame, this_prologue_cache);
  CORE_ADDR frame_base = m32c_frame_base (this_frame, this_prologue_cache);

  if (regnum == tdep->sp->num)
    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)
    return 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.  */
  return frame_unwind_got_register (this_frame, regnum, regnum);
}


static const struct frame_unwind m32c_unwind = {
  "m32c prologue",
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  m32c_this_id,
  m32c_prev_register,
  NULL,
  default_frame_sniffer
};


/* Inferior calls.  */

/* The calling conventions, according to GCC:

   r8c, m16c
   ---------
   First arg may be passed in r1l or r1 if it (1) fits (QImode or
   HImode), (2) is named, and (3) is an integer or pointer type (no
   structs, floats, etc).  Otherwise, it's passed on the stack.

   Second arg may be passed in r2, same restrictions (but not QImode),
   even if the first arg is passed on the stack.

   Third and further args are passed on the stack.  No padding is
   used, stack "alignment" is 8 bits.

   m32cm, m32c
   -----------

   First arg may be passed in r0l or r0, same restrictions as above.

   Second and further args are passed on the stack.  Padding is used
   after QImode parameters (i.e. lower-addressed byte is the value,
   higher-addressed byte is the padding), stack "alignment" is 16
   bits.  */


/* Return true if TYPE is a type that can be passed in registers.  (We
   ignore the size, and pay attention only to the type code;
   acceptable sizes depends on which register is being considered to
   hold it.)  */
static int
m32c_reg_arg_type (struct type *type)
{
  enum type_code code = type->code ();

  return (code == TYPE_CODE_INT
	  || code == TYPE_CODE_ENUM
	  || code == TYPE_CODE_PTR
	  || TYPE_IS_REFERENCE (type)
	  || code == TYPE_CODE_BOOL
	  || code == TYPE_CODE_CHAR);
}


static CORE_ADDR
m32c_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
		      struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
		      struct value **args, CORE_ADDR sp,
		      function_call_return_method return_method,
		      CORE_ADDR struct_addr)
{
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach;
  CORE_ADDR cfa;
  int i;

  /* The number of arguments given in this function's prototype, or
     zero if it has a non-prototyped function type.  The m32c ABI
     passes arguments mentioned in the prototype differently from
     those in the ellipsis of a varargs function, or from those passed
     to a non-prototyped function.  */
  int num_prototyped_args = 0;

  {
    struct type *func_type = value_type (function);

    /* Dereference function pointer types.  */
    if (func_type->code () == TYPE_CODE_PTR)
      func_type = TYPE_TARGET_TYPE (func_type);

    gdb_assert (func_type->code () == TYPE_CODE_FUNC ||
		func_type->code () == TYPE_CODE_METHOD);

#if 0
    /* The ABI description in gcc/config/m32c/m32c.abi says that
       we need to handle prototyped and non-prototyped functions
       separately, but the code in GCC doesn't actually do so.  */
    if (TYPE_PROTOTYPED (func_type))
#endif
      num_prototyped_args = func_type->num_fields ();
  }

  /* First, if the function returns an aggregate by value, push a
     pointer to a buffer for it.  This doesn't affect the way
     subsequent arguments are allocated to registers.  */
  if (return_method == return_method_struct)
    {
      int ptr_len = TYPE_LENGTH (tdep->ptr_voyd);
      sp -= ptr_len;
      write_memory_unsigned_integer (sp, ptr_len, byte_order, struct_addr);
    }

  /* Push the arguments.  */
  for (i = nargs - 1; i >= 0; i--)
    {
      struct value *arg = args[i];
      const gdb_byte *arg_bits = value_contents (arg).data ();
      struct type *arg_type = value_type (arg);
      ULONGEST arg_size = TYPE_LENGTH (arg_type);

      /* Can it go in r1 or r1l (for m16c) or r0 or r0l (for m32c)?  */
      if (i == 0
	  && arg_size <= 2
	  && i < num_prototyped_args
	  && m32c_reg_arg_type (arg_type))
	{
	  /* Extract and re-store as an integer as a terse way to make
	     sure it ends up in the least significant end of r1.  (GDB
	     should avoid assuming endianness, even on uni-endian
	     processors.)  */
	  ULONGEST u = extract_unsigned_integer (arg_bits, arg_size,
						 byte_order);
	  struct m32c_reg *reg = (mach == bfd_mach_m16c) ? tdep->r1 : tdep->r0;
	  regcache_cooked_write_unsigned (regcache, reg->num, u);
	}

      /* Can it go in r2?  */
      else if (mach == bfd_mach_m16c
	       && i == 1
	       && arg_size == 2
	       && i < num_prototyped_args
	       && m32c_reg_arg_type (arg_type))
	regcache->cooked_write (tdep->r2->num, arg_bits);

      /* Everything else goes on the stack.  */
      else
	{
	  sp -= arg_size;

	  /* Align the stack.  */
	  if (mach == bfd_mach_m32c)
	    sp &= ~1;

	  write_memory (sp, arg_bits, arg_size);
	}
    }

  /* This is the CFA we use to identify the dummy frame.  */
  cfa = sp;

  /* Push the return address.  */
  sp -= tdep->ret_addr_bytes;
  write_memory_unsigned_integer (sp, tdep->ret_addr_bytes, byte_order,
				 bp_addr);

  /* Update the stack pointer.  */
  regcache_cooked_write_unsigned (regcache, tdep->sp->num, sp);

  /* We need to borrow an odd trick from the i386 target here.

     The value we return from this function gets used as the stack
     address (the CFA) for the dummy frame's ID.  The obvious thing is
     to return the new TOS.  However, that points at the return
     address, saved on the stack, which is inconsistent with the CFA's
     described by GCC's DWARF 2 .debug_frame information: DWARF 2
     .debug_frame info uses the address immediately after the saved
     return address.  So you end up with a dummy frame whose CFA
     points at the return address, but the frame for the function
     being called has a CFA pointing after the return address: the
     younger CFA is *greater than* the older CFA.  The sanity checks
     in frame.c don't like that.

     So we try to be consistent with the CFA's used by DWARF 2.
     Having a dummy frame and a real frame with the *same* CFA is
     tolerable.  */
  return cfa;
}



/* Return values.  */

/* Return value conventions, according to GCC:

   r8c, m16c
   ---------

   QImode in r0l
   HImode in r0
   SImode in r2r0
   near pointer in r0
   far pointer in r2r0

   Aggregate values (regardless of size) are returned by pushing a
   pointer to a temporary area on the stack after the args are pushed.
   The function fills in this area with the value.  Note that this
   pointer on the stack does not affect how register arguments, if any,
   are configured.

   m32cm, m32c
   -----------
   Same.  */

/* Return non-zero if values of type TYPE are returned by storing them
   in a buffer whose address is passed on the stack, ahead of the
   other arguments.  */
static int
m32c_return_by_passed_buf (struct type *type)
{
  enum type_code code = type->code ();

  return (code == TYPE_CODE_STRUCT
	  || code == TYPE_CODE_UNION);
}

static enum return_value_convention
m32c_return_value (struct gdbarch *gdbarch,
		   struct value *function,
		   struct type *valtype,
		   struct regcache *regcache,
		   gdb_byte *readbuf,
		   const gdb_byte *writebuf)
{
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  enum return_value_convention conv;
  ULONGEST valtype_len = TYPE_LENGTH (valtype);

  if (m32c_return_by_passed_buf (valtype))
    conv = RETURN_VALUE_STRUCT_CONVENTION;
  else
    conv = RETURN_VALUE_REGISTER_CONVENTION;

  if (readbuf)
    {
      /* We should never be called to find values being returned by
	 RETURN_VALUE_STRUCT_CONVENTION.  Those can't be located,
	 unless we made the call ourselves.  */
      gdb_assert (conv == RETURN_VALUE_REGISTER_CONVENTION);

      gdb_assert (valtype_len <= 8);

      /* Anything that fits in r0 is returned there.  */
      if (valtype_len <= TYPE_LENGTH (tdep->r0->type))
	{
	  ULONGEST u;
	  regcache_cooked_read_unsigned (regcache, tdep->r0->num, &u);
	  store_unsigned_integer (readbuf, valtype_len, byte_order, u);
	}
      else
	{
	  /* Everything else is passed in mem0, using as many bytes as
	     needed.  This is not what the Renesas tools do, but it's
	     what GCC does at the moment.  */
	  struct bound_minimal_symbol mem0
	    = lookup_minimal_symbol ("mem0", NULL, NULL);

	  if (! mem0.minsym)
	    error (_("The return value is stored in memory at 'mem0', "
		     "but GDB cannot find\n"
		     "its address."));
	  read_memory (mem0.value_address (), readbuf, valtype_len);
	}
    }

  if (writebuf)
    {
      /* We should never be called to store values to be returned
	 using RETURN_VALUE_STRUCT_CONVENTION.  We have no way of
	 finding the buffer, unless we made the call ourselves.  */
      gdb_assert (conv == RETURN_VALUE_REGISTER_CONVENTION);

      gdb_assert (valtype_len <= 8);

      /* Anything that fits in r0 is returned there.  */
      if (valtype_len <= TYPE_LENGTH (tdep->r0->type))
	{
	  ULONGEST u = extract_unsigned_integer (writebuf, valtype_len,
						 byte_order);
	  regcache_cooked_write_unsigned (regcache, tdep->r0->num, u);
	}
      else
	{
	  /* Everything else is passed in mem0, using as many bytes as
	     needed.  This is not what the Renesas tools do, but it's
	     what GCC does at the moment.  */
	  struct bound_minimal_symbol mem0
	    = lookup_minimal_symbol ("mem0", NULL, NULL);

	  if (! mem0.minsym)
	    error (_("The return value is stored in memory at 'mem0', "
		     "but GDB cannot find\n"
		     " its address."));
	  write_memory (mem0.value_address (), writebuf, valtype_len);
	}
    }

  return conv;
}



/* Trampolines.  */

/* The m16c and m32c use a trampoline function for indirect function
   calls.  An indirect call looks like this:

	     ... push arguments ...
	     ... push target function address ...
	     jsr.a m32c_jsri16

   The code for m32c_jsri16 looks like this:

     m32c_jsri16:

	     # Save return address.
	     pop.w	m32c_jsri_ret
	     pop.b	m32c_jsri_ret+2

	     # Store target function address.
	     pop.w	m32c_jsri_addr

	     # Re-push return address.
	     push.b	m32c_jsri_ret+2
	     push.w	m32c_jsri_ret

	     # Call the target function.
	     jmpi.a	m32c_jsri_addr

   Without further information, GDB will treat calls to m32c_jsri16
   like calls to any other function.  Since m32c_jsri16 doesn't have
   debugging information, that normally means that GDB sets a step-
   resume breakpoint and lets the program continue --- which is not
   what the user wanted.  (Giving the trampoline debugging info
   doesn't help: the user expects the program to stop in the function
   their program is calling, not in some trampoline code they've never
   seen before.)

   The gdbarch_skip_trampoline_code method tells GDB how to step
   through such trampoline functions transparently to the user.  When
   given the address of a trampoline function's first instruction,
   gdbarch_skip_trampoline_code should return the address of the first
   instruction of the function really being called.  If GDB decides it
   wants to step into that function, it will set a breakpoint there
   and silently continue to it.

   We recognize the trampoline by name, and extract the target address
   directly from the stack.  This isn't great, but recognizing by its
   code sequence seems more fragile.  */

static CORE_ADDR
m32c_skip_trampoline_code (struct frame_info *frame, CORE_ADDR stop_pc)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  /* It would be nicer to simply look up the addresses of known
     trampolines once, and then compare stop_pc with them.  However,
     we'd need to ensure that that cached address got invalidated when
     someone loaded a new executable, and I'm not quite sure of the
     best way to do that.  find_pc_partial_function does do some
     caching, so we'll see how this goes.  */
  const char *name;
  CORE_ADDR start, end;

  if (find_pc_partial_function (stop_pc, &name, &start, &end))
    {
      /* Are we stopped at the beginning of the trampoline function?  */
      if (strcmp (name, "m32c_jsri16") == 0
	  && stop_pc == start)
	{
	  /* Get the stack pointer.  The return address is at the top,
	     and the target function's address is just below that.  We
	     know it's a two-byte address, since the trampoline is
	     m32c_jsri*16*.  */
	  CORE_ADDR sp = get_frame_sp (get_current_frame ());
	  CORE_ADDR target
	    = read_memory_unsigned_integer (sp + tdep->ret_addr_bytes,
					    2, byte_order);

	  /* What we have now is the address of a jump instruction.
	     What we need is the destination of that jump.
	     The opcode is 1 byte, and the destination is the next 3 bytes.  */

	  target = read_memory_unsigned_integer (target + 1, 3, byte_order);
	  return target;
	}
    }

  return 0;
}


/* Address/pointer conversions.  */

/* On the m16c, there is a 24-bit address space, but only a very few
   instructions can generate addresses larger than 0xffff: jumps,
   jumps to subroutines, and the lde/std (load/store extended)
   instructions.

   Since GCC can only support one size of pointer, we can't have
   distinct 'near' and 'far' pointer types; we have to pick one size
   for everything.  If we wanted to use 24-bit pointers, then GCC
   would have to use lde and ste for all memory references, which
   would be terrible for performance and code size.  So the GNU
   toolchain uses 16-bit pointers for everything, and gives up the
   ability to have pointers point outside the first 64k of memory.

   However, as a special hack, we let the linker place functions at
   addresses above 0xffff, as long as it also places a trampoline in
   the low 64k for every function whose address is taken.  Each
   trampoline consists of a single jmp.a instruction that jumps to the
   function's real entry point.  Pointers to functions can be 16 bits
   long, even though the functions themselves are at higher addresses:
   the pointers refer to the trampolines, not the functions.

   This complicates things for GDB, however: given the address of a
   function (from debug info or linker symbols, say) which could be
   anywhere in the 24-bit address space, how can we find an
   appropriate 16-bit value to use as a pointer to it?

   If the linker has not generated a trampoline for the function,
   we're out of luck.  Well, I guess we could malloc some space and
   write a jmp.a instruction to it, but I'm not going to get into that
   at the moment.

   If the linker has generated a trampoline for the function, then it
   also emitted a symbol for the trampoline: if the function's linker
   symbol is named NAME, then the function's trampoline's linker
   symbol is named NAME.plt.

   So, given a code address:
   - We try to find a linker symbol at that address.
   - If we find such a symbol named NAME, we look for a linker symbol
     named NAME.plt.
   - If we find such a symbol, we assume it is a trampoline, and use
     its address as the pointer value.

   And, given a function pointer:
   - We try to find a linker symbol at that address named NAME.plt.
   - If we find such a symbol, we look for a linker symbol named NAME.
   - If we find that, we provide that as the function's address.
   - If any of the above steps fail, we return the original address
     unchanged; it might really be a function in the low 64k.

   See?  You *knew* there was a reason you wanted to be a computer
   programmer!  :)  */

static void
m32c_m16c_address_to_pointer (struct gdbarch *gdbarch,
			      struct type *type, gdb_byte *buf, CORE_ADDR addr)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  enum type_code target_code;
  gdb_assert (type->code () == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type));

  target_code = TYPE_TARGET_TYPE (type)->code ();

  if (target_code == TYPE_CODE_FUNC || target_code == TYPE_CODE_METHOD)
    {
      const char *func_name;
      char *tramp_name;
      struct bound_minimal_symbol tramp_msym;

      /* Try to find a linker symbol at this address.  */
      struct bound_minimal_symbol func_msym
	= lookup_minimal_symbol_by_pc (addr);

      if (! func_msym.minsym)
	error (_("Cannot convert code address %s to function pointer:\n"
	       "couldn't find a symbol at that address, to find trampoline."),
	       paddress (gdbarch, addr));

      func_name = func_msym.minsym->linkage_name ();
      tramp_name = (char *) xmalloc (strlen (func_name) + 5);
      strcpy (tramp_name, func_name);
      strcat (tramp_name, ".plt");

      /* Try to find a linker symbol for the trampoline.  */
      tramp_msym = lookup_minimal_symbol (tramp_name, NULL, NULL);

      /* We've either got another copy of the name now, or don't need
	 the name any more.  */
      xfree (tramp_name);

      if (! tramp_msym.minsym)
	{
	  CORE_ADDR ptrval;

	  /* No PLT entry found.  Mask off the upper bits of the address
	     to make a pointer.  As noted in the warning to the user
	     below, this value might be useful if converted back into
	     an address by GDB, but will otherwise, almost certainly,
	     be garbage.
	     
	     Using this masked result does seem to be useful
	     in gdb.cp/cplusfuncs.exp in which ~40 FAILs turn into
	     PASSes.  These results appear to be correct as well.
	     
	     We print a warning here so that the user can make a
	     determination about whether the result is useful or not.  */
	  ptrval = addr & 0xffff;

	  warning (_("Cannot convert code address %s to function pointer:\n"
		   "couldn't find trampoline named '%s.plt'.\n"
		   "Returning pointer value %s instead; this may produce\n"
		   "a useful result if converted back into an address by GDB,\n"
		   "but will most likely not be useful otherwise."),
		   paddress (gdbarch, addr), func_name,
		   paddress (gdbarch, ptrval));

	  addr = ptrval;

	}
      else
	{
	  /* The trampoline's address is our pointer.  */
	  addr = tramp_msym.value_address ();
	}
    }

  store_unsigned_integer (buf, TYPE_LENGTH (type), byte_order, addr);
}


static CORE_ADDR
m32c_m16c_pointer_to_address (struct gdbarch *gdbarch,
			      struct type *type, const gdb_byte *buf)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR ptr;
  enum type_code target_code;

  gdb_assert (type->code () == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type));

  ptr = extract_unsigned_integer (buf, TYPE_LENGTH (type), byte_order);

  target_code = TYPE_TARGET_TYPE (type)->code ();

  if (target_code == TYPE_CODE_FUNC || target_code == TYPE_CODE_METHOD)
    {
      /* See if there is a minimal symbol at that address whose name is
	 "NAME.plt".  */
      struct bound_minimal_symbol ptr_msym = lookup_minimal_symbol_by_pc (ptr);

      if (ptr_msym.minsym)
	{
	  const char *ptr_msym_name = ptr_msym.minsym->linkage_name ();
	  int len = strlen (ptr_msym_name);

	  if (len > 4
	      && strcmp (ptr_msym_name + len - 4, ".plt") == 0)
	    {
	      struct bound_minimal_symbol func_msym;
	      /* We have a .plt symbol; try to find the symbol for the
		 corresponding function.

		 Since the trampoline contains a jump instruction, we
		 could also just extract the jump's target address.  I
		 don't see much advantage one way or the other.  */
	      char *func_name = (char *) xmalloc (len - 4 + 1);
	      memcpy (func_name, ptr_msym_name, len - 4);
	      func_name[len - 4] = '\0';
	      func_msym
		= lookup_minimal_symbol (func_name, NULL, NULL);

	      /* If we do have such a symbol, return its value as the
		 function's true address.  */
	      if (func_msym.minsym)
		ptr = func_msym.value_address ();
	    }
	}
      else
	{
	  int aspace;

	  for (aspace = 1; aspace <= 15; aspace++)
	    {
	      ptr_msym = lookup_minimal_symbol_by_pc ((aspace << 16) | ptr);
	      
	      if (ptr_msym.minsym)
		ptr |= aspace << 16;
	    }
	}
    }

  return ptr;
}

static void
m32c_virtual_frame_pointer (struct gdbarch *gdbarch, CORE_ADDR pc,
			    int *frame_regnum,
			    LONGEST *frame_offset)
{
  const char *name;
  CORE_ADDR func_addr, func_end;
  struct m32c_prologue p;

  struct regcache *regcache = get_current_regcache ();
  m32c_gdbarch_tdep *tdep = (m32c_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  
  if (!find_pc_partial_function (pc, &name, &func_addr, &func_end))
    internal_error (__FILE__, __LINE__,
		    _("No virtual frame pointer available"));

  m32c_analyze_prologue (gdbarch, func_addr, pc, &p);
  switch (p.kind)
    {
    case prologue_with_frame_ptr:
      *frame_regnum = m32c_banked_register (tdep->fb, regcache)->num;
      *frame_offset = p.frame_ptr_offset;
      break;
    case prologue_sans_frame_ptr:
      *frame_regnum = m32c_banked_register (tdep->sp, regcache)->num;
      *frame_offset = p.frame_size;
      break;
    default:
      *frame_regnum = m32c_banked_register (tdep->sp, regcache)->num;
      *frame_offset = 0;
      break;
    }
  /* Sanity check */
  if (*frame_regnum > gdbarch_num_regs (gdbarch))
    internal_error (__FILE__, __LINE__,
		    _("No virtual frame pointer available"));
}


/* Initialization.  */

static struct gdbarch *
m32c_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  struct gdbarch *gdbarch;
  unsigned long mach = info.bfd_arch_info->mach;

  /* Find a candidate among the list of architectures we've created
     already.  */
  for (arches = gdbarch_list_lookup_by_info (arches, &info);
       arches != NULL;
       arches = gdbarch_list_lookup_by_info (arches->next, &info))
    return arches->gdbarch;

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

  /* Essential types.  */
  make_types (gdbarch);

  /* Address/pointer conversions.  */
  if (mach == bfd_mach_m16c)
    {
      set_gdbarch_address_to_pointer (gdbarch, m32c_m16c_address_to_pointer);
      set_gdbarch_pointer_to_address (gdbarch, m32c_m16c_pointer_to_address);
    }

  /* Register set.  */
  make_regs (gdbarch);

  /* Breakpoints.  */
  set_gdbarch_breakpoint_kind_from_pc (gdbarch, m32c_breakpoint::kind_from_pc);
  set_gdbarch_sw_breakpoint_from_kind (gdbarch, m32c_breakpoint::bp_from_kind);

  /* Prologue analysis and unwinding.  */
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
  set_gdbarch_skip_prologue (gdbarch, m32c_skip_prologue);
#if 0
  /* I'm dropping the dwarf2 sniffer because it has a few problems.
     They may be in the dwarf2 cfi code in GDB, or they may be in
     the debug info emitted by the upstream toolchain.  I don't 
     know which, but I do know that the prologue analyzer works better.
     MVS 04/13/06  */
  dwarf2_append_sniffers (gdbarch);
#endif
  frame_unwind_append_unwinder (gdbarch, &m32c_unwind);

  /* Inferior calls.  */
  set_gdbarch_push_dummy_call (gdbarch, m32c_push_dummy_call);
  set_gdbarch_return_value (gdbarch, m32c_return_value);

  /* Trampolines.  */
  set_gdbarch_skip_trampoline_code (gdbarch, m32c_skip_trampoline_code);

  set_gdbarch_virtual_frame_pointer (gdbarch, m32c_virtual_frame_pointer);

  /* m32c function boundary addresses are not necessarily even.
     Therefore, the `vbit', which indicates a pointer to a virtual
     member function, is stored in the delta field, rather than as
     the low bit of a function pointer address.

     In order to verify this, see the definition of
     TARGET_PTRMEMFUNC_VBIT_LOCATION in gcc/defaults.h along with the
     definition of FUNCTION_BOUNDARY in gcc/config/m32c/m32c.h.  */
  set_gdbarch_vbit_in_delta (gdbarch, 1);

  return gdbarch;
}

void _initialize_m32c_tdep ();
void
_initialize_m32c_tdep ()
{
  register_gdbarch_init (bfd_arch_m32c, m32c_gdbarch_init);

  m32c_dma_reggroup = reggroup_new ("dma", USER_REGGROUP);
}
