/* Target-dependent code for the Matsushita MN10300 for GDB, the GNU debugger.

   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
   2007, 2008 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

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

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

#include "defs.h"
#include "arch-utils.h"
#include "dis-asm.h"
#include "gdbtypes.h"
#include "regcache.h"
#include "gdb_string.h"
#include "gdb_assert.h"
#include "gdbcore.h"	/* for write_memory_unsigned_integer */
#include "value.h"
#include "gdbtypes.h"
#include "frame.h"
#include "frame-unwind.h"
#include "frame-base.h"
#include "trad-frame.h"
#include "symtab.h"
#include "dwarf2-frame.h"
#include "osabi.h"
#include "infcall.h"
#include "target.h"

#include "mn10300-tdep.h"

/* Forward decl.  */
extern struct trad_frame_cache *mn10300_frame_unwind_cache (struct frame_info*,
							    void **);

/* Compute the alignment required by a type.  */

static int
mn10300_type_align (struct type *type)
{
  int i, align = 1;

  switch (TYPE_CODE (type))
    {
    case TYPE_CODE_INT:
    case TYPE_CODE_ENUM:
    case TYPE_CODE_SET:
    case TYPE_CODE_RANGE:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_BOOL:
    case TYPE_CODE_FLT:
    case TYPE_CODE_PTR:
    case TYPE_CODE_REF:
      return TYPE_LENGTH (type);

    case TYPE_CODE_COMPLEX:
      return TYPE_LENGTH (type) / 2;

    case TYPE_CODE_STRUCT:
    case TYPE_CODE_UNION:
      for (i = 0; i < TYPE_NFIELDS (type); i++)
	{
	  int falign = mn10300_type_align (TYPE_FIELD_TYPE (type, i));
	  while (align < falign)
	    align <<= 1;
	}
      return align;

    case TYPE_CODE_ARRAY:
      /* HACK!  Structures containing arrays, even small ones, are not
	 elligible for returning in registers.  */
      return 256;

    case TYPE_CODE_TYPEDEF:
      return mn10300_type_align (check_typedef (type));

    default:
      internal_error (__FILE__, __LINE__, _("bad switch"));
    }
}

/* Should call_function allocate stack space for a struct return?  */
static int
mn10300_use_struct_convention (struct type *type)
{
  /* Structures bigger than a pair of words can't be returned in
     registers.  */
  if (TYPE_LENGTH (type) > 8)
    return 1;

  switch (TYPE_CODE (type))
    {
    case TYPE_CODE_STRUCT:
    case TYPE_CODE_UNION:
      /* Structures with a single field are handled as the field
	 itself.  */
      if (TYPE_NFIELDS (type) == 1)
	return mn10300_use_struct_convention (TYPE_FIELD_TYPE (type, 0));

      /* Structures with word or double-word size are passed in memory, as
	 long as they require at least word alignment.  */
      if (mn10300_type_align (type) >= 4)
	return 0;

      return 1;

      /* Arrays are addressable, so they're never returned in
	 registers.  This condition can only hold when the array is
	 the only field of a struct or union.  */
    case TYPE_CODE_ARRAY:
      return 1;

    case TYPE_CODE_TYPEDEF:
      return mn10300_use_struct_convention (check_typedef (type));

    default:
      return 0;
    }
}

static void
mn10300_store_return_value (struct gdbarch *gdbarch, struct type *type,
			    struct regcache *regcache, const void *valbuf)
{
  int len = TYPE_LENGTH (type);
  int reg, regsz;
  
  if (TYPE_CODE (type) == TYPE_CODE_PTR)
    reg = 4;
  else
    reg = 0;

  regsz = register_size (gdbarch, reg);

  if (len <= regsz)
    regcache_raw_write_part (regcache, reg, 0, len, valbuf);
  else if (len <= 2 * regsz)
    {
      regcache_raw_write (regcache, reg, valbuf);
      gdb_assert (regsz == register_size (gdbarch, reg + 1));
      regcache_raw_write_part (regcache, reg+1, 0,
			       len - regsz, (char *) valbuf + regsz);
    }
  else
    internal_error (__FILE__, __LINE__,
		    _("Cannot store return value %d bytes long."), len);
}

static void
mn10300_extract_return_value (struct gdbarch *gdbarch, struct type *type,
			      struct regcache *regcache, void *valbuf)
{
  char buf[MAX_REGISTER_SIZE];
  int len = TYPE_LENGTH (type);
  int reg, regsz;

  if (TYPE_CODE (type) == TYPE_CODE_PTR)
    reg = 4;
  else
    reg = 0;

  regsz = register_size (gdbarch, reg);
  if (len <= regsz)
    {
      regcache_raw_read (regcache, reg, buf);
      memcpy (valbuf, buf, len);
    }
  else if (len <= 2 * regsz)
    {
      regcache_raw_read (regcache, reg, buf);
      memcpy (valbuf, buf, regsz);
      gdb_assert (regsz == register_size (gdbarch, reg + 1));
      regcache_raw_read (regcache, reg + 1, buf);
      memcpy ((char *) valbuf + regsz, buf, len - regsz);
    }
  else
    internal_error (__FILE__, __LINE__,
		    _("Cannot extract return value %d bytes long."), len);
}

/* Determine, for architecture GDBARCH, how a return value of TYPE
   should be returned.  If it is supposed to be returned in registers,
   and READBUF is non-zero, read the appropriate value from REGCACHE,
   and copy it into READBUF.  If WRITEBUF is non-zero, write the value
   from WRITEBUF into REGCACHE.  */

static enum return_value_convention
mn10300_return_value (struct gdbarch *gdbarch, struct type *func_type,
		      struct type *type, struct regcache *regcache,
		      gdb_byte *readbuf, const gdb_byte *writebuf)
{
  if (mn10300_use_struct_convention (type))
    return RETURN_VALUE_STRUCT_CONVENTION;

  if (readbuf)
    mn10300_extract_return_value (gdbarch, type, regcache, readbuf);
  if (writebuf)
    mn10300_store_return_value (gdbarch, type, regcache, writebuf);

  return RETURN_VALUE_REGISTER_CONVENTION;
}

static char *
register_name (int reg, char **regs, long sizeof_regs)
{
  if (reg < 0 || reg >= sizeof_regs / sizeof (regs[0]))
    return NULL;
  else
    return regs[reg];
}

static const char *
mn10300_generic_register_name (struct gdbarch *gdbarch, int reg)
{
  static char *regs[] =
  { "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3",
    "sp", "pc", "mdr", "psw", "lir", "lar", "", "",
    "", "", "", "", "", "", "", "",
    "", "", "", "", "", "", "", "fp"
  };
  return register_name (reg, regs, sizeof regs);
}


static const char *
am33_register_name (struct gdbarch *gdbarch, int reg)
{
  static char *regs[] =
  { "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3",
    "sp", "pc", "mdr", "psw", "lir", "lar", "",
    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
    "ssp", "msp", "usp", "mcrh", "mcrl", "mcvf", "", "", ""
  };
  return register_name (reg, regs, sizeof regs);
}

static const char *
am33_2_register_name (struct gdbarch *gdbarch, int reg)
{
  static char *regs[] =
  {
    "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3",
    "sp", "pc", "mdr", "psw", "lir", "lar", "mdrq", "r0",
    "r1", "r2", "r3", "r4", "r5", "r6", "r7", "ssp",
    "msp", "usp", "mcrh", "mcrl", "mcvf", "fpcr", "", "",
    "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7",
    "fs8", "fs9", "fs10", "fs11", "fs12", "fs13", "fs14", "fs15",
    "fs16", "fs17", "fs18", "fs19", "fs20", "fs21", "fs22", "fs23",
    "fs24", "fs25", "fs26", "fs27", "fs28", "fs29", "fs30", "fs31"
  };
  return register_name (reg, regs, sizeof regs);
}

static struct type *
mn10300_register_type (struct gdbarch *gdbarch, int reg)
{
  return builtin_type_int;
}

static CORE_ADDR
mn10300_read_pc (struct regcache *regcache)
{
  ULONGEST val;
  regcache_cooked_read_unsigned (regcache, E_PC_REGNUM, &val);
  return val;
}

static void
mn10300_write_pc (struct regcache *regcache, CORE_ADDR val)
{
  regcache_cooked_write_unsigned (regcache, E_PC_REGNUM, val);
}

/* The breakpoint instruction must be the same size as the smallest
   instruction in the instruction set.

   The Matsushita mn10x00 processors have single byte instructions
   so we need a single byte breakpoint.  Matsushita hasn't defined
   one, so we defined it ourselves.  */

const static unsigned char *
mn10300_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
			    int *bp_size)
{
  static char breakpoint[] = {0xff};
  *bp_size = 1;
  return breakpoint;
}

/* Set offsets of saved registers.
   This is a helper function for mn10300_analyze_prologue.  */

static void
set_reg_offsets (struct frame_info *fi, 
		  void **this_cache, 
		  int movm_args,
		  int fpregmask,
		  int stack_extra_size,
		  int frame_in_fp)
{
  struct gdbarch *gdbarch;
  struct trad_frame_cache *cache;
  int offset = 0;
  CORE_ADDR base;

  if (fi == NULL || this_cache == NULL)
    return;

  cache = mn10300_frame_unwind_cache (fi, this_cache);
  if (cache == NULL)
    return;
  gdbarch = get_frame_arch (fi);

  if (frame_in_fp)
    {
      base = frame_unwind_register_unsigned (fi, E_A3_REGNUM);
    }
  else
    {
      base = frame_unwind_register_unsigned (fi, E_SP_REGNUM)
	       + stack_extra_size;
    }

  trad_frame_set_this_base (cache, base);

  if (AM33_MODE (gdbarch) == 2)
    {
      /* If bit N is set in fpregmask, fsN is saved on the stack.
	 The floating point registers are saved in ascending order.
	 For example:  fs16 <- Frame Pointer
	               fs17    Frame Pointer + 4 */
      if (fpregmask != 0)
	{
	  int i;
	  for (i = 0; i < 32; i++)
	    {
	      if (fpregmask & (1 << i))
		{
		  trad_frame_set_reg_addr (cache, E_FS0_REGNUM + i,
					   base + offset);
		  offset += 4;
		}
	    }
	}
    }


  if (movm_args & movm_other_bit)
    {
      /* The `other' bit leaves a blank area of four bytes at the
         beginning of its block of saved registers, making it 32 bytes
         long in total.  */
      trad_frame_set_reg_addr (cache, E_LAR_REGNUM,    base + offset + 4);
      trad_frame_set_reg_addr (cache, E_LIR_REGNUM,    base + offset + 8);
      trad_frame_set_reg_addr (cache, E_MDR_REGNUM,    base + offset + 12);
      trad_frame_set_reg_addr (cache, E_A0_REGNUM + 1, base + offset + 16);
      trad_frame_set_reg_addr (cache, E_A0_REGNUM,     base + offset + 20);
      trad_frame_set_reg_addr (cache, E_D0_REGNUM + 1, base + offset + 24);
      trad_frame_set_reg_addr (cache, E_D0_REGNUM,     base + offset + 28);
      offset += 32;
    }

  if (movm_args & movm_a3_bit)
    {
      trad_frame_set_reg_addr (cache, E_A3_REGNUM, base + offset);
      offset += 4;
    }
  if (movm_args & movm_a2_bit)
    {
      trad_frame_set_reg_addr (cache, E_A2_REGNUM, base + offset);
      offset += 4;
    }
  if (movm_args & movm_d3_bit)
    {
      trad_frame_set_reg_addr (cache, E_D3_REGNUM, base + offset);
      offset += 4;
    }
  if (movm_args & movm_d2_bit)
    {
      trad_frame_set_reg_addr (cache, E_D2_REGNUM, base + offset);
      offset += 4;
    }
  if (AM33_MODE (gdbarch))
    {
      if (movm_args & movm_exother_bit)
        {
	  trad_frame_set_reg_addr (cache, E_MCVF_REGNUM, base + offset);
	  trad_frame_set_reg_addr (cache, E_MCRL_REGNUM, base + offset + 4);
	  trad_frame_set_reg_addr (cache, E_MCRH_REGNUM, base + offset + 8);
	  trad_frame_set_reg_addr (cache, E_MDRQ_REGNUM, base + offset + 12);
	  trad_frame_set_reg_addr (cache, E_E1_REGNUM,   base + offset + 16);
	  trad_frame_set_reg_addr (cache, E_E0_REGNUM,   base + offset + 20);
          offset += 24;
        }
      if (movm_args & movm_exreg1_bit)
        {
	  trad_frame_set_reg_addr (cache, E_E7_REGNUM, base + offset);
	  trad_frame_set_reg_addr (cache, E_E6_REGNUM, base + offset + 4);
	  trad_frame_set_reg_addr (cache, E_E5_REGNUM, base + offset + 8);
	  trad_frame_set_reg_addr (cache, E_E4_REGNUM, base + offset + 12);
          offset += 16;
        }
      if (movm_args & movm_exreg0_bit)
        {
	  trad_frame_set_reg_addr (cache, E_E3_REGNUM, base + offset);
	  trad_frame_set_reg_addr (cache, E_E2_REGNUM, base + offset + 4);
          offset += 8;
        }
    }
  /* The last (or first) thing on the stack will be the PC.  */
  trad_frame_set_reg_addr (cache, E_PC_REGNUM, base + offset);
  /* Save the SP in the 'traditional' way.  
     This will be the same location where the PC is saved.  */
  trad_frame_set_reg_value (cache, E_SP_REGNUM, base + offset);
}

/* The main purpose of this file is dealing with prologues to extract
   information about stack frames and saved registers.

   In gcc/config/mn13000/mn10300.c, the expand_prologue prologue
   function is pretty readable, and has a nice explanation of how the
   prologue is generated.  The prologues generated by that code will
   have the following form (NOTE: the current code doesn't handle all
   this!):

   + If this is an old-style varargs function, then its arguments
     need to be flushed back to the stack:
     
        mov d0,(4,sp)
        mov d1,(4,sp)

   + If we use any of the callee-saved registers, save them now.
     
        movm [some callee-saved registers],(sp)

   + If we have any floating-point registers to save:

     - Decrement the stack pointer to reserve space for the registers.
       If the function doesn't need a frame pointer, we may combine
       this with the adjustment that reserves space for the frame.

        add -SIZE, sp

     - Save the floating-point registers.  We have two possible
       strategies:

       . Save them at fixed offset from the SP:

        fmov fsN,(OFFSETN,sp)
        fmov fsM,(OFFSETM,sp)
        ...

       Note that, if OFFSETN happens to be zero, you'll get the
       different opcode: fmov fsN,(sp)

       . Or, set a0 to the start of the save area, and then use
       post-increment addressing to save the FP registers.

        mov sp, a0
        add SIZE, a0
        fmov fsN,(a0+)
        fmov fsM,(a0+)
        ...

   + If the function needs a frame pointer, we set it here.

        mov sp, a3

   + Now we reserve space for the stack frame proper.  This could be
     merged into the `add -SIZE, sp' instruction for FP saves up
     above, unless we needed to set the frame pointer in the previous
     step, or the frame is so large that allocating the whole thing at
     once would put the FP register save slots out of reach of the
     addressing mode (128 bytes).
      
        add -SIZE, sp        

   One day we might keep the stack pointer constant, that won't
   change the code for prologues, but it will make the frame
   pointerless case much more common.  */

/* Analyze the prologue to determine where registers are saved,
   the end of the prologue, etc etc.  Return the end of the prologue
   scanned.

   We store into FI (if non-null) several tidbits of information:

   * stack_size -- size of this stack frame.  Note that if we stop in
   certain parts of the prologue/epilogue we may claim the size of the
   current frame is zero.  This happens when the current frame has
   not been allocated yet or has already been deallocated.

   * fsr -- Addresses of registers saved in the stack by this frame.

   * status -- A (relatively) generic status indicator.  It's a bitmask
   with the following bits: 

   MY_FRAME_IN_SP: The base of the current frame is actually in
   the stack pointer.  This can happen for frame pointerless
   functions, or cases where we're stopped in the prologue/epilogue
   itself.  For these cases mn10300_analyze_prologue will need up
   update fi->frame before returning or analyzing the register
   save instructions.

   MY_FRAME_IN_FP: The base of the current frame is in the
   frame pointer register ($a3).

   NO_MORE_FRAMES: Set this if the current frame is "start" or
   if the first instruction looks like mov <imm>,sp.  This tells
   frame chain to not bother trying to unwind past this frame.  */

static CORE_ADDR
mn10300_analyze_prologue (struct gdbarch *gdbarch, struct frame_info *fi, 
			  void **this_cache, 
			  CORE_ADDR pc)
{
  CORE_ADDR func_addr, func_end, addr, stop;
  long stack_extra_size = 0;
  int imm_size;
  unsigned char buf[4];
  int status;
  int movm_args = 0;
  int fpregmask = 0;
  char *name;
  int frame_in_fp = 0;

  /* Use the PC in the frame if it's provided to look up the
     start of this function.

     Note: kevinb/2003-07-16: We used to do the following here:
	pc = (fi ? get_frame_pc (fi) : pc);
     But this is (now) badly broken when called from analyze_dummy_frame().
  */
  if (fi)
    {
      pc = (pc ? pc : get_frame_pc (fi));
    }

  /* Find the start of this function.  */
  status = find_pc_partial_function (pc, &name, &func_addr, &func_end);

  /* Do nothing if we couldn't find the start of this function 

     MVS: comment went on to say "or if we're stopped at the first
     instruction in the prologue" -- but code doesn't reflect that, 
     and I don't want to do that anyway.  */
  if (status == 0)
    {
      addr = pc;
      goto finish_prologue;
    }

  /* If we're in start, then give up.  */
  if (strcmp (name, "start") == 0)
    {
      addr = pc;
      goto finish_prologue;
    }

  /* Figure out where to stop scanning.  */
  stop = fi ? pc : func_end;

  /* Don't walk off the end of the function.  */
  stop = stop > func_end ? func_end : stop;

  /* Start scanning on the first instruction of this function.  */
  addr = func_addr;

  /* Suck in two bytes.  */
  if (addr + 2 > stop || !safe_frame_unwind_memory (fi, addr, buf, 2))
    goto finish_prologue;

  /* First see if this insn sets the stack pointer from a register; if
     so, it's probably the initialization of the stack pointer in _start,
     so mark this as the bottom-most frame.  */
  if (buf[0] == 0xf2 && (buf[1] & 0xf3) == 0xf0)
    {
      goto finish_prologue;
    }

  /* Now look for movm [regs],sp, which saves the callee saved registers.

     At this time we don't know if fi->frame is valid, so we only note
     that we encountered a movm instruction.  Later, we'll set the entries
     in fsr.regs as needed.  */
  if (buf[0] == 0xcf)
    {
      /* Extract the register list for the movm instruction.  */
      movm_args = buf[1];

      addr += 2;

      /* Quit now if we're beyond the stop point.  */
      if (addr >= stop)
	goto finish_prologue;

      /* Get the next two bytes so the prologue scan can continue.  */
      if (!safe_frame_unwind_memory (fi, addr, buf, 2))
	goto finish_prologue;
    }

  /* Check for "mov pc, a2", an instruction found in optimized, position
     independent code.  Skip it if found.  */
  if (buf[0] == 0xf0 && buf[1] == 0x2e)
    {
      addr += 2;

      /* Quit now if we're beyond the stop point.  */
      if (addr >= stop)
	goto finish_prologue;

      /* Get the next two bytes so the prologue scan can continue.  */
      status = target_read_memory (addr, buf, 2);
      if (status != 0)
	goto finish_prologue;
    }

  if (AM33_MODE (gdbarch) == 2)
    {
      /* Determine if any floating point registers are to be saved.
	 Look for one of the following three prologue formats:

	[movm [regs],(sp)] [movm [regs],(sp)] [movm [regs],(sp)]

	 add -SIZE,sp       add -SIZE,sp       add -SIZE,sp
	 fmov fs#,(sp)      mov sp,a0/a1       mov sp,a0/a1
	 fmov fs#,(#,sp)    fmov fs#,(a0/a1+)  add SIZE2,a0/a1
	 ...                ...                fmov fs#,(a0/a1+)
	 ...                ...                ...
	 fmov fs#,(#,sp)    fmov fs#,(a0/a1+)  fmov fs#,(a0/a1+)

	[mov sp,a3]        [mov sp,a3]
	[add -SIZE2,sp]    [add -SIZE2,sp]                                 */

      /* Remember the address at which we started in the event that we
	 don't ultimately find an fmov instruction.  Once we're certain
	 that we matched one of the above patterns, we'll set
	 ``restore_addr'' to the appropriate value.  Note: At one time
	 in the past, this code attempted to not adjust ``addr'' until
	 there was a fair degree of certainty that the pattern would be
	 matched.  However, that code did not wait until an fmov instruction
	 was actually encountered.  As a consequence, ``addr'' would
	 sometimes be advanced even when no fmov instructions were found.  */
      CORE_ADDR restore_addr = addr;
      int fmov_found = 0;

      /* First, look for add -SIZE,sp (i.e. add imm8,sp  (0xf8feXX)
                                         or add imm16,sp (0xfafeXXXX)
                                         or add imm32,sp (0xfcfeXXXXXXXX)) */
      imm_size = 0;
      if (buf[0] == 0xf8 && buf[1] == 0xfe)
	imm_size = 1;
      else if (buf[0] == 0xfa && buf[1] == 0xfe)
	imm_size = 2;
      else if (buf[0] == 0xfc && buf[1] == 0xfe)
	imm_size = 4;
      if (imm_size != 0)
	{
	  /* An "add -#,sp" instruction has been found. "addr + 2 + imm_size"
	     is the address of the next instruction. Don't modify "addr" until
	     the next "floating point prologue" instruction is found. If this
	     is not a prologue that saves floating point registers we need to
	     be able to back out of this bit of code and continue with the
	     prologue analysis. */
	  if (addr + 2 + imm_size < stop)
	    {
	      if (!safe_frame_unwind_memory (fi, addr + 2 + imm_size, buf, 3))
		goto finish_prologue;
	      if ((buf[0] & 0xfc) == 0x3c)
		{
		  /* Occasionally, especially with C++ code, the "fmov"
		     instructions will be preceded by "mov sp,aN"
		     (aN => a0, a1, a2, or a3).

		     This is a one byte instruction:  mov sp,aN = 0011 11XX
		     where XX is the register number.

		     Skip this instruction by incrementing addr.  The "fmov"
		     instructions will have the form "fmov fs#,(aN+)" in this
		     case, but that will not necessitate a change in the
		     "fmov" parsing logic below. */

		  addr++;

		  if ((buf[1] & 0xfc) == 0x20)
		    {
		      /* Occasionally, especially with C++ code compiled with
			 the -fomit-frame-pointer or -O3 options, the
			 "mov sp,aN" instruction will be followed by an
			 "add #,aN" instruction. This indicates the
			 "stack_size", the size of the portion of the stack
			 containing the arguments. This instruction format is:
			 add #,aN = 0010 00XX YYYY YYYY
			 where XX        is the register number
			       YYYY YYYY is the constant.
			 Note the size of the stack (as a negative number) in
			 the frame info structure. */
		      if (fi)
			stack_extra_size += -buf[2];

		      addr += 2;
		    }
		}

	      if ((buf[0] & 0xfc) == 0x3c ||
		  buf[0] == 0xf9 || buf[0] == 0xfb)
		{
		  /* An "fmov" instruction has been found indicating that this
		     prologue saves floating point registers (or, as described
		     above, a "mov sp,aN" and possible "add #,aN" have been
		     found and we will assume an "fmov" follows). Process the
		     consecutive "fmov" instructions. */
		  for (addr += 2 + imm_size;;addr += imm_size)
		    {
		      int regnum;

		      /* Read the "fmov" instruction. */
		      if (addr >= stop ||
			  !safe_frame_unwind_memory (fi, addr, buf, 4))
			goto finish_prologue;

		      if (buf[0] != 0xf9 && buf[0] != 0xfb)
			break;

		      /* An fmov instruction has just been seen.  We can
		         now really commit to the pattern match.  */

		      fmov_found = 1;

		      /* Get the floating point register number from the 
			 2nd and 3rd bytes of the "fmov" instruction:
			 Machine Code: 0000 00X0 YYYY 0000 =>
			 Regnum: 000X YYYY */
		      regnum = (buf[1] & 0x02) << 3;
		      regnum |= ((buf[2] & 0xf0) >> 4) & 0x0f;

		      /* Add this register number to the bit mask of floating
			 point registers that have been saved. */
		      fpregmask |= 1 << regnum;
		  
		      /* Determine the length of this "fmov" instruction.
			 fmov fs#,(sp)   => 3 byte instruction
			 fmov fs#,(#,sp) => 4 byte instruction */
		      imm_size = (buf[0] == 0xf9) ? 3 : 4;
		    }
		}
	    }
	}
      /* If no fmov instructions were found by the above sequence, reset
         the state and pretend that the above bit of code never happened.  */
      if (!fmov_found)
	{
	  addr = restore_addr;
	  status = target_read_memory (addr, buf, 2);
	  if (status != 0)
	    goto finish_prologue;
	  stack_extra_size = 0;
	}
    }

  /* Now see if we set up a frame pointer via "mov sp,a3" */
  if (buf[0] == 0x3f)
    {
      addr += 1;

      /* The frame pointer is now valid.  */
      if (fi)
	{
	  frame_in_fp = 1;
	}

      /* Quit now if we're beyond the stop point.  */
      if (addr >= stop)
	goto finish_prologue;

      /* Get two more bytes so scanning can continue.  */
      if (!safe_frame_unwind_memory (fi, addr, buf, 2))
	goto finish_prologue;
    }

  /* Next we should allocate the local frame.  No more prologue insns
     are found after allocating the local frame.

     Search for add imm8,sp (0xf8feXX)
     or add imm16,sp (0xfafeXXXX)
     or add imm32,sp (0xfcfeXXXXXXXX).

     If none of the above was found, then this prologue has no 
     additional stack.  */

  imm_size = 0;
  if (buf[0] == 0xf8 && buf[1] == 0xfe)
    imm_size = 1;
  else if (buf[0] == 0xfa && buf[1] == 0xfe)
    imm_size = 2;
  else if (buf[0] == 0xfc && buf[1] == 0xfe)
    imm_size = 4;

  if (imm_size != 0)
    {
      /* Suck in imm_size more bytes, they'll hold the size of the
         current frame.  */
      if (!safe_frame_unwind_memory (fi, addr + 2, buf, imm_size))
	goto finish_prologue;

      /* Note the size of the stack.  */
      stack_extra_size -= extract_signed_integer (buf, imm_size);

      /* We just consumed 2 + imm_size bytes.  */
      addr += 2 + imm_size;

      /* No more prologue insns follow, so begin preparation to return.  */
      goto finish_prologue;
    }
  /* Do the essentials and get out of here.  */
 finish_prologue:
  /* Note if/where callee saved registers were saved.  */
  if (fi)
    set_reg_offsets (fi, this_cache, movm_args, fpregmask, stack_extra_size,
		     frame_in_fp);
  return addr;
}

/* Function: skip_prologue
   Return the address of the first inst past the prologue of the function.  */

static CORE_ADDR
mn10300_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  return mn10300_analyze_prologue (gdbarch, NULL, NULL, pc);
}

/* Simple frame_unwind_cache.  
   This finds the "extra info" for the frame.  */
struct trad_frame_cache *
mn10300_frame_unwind_cache (struct frame_info *next_frame,
			    void **this_prologue_cache)
{
  struct gdbarch *gdbarch;
  struct trad_frame_cache *cache;
  CORE_ADDR pc, start, end;
  void *cache_p;

  if (*this_prologue_cache)
    return (*this_prologue_cache);

  gdbarch = get_frame_arch (next_frame);
  cache_p = trad_frame_cache_zalloc (next_frame);
  pc = gdbarch_unwind_pc (gdbarch, next_frame);
  mn10300_analyze_prologue (gdbarch, next_frame, &cache_p, pc);
  cache = cache_p;

  if (find_pc_partial_function (pc, NULL, &start, &end))
    trad_frame_set_id (cache, 
		       frame_id_build (trad_frame_get_this_base (cache), 
				       start));
  else
    {
      start = frame_func_unwind (next_frame, NORMAL_FRAME);
      trad_frame_set_id (cache,
			 frame_id_build (trad_frame_get_this_base (cache),
					 start));
    }

  (*this_prologue_cache) = cache;
  return cache;
}

/* Here is a dummy implementation.  */
static struct frame_id
mn10300_unwind_dummy_id (struct gdbarch *gdbarch,
			 struct frame_info *next_frame)
{
  return frame_id_build (frame_sp_unwind (next_frame), 
			 frame_pc_unwind (next_frame));
}

/* Trad frame implementation.  */
static void
mn10300_frame_this_id (struct frame_info *next_frame,
		       void **this_prologue_cache,
		       struct frame_id *this_id)
{
  struct trad_frame_cache *cache = 
    mn10300_frame_unwind_cache (next_frame, this_prologue_cache);

  trad_frame_get_id (cache, this_id);
}

static void
mn10300_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, gdb_byte *bufferp)
{
  struct trad_frame_cache *cache =
    mn10300_frame_unwind_cache (next_frame, this_prologue_cache);

  trad_frame_get_register (cache, next_frame, regnum, optimizedp, 
			   lvalp, addrp, realnump, bufferp);
  /* Or...
  trad_frame_get_prev_register (next_frame, cache->prev_regs, regnum, 
			   optimizedp, lvalp, addrp, realnump, bufferp);
  */
}

static const struct frame_unwind mn10300_frame_unwind = {
  NORMAL_FRAME,
  mn10300_frame_this_id, 
  mn10300_frame_prev_register
};

static CORE_ADDR
mn10300_frame_base_address (struct frame_info *next_frame,
			    void **this_prologue_cache)
{
  struct trad_frame_cache *cache = 
    mn10300_frame_unwind_cache (next_frame, this_prologue_cache);

  return trad_frame_get_this_base (cache);
}

static const struct frame_unwind *
mn10300_frame_sniffer (struct frame_info *next_frame)
{
  return &mn10300_frame_unwind;
}

static const struct frame_base mn10300_frame_base = {
  &mn10300_frame_unwind, 
  mn10300_frame_base_address, 
  mn10300_frame_base_address,
  mn10300_frame_base_address
};

static CORE_ADDR
mn10300_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
  ULONGEST pc;

  pc = frame_unwind_register_unsigned (next_frame, E_PC_REGNUM);
  return pc;
}

static CORE_ADDR
mn10300_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
  ULONGEST sp;

  sp = frame_unwind_register_unsigned (next_frame, E_SP_REGNUM);
  return sp;
}

static void
mn10300_frame_unwind_init (struct gdbarch *gdbarch)
{
  frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
  frame_unwind_append_sniffer (gdbarch, mn10300_frame_sniffer);
  frame_base_set_default (gdbarch, &mn10300_frame_base);
  set_gdbarch_unwind_dummy_id (gdbarch, mn10300_unwind_dummy_id);
  set_gdbarch_unwind_pc (gdbarch, mn10300_unwind_pc);
  set_gdbarch_unwind_sp (gdbarch, mn10300_unwind_sp);
}

/* Function: push_dummy_call
 *
 * Set up machine state for a target call, including
 * function arguments, stack, return address, etc.
 *
 */

static CORE_ADDR
mn10300_push_dummy_call (struct gdbarch *gdbarch, 
			 struct value *target_func,
			 struct regcache *regcache,
			 CORE_ADDR bp_addr, 
			 int nargs, struct value **args,
			 CORE_ADDR sp, 
			 int struct_return,
			 CORE_ADDR struct_addr)
{
  const int push_size = register_size (gdbarch, E_PC_REGNUM);
  int regs_used;
  int len, arg_len; 
  int stack_offset = 0;
  int argnum;
  char *val, valbuf[MAX_REGISTER_SIZE];

  /* This should be a nop, but align the stack just in case something
     went wrong.  Stacks are four byte aligned on the mn10300.  */
  sp &= ~3;

  /* Now make space on the stack for the args.

     XXX This doesn't appear to handle pass-by-invisible reference
     arguments.  */
  regs_used = struct_return ? 1 : 0;
  for (len = 0, argnum = 0; argnum < nargs; argnum++)
    {
      arg_len = (TYPE_LENGTH (value_type (args[argnum])) + 3) & ~3;
      while (regs_used < 2 && arg_len > 0)
	{
	  regs_used++;
	  arg_len -= push_size;
	}
      len += arg_len;
    }

  /* Allocate stack space.  */
  sp -= len;

  if (struct_return)
    {
      regs_used = 1;
      regcache_cooked_write_unsigned (regcache, E_D0_REGNUM, struct_addr);
    }
  else
    regs_used = 0;

  /* Push all arguments onto the stack. */
  for (argnum = 0; argnum < nargs; argnum++)
    {
      /* FIXME what about structs?  Unions?  */
      if (TYPE_CODE (value_type (*args)) == TYPE_CODE_STRUCT
	  && TYPE_LENGTH (value_type (*args)) > 8)
	{
	  /* Change to pointer-to-type.  */
	  arg_len = push_size;
	  store_unsigned_integer (valbuf, push_size, 
				  VALUE_ADDRESS (*args));
	  val = &valbuf[0];
	}
      else
	{
	  arg_len = TYPE_LENGTH (value_type (*args));
	  val = (char *) value_contents (*args);
	}

      while (regs_used < 2 && arg_len > 0)
	{
	  regcache_cooked_write_unsigned (regcache, regs_used, 
				  extract_unsigned_integer (val, push_size));
	  val += push_size;
	  arg_len -= push_size;
	  regs_used++;
	}

      while (arg_len > 0)
	{
	  write_memory (sp + stack_offset, val, push_size);
	  arg_len -= push_size;
	  val += push_size;
	  stack_offset += push_size;
	}

      args++;
    }

  /* Make space for the flushback area.  */
  sp -= 8;

  /* Push the return address that contains the magic breakpoint.  */
  sp -= 4;
  write_memory_unsigned_integer (sp, push_size, bp_addr);

  /* The CPU also writes the return address always into the
     MDR register on "call".  */
  regcache_cooked_write_unsigned (regcache, E_MDR_REGNUM, bp_addr);

  /* Update $sp.  */
  regcache_cooked_write_unsigned (regcache, E_SP_REGNUM, sp);

  /* On the mn10300, it's possible to move some of the stack adjustment
     and saving of the caller-save registers out of the prologue and
     into the call sites.  (When using gcc, this optimization can
     occur when using the -mrelax switch.) If this occurs, the dwarf2
     info will reflect this fact.  We can test to see if this is the
     case by creating a new frame using the current stack pointer and
     the address of the function that we're about to call.  We then
     unwind SP and see if it's different than the SP of our newly
     created frame.  If the SP values are the same, the caller is not
     expected to allocate any additional stack.  On the other hand, if
     the SP values are different, the difference determines the
     additional stack that must be allocated.
     
     Note that we don't update the return value though because that's
     the value of the stack just after pushing the arguments, but prior
     to performing the call.  This value is needed in order to
     construct the frame ID of the dummy call.   */
  {
    CORE_ADDR func_addr = find_function_addr (target_func, NULL);
    CORE_ADDR unwound_sp 
      = mn10300_unwind_sp (gdbarch, create_new_frame (sp, func_addr));
    if (sp != unwound_sp)
      regcache_cooked_write_unsigned (regcache, E_SP_REGNUM,
                                      sp - (unwound_sp - sp));
  }

  return sp;
}

/* If DWARF2 is a register number appearing in Dwarf2 debug info, then
   mn10300_dwarf2_reg_to_regnum (DWARF2) is the corresponding GDB
   register number.  Why don't Dwarf2 and GDB use the same numbering?
   Who knows?  But since people have object files lying around with
   the existing Dwarf2 numbering, and other people have written stubs
   to work with the existing GDB, neither of them can change.  So we
   just have to cope.  */
static int
mn10300_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int dwarf2)
{
  /* This table is supposed to be shaped like the gdbarch_register_name
     initializer in gcc/config/mn10300/mn10300.h.  Registers which
     appear in GCC's numbering, but have no counterpart in GDB's
     world, are marked with a -1.  */
  static int dwarf2_to_gdb[] = {
    0,  1,  2,  3,  4,  5,  6,  7, -1, 8,
    15, 16, 17, 18, 19, 20, 21, 22,
    32, 33, 34, 35, 36, 37, 38, 39,
    40, 41, 42, 43, 44, 45, 46, 47,
    48, 49, 50, 51, 52, 53, 54, 55,
    56, 57, 58, 59, 60, 61, 62, 63,
    9
  };

  if (dwarf2 < 0
      || dwarf2 >= ARRAY_SIZE (dwarf2_to_gdb))
    {
      warning (_("Bogus register number in debug info: %d"), dwarf2);
      return -1;
    }

  return dwarf2_to_gdb[dwarf2];
}

static struct gdbarch *
mn10300_gdbarch_init (struct gdbarch_info info,
		      struct gdbarch_list *arches)
{
  struct gdbarch *gdbarch;
  struct gdbarch_tdep *tdep;
  int num_regs;

  arches = gdbarch_list_lookup_by_info (arches, &info);
  if (arches != NULL)
    return arches->gdbarch;

  tdep = xmalloc (sizeof (struct gdbarch_tdep));
  gdbarch = gdbarch_alloc (&info, tdep);

  switch (info.bfd_arch_info->mach)
    {
    case 0:
    case bfd_mach_mn10300:
      set_gdbarch_register_name (gdbarch, mn10300_generic_register_name);
      tdep->am33_mode = 0;
      num_regs = 32;
      break;
    case bfd_mach_am33:
      set_gdbarch_register_name (gdbarch, am33_register_name);
      tdep->am33_mode = 1;
      num_regs = 32;
      break;
    case bfd_mach_am33_2:
      set_gdbarch_register_name (gdbarch, am33_2_register_name);
      tdep->am33_mode = 2;
      num_regs = 64;
      set_gdbarch_fp0_regnum (gdbarch, 32);
      break;
    default:
      internal_error (__FILE__, __LINE__,
		      _("mn10300_gdbarch_init: Unknown mn10300 variant"));
      break;
    }

  /* Registers.  */
  set_gdbarch_num_regs (gdbarch, num_regs);
  set_gdbarch_register_type (gdbarch, mn10300_register_type);
  set_gdbarch_skip_prologue (gdbarch, mn10300_skip_prologue);
  set_gdbarch_read_pc (gdbarch, mn10300_read_pc);
  set_gdbarch_write_pc (gdbarch, mn10300_write_pc);
  set_gdbarch_pc_regnum (gdbarch, E_PC_REGNUM);
  set_gdbarch_sp_regnum (gdbarch, E_SP_REGNUM);
  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, mn10300_dwarf2_reg_to_regnum);

  /* Stack unwinding.  */
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
  /* Breakpoints.  */
  set_gdbarch_breakpoint_from_pc (gdbarch, mn10300_breakpoint_from_pc);
  /* decr_pc_after_break? */
  /* Disassembly.  */
  set_gdbarch_print_insn (gdbarch, print_insn_mn10300);

  /* Stage 2 */
  set_gdbarch_return_value (gdbarch, mn10300_return_value);
  
  /* Stage 3 -- get target calls working.  */
  set_gdbarch_push_dummy_call (gdbarch, mn10300_push_dummy_call);
  /* set_gdbarch_return_value (store, extract) */


  mn10300_frame_unwind_init (gdbarch);

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

  return gdbarch;
}
 
/* Dump out the mn10300 specific architecture information. */

static void
mn10300_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  fprintf_unfiltered (file, "mn10300_dump_tdep: am33_mode = %d\n",
		      tdep->am33_mode);
}

void
_initialize_mn10300_tdep (void)
{
  gdbarch_register (bfd_arch_mn10300, mn10300_gdbarch_init, mn10300_dump_tdep);
}

