/* Target-machine dependent code for the AMD 29000
   Copyright 1990, 1991, 1992, 1993, 1994, 1995
   Free Software Foundation, Inc.
   Contributed by Cygnus Support.  Written by Jim Kingdon.

   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 "gdbcore.h"
#include "frame.h"
#include "value.h"
#include "symtab.h"
#include "inferior.h"
#include "gdbcmd.h"

/* If all these bits in an instruction word are zero, it is a "tag word"
   which precedes a function entry point and gives stack traceback info.
   This used to be defined as 0xff000000, but that treated 0x00000deb as
   a tag word, while it is really used as a breakpoint.  */
#define	TAGWORD_ZERO_MASK	0xff00f800

extern CORE_ADDR text_start;	/* FIXME, kludge... */

/* The user-settable top of the register stack in virtual memory.  We
   won't attempt to access any stored registers above this address, if set
   nonzero.  */

static CORE_ADDR rstack_high_address = UINT_MAX;


/* Should call_function allocate stack space for a struct return?  */
/* On the a29k objects over 16 words require the caller to allocate space.  */
int
a29k_use_struct_convention (gcc_p, type)
     int gcc_p;
     struct type *type;
{
  return (TYPE_LENGTH (type) > 16 * 4);
}


/* Structure to hold cached info about function prologues.  */

struct prologue_info
{
  CORE_ADDR pc;			/* First addr after fn prologue */
  unsigned rsize, msize;	/* register stack frame size, mem stack ditto */
  unsigned mfp_used:1;		/* memory frame pointer used */
  unsigned rsize_valid:1;	/* Validity bits for the above */
  unsigned msize_valid:1;
  unsigned mfp_valid:1;
};

/* Examine the prologue of a function which starts at PC.  Return
   the first addess past the prologue.  If MSIZE is non-NULL, then
   set *MSIZE to the memory stack frame size.  If RSIZE is non-NULL,
   then set *RSIZE to the register stack frame size (not including
   incoming arguments and the return address & frame pointer stored
   with them).  If no prologue is found, *RSIZE is set to zero.
   If no prologue is found, or a prologue which doesn't involve
   allocating a memory stack frame, then set *MSIZE to zero.

   Note that both msize and rsize are in bytes.  This is not consistent
   with the _User's Manual_ with respect to rsize, but it is much more
   convenient.

   If MFP_USED is non-NULL, *MFP_USED is set to nonzero if a memory
   frame pointer is being used.  */

CORE_ADDR
examine_prologue (pc, rsize, msize, mfp_used)
     CORE_ADDR pc;
     unsigned *msize;
     unsigned *rsize;
     int *mfp_used;
{
  long insn;
  CORE_ADDR p = pc;
  struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc);
  struct prologue_info *mi = 0;

  if (msymbol != NULL)
    mi = (struct prologue_info *) msymbol->info;

  if (mi != 0)
    {
      int valid = 1;
      if (rsize != NULL)
	{
	  *rsize = mi->rsize;
	  valid &= mi->rsize_valid;
	}
      if (msize != NULL)
	{
	  *msize = mi->msize;
	  valid &= mi->msize_valid;
	}
      if (mfp_used != NULL)
	{
	  *mfp_used = mi->mfp_used;
	  valid &= mi->mfp_valid;
	}
      if (valid)
	return mi->pc;
    }

  if (rsize != NULL)
    *rsize = 0;
  if (msize != NULL)
    *msize = 0;
  if (mfp_used != NULL)
    *mfp_used = 0;

  /* Prologue must start with subtracting a constant from gr1.
     Normally this is sub gr1,gr1,<rsize * 4>.  */
  insn = read_memory_integer (p, 4);
  if ((insn & 0xffffff00) != 0x25010100)
    {
      /* If the frame is large, instead of a single instruction it
         might be a pair of instructions:
         const <reg>, <rsize * 4>
         sub gr1,gr1,<reg>
       */
      int reg;
      /* Possible value for rsize.  */
      unsigned int rsize0;

      if ((insn & 0xff000000) != 0x03000000)
	{
	  p = pc;
	  goto done;
	}
      reg = (insn >> 8) & 0xff;
      rsize0 = (((insn >> 8) & 0xff00) | (insn & 0xff));
      p += 4;
      insn = read_memory_integer (p, 4);
      if ((insn & 0xffffff00) != 0x24010100
	  || (insn & 0xff) != reg)
	{
	  p = pc;
	  goto done;
	}
      if (rsize != NULL)
	*rsize = rsize0;
    }
  else
    {
      if (rsize != NULL)
	*rsize = (insn & 0xff);
    }
  p += 4;

  /* Next instruction ought to be asgeu V_SPILL,gr1,rab.  
   * We don't check the vector number to allow for kernel debugging.  The 
   * kernel will use a different trap number. 
   * If this insn is missing, we just keep going; Metaware R2.3u compiler
   * generates prologue that intermixes initializations and puts the asgeu
   * way down.
   */
  insn = read_memory_integer (p, 4);
  if ((insn & 0xff00ffff) == (0x5e000100 | RAB_HW_REGNUM))
    {
      p += 4;
    }

  /* Next instruction usually sets the frame pointer (lr1) by adding
     <size * 4> from gr1.  However, this can (and high C does) be
     deferred until anytime before the first function call.  So it is
     OK if we don't see anything which sets lr1.  
     To allow for alternate register sets (gcc -mkernel-registers)  the msp
     register number is a compile time constant. */

  /* Normally this is just add lr1,gr1,<size * 4>.  */
  insn = read_memory_integer (p, 4);
  if ((insn & 0xffffff00) == 0x15810100)
    p += 4;
  else
    {
      /* However, for large frames it can be
         const <reg>, <size *4>
         add lr1,gr1,<reg>
       */
      int reg;
      CORE_ADDR q;

      if ((insn & 0xff000000) == 0x03000000)
	{
	  reg = (insn >> 8) & 0xff;
	  q = p + 4;
	  insn = read_memory_integer (q, 4);
	  if ((insn & 0xffffff00) == 0x14810100
	      && (insn & 0xff) == reg)
	    p = q;
	}
    }

  /* Next comes "add lr{<rsize-1>},msp,0", but only if a memory
     frame pointer is in use.  We just check for add lr<anything>,msp,0;
     we don't check this rsize against the first instruction, and
     we don't check that the trace-back tag indicates a memory frame pointer
     is in use.  
     To allow for alternate register sets (gcc -mkernel-registers)  the msp
     register number is a compile time constant.

     The recommended instruction is actually "sll lr<whatever>,msp,0". 
     We check for that, too.  Originally Jim Kingdon's code seemed
     to be looking for a "sub" instruction here, but the mask was set
     up to lose all the time. */
  insn = read_memory_integer (p, 4);
  if (((insn & 0xff80ffff) == (0x15800000 | (MSP_HW_REGNUM << 8)))	/* add */
      || ((insn & 0xff80ffff) == (0x81800000 | (MSP_HW_REGNUM << 8))))	/* sll */
    {
      p += 4;
      if (mfp_used != NULL)
	*mfp_used = 1;
    }

  /* Next comes a subtraction from msp to allocate a memory frame,
     but only if a memory frame is
     being used.  We don't check msize against the trace-back tag.

     To allow for alternate register sets (gcc -mkernel-registers) the msp
     register number is a compile time constant.

     Normally this is just
     sub msp,msp,<msize>
   */
  insn = read_memory_integer (p, 4);
  if ((insn & 0xffffff00) ==
      (0x25000000 | (MSP_HW_REGNUM << 16) | (MSP_HW_REGNUM << 8)))
    {
      p += 4;
      if (msize != NULL)
	*msize = insn & 0xff;
    }
  else
    {
      /* For large frames, instead of a single instruction it might
         be

         const <reg>, <msize>
         consth <reg>, <msize>     ; optional
         sub msp,msp,<reg>
       */
      int reg;
      unsigned msize0;
      CORE_ADDR q = p;

      if ((insn & 0xff000000) == 0x03000000)
	{
	  reg = (insn >> 8) & 0xff;
	  msize0 = ((insn >> 8) & 0xff00) | (insn & 0xff);
	  q += 4;
	  insn = read_memory_integer (q, 4);
	  /* Check for consth.  */
	  if ((insn & 0xff000000) == 0x02000000
	      && (insn & 0x0000ff00) == reg)
	    {
	      msize0 |= (insn << 8) & 0xff000000;
	      msize0 |= (insn << 16) & 0x00ff0000;
	      q += 4;
	      insn = read_memory_integer (q, 4);
	    }
	  /* Check for sub msp,msp,<reg>.  */
	  if ((insn & 0xffffff00) ==
	      (0x24000000 | (MSP_HW_REGNUM << 16) | (MSP_HW_REGNUM << 8))
	      && (insn & 0xff) == reg)
	    {
	      p = q + 4;
	      if (msize != NULL)
		*msize = msize0;
	    }
	}
    }

  /* Next instruction might be asgeu V_SPILL,gr1,rab.  
   * We don't check the vector number to allow for kernel debugging.  The 
   * kernel will use a different trap number. 
   * Metaware R2.3u compiler
   * generates prologue that intermixes initializations and puts the asgeu
   * way down after everything else.
   */
  insn = read_memory_integer (p, 4);
  if ((insn & 0xff00ffff) == (0x5e000100 | RAB_HW_REGNUM))
    {
      p += 4;
    }

done:
  if (msymbol != NULL)
    {
      if (mi == 0)
	{
	  /* Add a new cache entry.  */
	  mi = (struct prologue_info *) xmalloc (sizeof (struct prologue_info));
	  msymbol->info = (char *) mi;
	  mi->rsize_valid = 0;
	  mi->msize_valid = 0;
	  mi->mfp_valid = 0;
	}
      /* else, cache entry exists, but info is incomplete.  */
      mi->pc = p;
      if (rsize != NULL)
	{
	  mi->rsize = *rsize;
	  mi->rsize_valid = 1;
	}
      if (msize != NULL)
	{
	  mi->msize = *msize;
	  mi->msize_valid = 1;
	}
      if (mfp_used != NULL)
	{
	  mi->mfp_used = *mfp_used;
	  mi->mfp_valid = 1;
	}
    }
  return p;
}

/* Advance PC across any function entry prologue instructions
   to reach some "real" code.  */

CORE_ADDR
a29k_skip_prologue (pc)
     CORE_ADDR pc;
{
  return examine_prologue (pc, NULL, NULL, NULL);
}

/*
 * Examine the one or two word tag at the beginning of a function.
 * The tag word is expect to be at 'p', if it is not there, we fail
 * by returning 0.  The documentation for the tag word was taken from
 * page 7-15 of the 29050 User's Manual.  We are assuming that the
 * m bit is in bit 22 of the tag word, which seems to be the agreed upon
 * convention today (1/15/92).
 * msize is return in bytes.
 */

static int			/* 0/1 - failure/success of finding the tag word  */
examine_tag (p, is_trans, argcount, msize, mfp_used)
     CORE_ADDR p;
     int *is_trans;
     int *argcount;
     unsigned *msize;
     int *mfp_used;
{
  unsigned int tag1, tag2;

  tag1 = read_memory_integer (p, 4);
  if ((tag1 & TAGWORD_ZERO_MASK) != 0)	/* Not a tag word */
    return 0;
  if (tag1 & (1 << 23))		/* A two word tag */
    {
      tag2 = read_memory_integer (p - 4, 4);
      if (msize)
	*msize = tag2 * 2;
    }
  else
    /* A one word tag */
    {
      if (msize)
	*msize = tag1 & 0x7ff;
    }
  if (is_trans)
    *is_trans = ((tag1 & (1 << 21)) ? 1 : 0);
  /* Note that this includes the frame pointer and the return address
     register, so the actual number of registers of arguments is two less.
     argcount can be zero, however, sometimes, for strange assembler
     routines.  */
  if (argcount)
    *argcount = (tag1 >> 16) & 0x1f;
  if (mfp_used)
    *mfp_used = ((tag1 & (1 << 22)) ? 1 : 0);
  return 1;
}

/* Initialize the frame.  In addition to setting "extra" frame info,
   we also set ->frame because we use it in a nonstandard way, and ->pc
   because we need to know it to get the other stuff.  See the diagram
   of stacks and the frame cache in tm-a29k.h for more detail.  */

static void
init_frame_info (innermost_frame, frame)
     int innermost_frame;
     struct frame_info *frame;
{
  CORE_ADDR p;
  long insn;
  unsigned rsize;
  unsigned msize;
  int mfp_used, trans;
  struct symbol *func;

  p = frame->pc;

  if (innermost_frame)
    frame->frame = read_register (GR1_REGNUM);
  else
    frame->frame = frame->next->frame + frame->next->rsize;

#if 0				/* CALL_DUMMY_LOCATION == ON_STACK */
  This wont work;
#else
  if (PC_IN_CALL_DUMMY (p, 0, 0))
#endif
    {
      frame->rsize = DUMMY_FRAME_RSIZE;
      /* This doesn't matter since we never try to get locals or args
         from a dummy frame.  */
      frame->msize = 0;
      /* Dummy frames always use a memory frame pointer.  */
      frame->saved_msp =
	read_register_stack_integer (frame->frame + DUMMY_FRAME_RSIZE - 4, 4);
      frame->flags |= (TRANSPARENT_FRAME | MFP_USED);
      return;
    }

  func = find_pc_function (p);
  if (func != NULL)
    p = BLOCK_START (SYMBOL_BLOCK_VALUE (func));
  else
    {
      /* Search backward to find the trace-back tag.  However,
         do not trace back beyond the start of the text segment
         (just as a sanity check to avoid going into never-never land).  */
#if 1
      while (p >= text_start
	  && ((insn = read_memory_integer (p, 4)) & TAGWORD_ZERO_MASK) != 0)
	p -= 4;
#else /* 0 */
      char pat[4] =
      {0, 0, 0, 0};
      char mask[4];
      char insn_raw[4];
      store_unsigned_integer (mask, 4, TAGWORD_ZERO_MASK);
      /* Enable this once target_search is enabled and tested.  */
      target_search (4, pat, mask, p, -4, text_start, p + 1, &p, &insn_raw);
      insn = extract_unsigned_integer (insn_raw, 4);
#endif /* 0 */

      if (p < text_start)
	{
	  /* Couldn't find the trace-back tag.
	     Something strange is going on.  */
	  frame->saved_msp = 0;
	  frame->rsize = 0;
	  frame->msize = 0;
	  frame->flags = TRANSPARENT_FRAME;
	  return;
	}
      else
	/* Advance to the first word of the function, i.e. the word
	   after the trace-back tag.  */
	p += 4;
    }

  /* We've found the start of the function.  
     Try looking for a tag word that indicates whether there is a
     memory frame pointer and what the memory stack allocation is.
     If one doesn't exist, try using a more exhaustive search of
     the prologue.  */

  if (examine_tag (p - 4, &trans, (int *) NULL, &msize, &mfp_used))	/* Found good tag */
    examine_prologue (p, &rsize, 0, 0);
  else				/* No tag try prologue */
    examine_prologue (p, &rsize, &msize, &mfp_used);

  frame->rsize = rsize;
  frame->msize = msize;
  frame->flags = 0;
  if (mfp_used)
    frame->flags |= MFP_USED;
  if (trans)
    frame->flags |= TRANSPARENT_FRAME;
  if (innermost_frame)
    {
      frame->saved_msp = read_register (MSP_REGNUM) + msize;
    }
  else
    {
      if (mfp_used)
	frame->saved_msp =
	  read_register_stack_integer (frame->frame + rsize - 4, 4);
      else
	frame->saved_msp = frame->next->saved_msp + msize;
    }
}

void
init_extra_frame_info (frame)
     struct frame_info *frame;
{
  if (frame->next == 0)
    /* Assume innermost frame.  May produce strange results for "info frame"
       but there isn't any way to tell the difference.  */
    init_frame_info (1, frame);
  else
    {
      /* We're in get_prev_frame.
         Take care of everything in init_frame_pc.  */
      ;
    }
}

void
init_frame_pc (fromleaf, frame)
     int fromleaf;
     struct frame_info *frame;
{
  frame->pc = (fromleaf ? SAVED_PC_AFTER_CALL (frame->next) :
	       frame->next ? FRAME_SAVED_PC (frame->next) : read_pc ());
  init_frame_info (fromleaf, frame);
}

/* Local variables (i.e. LOC_LOCAL) are on the memory stack, with their
   offsets being relative to the memory stack pointer (high C) or
   saved_msp (gcc).  */

CORE_ADDR
frame_locals_address (fi)
     struct frame_info *fi;
{
  if (fi->flags & MFP_USED)
    return fi->saved_msp;
  else
    return fi->saved_msp - fi->msize;
}

/* Routines for reading the register stack.  The caller gets to treat
   the register stack as a uniform stack in memory, from address $gr1
   straight through $rfb and beyond.  */

/* Analogous to read_memory except the length is understood to be 4.
   Also, myaddr can be NULL (meaning don't bother to read), and
   if actual_mem_addr is non-NULL, store there the address that it
   was fetched from (or if from a register the offset within
   registers).  Set *LVAL to lval_memory or lval_register, depending
   on where it came from.  The contents written into MYADDR are in
   target format.  */
void
read_register_stack (memaddr, myaddr, actual_mem_addr, lval)
     CORE_ADDR memaddr;
     char *myaddr;
     CORE_ADDR *actual_mem_addr;
     enum lval_type *lval;
{
  long rfb = read_register (RFB_REGNUM);
  long rsp = read_register (RSP_REGNUM);

  /* If we don't do this 'info register' stops in the middle. */
  if (memaddr >= rstack_high_address)
    {
      /* a bogus value */
      static char val[] =
      {~0, ~0, ~0, ~0};
      /* It's in a local register, but off the end of the stack.  */
      int regnum = (memaddr - rsp) / 4 + LR0_REGNUM;
      if (myaddr != NULL)
	{
	  /* Provide bogusness */
	  memcpy (myaddr, val, 4);
	}
      supply_register (regnum, val);	/* More bogusness */
      if (lval != NULL)
	*lval = lval_register;
      if (actual_mem_addr != NULL)
	*actual_mem_addr = REGISTER_BYTE (regnum);
    }
  /* If it's in the part of the register stack that's in real registers,
     get the value from the registers.  If it's anywhere else in memory
     (e.g. in another thread's saved stack), skip this part and get
     it from real live memory.  */
  else if (memaddr < rfb && memaddr >= rsp)
    {
      /* It's in a register.  */
      int regnum = (memaddr - rsp) / 4 + LR0_REGNUM;
      if (regnum > LR0_REGNUM + 127)
	error ("Attempt to read register stack out of range.");
      if (myaddr != NULL)
	read_register_gen (regnum, myaddr);
      if (lval != NULL)
	*lval = lval_register;
      if (actual_mem_addr != NULL)
	*actual_mem_addr = REGISTER_BYTE (regnum);
    }
  else
    {
      /* It's in the memory portion of the register stack.  */
      if (myaddr != NULL)
	read_memory (memaddr, myaddr, 4);
      if (lval != NULL)
	*lval = lval_memory;
      if (actual_mem_addr != NULL)
	*actual_mem_addr = memaddr;
    }
}

/* Analogous to read_memory_integer
   except the length is understood to be 4.  */
long
read_register_stack_integer (memaddr, len)
     CORE_ADDR memaddr;
     int len;
{
  char buf[4];
  read_register_stack (memaddr, buf, NULL, NULL);
  return extract_signed_integer (buf, 4);
}

/* Copy 4 bytes from GDB memory at MYADDR into inferior memory
   at MEMADDR and put the actual address written into in
   *ACTUAL_MEM_ADDR.  */
static void
write_register_stack (memaddr, myaddr, actual_mem_addr)
     CORE_ADDR memaddr;
     char *myaddr;
     CORE_ADDR *actual_mem_addr;
{
  long rfb = read_register (RFB_REGNUM);
  long rsp = read_register (RSP_REGNUM);
  /* If we don't do this 'info register' stops in the middle. */
  if (memaddr >= rstack_high_address)
    {
      /* It's in a register, but off the end of the stack.  */
      if (actual_mem_addr != NULL)
	*actual_mem_addr = 0;
    }
  else if (memaddr < rfb)
    {
      /* It's in a register.  */
      int regnum = (memaddr - rsp) / 4 + LR0_REGNUM;
      if (regnum < LR0_REGNUM || regnum > LR0_REGNUM + 127)
	error ("Attempt to read register stack out of range.");
      if (myaddr != NULL)
	write_register (regnum, *(long *) myaddr);
      if (actual_mem_addr != NULL)
	*actual_mem_addr = 0;
    }
  else
    {
      /* It's in the memory portion of the register stack.  */
      if (myaddr != NULL)
	write_memory (memaddr, myaddr, 4);
      if (actual_mem_addr != NULL)
	*actual_mem_addr = memaddr;
    }
}

/* Find register number REGNUM relative to FRAME and put its
   (raw) contents in *RAW_BUFFER.  Set *OPTIMIZED if the variable
   was optimized out (and thus can't be fetched).  If the variable
   was fetched from memory, set *ADDRP to where it was fetched from,
   otherwise it was fetched from a register.

   The argument RAW_BUFFER must point to aligned memory.  */

void
a29k_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lvalp)
     char *raw_buffer;
     int *optimized;
     CORE_ADDR *addrp;
     struct frame_info *frame;
     int regnum;
     enum lval_type *lvalp;
{
  struct frame_info *fi;
  CORE_ADDR addr;
  enum lval_type lval;

  if (!target_has_registers)
    error ("No registers.");

  /* Probably now redundant with the target_has_registers check.  */
  if (frame == 0)
    return;

  /* Once something has a register number, it doesn't get optimized out.  */
  if (optimized != NULL)
    *optimized = 0;
  if (regnum == RSP_REGNUM)
    {
      if (raw_buffer != NULL)
	{
	  store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), frame->frame);
	}
      if (lvalp != NULL)
	*lvalp = not_lval;
      return;
    }
  else if (regnum == PC_REGNUM && frame->next != NULL)
    {
      if (raw_buffer != NULL)
	{
	  store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), frame->pc);
	}

      /* Not sure we have to do this.  */
      if (lvalp != NULL)
	*lvalp = not_lval;

      return;
    }
  else if (regnum == MSP_REGNUM)
    {
      if (raw_buffer != NULL)
	{
	  if (frame->next != NULL)
	    {
	      store_address (raw_buffer, REGISTER_RAW_SIZE (regnum),
			     frame->next->saved_msp);
	    }
	  else
	    read_register_gen (MSP_REGNUM, raw_buffer);
	}
      /* The value may have been computed, not fetched.  */
      if (lvalp != NULL)
	*lvalp = not_lval;
      return;
    }
  else if (regnum < LR0_REGNUM || regnum >= LR0_REGNUM + 128)
    {
      /* These registers are not saved over procedure calls,
         so just print out the current values.  */
      if (raw_buffer != NULL)
	read_register_gen (regnum, raw_buffer);
      if (lvalp != NULL)
	*lvalp = lval_register;
      if (addrp != NULL)
	*addrp = REGISTER_BYTE (regnum);
      return;
    }

  addr = frame->frame + (regnum - LR0_REGNUM) * 4;
  if (raw_buffer != NULL)
    read_register_stack (addr, raw_buffer, &addr, &lval);
  if (lvalp != NULL)
    *lvalp = lval;
  if (addrp != NULL)
    *addrp = addr;
}


/* Discard from the stack the innermost frame,
   restoring all saved registers.  */

void
pop_frame ()
{
  struct frame_info *frame = get_current_frame ();
  CORE_ADDR rfb = read_register (RFB_REGNUM);
  CORE_ADDR gr1 = frame->frame + frame->rsize;
  CORE_ADDR lr1;
  CORE_ADDR original_lr0;
  int must_fix_lr0 = 0;
  int i;

  /* If popping a dummy frame, need to restore registers.  */
  if (PC_IN_CALL_DUMMY (read_register (PC_REGNUM),
			read_register (SP_REGNUM),
			FRAME_FP (frame)))
    {
      int lrnum = LR0_REGNUM + DUMMY_ARG / 4;
      for (i = 0; i < DUMMY_SAVE_SR128; ++i)
	write_register (SR_REGNUM (i + 128), read_register (lrnum++));
      for (i = 0; i < DUMMY_SAVE_SR160; ++i)
	write_register (SR_REGNUM (i + 160), read_register (lrnum++));
      for (i = 0; i < DUMMY_SAVE_GREGS; ++i)
	write_register (RETURN_REGNUM + i, read_register (lrnum++));
      /* Restore the PCs and prepare to restore LR0.  */
      write_register (PC_REGNUM, read_register (lrnum++));
      write_register (NPC_REGNUM, read_register (lrnum++));
      write_register (PC2_REGNUM, read_register (lrnum++));
      original_lr0 = read_register (lrnum++);
      must_fix_lr0 = 1;
    }

  /* Restore the memory stack pointer.  */
  write_register (MSP_REGNUM, frame->saved_msp);
  /* Restore the register stack pointer.  */
  write_register (GR1_REGNUM, gr1);

  /* If we popped a dummy frame, restore lr0 now that gr1 has been restored. */
  if (must_fix_lr0)
    write_register (LR0_REGNUM, original_lr0);

  /* Check whether we need to fill registers.  */
  lr1 = read_register (LR0_REGNUM + 1);
  if (lr1 > rfb)
    {
      /* Fill.  */
      int num_bytes = lr1 - rfb;
      int i;
      long word;

      write_register (RAB_REGNUM, read_register (RAB_REGNUM) + num_bytes);
      write_register (RFB_REGNUM, lr1);
      for (i = 0; i < num_bytes; i += 4)
	{
	  /* Note: word is in host byte order.  */
	  word = read_memory_integer (rfb + i, 4);
	  write_register (LR0_REGNUM + ((rfb - gr1) % 0x80) + i / 4, word);
	}
    }
  flush_cached_frames ();
}

/* Push an empty stack frame, to record the current PC, etc.  */

void
push_dummy_frame ()
{
  long w;
  CORE_ADDR rab, gr1;
  CORE_ADDR msp = read_register (MSP_REGNUM);
  int lrnum, i;
  CORE_ADDR original_lr0;

  /* Read original lr0 before changing gr1.  This order isn't really needed
     since GDB happens to have a snapshot of all the regs and doesn't toss
     it when gr1 is changed.  But it's The Right Thing To Do.  */
  original_lr0 = read_register (LR0_REGNUM);

  /* Allocate the new frame. */
  gr1 = read_register (GR1_REGNUM) - DUMMY_FRAME_RSIZE;
  write_register (GR1_REGNUM, gr1);

#ifdef VXWORKS_TARGET
  /* We force re-reading all registers to get the new local registers set
     after gr1 has been modified. This fix is due to the lack of single
     register read/write operation in the RPC interface between VxGDB and
     VxWorks. This really must be changed ! */

  vx_read_register (-1);

#endif /* VXWORK_TARGET */

  rab = read_register (RAB_REGNUM);
  if (gr1 < rab)
    {
      /* We need to spill registers.  */
      int num_bytes = rab - gr1;
      CORE_ADDR rfb = read_register (RFB_REGNUM);
      int i;
      long word;

      write_register (RFB_REGNUM, rfb - num_bytes);
      write_register (RAB_REGNUM, gr1);
      for (i = 0; i < num_bytes; i += 4)
	{
	  /* Note:  word is in target byte order.  */
	  read_register_gen (LR0_REGNUM + i / 4, (char *) &word);
	  write_memory (rfb - num_bytes + i, (char *) &word, 4);
	}
    }

  /* There are no arguments in to the dummy frame, so we don't need
     more than rsize plus the return address and lr1.  */
  write_register (LR0_REGNUM + 1, gr1 + DUMMY_FRAME_RSIZE + 2 * 4);

  /* Set the memory frame pointer.  */
  write_register (LR0_REGNUM + DUMMY_FRAME_RSIZE / 4 - 1, msp);

  /* Allocate arg_slop.  */
  write_register (MSP_REGNUM, msp - 16 * 4);

  /* Save registers.  */
  lrnum = LR0_REGNUM + DUMMY_ARG / 4;
  for (i = 0; i < DUMMY_SAVE_SR128; ++i)
    write_register (lrnum++, read_register (SR_REGNUM (i + 128)));
  for (i = 0; i < DUMMY_SAVE_SR160; ++i)
    write_register (lrnum++, read_register (SR_REGNUM (i + 160)));
  for (i = 0; i < DUMMY_SAVE_GREGS; ++i)
    write_register (lrnum++, read_register (RETURN_REGNUM + i));
  /* Save the PCs and LR0.  */
  write_register (lrnum++, read_register (PC_REGNUM));
  write_register (lrnum++, read_register (NPC_REGNUM));
  write_register (lrnum++, read_register (PC2_REGNUM));

  /* Why are we saving LR0?  What would clobber it? (the dummy frame should
     be below it on the register stack, no?).  */
  write_register (lrnum++, original_lr0);
}



/*
   This routine takes three arguments and makes the cached frames look
   as if these arguments defined a frame on the cache.  This allows the
   rest of `info frame' to extract the important arguments without much
   difficulty.  Since an individual frame on the 29K is determined by
   three values (FP, PC, and MSP), we really need all three to do a
   good job.  */

struct frame_info *
setup_arbitrary_frame (argc, argv)
     int argc;
     CORE_ADDR *argv;
{
  struct frame_info *frame;

  if (argc != 3)
    error ("AMD 29k frame specifications require three arguments: rsp pc msp");

  frame = create_new_frame (argv[0], argv[1]);

  if (!frame)
    internal_error ("create_new_frame returned invalid frame id");

  /* Creating a new frame munges the `frame' value from the current
     GR1, so we restore it again here.  FIXME, untangle all this
     29K frame stuff...  */
  frame->frame = argv[0];

  /* Our MSP is in argv[2].  It'd be intelligent if we could just
     save this value in the FRAME.  But the way it's set up (FIXME),
     we must save our caller's MSP.  We compute that by adding our
     memory stack frame size to our MSP.  */
  frame->saved_msp = argv[2] + frame->msize;

  return frame;
}

int
gdb_print_insn_a29k (memaddr, info)
     bfd_vma memaddr;
     disassemble_info *info;
{
  if (TARGET_BYTE_ORDER == BIG_ENDIAN)
    return print_insn_big_a29k (memaddr, info);
  else
    return print_insn_little_a29k (memaddr, info);
}

enum a29k_processor_types processor_type = a29k_unknown;

void
a29k_get_processor_type ()
{
  unsigned int cfg_reg = (unsigned int) read_register (CFG_REGNUM);

  /* Most of these don't have freeze mode.  */
  processor_type = a29k_no_freeze_mode;

  switch ((cfg_reg >> 28) & 0xf)
    {
    case 0:
      fprintf_filtered (gdb_stderr, "Remote debugging an Am29000");
      break;
    case 1:
      fprintf_filtered (gdb_stderr, "Remote debugging an Am29005");
      break;
    case 2:
      fprintf_filtered (gdb_stderr, "Remote debugging an Am29050");
      processor_type = a29k_freeze_mode;
      break;
    case 3:
      fprintf_filtered (gdb_stderr, "Remote debugging an Am29035");
      break;
    case 4:
      fprintf_filtered (gdb_stderr, "Remote debugging an Am29030");
      break;
    case 5:
      fprintf_filtered (gdb_stderr, "Remote debugging an Am2920*");
      break;
    case 6:
      fprintf_filtered (gdb_stderr, "Remote debugging an Am2924*");
      break;
    case 7:
      fprintf_filtered (gdb_stderr, "Remote debugging an Am29040");
      break;
    default:
      fprintf_filtered (gdb_stderr, "Remote debugging an unknown Am29k\n");
      /* Don't bother to print the revision.  */
      return;
    }
  fprintf_filtered (gdb_stderr, " revision %c\n", 'A' + ((cfg_reg >> 24) & 0x0f));
}

#ifdef GET_LONGJMP_TARGET
/* Figure out where the longjmp will land.  We expect that we have just entered
   longjmp and haven't yet setup the stack frame, so the args are still in the
   output regs.  lr2 (LR2_REGNUM) points at the jmp_buf structure from which we
   extract the pc (JB_PC) that we will land at.  The pc is copied into ADDR.
   This routine returns true on success */

int
get_longjmp_target (pc)
     CORE_ADDR *pc;
{
  CORE_ADDR jb_addr;
  char buf[sizeof (CORE_ADDR)];

  jb_addr = read_register (LR2_REGNUM);

  if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, (char *) buf,
			  sizeof (CORE_ADDR)))
    return 0;

  *pc = extract_address ((PTR) buf, sizeof (CORE_ADDR));
  return 1;
}
#endif /* GET_LONGJMP_TARGET */

void
_initialize_a29k_tdep ()
{
  extern CORE_ADDR text_end;

  tm_print_insn = gdb_print_insn_a29k;

  /* FIXME, there should be a way to make a CORE_ADDR variable settable. */
  add_show_from_set
    (add_set_cmd ("rstack_high_address", class_support, var_uinteger,
		  (char *) &rstack_high_address,
		  "Set top address in memory of the register stack.\n\
Attempts to access registers saved above this address will be ignored\n\
or will produce the value -1.", &setlist),
     &showlist);

  /* FIXME, there should be a way to make a CORE_ADDR variable settable. */
  add_show_from_set
    (add_set_cmd ("call_scratch_address", class_support, var_uinteger,
		  (char *) &text_end,
		  "Set address in memory where small amounts of RAM can be used\n\
when making function calls into the inferior.", &setlist),
     &showlist);
}
