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

   Copyright (C) 2004-2024 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 "extract-store-integer.h"
#include "sim/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_base
{
  /* 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 = gdbarch_tdep<m32c_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.  */
  type_allocator alloc (arch);
  tdep->voyd = alloc.new_type (TYPE_CODE_VOID, TARGET_CHAR_BIT, "void");
  tdep->ptr_voyd
    = init_pointer_type (alloc, 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
    = init_pointer_type (alloc, 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
    = init_pointer_type (alloc, code_addr_reg_bits, type_name,
			 tdep->func_voyd);

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



/* Register set.  */

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


static struct type *
m32c_register_type (struct gdbarch *arch, int reg_nr)
{
  m32c_gdbarch_tdep *tdep = gdbarch_tdep<m32c_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 = gdbarch_tdep<m32c_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 = gdbarch_tdep<m32c_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 = gdbarch_tdep<m32c_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 = gdbarch_tdep<m32c_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 = reg->rx->type->length ();

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

  /* 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 = reg->rx->type->length () - 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, reg->type->length ());
  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 = reg->rx->type->length ();
  int low_bytes  = reg->ry->type->length ();
  enum register_status status;

  gdb_assert (reg->type->length () == 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 = reg->rx->type->length ();
  int low_bytes  = reg->ry->type->length ();

  gdb_assert (reg->type->length () == 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 = gdbarch_tdep<m32c_gdbarch_tdep> (arch);
  int len = tdep->r0->type->length ();
  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 = gdbarch_tdep<m32c_gdbarch_tdep> (arch);
  int len = tdep->r0->type->length ();

  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 = gdbarch_tdep<m32c_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 = gdbarch_tdep<m32c_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 = gdbarch_tdep<m32c_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 = gdbarch_tdep<m32c_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("", tdep->int16, SIM (name ## _bank0)),		\
   R("", 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("", tdep->data_addr_reg_type, SIM (name ## _bank0)),	\
   R("", 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 = gdbarch_tdep<m32c_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_deprecated_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 = gdbarch_tdep<m32c_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 = gdbarch_tdep<m32c_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 = gdbarch_tdep<m32c_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 = gdbarch_tdep<m32c_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 = gdbarch_tdep<m32c_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 = gdbarch_tdep<m32c_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 = gdbarch_tdep<m32c_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 = gdbarch_tdep<m32c_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 = gdbarch_tdep<m32c_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 (const frame_info_ptr &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 (const frame_info_ptr &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 = gdbarch_tdep<m32c_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 (const frame_info_ptr &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 (const frame_info_ptr &this_frame,
		    void **this_prologue_cache, int regnum)
{
  gdbarch *arch = get_frame_arch (this_frame);
  m32c_gdbarch_tdep *tdep = gdbarch_tdep<m32c_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 = gdbarch_tdep<m32c_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 = function->type ();

    /* Dereference function pointer types.  */
    if (func_type->code () == TYPE_CODE_PTR)
      func_type = func_type->target_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 = tdep->ptr_voyd->length ();
      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 = arg->contents ().data ();
      struct type *arg_type = arg->type ();
      ULONGEST arg_size = arg_type->length ();

      /* 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 = gdbarch_tdep<m32c_gdbarch_tdep> (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  enum return_value_convention conv;
  ULONGEST valtype_len = valtype->length ();

  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 <= tdep->r0->type->length ())
	{
	  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.  */
	  bound_minimal_symbol mem0
	    = lookup_minimal_symbol (current_program_space, "mem0");

	  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 <= tdep->r0->type->length ())
	{
	  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.  */
	  bound_minimal_symbol mem0
	    = lookup_minimal_symbol (current_program_space, "mem0");

	  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 (const frame_info_ptr &frame, CORE_ADDR stop_pc)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  m32c_gdbarch_tdep *tdep = gdbarch_tdep<m32c_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 ()->code ();

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

      /* Try to find a linker symbol at this address.  */
      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.  */
      bound_minimal_symbol tramp_msym
	= lookup_minimal_symbol (current_program_space, tramp_name);

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

  target_code = type->target_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".  */
      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)
	    {
	      /* 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';
	      bound_minimal_symbol func_msym
		= lookup_minimal_symbol (current_program_space, func_name);

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

  regcache *regcache = get_thread_regcache (inferior_thread ());
  m32c_gdbarch_tdep *tdep = gdbarch_tdep<m32c_gdbarch_tdep> (gdbarch);
  
  if (!find_pc_partial_function (pc, &name, &func_addr, &func_end))
    internal_error (_("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 (_("No virtual frame pointer available"));
}


/* Initialization.  */

static struct gdbarch *
m32c_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  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;

  gdbarch *gdbarch
    = gdbarch_alloc (&info, gdbarch_tdep_up (new m32c_gdbarch_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 ()
{
  gdbarch_register (bfd_arch_m32c, m32c_gdbarch_init);

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