/* Target-dependent code for Renesas M32R, for GDB.

   Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 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 2 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, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

#include "defs.h"
#include "frame.h"
#include "frame-unwind.h"
#include "frame-base.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "gdbcmd.h"
#include "gdbcore.h"
#include "gdb_string.h"
#include "value.h"
#include "inferior.h"
#include "symfile.h"
#include "objfiles.h"
#include "osabi.h"
#include "language.h"
#include "arch-utils.h"
#include "regcache.h"
#include "trad-frame.h"
#include "dis-asm.h"

#include "gdb_assert.h"

#include "m32r-tdep.h"

/* Local functions */

extern void _initialize_m32r_tdep (void);

static CORE_ADDR
m32r_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
{
  /* Align to the size of an instruction (so that they can safely be
     pushed onto the stack.  */
  return sp & ~3;
}


/* Breakpoints
 
   The little endian mode of M32R is unique. In most of architectures,
   two 16-bit instructions, A and B, are placed as the following:
  
   Big endian:
   A0 A1 B0 B1
  
   Little endian:
   A1 A0 B1 B0
  
   In M32R, they are placed like this:
  
   Big endian:
   A0 A1 B0 B1
  
   Little endian:
   B1 B0 A1 A0
  
   This is because M32R always fetches instructions in 32-bit.
  
   The following functions take care of this behavior. */

static int
m32r_memory_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
{
  int val;
  char buf[4];
  char bp_entry[] = { 0x10, 0xf1 };	/* dpt */

  /* Save the memory contents.  */
  val = target_read_memory (addr & 0xfffffffc, contents_cache, 4);
  if (val != 0)
    return val;			/* return error */

  /* Determine appropriate breakpoint contents and size for this address.  */
  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
    {
      if ((addr & 3) == 0)
	{
	  buf[0] = bp_entry[0];
	  buf[1] = bp_entry[1];
	  buf[2] = contents_cache[2] & 0x7f;
	  buf[3] = contents_cache[3];
	}
      else
	{
	  buf[0] = contents_cache[0];
	  buf[1] = contents_cache[1];
	  buf[2] = bp_entry[0];
	  buf[3] = bp_entry[1];
	}
    }
  else				/* little-endian */
    {
      if ((addr & 3) == 0)
	{
	  buf[0] = contents_cache[0];
	  buf[1] = contents_cache[1] & 0x7f;
	  buf[2] = bp_entry[1];
	  buf[3] = bp_entry[0];
	}
      else
	{
	  buf[0] = bp_entry[1];
	  buf[1] = bp_entry[0];
	  buf[2] = contents_cache[2];
	  buf[3] = contents_cache[3];
	}
    }

  /* Write the breakpoint.  */
  val = target_write_memory (addr & 0xfffffffc, buf, 4);
  return val;
}

static int
m32r_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
{
  int val;
  char buf[4];

  buf[0] = contents_cache[0];
  buf[1] = contents_cache[1];
  buf[2] = contents_cache[2];
  buf[3] = contents_cache[3];

  /* Remove parallel bit.  */
  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
    {
      if ((buf[0] & 0x80) == 0 && (buf[2] & 0x80) != 0)
	buf[2] &= 0x7f;
    }
  else				/* little-endian */
    {
      if ((buf[3] & 0x80) == 0 && (buf[1] & 0x80) != 0)
	buf[1] &= 0x7f;
    }

  /* Write contents.  */
  val = target_write_memory (addr & 0xfffffffc, buf, 4);
  return val;
}

static const unsigned char *
m32r_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
{
  static char be_bp_entry[] = { 0x10, 0xf1, 0x70, 0x00 };	/* dpt -> nop */
  static char le_bp_entry[] = { 0x00, 0x70, 0xf1, 0x10 };	/* dpt -> nop */
  unsigned char *bp;

  /* Determine appropriate breakpoint.  */
  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
    {
      if ((*pcptr & 3) == 0)
	{
	  bp = be_bp_entry;
	  *lenptr = 4;
	}
      else
	{
	  bp = be_bp_entry;
	  *lenptr = 2;
	}
    }
  else
    {
      if ((*pcptr & 3) == 0)
	{
	  bp = le_bp_entry;
	  *lenptr = 4;
	}
      else
	{
	  bp = le_bp_entry + 2;
	  *lenptr = 2;
	}
    }

  return bp;
}


char *m32r_register_names[] = {
  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
  "r8", "r9", "r10", "r11", "r12", "fp", "lr", "sp",
  "psw", "cbr", "spi", "spu", "bpc", "pc", "accl", "acch",
  "evb"
};

static const char *
m32r_register_name (int reg_nr)
{
  if (reg_nr < 0)
    return NULL;
  if (reg_nr >= M32R_NUM_REGS)
    return NULL;
  return m32r_register_names[reg_nr];
}


/* Return the GDB type object for the "standard" data type
   of data in register N.  */

static struct type *
m32r_register_type (struct gdbarch *gdbarch, int reg_nr)
{
  if (reg_nr == M32R_PC_REGNUM)
    return builtin_type_void_func_ptr;
  else if (reg_nr == M32R_SP_REGNUM || reg_nr == M32R_FP_REGNUM)
    return builtin_type_void_data_ptr;
  else
    return builtin_type_int32;
}


/* Write into appropriate registers a function return value
   of type TYPE, given in virtual format.  

   Things always get returned in RET1_REGNUM, RET2_REGNUM. */

static void
m32r_store_return_value (struct type *type, struct regcache *regcache,
			 const void *valbuf)
{
  CORE_ADDR regval;
  int len = TYPE_LENGTH (type);

  regval = extract_unsigned_integer (valbuf, len > 4 ? 4 : len);
  regcache_cooked_write_unsigned (regcache, RET1_REGNUM, regval);

  if (len > 4)
    {
      regval = extract_unsigned_integer ((char *) valbuf + 4, len - 4);
      regcache_cooked_write_unsigned (regcache, RET1_REGNUM + 1, regval);
    }
}

/* This is required by skip_prologue. The results of decoding a prologue
   should be cached because this thrashing is getting nuts.  */

static int
decode_prologue (CORE_ADDR start_pc, CORE_ADDR scan_limit,
		 CORE_ADDR *pl_endptr, unsigned long *framelength)
{
  unsigned long framesize;
  int insn;
  int op1;
  CORE_ADDR after_prologue = 0;
  CORE_ADDR after_push = 0;
  CORE_ADDR after_stack_adjust = 0;
  CORE_ADDR current_pc;
  LONGEST return_value;

  framesize = 0;
  after_prologue = 0;

  for (current_pc = start_pc; current_pc < scan_limit; current_pc += 2)
    {
      /* Check if current pc's location is readable. */
      if (!safe_read_memory_integer (current_pc, 2, &return_value))
	return -1;

      insn = read_memory_unsigned_integer (current_pc, 2);

      if (insn == 0x0000)
	break;

      /* If this is a 32 bit instruction, we dont want to examine its
         immediate data as though it were an instruction */
      if (current_pc & 0x02)
	{
	  /* decode this instruction further */
	  insn &= 0x7fff;
	}
      else
	{
	  if (insn & 0x8000)
	    {
	      if (current_pc == scan_limit)
		scan_limit += 2;	/* extend the search */

	      current_pc += 2;	/* skip the immediate data */

	      /* Check if current pc's location is readable. */
	      if (!safe_read_memory_integer (current_pc, 2, &return_value))
		return -1;

	      if (insn == 0x8faf)	/* add3 sp, sp, xxxx */
		/* add 16 bit sign-extended offset */
		{
		  framesize +=
		    -((short) read_memory_unsigned_integer (current_pc, 2));
		}
	      else
		{
		  if (((insn >> 8) == 0xe4)	/* ld24 r4, xxxxxx; sub sp, r4 */
		      && safe_read_memory_integer (current_pc + 2, 2,
						   &return_value)
		      && read_memory_unsigned_integer (current_pc + 2,
						       2) == 0x0f24)
		    /* subtract 24 bit sign-extended negative-offset */
		    {
		      insn = read_memory_unsigned_integer (current_pc - 2, 4);
		      if (insn & 0x00800000)	/* sign extend */
			insn |= 0xff000000;	/* negative */
		      else
			insn &= 0x00ffffff;	/* positive */
		      framesize += insn;
		    }
		}
	      after_push = current_pc + 2;
	      continue;
	    }
	}
      op1 = insn & 0xf000;	/* isolate just the first nibble */

      if ((insn & 0xf0ff) == 0x207f)
	{			/* st reg, @-sp */
	  int regno;
	  framesize += 4;
	  regno = ((insn >> 8) & 0xf);
	  after_prologue = 0;
	  continue;
	}
      if ((insn >> 8) == 0x4f)	/* addi sp, xx */
	/* add 8 bit sign-extended offset */
	{
	  int stack_adjust = (char) (insn & 0xff);

	  /* there are probably two of these stack adjustments:
	     1) A negative one in the prologue, and
	     2) A positive one in the epilogue.
	     We are only interested in the first one.  */

	  if (stack_adjust < 0)
	    {
	      framesize -= stack_adjust;
	      after_prologue = 0;
	      /* A frameless function may have no "mv fp, sp".
	         In that case, this is the end of the prologue.  */
	      after_stack_adjust = current_pc + 2;
	    }
	  continue;
	}
      if (insn == 0x1d8f)
	{			/* mv fp, sp */
	  after_prologue = current_pc + 2;
	  break;		/* end of stack adjustments */
	}

      /* Nop looks like a branch, continue explicitly */
      if (insn == 0x7000)
	{
	  after_prologue = current_pc + 2;
	  continue;		/* nop occurs between pushes */
	}
      /* End of prolog if any of these are trap instructions */
      if ((insn & 0xfff0) == 0x10f0)
	{
	  after_prologue = current_pc;
	  break;
	}
      /* End of prolog if any of these are branch instructions */
      if ((op1 == 0x7000) || (op1 == 0xb000) || (op1 == 0xf000))
	{
	  after_prologue = current_pc;
	  continue;
	}
      /* Some of the branch instructions are mixed with other types */
      if (op1 == 0x1000)
	{
	  int subop = insn & 0x0ff0;
	  if ((subop == 0x0ec0) || (subop == 0x0fc0))
	    {
	      after_prologue = current_pc;
	      continue;		/* jmp , jl */
	    }
	}
    }

  if (framelength)
    *framelength = framesize;

  if (current_pc >= scan_limit)
    {
      if (pl_endptr)
	{
	  if (after_stack_adjust != 0)
	    /* We did not find a "mv fp,sp", but we DID find
	       a stack_adjust.  Is it safe to use that as the
	       end of the prologue?  I just don't know. */
	    {
	      *pl_endptr = after_stack_adjust;
	    }
	  else if (after_push != 0)
	    /* We did not find a "mv fp,sp", but we DID find
	       a push.  Is it safe to use that as the
	       end of the prologue?  I just don't know. */
	    {
	      *pl_endptr = after_push;
	    }
	  else
	    /* We reached the end of the loop without finding the end
	       of the prologue.  No way to win -- we should report failure.  
	       The way we do that is to return the original start_pc.
	       GDB will set a breakpoint at the start of the function (etc.) */
	    *pl_endptr = start_pc;
	}
      return 0;
    }

  if (after_prologue == 0)
    after_prologue = current_pc;

  if (pl_endptr)
    *pl_endptr = after_prologue;

  return 0;
}				/*  decode_prologue */

/* Function: skip_prologue
   Find end of function prologue */

#define DEFAULT_SEARCH_LIMIT 128

CORE_ADDR
m32r_skip_prologue (CORE_ADDR pc)
{
  CORE_ADDR func_addr, func_end;
  struct symtab_and_line sal;
  LONGEST return_value;

  /* See what the symbol table says */

  if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
    {
      sal = find_pc_line (func_addr, 0);

      if (sal.line != 0 && sal.end <= func_end)
	{
	  func_end = sal.end;
	}
      else
	/* Either there's no line info, or the line after the prologue is after
	   the end of the function.  In this case, there probably isn't a
	   prologue.  */
	{
	  func_end = min (func_end, func_addr + DEFAULT_SEARCH_LIMIT);
	}
    }
  else
    func_end = pc + DEFAULT_SEARCH_LIMIT;

  /* If pc's location is not readable, just quit. */
  if (!safe_read_memory_integer (pc, 4, &return_value))
    return pc;

  /* Find the end of prologue.  */
  if (decode_prologue (pc, func_end, &sal.end, NULL) < 0)
    return pc;

  return sal.end;
}

struct m32r_unwind_cache
{
  /* The previous frame's inner most stack address.  Used as this
     frame ID's stack_addr.  */
  CORE_ADDR prev_sp;
  /* The frame's base, optionally used by the high-level debug info.  */
  CORE_ADDR base;
  int size;
  /* How far the SP and r13 (FP) have been offset from the start of
     the stack frame (as defined by the previous frame's stack
     pointer).  */
  LONGEST sp_offset;
  LONGEST r13_offset;
  int uses_frame;
  /* Table indicating the location of each and every register.  */
  struct trad_frame_saved_reg *saved_regs;
};

/* Put here the code to store, into fi->saved_regs, the addresses of
   the saved registers of frame described by FRAME_INFO.  This
   includes special registers such as pc and fp saved in special ways
   in the stack frame.  sp is even more special: the address we return
   for it IS the sp for the next frame. */

static struct m32r_unwind_cache *
m32r_frame_unwind_cache (struct frame_info *next_frame,
			 void **this_prologue_cache)
{
  CORE_ADDR pc, scan_limit;
  ULONGEST prev_sp;
  ULONGEST this_base;
  unsigned long op, op2;
  int i;
  struct m32r_unwind_cache *info;


  if ((*this_prologue_cache))
    return (*this_prologue_cache);

  info = FRAME_OBSTACK_ZALLOC (struct m32r_unwind_cache);
  (*this_prologue_cache) = info;
  info->saved_regs = trad_frame_alloc_saved_regs (next_frame);

  info->size = 0;
  info->sp_offset = 0;
  info->uses_frame = 0;

  scan_limit = frame_pc_unwind (next_frame);
  for (pc = frame_func_unwind (next_frame);
       pc > 0 && pc < scan_limit; pc += 2)
    {
      if ((pc & 2) == 0)
	{
	  op = get_frame_memory_unsigned (next_frame, pc, 4);
	  if ((op & 0x80000000) == 0x80000000)
	    {
	      /* 32-bit instruction */
	      if ((op & 0xffff0000) == 0x8faf0000)
		{
		  /* add3 sp,sp,xxxx */
		  short n = op & 0xffff;
		  info->sp_offset += n;
		}
	      else if (((op >> 8) == 0xe4)
		       && get_frame_memory_unsigned (next_frame, pc + 2,
						     2) == 0x0f24)
		{
		  /* ld24 r4, xxxxxx; sub sp, r4 */
		  unsigned long n = op & 0xffffff;
		  info->sp_offset += n;
		  pc += 2;	/* skip sub instruction */
		}

	      if (pc == scan_limit)
		scan_limit += 2;	/* extend the search */
	      pc += 2;		/* skip the immediate data */
	      continue;
	    }
	}

      /* 16-bit instructions */
      op = get_frame_memory_unsigned (next_frame, pc, 2) & 0x7fff;
      if ((op & 0xf0ff) == 0x207f)
	{
	  /* st rn, @-sp */
	  int regno = ((op >> 8) & 0xf);
	  info->sp_offset -= 4;
	  info->saved_regs[regno].addr = info->sp_offset;
	}
      else if ((op & 0xff00) == 0x4f00)
	{
	  /* addi sp, xx */
	  int n = (char) (op & 0xff);
	  info->sp_offset += n;
	}
      else if (op == 0x1d8f)
	{
	  /* mv fp, sp */
	  info->uses_frame = 1;
	  info->r13_offset = info->sp_offset;
	  break;		/* end of stack adjustments */
	}
      else if ((op & 0xfff0) == 0x10f0)
	{
	  /* end of prologue if this is a trap instruction */
	  break;		/* end of stack adjustments */
	}
    }

  info->size = -info->sp_offset;

  /* Compute the previous frame's stack pointer (which is also the
     frame's ID's stack address), and this frame's base pointer.  */
  if (info->uses_frame)
    {
      /* The SP was moved to the FP.  This indicates that a new frame
         was created.  Get THIS frame's FP value by unwinding it from
         the next frame.  */
      this_base = frame_unwind_register_unsigned (next_frame, M32R_FP_REGNUM);
      /* The FP points at the last saved register.  Adjust the FP back
         to before the first saved register giving the SP.  */
      prev_sp = this_base + info->size;
    }
  else
    {
      /* Assume that the FP is this frame's SP but with that pushed
         stack space added back.  */
      this_base = frame_unwind_register_unsigned (next_frame, M32R_SP_REGNUM);
      prev_sp = this_base + info->size;
    }

  /* Convert that SP/BASE into real addresses.  */
  info->prev_sp = prev_sp;
  info->base = this_base;

  /* Adjust all the saved registers so that they contain addresses and
     not offsets.  */
  for (i = 0; i < NUM_REGS - 1; i++)
    if (trad_frame_addr_p (info->saved_regs, i))
      info->saved_regs[i].addr = (info->prev_sp + info->saved_regs[i].addr);

  /* The call instruction moves the caller's PC in the callee's LR.
     Since this is an unwind, do the reverse.  Copy the location of LR
     into PC (the address / regnum) so that a request for PC will be
     converted into a request for the LR.  */
  info->saved_regs[M32R_PC_REGNUM] = info->saved_regs[LR_REGNUM];

  /* The previous frame's SP needed to be computed.  Save the computed
     value.  */
  trad_frame_set_value (info->saved_regs, M32R_SP_REGNUM, prev_sp);

  return info;
}

static CORE_ADDR
m32r_read_pc (ptid_t ptid)
{
  ptid_t save_ptid;
  ULONGEST pc;

  save_ptid = inferior_ptid;
  inferior_ptid = ptid;
  regcache_cooked_read_unsigned (current_regcache, M32R_PC_REGNUM, &pc);
  inferior_ptid = save_ptid;
  return pc;
}

static void
m32r_write_pc (CORE_ADDR val, ptid_t ptid)
{
  ptid_t save_ptid;

  save_ptid = inferior_ptid;
  inferior_ptid = ptid;
  write_register (M32R_PC_REGNUM, val);
  inferior_ptid = save_ptid;
}

static CORE_ADDR
m32r_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
  return frame_unwind_register_unsigned (next_frame, M32R_SP_REGNUM);
}


static CORE_ADDR
m32r_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
		      struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
		      struct value **args, CORE_ADDR sp, int struct_return,
		      CORE_ADDR struct_addr)
{
  int stack_offset, stack_alloc;
  int argreg = ARG1_REGNUM;
  int argnum;
  struct type *type;
  enum type_code typecode;
  CORE_ADDR regval;
  char *val;
  char valbuf[MAX_REGISTER_SIZE];
  int len;
  int odd_sized_struct;

  /* first force sp to a 4-byte alignment */
  sp = sp & ~3;

  /* Set the return address.  For the m32r, the return breakpoint is
     always at BP_ADDR.  */
  regcache_cooked_write_unsigned (regcache, LR_REGNUM, bp_addr);

  /* If STRUCT_RETURN is true, then the struct return address (in
     STRUCT_ADDR) will consume the first argument-passing register.
     Both adjust the register count and store that value.  */
  if (struct_return)
    {
      regcache_cooked_write_unsigned (regcache, argreg, struct_addr);
      argreg++;
    }

  /* Now make sure there's space on the stack */
  for (argnum = 0, stack_alloc = 0; argnum < nargs; argnum++)
    stack_alloc += ((TYPE_LENGTH (value_type (args[argnum])) + 3) & ~3);
  sp -= stack_alloc;		/* make room on stack for args */

  for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++)
    {
      type = value_type (args[argnum]);
      typecode = TYPE_CODE (type);
      len = TYPE_LENGTH (type);

      memset (valbuf, 0, sizeof (valbuf));

      /* Passes structures that do not fit in 2 registers by reference.  */
      if (len > 8
	  && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
	{
	  store_unsigned_integer (valbuf, 4, VALUE_ADDRESS (args[argnum]));
	  typecode = TYPE_CODE_PTR;
	  len = 4;
	  val = valbuf;
	}
      else if (len < 4)
	{
	  /* value gets right-justified in the register or stack word */
	  memcpy (valbuf + (register_size (gdbarch, argreg) - len),
		  (char *) value_contents (args[argnum]), len);
	  val = valbuf;
	}
      else
	val = (char *) value_contents (args[argnum]);

      while (len > 0)
	{
	  if (argreg > ARGN_REGNUM)
	    {
	      /* must go on the stack */
	      write_memory (sp + stack_offset, val, 4);
	      stack_offset += 4;
	    }
	  else if (argreg <= ARGN_REGNUM)
	    {
	      /* there's room in a register */
	      regval =
		extract_unsigned_integer (val,
					  register_size (gdbarch, argreg));
	      regcache_cooked_write_unsigned (regcache, argreg++, regval);
	    }

	  /* Store the value 4 bytes at a time.  This means that things
	     larger than 4 bytes may go partly in registers and partly
	     on the stack.  */
	  len -= register_size (gdbarch, argreg);
	  val += register_size (gdbarch, argreg);
	}
    }

  /* Finally, update the SP register.  */
  regcache_cooked_write_unsigned (regcache, M32R_SP_REGNUM, sp);

  return sp;
}


/* Given a return value in `regbuf' with a type `valtype', 
   extract and copy its value into `valbuf'.  */

static void
m32r_extract_return_value (struct type *type, struct regcache *regcache,
			   void *dst)
{
  bfd_byte *valbuf = dst;
  int len = TYPE_LENGTH (type);
  ULONGEST tmp;

  /* By using store_unsigned_integer we avoid having to do
     anything special for small big-endian values.  */
  regcache_cooked_read_unsigned (regcache, RET1_REGNUM, &tmp);
  store_unsigned_integer (valbuf, (len > 4 ? len - 4 : len), tmp);

  /* Ignore return values more than 8 bytes in size because the m32r
     returns anything more than 8 bytes in the stack. */
  if (len > 4)
    {
      regcache_cooked_read_unsigned (regcache, RET1_REGNUM + 1, &tmp);
      store_unsigned_integer (valbuf + len - 4, 4, tmp);
    }
}

enum return_value_convention
m32r_return_value (struct gdbarch *gdbarch, struct type *valtype,
		   struct regcache *regcache, void *readbuf,
		   const void *writebuf)
{
  if (TYPE_LENGTH (valtype) > 8)
    return RETURN_VALUE_STRUCT_CONVENTION;
  else
    {
      if (readbuf != NULL)
	m32r_extract_return_value (valtype, regcache, readbuf);
      if (writebuf != NULL)
	m32r_store_return_value (valtype, regcache, writebuf);
      return RETURN_VALUE_REGISTER_CONVENTION;
    }
}



static CORE_ADDR
m32r_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
  return frame_unwind_register_unsigned (next_frame, M32R_PC_REGNUM);
}

/* Given a GDB frame, determine the address of the calling function's
   frame.  This will be used to create a new GDB frame struct.  */

static void
m32r_frame_this_id (struct frame_info *next_frame,
		    void **this_prologue_cache, struct frame_id *this_id)
{
  struct m32r_unwind_cache *info
    = m32r_frame_unwind_cache (next_frame, this_prologue_cache);
  CORE_ADDR base;
  CORE_ADDR func;
  struct minimal_symbol *msym_stack;
  struct frame_id id;

  /* The FUNC is easy.  */
  func = frame_func_unwind (next_frame);

  /* Check if the stack is empty.  */
  msym_stack = lookup_minimal_symbol ("_stack", NULL, NULL);
  if (msym_stack && info->base == SYMBOL_VALUE_ADDRESS (msym_stack))
    return;

  /* Hopefully the prologue analysis either correctly determined the
     frame's base (which is the SP from the previous frame), or set
     that base to "NULL".  */
  base = info->prev_sp;
  if (base == 0)
    return;

  id = frame_id_build (base, func);
  (*this_id) = id;
}

static void
m32r_frame_prev_register (struct frame_info *next_frame,
			  void **this_prologue_cache,
			  int regnum, int *optimizedp,
			  enum lval_type *lvalp, CORE_ADDR *addrp,
			  int *realnump, void *bufferp)
{
  struct m32r_unwind_cache *info
    = m32r_frame_unwind_cache (next_frame, this_prologue_cache);
  trad_frame_get_prev_register (next_frame, info->saved_regs, regnum,
				optimizedp, lvalp, addrp, realnump, bufferp);
}

static const struct frame_unwind m32r_frame_unwind = {
  NORMAL_FRAME,
  m32r_frame_this_id,
  m32r_frame_prev_register
};

static const struct frame_unwind *
m32r_frame_sniffer (struct frame_info *next_frame)
{
  return &m32r_frame_unwind;
}

static CORE_ADDR
m32r_frame_base_address (struct frame_info *next_frame, void **this_cache)
{
  struct m32r_unwind_cache *info
    = m32r_frame_unwind_cache (next_frame, this_cache);
  return info->base;
}

static const struct frame_base m32r_frame_base = {
  &m32r_frame_unwind,
  m32r_frame_base_address,
  m32r_frame_base_address,
  m32r_frame_base_address
};

/* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that
   dummy frame.  The frame ID's base needs to match the TOS value
   saved by save_dummy_frame_tos(), and the PC match the dummy frame's
   breakpoint.  */

static struct frame_id
m32r_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
  return frame_id_build (m32r_unwind_sp (gdbarch, next_frame),
			 frame_pc_unwind (next_frame));
}


static gdbarch_init_ftype m32r_gdbarch_init;

static struct gdbarch *
m32r_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  struct gdbarch *gdbarch;
  struct gdbarch_tdep *tdep;

  /* If there is already a candidate, use it.  */
  arches = gdbarch_list_lookup_by_info (arches, &info);
  if (arches != NULL)
    return arches->gdbarch;

  /* Allocate space for the new architecture.  */
  tdep = XMALLOC (struct gdbarch_tdep);
  gdbarch = gdbarch_alloc (&info, tdep);

  set_gdbarch_read_pc (gdbarch, m32r_read_pc);
  set_gdbarch_write_pc (gdbarch, m32r_write_pc);
  set_gdbarch_unwind_sp (gdbarch, m32r_unwind_sp);

  set_gdbarch_num_regs (gdbarch, M32R_NUM_REGS);
  set_gdbarch_sp_regnum (gdbarch, M32R_SP_REGNUM);
  set_gdbarch_register_name (gdbarch, m32r_register_name);
  set_gdbarch_register_type (gdbarch, m32r_register_type);

  set_gdbarch_push_dummy_call (gdbarch, m32r_push_dummy_call);
  set_gdbarch_return_value (gdbarch, m32r_return_value);

  set_gdbarch_skip_prologue (gdbarch, m32r_skip_prologue);
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
  set_gdbarch_breakpoint_from_pc (gdbarch, m32r_breakpoint_from_pc);
  set_gdbarch_memory_insert_breakpoint (gdbarch,
					m32r_memory_insert_breakpoint);
  set_gdbarch_memory_remove_breakpoint (gdbarch,
					m32r_memory_remove_breakpoint);

  set_gdbarch_frame_align (gdbarch, m32r_frame_align);

  frame_base_set_default (gdbarch, &m32r_frame_base);

  /* Methods for saving / extracting a dummy frame's ID.  The ID's
     stack address must match the SP value returned by
     PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos.  */
  set_gdbarch_unwind_dummy_id (gdbarch, m32r_unwind_dummy_id);

  /* Return the unwound PC value.  */
  set_gdbarch_unwind_pc (gdbarch, m32r_unwind_pc);

  set_gdbarch_print_insn (gdbarch, print_insn_m32r);

  /* Hook in ABI-specific overrides, if they have been registered.  */
  gdbarch_init_osabi (info, gdbarch);

  /* Hook in the default unwinders.  */
  frame_unwind_append_sniffer (gdbarch, m32r_frame_sniffer);

  return gdbarch;
}

void
_initialize_m32r_tdep (void)
{
  register_gdbarch_init (bfd_arch_m32r, m32r_gdbarch_init);
}
