/* Target-dependent code for the Xtensa port of GDB, the GNU debugger.

   Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009, 2010
   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 "frame.h"
#include "solib-svr4.h"
#include "symtab.h"
#include "symfile.h"
#include "objfiles.h"
#include "gdbtypes.h"
#include "gdbcore.h"
#include "value.h"
#include "dis-asm.h"
#include "inferior.h"
#include "floatformat.h"
#include "regcache.h"
#include "reggroups.h"
#include "regset.h"

#include "dummy-frame.h"
#include "dwarf2.h"
#include "dwarf2-frame.h"
#include "dwarf2loc.h"
#include "frame.h"
#include "frame-base.h"
#include "frame-unwind.h"

#include "arch-utils.h"
#include "gdbarch.h"
#include "remote.h"
#include "serial.h"

#include "command.h"
#include "gdbcmd.h"
#include "gdb_assert.h"

#include "xtensa-isa.h"
#include "xtensa-tdep.h"
#include "xtensa-config.h"


static int xtensa_debug_level = 0;

#define DEBUGWARN(args...) \
  if (xtensa_debug_level > 0) \
    fprintf_unfiltered (gdb_stdlog, "(warn ) " args)

#define DEBUGINFO(args...) \
  if (xtensa_debug_level > 1) \
    fprintf_unfiltered (gdb_stdlog, "(info ) " args)

#define DEBUGTRACE(args...) \
  if (xtensa_debug_level > 2) \
    fprintf_unfiltered (gdb_stdlog, "(trace) " args)

#define DEBUGVERB(args...) \
  if (xtensa_debug_level > 3) \
    fprintf_unfiltered (gdb_stdlog, "(verb ) " args)


/* According to the ABI, the SP must be aligned to 16-byte boundaries.  */
#define SP_ALIGNMENT 16


/* On Windowed ABI, we use a6 through a11 for passing arguments
   to a function called by GDB because CALL4 is used.  */
#define ARGS_NUM_REGS		6
#define REGISTER_SIZE		4


/* Extract the call size from the return address or PS register.  */
#define PS_CALLINC_SHIFT	16
#define PS_CALLINC_MASK		0x00030000
#define CALLINC(ps)		(((ps) & PS_CALLINC_MASK) >> PS_CALLINC_SHIFT)
#define WINSIZE(ra)		(4 * (( (ra) >> 30) & 0x3))

/* ABI-independent macros.  */
#define ARG_NOF(gdbarch) \
  (gdbarch_tdep (gdbarch)->call_abi \
   == CallAbiCall0Only ? C0_NARGS : (ARGS_NUM_REGS))
#define ARG_1ST(gdbarch) \
  (gdbarch_tdep (gdbarch)->call_abi  == CallAbiCall0Only \
   ? (gdbarch_tdep (gdbarch)->a0_base + C0_ARGS) \
   : (gdbarch_tdep (gdbarch)->a0_base + 6))

/* XTENSA_IS_ENTRY tests whether the first byte of an instruction
   indicates that the instruction is an ENTRY instruction.  */

#define XTENSA_IS_ENTRY(gdbarch, op1) \
  ((gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) \
   ? ((op1) == 0x6c) : ((op1) == 0x36))

#define XTENSA_ENTRY_LENGTH	3

/* windowing_enabled() returns true, if windowing is enabled.
   WOE must be set to 1; EXCM to 0.
   Note: We assume that EXCM is always 0 for XEA1.  */

#define PS_WOE			(1<<18)
#define PS_EXC			(1<<4)

/* Convert a live A-register number to the corresponding AR-register number.  */
static int
arreg_number (struct gdbarch *gdbarch, int a_regnum, ULONGEST wb)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  int arreg;

  arreg = a_regnum - tdep->a0_base;
  arreg += (wb & ((tdep->num_aregs - 1) >> 2)) << WB_SHIFT;
  arreg &= tdep->num_aregs - 1;

  return arreg + tdep->ar_base;
}

/* Convert a live AR-register number to the corresponding A-register order
   number in a range [0..15].  Return -1, if AR_REGNUM is out of WB window.  */
static int
areg_number (struct gdbarch *gdbarch, int ar_regnum, unsigned int wb)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  int areg;

  areg = ar_regnum - tdep->ar_base;
  if (areg < 0 || areg >= tdep->num_aregs)
    return -1;
  areg = (areg - wb * 4) & (tdep->num_aregs - 1);
  return (areg > 15) ? -1 : areg;
}

static inline int
windowing_enabled (CORE_ADDR ps)
{
  return ((ps & PS_EXC) == 0 && (ps & PS_WOE) != 0);
}

/* Return the window size of the previous call to the function from which we
   have just returned.

   This function is used to extract the return value after a called function
   has returned to the caller.  On Xtensa, the register that holds the return
   value (from the perspective of the caller) depends on what call
   instruction was used.  For now, we are assuming that the call instruction
   precedes the current address, so we simply analyze the call instruction.
   If we are in a dummy frame, we simply return 4 as we used a 'pseudo-call4'
   method to call the inferior function.  */

static int
extract_call_winsize (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int winsize = 4;
  int insn;
  gdb_byte buf[4];

  DEBUGTRACE ("extract_call_winsize (pc = 0x%08x)\n", (int) pc);

  /* Read the previous instruction (should be a call[x]{4|8|12}.  */
  read_memory (pc-3, buf, 3);
  insn = extract_unsigned_integer (buf, 3, byte_order);

  /* Decode call instruction:
     Little Endian
       call{0,4,8,12}   OFFSET || {00,01,10,11} || 0101
       callx{0,4,8,12}  OFFSET || 11 || {00,01,10,11} || 0000
     Big Endian
       call{0,4,8,12}   0101 || {00,01,10,11} || OFFSET
       callx{0,4,8,12}  0000 || {00,01,10,11} || 11 || OFFSET.  */

  if (byte_order == BFD_ENDIAN_LITTLE)
    {
      if (((insn & 0xf) == 0x5) || ((insn & 0xcf) == 0xc0))
	winsize = (insn & 0x30) >> 2;   /* 0, 4, 8, 12.  */
    }
  else
    {
      if (((insn >> 20) == 0x5) || (((insn >> 16) & 0xf3) == 0x03))
	winsize = (insn >> 16) & 0xc;   /* 0, 4, 8, 12.  */
    }
  return winsize;
}


/* REGISTER INFORMATION */

/* Returns the name of a register.  */
static const char *
xtensa_register_name (struct gdbarch *gdbarch, int regnum)
{
  /* Return the name stored in the register map.  */
  if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch)
			      + gdbarch_num_pseudo_regs (gdbarch))
    return gdbarch_tdep (gdbarch)->regmap[regnum].name;

  internal_error (__FILE__, __LINE__, _("invalid register %d"), regnum);
  return 0;
}

/* Return the type of a register.  Create a new type, if necessary.  */

static struct type *
xtensa_register_type (struct gdbarch *gdbarch, int regnum)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  /* Return signed integer for ARx and Ax registers.  */
  if ((regnum >= tdep->ar_base
       && regnum < tdep->ar_base + tdep->num_aregs)
      || (regnum >= tdep->a0_base
	  && regnum < tdep->a0_base + 16))
    return builtin_type (gdbarch)->builtin_int;

  if (regnum == gdbarch_pc_regnum (gdbarch)
      || regnum == tdep->a0_base + 1)
    return builtin_type (gdbarch)->builtin_data_ptr;

  /* Return the stored type for all other registers.  */
  else if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch)
				   + gdbarch_num_pseudo_regs (gdbarch))
    {
      xtensa_register_t* reg = &tdep->regmap[regnum];

      /* Set ctype for this register (only the first time).  */

      if (reg->ctype == 0)
	{
	  struct ctype_cache *tp;
	  int size = reg->byte_size;

	  /* We always use the memory representation,
	     even if the register width is smaller.  */
	  switch (size)
	    {
	    case 1:
	      reg->ctype = builtin_type (gdbarch)->builtin_uint8;
	      break;

	    case 2:
	      reg->ctype = builtin_type (gdbarch)->builtin_uint16;
	      break;

	    case 4:
	      reg->ctype = builtin_type (gdbarch)->builtin_uint32;
	      break;

	    case 8:
	      reg->ctype = builtin_type (gdbarch)->builtin_uint64;
	      break;

	    case 16:
	      reg->ctype = builtin_type (gdbarch)->builtin_uint128;
	      break;

	    default:
	      for (tp = tdep->type_entries; tp != NULL; tp = tp->next)
		if (tp->size == size)
		  break;

	      if (tp == NULL)
		{
		  char *name = xmalloc (16);
		  tp = xmalloc (sizeof (struct ctype_cache));
		  tp->next = tdep->type_entries;
		  tdep->type_entries = tp;
		  tp->size = size;

		  sprintf (name, "int%d", size * 8);
		  tp->virtual_type
		    = arch_integer_type (gdbarch, size * 8, 1, xstrdup (name));
		}

	      reg->ctype = tp->virtual_type;
	    }
	}
      return reg->ctype;
    }

  internal_error (__FILE__, __LINE__, _("invalid register number %d"), regnum);
  return 0;
}


/* Return the 'local' register number for stubs, dwarf2, etc.
   The debugging information enumerates registers starting from 0 for A0
   to n for An.  So, we only have to add the base number for A0.  */

static int
xtensa_reg_to_regnum (struct gdbarch *gdbarch, int regnum)
{
  int i;

  if (regnum >= 0 && regnum < 16)
    return gdbarch_tdep (gdbarch)->a0_base + regnum;

  for (i = 0;
       i < gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
       i++)
    if (regnum == gdbarch_tdep (gdbarch)->regmap[i].target_number)
      return i;

  internal_error (__FILE__, __LINE__,
		  _("invalid dwarf/stabs register number %d"), regnum);
  return 0;
}


/* Write the bits of a masked register to the various registers.
   Only the masked areas of these registers are modified; the other
   fields are untouched.  The size of masked registers is always less
   than or equal to 32 bits.  */

static void
xtensa_register_write_masked (struct regcache *regcache,
			      xtensa_register_t *reg, const gdb_byte *buffer)
{
  unsigned int value[(MAX_REGISTER_SIZE + 3) / 4];
  const xtensa_mask_t *mask = reg->mask;

  int shift = 0;		/* Shift for next mask (mod 32).  */
  int start, size;		/* Start bit and size of current mask.  */

  unsigned int *ptr = value;
  unsigned int regval, m, mem = 0;

  int bytesize = reg->byte_size;
  int bitsize = bytesize * 8;
  int i, r;

  DEBUGTRACE ("xtensa_register_write_masked ()\n");

  /* Copy the masked register to host byte-order.  */
  if (gdbarch_byte_order (get_regcache_arch (regcache)) == BFD_ENDIAN_BIG)
    for (i = 0; i < bytesize; i++)
      {
	mem >>= 8;
	mem |= (buffer[bytesize - i - 1] << 24);
	if ((i & 3) == 3)
	  *ptr++ = mem;
      }
  else
    for (i = 0; i < bytesize; i++)
      {
	mem >>= 8;
	mem |= (buffer[i] << 24);
	if ((i & 3) == 3)
	  *ptr++ = mem;
      }

  /* We might have to shift the final value:
     bytesize & 3 == 0 -> nothing to do, we use the full 32 bits,
     bytesize & 3 == x -> shift (4-x) * 8.  */

  *ptr = mem >> (((0 - bytesize) & 3) * 8);
  ptr = value;
  mem = *ptr;

  /* Write the bits to the masked areas of the other registers.  */
  for (i = 0; i < mask->count; i++)
    {
      start = mask->mask[i].bit_start;
      size = mask->mask[i].bit_size;
      regval = mem >> shift;

      if ((shift += size) > bitsize)
	error (_("size of all masks is larger than the register"));

      if (shift >= 32)
	{
	  mem = *(++ptr);
	  shift -= 32;
	  bitsize -= 32;

	  if (shift > 0)
	    regval |= mem << (size - shift);
	}

      /* Make sure we have a valid register.  */
      r = mask->mask[i].reg_num;
      if (r >= 0 && size > 0)
	{
	  /* Don't overwrite the unmasked areas.  */
	  ULONGEST old_val;
	  regcache_cooked_read_unsigned (regcache, r, &old_val);
	  m = 0xffffffff >> (32 - size) << start;
	  regval <<= start;
	  regval = (regval & m) | (old_val & ~m);
	  regcache_cooked_write_unsigned (regcache, r, regval);
	}
    }
}


/* Read a tie state or mapped registers.  Read the masked areas
   of the registers and assemble them into a single value.  */

static void
xtensa_register_read_masked (struct regcache *regcache,
			     xtensa_register_t *reg, gdb_byte *buffer)
{
  unsigned int value[(MAX_REGISTER_SIZE + 3) / 4];
  const xtensa_mask_t *mask = reg->mask;

  int shift = 0;
  int start, size;

  unsigned int *ptr = value;
  unsigned int regval, mem = 0;

  int bytesize = reg->byte_size;
  int bitsize = bytesize * 8;
  int i;

  DEBUGTRACE ("xtensa_register_read_masked (reg \"%s\", ...)\n",
	      reg->name == 0 ? "" : reg->name);

  /* Assemble the register from the masked areas of other registers.  */
  for (i = 0; i < mask->count; i++)
    {
      int r = mask->mask[i].reg_num;
      if (r >= 0)
	{
	  ULONGEST val;
	  regcache_cooked_read_unsigned (regcache, r, &val);
	  regval = (unsigned int) val;
	}
      else
	regval = 0;

      start = mask->mask[i].bit_start;
      size = mask->mask[i].bit_size;

      regval >>= start;

      if (size < 32)
	regval &= (0xffffffff >> (32 - size));

      mem |= regval << shift;

      if ((shift += size) > bitsize)
	error (_("size of all masks is larger than the register"));

      if (shift >= 32)
	{
	  *ptr++ = mem;
	  bitsize -= 32;
	  shift -= 32;

	  if (shift == 0)
	    mem = 0;
	  else
	    mem = regval >> (size - shift);
	}
    }

  if (shift > 0)
    *ptr = mem;

  /* Copy value to target byte order.  */
  ptr = value;
  mem = *ptr;

  if (gdbarch_byte_order (get_regcache_arch (regcache)) == BFD_ENDIAN_BIG)
    for (i = 0; i < bytesize; i++)
      {
	if ((i & 3) == 0)
	  mem = *ptr++;
	buffer[bytesize - i - 1] = mem & 0xff;
	mem >>= 8;
      }
  else
    for (i = 0; i < bytesize; i++)
      {
	if ((i & 3) == 0)
	  mem = *ptr++;
	buffer[i] = mem & 0xff;
	mem >>= 8;
      }
}


/* Read pseudo registers.  */

static void
xtensa_pseudo_register_read (struct gdbarch *gdbarch,
			     struct regcache *regcache,
			     int regnum,
			     gdb_byte *buffer)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  DEBUGTRACE ("xtensa_pseudo_register_read (... regnum = %d (%s) ...)\n",
	      regnum, xtensa_register_name (gdbarch, regnum));

  if (regnum == gdbarch_num_regs (gdbarch)
		+ gdbarch_num_pseudo_regs (gdbarch) - 1)
     regnum = gdbarch_tdep (gdbarch)->a0_base + 1;

  /* Read aliases a0..a15, if this is a Windowed ABI.  */
  if (gdbarch_tdep (gdbarch)->isa_use_windowed_registers
      && (regnum >= gdbarch_tdep (gdbarch)->a0_base)
      && (regnum <= gdbarch_tdep (gdbarch)->a0_base + 15))
    {
      gdb_byte *buf = (gdb_byte *) alloca (MAX_REGISTER_SIZE);

      regcache_raw_read (regcache, gdbarch_tdep (gdbarch)->wb_regnum, buf);
      regnum = arreg_number (gdbarch, regnum,
			     extract_unsigned_integer (buf, 4, byte_order));
    }

  /* We can always read non-pseudo registers.  */
  if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch))
    regcache_raw_read (regcache, regnum, buffer);


  /* We have to find out how to deal with priveleged registers.
     Let's treat them as pseudo-registers, but we cannot read/write them.  */
     
  else if (regnum < gdbarch_tdep (gdbarch)->a0_base)
    {
      buffer[0] = (gdb_byte)0;
      buffer[1] = (gdb_byte)0;
      buffer[2] = (gdb_byte)0;
      buffer[3] = (gdb_byte)0;
    }
  /* Pseudo registers.  */
  else if (regnum >= 0
	    && regnum < gdbarch_num_regs (gdbarch)
			+ gdbarch_num_pseudo_regs (gdbarch))
    {
      xtensa_register_t *reg = &gdbarch_tdep (gdbarch)->regmap[regnum];
      xtensa_register_type_t type = reg->type;
      int flags = gdbarch_tdep (gdbarch)->target_flags;

      /* We cannot read Unknown or Unmapped registers.  */
      if (type == xtRegisterTypeUnmapped || type == xtRegisterTypeUnknown)
	{
	  if ((flags & xtTargetFlagsNonVisibleRegs) == 0)
	    {
	      warning (_("cannot read register %s"),
		       xtensa_register_name (gdbarch, regnum));
	      return;
	    }
	}

      /* Some targets cannot read TIE register files.  */
      else if (type == xtRegisterTypeTieRegfile)
        {
	  /* Use 'fetch' to get register?  */
	  if (flags & xtTargetFlagsUseFetchStore)
	    {
	      warning (_("cannot read register"));
	      return;
	    }

	  /* On some targets (esp. simulators), we can always read the reg.  */
	  else if ((flags & xtTargetFlagsNonVisibleRegs) == 0)
	    {
	      warning (_("cannot read register"));
	      return;
	    }
	}

      /* We can always read mapped registers.  */
      else if (type == xtRegisterTypeMapped || type == xtRegisterTypeTieState)
        {
	  xtensa_register_read_masked (regcache, reg, buffer);
	  return;
	}

      /* Assume that we can read the register.  */
      regcache_raw_read (regcache, regnum, buffer);
    }
  else
    internal_error (__FILE__, __LINE__,
		    _("invalid register number %d"), regnum);
}


/* Write pseudo registers.  */

static void
xtensa_pseudo_register_write (struct gdbarch *gdbarch,
			      struct regcache *regcache,
			      int regnum,
			      const gdb_byte *buffer)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  DEBUGTRACE ("xtensa_pseudo_register_write (... regnum = %d (%s) ...)\n",
	      regnum, xtensa_register_name (gdbarch, regnum));

  if (regnum == gdbarch_num_regs (gdbarch)
		+ gdbarch_num_pseudo_regs (gdbarch) -1)
     regnum = gdbarch_tdep (gdbarch)->a0_base + 1;

  /* Renumber register, if aliase a0..a15 on Windowed ABI.  */
  if (gdbarch_tdep (gdbarch)->isa_use_windowed_registers
      && (regnum >= gdbarch_tdep (gdbarch)->a0_base)
      && (regnum <= gdbarch_tdep (gdbarch)->a0_base + 15))
    {
      gdb_byte *buf = (gdb_byte *) alloca (MAX_REGISTER_SIZE);
      unsigned int wb;

      regcache_raw_read (regcache,
			 gdbarch_tdep (gdbarch)->wb_regnum, buf);
      regnum = arreg_number (gdbarch, regnum,
			     extract_unsigned_integer (buf, 4, byte_order));
    }

  /* We can always write 'core' registers.
     Note: We might have converted Ax->ARy.  */
  if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch))
    regcache_raw_write (regcache, regnum, buffer);

  /* We have to find out how to deal with priveleged registers.
     Let's treat them as pseudo-registers, but we cannot read/write them.  */

  else if (regnum < gdbarch_tdep (gdbarch)->a0_base)
    {
      return;
    }
  /* Pseudo registers.  */
  else if (regnum >= 0
	   && regnum < gdbarch_num_regs (gdbarch)
		       + gdbarch_num_pseudo_regs (gdbarch))
    {
      xtensa_register_t *reg = &gdbarch_tdep (gdbarch)->regmap[regnum];
      xtensa_register_type_t type = reg->type;
      int flags = gdbarch_tdep (gdbarch)->target_flags;

      /* On most targets, we cannot write registers
	 of type "Unknown" or "Unmapped".  */
      if (type == xtRegisterTypeUnmapped || type == xtRegisterTypeUnknown)
        {
	  if ((flags & xtTargetFlagsNonVisibleRegs) == 0)
	    {
	      warning (_("cannot write register %s"),
		       xtensa_register_name (gdbarch, regnum));
	      return;
	    }
	}

      /* Some targets cannot read TIE register files.  */
      else if (type == xtRegisterTypeTieRegfile)
        {
	  /* Use 'store' to get register?  */
	  if (flags & xtTargetFlagsUseFetchStore)
	    {
	      warning (_("cannot write register"));
	      return;
	    }

	  /* On some targets (esp. simulators), we can always write
	     the register.  */
	  else if ((flags & xtTargetFlagsNonVisibleRegs) == 0)
	    {
	      warning (_("cannot write register"));
	      return;
	    }
	}

      /* We can always write mapped registers.  */
      else if (type == xtRegisterTypeMapped || type == xtRegisterTypeTieState)
        {
	  xtensa_register_write_masked (regcache, reg, buffer);
	  return;
	}

      /* Assume that we can write the register.  */
      regcache_raw_write (regcache, regnum, buffer);
    }
  else
    internal_error (__FILE__, __LINE__,
		    _("invalid register number %d"), regnum);
}

static struct reggroup *xtensa_ar_reggroup;
static struct reggroup *xtensa_user_reggroup;
static struct reggroup *xtensa_vectra_reggroup;
static struct reggroup *xtensa_cp[XTENSA_MAX_COPROCESSOR];

static void
xtensa_init_reggroups (void)
{
  xtensa_ar_reggroup = reggroup_new ("ar", USER_REGGROUP);
  xtensa_user_reggroup = reggroup_new ("user", USER_REGGROUP);
  xtensa_vectra_reggroup = reggroup_new ("vectra", USER_REGGROUP);

  xtensa_cp[0] = reggroup_new ("cp0", USER_REGGROUP);
  xtensa_cp[1] = reggroup_new ("cp1", USER_REGGROUP);
  xtensa_cp[2] = reggroup_new ("cp2", USER_REGGROUP);
  xtensa_cp[3] = reggroup_new ("cp3", USER_REGGROUP);
  xtensa_cp[4] = reggroup_new ("cp4", USER_REGGROUP);
  xtensa_cp[5] = reggroup_new ("cp5", USER_REGGROUP);
  xtensa_cp[6] = reggroup_new ("cp6", USER_REGGROUP);
  xtensa_cp[7] = reggroup_new ("cp7", USER_REGGROUP);
}

static void
xtensa_add_reggroups (struct gdbarch *gdbarch)
{
  int i;

  /* Predefined groups.  */
  reggroup_add (gdbarch, all_reggroup);
  reggroup_add (gdbarch, save_reggroup);
  reggroup_add (gdbarch, restore_reggroup);
  reggroup_add (gdbarch, system_reggroup);
  reggroup_add (gdbarch, vector_reggroup);
  reggroup_add (gdbarch, general_reggroup);
  reggroup_add (gdbarch, float_reggroup);

  /* Xtensa-specific groups.  */
  reggroup_add (gdbarch, xtensa_ar_reggroup);
  reggroup_add (gdbarch, xtensa_user_reggroup);
  reggroup_add (gdbarch, xtensa_vectra_reggroup);

  for (i = 0; i < XTENSA_MAX_COPROCESSOR; i++)
    reggroup_add (gdbarch, xtensa_cp[i]);
}

static int 
xtensa_coprocessor_register_group (struct reggroup *group)
{
  int i;

  for (i = 0; i < XTENSA_MAX_COPROCESSOR; i++)
    if (group == xtensa_cp[i])
      return i;

  return -1;
}

#define SAVE_REST_FLAGS	(XTENSA_REGISTER_FLAGS_READABLE \
			| XTENSA_REGISTER_FLAGS_WRITABLE \
			| XTENSA_REGISTER_FLAGS_VOLATILE)

#define SAVE_REST_VALID	(XTENSA_REGISTER_FLAGS_READABLE \
			| XTENSA_REGISTER_FLAGS_WRITABLE)

static int
xtensa_register_reggroup_p (struct gdbarch *gdbarch,
			    int regnum,
    			    struct reggroup *group)
{
  xtensa_register_t* reg = &gdbarch_tdep (gdbarch)->regmap[regnum];
  xtensa_register_type_t type = reg->type;
  xtensa_register_group_t rg = reg->group;
  int cp_number;

  /* First, skip registers that are not visible to this target
     (unknown and unmapped registers when not using ISS).  */

  if (type == xtRegisterTypeUnmapped || type == xtRegisterTypeUnknown)
    return 0;
  if (group == all_reggroup)
    return 1;
  if (group == xtensa_ar_reggroup)
    return rg & xtRegisterGroupAddrReg;
  if (group == xtensa_user_reggroup)
    return rg & xtRegisterGroupUser;
  if (group == float_reggroup)
    return rg & xtRegisterGroupFloat;
  if (group == general_reggroup)
    return rg & xtRegisterGroupGeneral;
  if (group == float_reggroup)
    return rg & xtRegisterGroupFloat;
  if (group == system_reggroup)
    return rg & xtRegisterGroupState;
  if (group == vector_reggroup || group == xtensa_vectra_reggroup)
    return rg & xtRegisterGroupVectra;
  if (group == save_reggroup || group == restore_reggroup)
    return (regnum < gdbarch_num_regs (gdbarch)
	    && (reg->flags & SAVE_REST_FLAGS) == SAVE_REST_VALID);
  if ((cp_number = xtensa_coprocessor_register_group (group)) >= 0)
    return rg & (xtRegisterGroupCP0 << cp_number);
  else
    return 1;
}


/* Supply register REGNUM from the buffer specified by GREGS and LEN
   in the general-purpose register set REGSET to register cache
   REGCACHE.  If REGNUM is -1 do this for all registers in REGSET.  */

static void
xtensa_supply_gregset (const struct regset *regset,
		       struct regcache *rc,
		       int regnum,
		       const void *gregs,
		       size_t len)
{
  const xtensa_elf_gregset_t *regs = gregs;
  struct gdbarch *gdbarch = get_regcache_arch (rc);
  int i;

  DEBUGTRACE ("xtensa_supply_gregset (..., regnum==%d, ...)\n", regnum);

  if (regnum == gdbarch_pc_regnum (gdbarch) || regnum == -1)
    regcache_raw_supply (rc, gdbarch_pc_regnum (gdbarch), (char *) &regs->pc);
  if (regnum == gdbarch_ps_regnum (gdbarch) || regnum == -1)
    regcache_raw_supply (rc, gdbarch_ps_regnum (gdbarch), (char *) &regs->ps);
  if (regnum == gdbarch_tdep (gdbarch)->wb_regnum || regnum == -1)
    regcache_raw_supply (rc, gdbarch_tdep (gdbarch)->wb_regnum,
			 (char *) &regs->windowbase);
  if (regnum == gdbarch_tdep (gdbarch)->ws_regnum || regnum == -1)
    regcache_raw_supply (rc, gdbarch_tdep (gdbarch)->ws_regnum,
			 (char *) &regs->windowstart);
  if (regnum == gdbarch_tdep (gdbarch)->lbeg_regnum || regnum == -1)
    regcache_raw_supply (rc, gdbarch_tdep (gdbarch)->lbeg_regnum,
			 (char *) &regs->lbeg);
  if (regnum == gdbarch_tdep (gdbarch)->lend_regnum || regnum == -1)
    regcache_raw_supply (rc, gdbarch_tdep (gdbarch)->lend_regnum,
			 (char *) &regs->lend);
  if (regnum == gdbarch_tdep (gdbarch)->lcount_regnum || regnum == -1)
    regcache_raw_supply (rc, gdbarch_tdep (gdbarch)->lcount_regnum,
			 (char *) &regs->lcount);
  if (regnum == gdbarch_tdep (gdbarch)->sar_regnum || regnum == -1)
    regcache_raw_supply (rc, gdbarch_tdep (gdbarch)->sar_regnum,
			 (char *) &regs->sar);
  if (regnum >=gdbarch_tdep (gdbarch)->ar_base
      && regnum < gdbarch_tdep (gdbarch)->ar_base
		    + gdbarch_tdep (gdbarch)->num_aregs)
    regcache_raw_supply (rc, regnum,
			 (char *) &regs->ar[regnum - gdbarch_tdep
			   (gdbarch)->ar_base]);
  else if (regnum == -1)
    {
      for (i = 0; i < gdbarch_tdep (gdbarch)->num_aregs; ++i)
	regcache_raw_supply (rc, gdbarch_tdep (gdbarch)->ar_base + i,
			     (char *) &regs->ar[i]);
    }
}


/* Xtensa register set.  */

static struct regset
xtensa_gregset =
{
  NULL,
  xtensa_supply_gregset
};


/* Return the appropriate register set for the core
   section identified by SECT_NAME and SECT_SIZE.  */

static const struct regset *
xtensa_regset_from_core_section (struct gdbarch *core_arch,
				 const char *sect_name,
				 size_t sect_size)
{
  DEBUGTRACE ("xtensa_regset_from_core_section "
	      "(..., sect_name==\"%s\", sect_size==%x)\n",
	      sect_name, (unsigned int) sect_size);

  if (strcmp (sect_name, ".reg") == 0
      && sect_size >= sizeof(xtensa_elf_gregset_t))
    return &xtensa_gregset;

  return NULL;
}


/* Handling frames.  */

/* Number of registers to save in case of Windowed ABI.  */
#define XTENSA_NUM_SAVED_AREGS		12

/* Frame cache part for Windowed ABI.  */
typedef struct xtensa_windowed_frame_cache
{
  int wb;		/* WINDOWBASE of the previous frame.  */
  int callsize;		/* Call size of this frame.  */
  int ws;		/* WINDOWSTART of the previous frame.  It keeps track of
			   life windows only.  If there is no bit set for the
			   window, that means it had been already spilled
			   because of window overflow.  */

  /* Spilled A-registers from the previous frame.
     AREGS[i] == -1, if corresponding AR is alive.  */
  CORE_ADDR aregs[XTENSA_NUM_SAVED_AREGS];
} xtensa_windowed_frame_cache_t;

/* Call0 ABI Definitions.  */

#define C0_MAXOPDS  3	/* Maximum number of operands for prologue analysis.  */
#define C0_NREGS   16	/* Number of A-registers to track.  */
#define C0_CLESV   12	/* Callee-saved registers are here and up.  */
#define C0_SP	    1	/* Register used as SP.  */
#define C0_FP	   15	/* Register used as FP.  */
#define C0_RA	    0	/* Register used as return address.  */
#define C0_ARGS	    2	/* Register used as first arg/retval.  */
#define C0_NARGS    6	/* Number of A-regs for args/retvals.  */

/* Each element of xtensa_call0_frame_cache.c0_rt[] describes for each
   A-register where the current content of the reg came from (in terms
   of an original reg and a constant).  Negative values of c0_rt[n].fp_reg
   mean that the orignal content of the register was saved to the stack.
   c0_rt[n].fr.ofs is NOT the offset from the frame base because we don't 
   know where SP will end up until the entire prologue has been analyzed.  */

#define C0_CONST   -1	/* fr_reg value if register contains a constant.  */
#define C0_INEXP   -2	/* fr_reg value if inexpressible as reg + offset.  */
#define C0_NOSTK   -1	/* to_stk value if register has not been stored.  */

extern xtensa_isa xtensa_default_isa;

typedef struct xtensa_c0reg
{
    int	    fr_reg;	/* original register from which register content
			   is derived, or C0_CONST, or C0_INEXP.  */
    int	    fr_ofs;	/* constant offset from reg, or immediate value.  */
    int	    to_stk;	/* offset from original SP to register (4-byte aligned),
			   or C0_NOSTK if register has not been saved.  */
} xtensa_c0reg_t;


/* Frame cache part for Call0 ABI.  */
typedef struct xtensa_call0_frame_cache
{
  int c0_frmsz;				/* Stack frame size.  */
  int c0_hasfp;				/* Current frame uses frame pointer.  */
  int fp_regnum;			/* A-register used as FP.  */
  int c0_fp;				/* Actual value of frame pointer.  */
  xtensa_c0reg_t c0_rt[C0_NREGS];	/* Register tracking information.  */
} xtensa_call0_frame_cache_t;

typedef struct xtensa_frame_cache
{
  CORE_ADDR base;	/* Stack pointer of this frame.  */
  CORE_ADDR pc;		/* PC at the entry point to the function.  */
  CORE_ADDR ra;		/* The raw return address (without CALLINC).  */
  CORE_ADDR ps;		/* The PS register of this frame.  */
  CORE_ADDR prev_sp;	/* Stack Pointer of the previous frame.  */
  int call0;		/* It's a call0 framework (else windowed).  */
  union
    {
      xtensa_windowed_frame_cache_t	wd;	/* call0 == false.  */
      xtensa_call0_frame_cache_t       	c0;	/* call0 == true.  */
    };
} xtensa_frame_cache_t;


static struct xtensa_frame_cache *
xtensa_alloc_frame_cache (int windowed)
{
  xtensa_frame_cache_t *cache;
  int i;

  DEBUGTRACE ("xtensa_alloc_frame_cache ()\n");

  cache = FRAME_OBSTACK_ZALLOC (xtensa_frame_cache_t);

  cache->base = 0;
  cache->pc = 0;
  cache->ra = 0;
  cache->ps = 0;
  cache->prev_sp = 0;
  cache->call0 = !windowed;
  if (cache->call0)
    {
      cache->c0.c0_frmsz  = -1;
      cache->c0.c0_hasfp  =  0;
      cache->c0.fp_regnum = -1;
      cache->c0.c0_fp     = -1;

      for (i = 0; i < C0_NREGS; i++)
	{
	  cache->c0.c0_rt[i].fr_reg = i;
	  cache->c0.c0_rt[i].fr_ofs = 0;
	  cache->c0.c0_rt[i].to_stk = C0_NOSTK;
	}
    }
  else
    {
      cache->wd.wb = 0;
      cache->wd.ws = 0;
      cache->wd.callsize = -1;

      for (i = 0; i < XTENSA_NUM_SAVED_AREGS; i++)
	cache->wd.aregs[i] = -1;
    }
  return cache;
}


static CORE_ADDR
xtensa_frame_align (struct gdbarch *gdbarch, CORE_ADDR address)
{
  return address & ~15;
}


static CORE_ADDR
xtensa_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
  gdb_byte buf[8];
  CORE_ADDR pc;

  DEBUGTRACE ("xtensa_unwind_pc (next_frame = %s)\n", 
		host_address_to_string (next_frame));

  frame_unwind_register (next_frame, gdbarch_pc_regnum (gdbarch), buf);
  pc = extract_typed_address (buf, builtin_type (gdbarch)->builtin_func_ptr);

  DEBUGINFO ("[xtensa_unwind_pc] pc = 0x%08x\n", (unsigned int) pc);

  return pc;
}


static struct frame_id
xtensa_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
{
  CORE_ADDR pc, fp;

  /* THIS-FRAME is a dummy frame.  Return a frame ID of that frame.  */

  pc = get_frame_pc (this_frame);
  fp = get_frame_register_unsigned
	 (this_frame, gdbarch_tdep (gdbarch)->a0_base + 1);

  /* Make dummy frame ID unique by adding a constant.  */
  return frame_id_build (fp + SP_ALIGNMENT, pc);
}

/* Returns the best guess about which register is a frame pointer
   for the function containing CURRENT_PC.  */

#define XTENSA_ISA_BSZ		32		/* Instruction buffer size.  */
#define XTENSA_ISA_BADPC	((CORE_ADDR)0)	/* Bad PC value.  */

static unsigned int
xtensa_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR current_pc)
{
#define RETURN_FP goto done

  unsigned int fp_regnum = gdbarch_tdep (gdbarch)->a0_base + 1;
  CORE_ADDR start_addr;
  xtensa_isa isa;
  xtensa_insnbuf ins, slot;
  char ibuf[XTENSA_ISA_BSZ];
  CORE_ADDR ia, bt, ba;
  xtensa_format ifmt;
  int ilen, islots, is;
  xtensa_opcode opc;
  const char *opcname;

  find_pc_partial_function (current_pc, NULL, &start_addr, NULL);
  if (start_addr == 0)
    return fp_regnum;

  if (!xtensa_default_isa)
    xtensa_default_isa = xtensa_isa_init (0, 0);
  isa = xtensa_default_isa;
  gdb_assert (XTENSA_ISA_BSZ >= xtensa_isa_maxlength (isa));
  ins = xtensa_insnbuf_alloc (isa);
  slot = xtensa_insnbuf_alloc (isa);
  ba = 0;

  for (ia = start_addr, bt = ia; ia < current_pc ; ia += ilen)
    {
      if (ia + xtensa_isa_maxlength (isa) > bt)
        {
	  ba = ia;
	  bt = (ba + XTENSA_ISA_BSZ) < current_pc
	    ? ba + XTENSA_ISA_BSZ : current_pc;
	  if (target_read_memory (ba, ibuf, bt - ba) != 0)
	    RETURN_FP;
	}

      xtensa_insnbuf_from_chars (isa, ins, &ibuf[ia-ba], 0);
      ifmt = xtensa_format_decode (isa, ins);
      if (ifmt == XTENSA_UNDEFINED)
	RETURN_FP;
      ilen = xtensa_format_length (isa, ifmt);
      if (ilen == XTENSA_UNDEFINED)
	RETURN_FP;
      islots = xtensa_format_num_slots (isa, ifmt);
      if (islots == XTENSA_UNDEFINED)
	RETURN_FP;
      
      for (is = 0; is < islots; ++is)
	{
	  if (xtensa_format_get_slot (isa, ifmt, is, ins, slot))
	    RETURN_FP;
	  
	  opc = xtensa_opcode_decode (isa, ifmt, is, slot);
	  if (opc == XTENSA_UNDEFINED) 
	    RETURN_FP;
	  
	  opcname = xtensa_opcode_name (isa, opc);

	  if (strcasecmp (opcname, "mov.n") == 0
	      || strcasecmp (opcname, "or") == 0)
	    {
	      unsigned int register_operand;

	      /* Possible candidate for setting frame pointer
		 from A1. This is what we are looking for.  */

	      if (xtensa_operand_get_field (isa, opc, 1, ifmt, 
					    is, slot, &register_operand) != 0)
		RETURN_FP;
	      if (xtensa_operand_decode (isa, opc, 1, &register_operand) != 0)
		RETURN_FP;
	      if (register_operand == 1)  /* Mov{.n} FP A1.  */
		{
		  if (xtensa_operand_get_field (isa, opc, 0, ifmt, is, slot, 
						&register_operand) != 0)
		    RETURN_FP;
		  if (xtensa_operand_decode (isa, opc, 0,
					     &register_operand) != 0)
		    RETURN_FP;

		  fp_regnum = gdbarch_tdep (gdbarch)->a0_base + register_operand;
		  RETURN_FP;
		}
	    }

	  if (
	      /* We have problems decoding the memory.  */
	      opcname == NULL 
	      || strcasecmp (opcname, "ill") == 0
	      || strcasecmp (opcname, "ill.n") == 0
	      /* Hit planted breakpoint.  */
	      || strcasecmp (opcname, "break") == 0
	      || strcasecmp (opcname, "break.n") == 0
	      /* Flow control instructions finish prologue.  */
	      || xtensa_opcode_is_branch (isa, opc) > 0
	      || xtensa_opcode_is_jump   (isa, opc) > 0
	      || xtensa_opcode_is_loop   (isa, opc) > 0
	      || xtensa_opcode_is_call   (isa, opc) > 0
	      || strcasecmp (opcname, "simcall") == 0
	      || strcasecmp (opcname, "syscall") == 0)
	    /* Can not continue analysis.  */
	    RETURN_FP;
	}
    }
done:
  xtensa_insnbuf_free(isa, slot);
  xtensa_insnbuf_free(isa, ins);
  return fp_regnum;
}

/* The key values to identify the frame using "cache" are 

	cache->base    = SP (or best guess about FP) of this frame;
	cache->pc      = entry-PC (entry point of the frame function);
	cache->prev_sp = SP of the previous frame.
*/

static void
call0_frame_cache (struct frame_info *this_frame,
		   xtensa_frame_cache_t *cache,
		   CORE_ADDR pc, CORE_ADDR litbase);

static struct xtensa_frame_cache *
xtensa_frame_cache (struct frame_info *this_frame, void **this_cache)
{
  xtensa_frame_cache_t *cache;
  CORE_ADDR ra, wb, ws, pc, sp, ps;
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  unsigned int fp_regnum;
  char op1;
  int  windowed;

  if (*this_cache)
    return *this_cache;

  ps = get_frame_register_unsigned (this_frame, gdbarch_ps_regnum (gdbarch));
  windowed = windowing_enabled (ps);

  /* Get pristine xtensa-frame.  */
  cache = xtensa_alloc_frame_cache (windowed);
  *this_cache = cache;

  pc = get_frame_register_unsigned (this_frame, gdbarch_pc_regnum (gdbarch));

  if (windowed)
    {
      /* Get WINDOWBASE, WINDOWSTART, and PS registers.  */
      wb = get_frame_register_unsigned (this_frame, 
					gdbarch_tdep (gdbarch)->wb_regnum);
      ws = get_frame_register_unsigned (this_frame,
					gdbarch_tdep (gdbarch)->ws_regnum);

      op1 = read_memory_integer (pc, 1, byte_order);
      if (XTENSA_IS_ENTRY (gdbarch, op1))
	{
	  int callinc = CALLINC (ps);
	  ra = get_frame_register_unsigned
	    (this_frame, gdbarch_tdep (gdbarch)->a0_base + callinc * 4);
	  
	  /* ENTRY hasn't been executed yet, therefore callsize is still 0.  */
	  cache->wd.callsize = 0;
	  cache->wd.wb = wb;
	  cache->wd.ws = ws;
	  cache->prev_sp = get_frame_register_unsigned
			     (this_frame, gdbarch_tdep (gdbarch)->a0_base + 1);

	  /* This only can be the outermost frame since we are
	     just about to execute ENTRY.  SP hasn't been set yet.
	     We can assume any frame size, because it does not
	     matter, and, let's fake frame base in cache.  */
	  cache->base = cache->prev_sp + 16;

	  cache->pc = pc;
	  cache->ra = (cache->pc & 0xc0000000) | (ra & 0x3fffffff);
	  cache->ps = (ps & ~PS_CALLINC_MASK)
	    | ((WINSIZE(ra)/4) << PS_CALLINC_SHIFT);

	  return cache;
	}
      else
	{
	  fp_regnum = xtensa_scan_prologue (gdbarch, pc);
	  ra = get_frame_register_unsigned (this_frame,
					    gdbarch_tdep (gdbarch)->a0_base);
	  cache->wd.callsize = WINSIZE (ra);
	  cache->wd.wb = (wb - cache->wd.callsize / 4)
			  & (gdbarch_tdep (gdbarch)->num_aregs / 4 - 1);
	  cache->wd.ws = ws & ~(1 << wb);

	  cache->pc = get_frame_func (this_frame);
	  cache->ra = (pc & 0xc0000000) | (ra & 0x3fffffff);
	  cache->ps = (ps & ~PS_CALLINC_MASK)
	    | ((WINSIZE(ra)/4) << PS_CALLINC_SHIFT);
	}

      if (cache->wd.ws == 0)
	{
	  int i;

	  /* Set A0...A3.  */
	  sp = get_frame_register_unsigned
	    (this_frame, gdbarch_tdep (gdbarch)->a0_base + 1) - 16;
	  
	  for (i = 0; i < 4; i++, sp += 4)
	    {
	      cache->wd.aregs[i] = sp;
	    }

	  if (cache->wd.callsize > 4)
	    {
	      /* Set A4...A7/A11.  */
	      /* Get the SP of the frame previous to the previous one.
	         To achieve this, we have to dereference SP twice.  */
	      sp = (CORE_ADDR) read_memory_integer (sp - 12, 4, byte_order);
	      sp = (CORE_ADDR) read_memory_integer (sp - 12, 4, byte_order);
	      sp -= cache->wd.callsize * 4;

	      for ( i = 4; i < cache->wd.callsize; i++, sp += 4)
		{
		  cache->wd.aregs[i] = sp;
		}
	    }
	}

      if ((cache->prev_sp == 0) && ( ra != 0 ))
	/* If RA is equal to 0 this frame is an outermost frame.  Leave
	   cache->prev_sp unchanged marking the boundary of the frame stack.  */
	{
	  if ((cache->wd.ws & (1 << cache->wd.wb)) == 0)
	    {
	      /* Register window overflow already happened.
		 We can read caller's SP from the proper spill loction.  */
	      sp = get_frame_register_unsigned
		(this_frame, gdbarch_tdep (gdbarch)->a0_base + 1);
	      cache->prev_sp = read_memory_integer (sp - 12, 4, byte_order);
	    }
	  else
	    {
	      /* Read caller's frame SP directly from the previous window.  */
	      int regnum = arreg_number
			     (gdbarch, gdbarch_tdep (gdbarch)->a0_base + 1,
			      cache->wd.wb);

	      cache->prev_sp = get_frame_register_unsigned (this_frame, regnum);
	    }
	}
    }
  else	/* Call0 framework.  */
    {
      unsigned int litbase_regnum = gdbarch_tdep (gdbarch)->litbase_regnum;
      CORE_ADDR litbase = (litbase_regnum == -1)
	? 0 : get_frame_register_unsigned (this_frame, litbase_regnum);

      call0_frame_cache (this_frame, cache, pc, litbase);
      fp_regnum = cache->c0.fp_regnum;
    }

  cache->base = get_frame_register_unsigned (this_frame, fp_regnum);

  return cache;
}

static void
xtensa_frame_this_id (struct frame_info *this_frame,
		      void **this_cache,
		      struct frame_id *this_id)
{
  struct xtensa_frame_cache *cache =
    xtensa_frame_cache (this_frame, this_cache);

  if (cache->prev_sp == 0)
    return;

  (*this_id) = frame_id_build (cache->prev_sp, cache->pc);
}

static struct value *
xtensa_frame_prev_register (struct frame_info *this_frame,
			    void **this_cache,
			    int regnum)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct xtensa_frame_cache *cache;
  ULONGEST saved_reg = 0;
  int done = 1;

  if (*this_cache == NULL)
    *this_cache = xtensa_frame_cache (this_frame, this_cache);
  cache = *this_cache;

  if (regnum ==gdbarch_pc_regnum (gdbarch))
    saved_reg = cache->ra;
  else if (regnum == gdbarch_tdep (gdbarch)->a0_base + 1)
    saved_reg = cache->prev_sp;
  else if (!cache->call0)
    {
      if (regnum == gdbarch_tdep (gdbarch)->ws_regnum)
	saved_reg = cache->wd.ws;
      else if (regnum == gdbarch_tdep (gdbarch)->wb_regnum)
	saved_reg = cache->wd.wb;
      else if (regnum == gdbarch_ps_regnum (gdbarch))
	saved_reg = cache->ps;
      else
	done = 0;
    }
  else
    done = 0;

  if (done)
    return frame_unwind_got_constant (this_frame, regnum, saved_reg);

  if (!cache->call0) /* Windowed ABI.  */
    {
      /* Convert A-register numbers to AR-register numbers,
	 if we deal with A-register.  */
      if (regnum >= gdbarch_tdep (gdbarch)->a0_base
          && regnum <= gdbarch_tdep (gdbarch)->a0_base + 15)
	regnum = arreg_number (gdbarch, regnum, cache->wd.wb);

      /* Check, if we deal with AR-register saved on stack.  */
      if (regnum >= gdbarch_tdep (gdbarch)->ar_base
	  && regnum <= (gdbarch_tdep (gdbarch)->ar_base
			 + gdbarch_tdep (gdbarch)->num_aregs))
	{
	  int areg = areg_number (gdbarch, regnum, cache->wd.wb);

	  if (areg >= 0
	      && areg < XTENSA_NUM_SAVED_AREGS
	      && cache->wd.aregs[areg] != -1)
	    return frame_unwind_got_memory (this_frame, regnum,
					    cache->wd.aregs[areg]);
	}
    }
  else /* Call0 ABI.  */
    {
      int reg = (regnum >= gdbarch_tdep (gdbarch)->ar_base
		&& regnum <= (gdbarch_tdep (gdbarch)->ar_base
			       + C0_NREGS))
		  ? regnum - gdbarch_tdep (gdbarch)->ar_base : regnum;

      if (reg < C0_NREGS)
	{
	  CORE_ADDR spe;
	  int stkofs;

	  /* If register was saved in the prologue, retrieve it.  */
	  stkofs = cache->c0.c0_rt[reg].to_stk;
	  if (stkofs != C0_NOSTK)
	    {
	      /* Determine SP on entry based on FP.  */
	      spe = cache->c0.c0_fp
		- cache->c0.c0_rt[cache->c0.fp_regnum].fr_ofs;

	      return frame_unwind_got_memory (this_frame, regnum, spe + stkofs);
	    }
	}
    }

  /* All other registers have been either saved to
     the stack or are still alive in the processor.  */

  return frame_unwind_got_register (this_frame, regnum, regnum);
}


static const struct frame_unwind
xtensa_unwind =
{
  NORMAL_FRAME,
  xtensa_frame_this_id,
  xtensa_frame_prev_register,
  NULL,
  default_frame_sniffer
};

static CORE_ADDR
xtensa_frame_base_address (struct frame_info *this_frame, void **this_cache)
{
  struct xtensa_frame_cache *cache =
    xtensa_frame_cache (this_frame, this_cache);

  return cache->base;
}

static const struct frame_base
xtensa_frame_base =
{
  &xtensa_unwind,
  xtensa_frame_base_address,
  xtensa_frame_base_address,
  xtensa_frame_base_address
};


static void
xtensa_extract_return_value (struct type *type,
			     struct regcache *regcache,
			     void *dst)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  bfd_byte *valbuf = dst;
  int len = TYPE_LENGTH (type);
  ULONGEST pc, wb;
  int callsize, areg;
  int offset = 0;

  DEBUGTRACE ("xtensa_extract_return_value (...)\n");

  gdb_assert(len > 0);

  if (gdbarch_tdep (gdbarch)->call_abi != CallAbiCall0Only)
    {
      /* First, we have to find the caller window in the register file.  */
      regcache_raw_read_unsigned (regcache, gdbarch_pc_regnum (gdbarch), &pc);
      callsize = extract_call_winsize (gdbarch, pc);

      /* On Xtensa, we can return up to 4 words (or 2 for call12).  */
      if (len > (callsize > 8 ? 8 : 16))
	internal_error (__FILE__, __LINE__,
			_("cannot extract return value of %d bytes long"), len);

      /* Get the register offset of the return
	 register (A2) in the caller window.  */
      regcache_raw_read_unsigned
	(regcache, gdbarch_tdep (gdbarch)->wb_regnum, &wb);
      areg = arreg_number (gdbarch,
			  gdbarch_tdep (gdbarch)->a0_base + 2 + callsize, wb);
    }
  else
    {
      /* No windowing hardware - Call0 ABI.  */
      areg = gdbarch_tdep (gdbarch)->a0_base + C0_ARGS;
    }

  DEBUGINFO ("[xtensa_extract_return_value] areg %d len %d\n", areg, len);

  if (len < 4 && gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
    offset = 4 - len;

  for (; len > 0; len -= 4, areg++, valbuf += 4)
    {
      if (len < 4)
	regcache_raw_read_part (regcache, areg, offset, len, valbuf);
      else
	regcache_raw_read (regcache, areg, valbuf);
    }
}


static void
xtensa_store_return_value (struct type *type,
			   struct regcache *regcache,
			   const void *dst)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  const bfd_byte *valbuf = dst;
  unsigned int areg;
  ULONGEST pc, wb;
  int callsize;
  int len = TYPE_LENGTH (type);
  int offset = 0;

  DEBUGTRACE ("xtensa_store_return_value (...)\n");

  if (gdbarch_tdep (gdbarch)->call_abi != CallAbiCall0Only)
    {
      regcache_raw_read_unsigned 
	(regcache, gdbarch_tdep (gdbarch)->wb_regnum, &wb);
      regcache_raw_read_unsigned (regcache, gdbarch_pc_regnum (gdbarch), &pc);
      callsize = extract_call_winsize (gdbarch, pc);

      if (len > (callsize > 8 ? 8 : 16))
	internal_error (__FILE__, __LINE__,
			_("unimplemented for this length: %d"),
			TYPE_LENGTH (type));
      areg = arreg_number (gdbarch,
			   gdbarch_tdep (gdbarch)->a0_base + 2 + callsize, wb);

      DEBUGTRACE ("[xtensa_store_return_value] callsize %d wb %d\n",
              callsize, (int) wb);
    }
  else
    {
      areg = gdbarch_tdep (gdbarch)->a0_base + C0_ARGS;
    }

  if (len < 4 && gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
    offset = 4 - len;

  for (; len > 0; len -= 4, areg++, valbuf += 4)
    {
      if (len < 4)
	regcache_raw_write_part (regcache, areg, offset, len, valbuf);
      else
	regcache_raw_write (regcache, areg, valbuf);
    }
}


static enum return_value_convention
xtensa_return_value (struct gdbarch *gdbarch,
		     struct type *func_type,
		     struct type *valtype,
		     struct regcache *regcache,
		     gdb_byte *readbuf,
		     const gdb_byte *writebuf)
{
  /* Structures up to 16 bytes are returned in registers.  */

  int struct_return = ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT
			|| TYPE_CODE (valtype) == TYPE_CODE_UNION
			|| TYPE_CODE (valtype) == TYPE_CODE_ARRAY)
		       && TYPE_LENGTH (valtype) > 16);

  if (struct_return)
    return RETURN_VALUE_STRUCT_CONVENTION;

  DEBUGTRACE ("xtensa_return_value(...)\n");

  if (writebuf != NULL)
    {
      xtensa_store_return_value (valtype, regcache, writebuf);
    }

  if (readbuf != NULL)
    {
      gdb_assert (!struct_return);
      xtensa_extract_return_value (valtype, regcache, readbuf);
    }
  return RETURN_VALUE_REGISTER_CONVENTION;
}


/* DUMMY FRAME */

static CORE_ADDR
xtensa_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)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int i;
  int size, onstack_size;
  gdb_byte *buf = (gdb_byte *) alloca (16);
  CORE_ADDR ra, ps;
  struct argument_info
  {
    const bfd_byte *contents;
    int length;
    int onstack;		/* onstack == 0 => in reg */
    int align;			/* alignment */
    union
    {
      int offset;		/* stack offset if on stack */
      int regno;		/* regno if in register */
    } u;
  };

  struct argument_info *arg_info =
    (struct argument_info *) alloca (nargs * sizeof (struct argument_info));

  CORE_ADDR osp = sp;

  DEBUGTRACE ("xtensa_push_dummy_call (...)\n");

  if (xtensa_debug_level > 3)
    {
      int i;
      DEBUGINFO ("[xtensa_push_dummy_call] nargs = %d\n", nargs);
      DEBUGINFO ("[xtensa_push_dummy_call] sp=0x%x, struct_return=%d, "
		 "struct_addr=0x%x\n",
		 (int) sp, (int) struct_return, (int) struct_addr);

      for (i = 0; i < nargs; i++)
        {
	  struct value *arg = args[i];
	  struct type *arg_type = check_typedef (value_type (arg));
	  fprintf_unfiltered (gdb_stdlog, "%2d: 0x%lx %3d ",
			      i, (unsigned long) arg, TYPE_LENGTH (arg_type));
	  switch (TYPE_CODE (arg_type))
	    {
	    case TYPE_CODE_INT:
	      fprintf_unfiltered (gdb_stdlog, "int");
	      break;
	    case TYPE_CODE_STRUCT:
	      fprintf_unfiltered (gdb_stdlog, "struct");
	      break;
	    default:
	      fprintf_unfiltered (gdb_stdlog, "%3d", TYPE_CODE (arg_type));
	      break;
	    }
	  fprintf_unfiltered (gdb_stdlog, " 0x%lx\n",
			      (unsigned long) value_contents (arg));
	}
    }

  /* First loop: collect information.
     Cast into type_long.  (This shouldn't happen often for C because
     GDB already does this earlier.)  It's possible that GDB could
     do it all the time but it's harmless to leave this code here.  */

  size = 0;
  onstack_size = 0;
  i = 0;

  if (struct_return)
    size = REGISTER_SIZE;

  for (i = 0; i < nargs; i++)
    {
      struct argument_info *info = &arg_info[i];
      struct value *arg = args[i];
      struct type *arg_type = check_typedef (value_type (arg));

      switch (TYPE_CODE (arg_type))
	{
	case TYPE_CODE_INT:
	case TYPE_CODE_BOOL:
	case TYPE_CODE_CHAR:
	case TYPE_CODE_RANGE:
	case TYPE_CODE_ENUM:

	  /* Cast argument to long if necessary as the mask does it too.  */
	  if (TYPE_LENGTH (arg_type)
	      < TYPE_LENGTH (builtin_type (gdbarch)->builtin_long))
	    {
	      arg_type = builtin_type (gdbarch)->builtin_long;
	      arg = value_cast (arg_type, arg);
	    }
	  /* Aligment is equal to the type length for the basic types.  */
	  info->align = TYPE_LENGTH (arg_type);
	  break;

	case TYPE_CODE_FLT:

	  /* Align doubles correctly.  */
	  if (TYPE_LENGTH (arg_type)
	      == TYPE_LENGTH (builtin_type (gdbarch)->builtin_double))
	    info->align = TYPE_LENGTH (builtin_type (gdbarch)->builtin_double);
	  else
	    info->align = TYPE_LENGTH (builtin_type (gdbarch)->builtin_long);
	  break;

	case TYPE_CODE_STRUCT:
	default:
	  info->align = TYPE_LENGTH (builtin_type (gdbarch)->builtin_long);
	  break;
	}
      info->length = TYPE_LENGTH (arg_type);
      info->contents = value_contents (arg);

      /* Align size and onstack_size.  */
      size = (size + info->align - 1) & ~(info->align - 1);
      onstack_size = (onstack_size + info->align - 1) & ~(info->align - 1);

      if (size + info->length > REGISTER_SIZE * ARG_NOF (gdbarch))
	{
	  info->onstack = 1;
	  info->u.offset = onstack_size;
	  onstack_size += info->length;
	}
      else
	{
	  info->onstack = 0;
	  info->u.regno = ARG_1ST (gdbarch) + size / REGISTER_SIZE;
	}
      size += info->length;
    }

  /* Adjust the stack pointer and align it.  */
  sp = align_down (sp - onstack_size, SP_ALIGNMENT);

  /* Simulate MOVSP, if Windowed ABI.  */
  if ((gdbarch_tdep (gdbarch)->call_abi != CallAbiCall0Only)
      && (sp != osp))
    {
      read_memory (osp - 16, buf, 16);
      write_memory (sp - 16, buf, 16);
    }

  /* Second Loop: Load arguments.  */

  if (struct_return)
    {
      store_unsigned_integer (buf, REGISTER_SIZE, byte_order, struct_addr);
      regcache_cooked_write (regcache, ARG_1ST (gdbarch), buf);
    }

  for (i = 0; i < nargs; i++)
    {
      struct argument_info *info = &arg_info[i];

      if (info->onstack)
	{
	  int n = info->length;
	  CORE_ADDR offset = sp + info->u.offset;

	  /* Odd-sized structs are aligned to the lower side of a memory
	     word in big-endian mode and require a shift.  This only
	     applies for structures smaller than one word.  */

	  if (n < REGISTER_SIZE
	      && gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
	    offset += (REGISTER_SIZE - n);

	  write_memory (offset, info->contents, info->length);

	}
      else
	{
	  int n = info->length;
	  const bfd_byte *cp = info->contents;
	  int r = info->u.regno;

	  /* Odd-sized structs are aligned to the lower side of registers in
	     big-endian mode and require a shift.  The odd-sized leftover will
	     be at the end.  Note that this is only true for structures smaller
	     than REGISTER_SIZE; for larger odd-sized structures the excess
	     will be left-aligned in the register on both endiannesses.  */

	  if (n < REGISTER_SIZE && byte_order == BFD_ENDIAN_BIG)
	    {
	      ULONGEST v;
	      v = extract_unsigned_integer (cp, REGISTER_SIZE, byte_order);
	      v = v >> ((REGISTER_SIZE - n) * TARGET_CHAR_BIT);

	      store_unsigned_integer (buf, REGISTER_SIZE, byte_order, v);
	      regcache_cooked_write (regcache, r, buf);

	      cp += REGISTER_SIZE;
	      n -= REGISTER_SIZE;
	      r++;
	    }
	  else
	    while (n > 0)
	      {
		regcache_cooked_write (regcache, r, cp);

		cp += REGISTER_SIZE;
		n -= REGISTER_SIZE;
		r++;
	      }
	}
    }

  /* Set the return address of dummy frame to the dummy address.
     The return address for the current function (in A0) is
     saved in the dummy frame, so we can savely overwrite A0 here.  */

  if (gdbarch_tdep (gdbarch)->call_abi != CallAbiCall0Only)
    {
      ra = (bp_addr & 0x3fffffff) | 0x40000000;
      regcache_raw_read (regcache, gdbarch_ps_regnum (gdbarch), buf);
      ps = extract_unsigned_integer (buf, 4, byte_order) & ~0x00030000;
      regcache_cooked_write_unsigned
	(regcache, gdbarch_tdep (gdbarch)->a0_base + 4, ra);
      regcache_cooked_write_unsigned (regcache,
				      gdbarch_ps_regnum (gdbarch),
				      ps | 0x00010000);

      /* All the registers have been saved.  After executing
	 dummy call, they all will be restored.  So it's safe
	 to modify WINDOWSTART register to make it look like there
	 is only one register window corresponding to WINDOWEBASE.  */

      regcache_raw_read (regcache, gdbarch_tdep (gdbarch)->wb_regnum, buf);
      regcache_cooked_write_unsigned
	(regcache, gdbarch_tdep (gdbarch)->ws_regnum,
	 1 << extract_unsigned_integer (buf, 4, byte_order));
    }
  else
    {
      /* Simulate CALL0: write RA into A0 register.  */
      regcache_cooked_write_unsigned
	(regcache, gdbarch_tdep (gdbarch)->a0_base, bp_addr);
    }

  /* Set new stack pointer and return it.  */
  regcache_cooked_write_unsigned (regcache,
				  gdbarch_tdep (gdbarch)->a0_base + 1, sp);
  /* Make dummy frame ID unique by adding a constant.  */
  return sp + SP_ALIGNMENT;
}


/* Return a breakpoint for the current location of PC.  We always use
   the density version if we have density instructions (regardless of the
   current instruction at PC), and use regular instructions otherwise.  */

#define BIG_BREAKPOINT { 0x00, 0x04, 0x00 }
#define LITTLE_BREAKPOINT { 0x00, 0x40, 0x00 }
#define DENSITY_BIG_BREAKPOINT { 0xd2, 0x0f }
#define DENSITY_LITTLE_BREAKPOINT { 0x2d, 0xf0 }

static const unsigned char *
xtensa_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
			   int *lenptr)
{
  static unsigned char big_breakpoint[] = BIG_BREAKPOINT;
  static unsigned char little_breakpoint[] = LITTLE_BREAKPOINT;
  static unsigned char density_big_breakpoint[] = DENSITY_BIG_BREAKPOINT;
  static unsigned char density_little_breakpoint[] = DENSITY_LITTLE_BREAKPOINT;

  DEBUGTRACE ("xtensa_breakpoint_from_pc (pc = 0x%08x)\n", (int) *pcptr);

  if (gdbarch_tdep (gdbarch)->isa_use_density_instructions)
    {
      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
	{
	  *lenptr = sizeof (density_big_breakpoint);
	  return density_big_breakpoint;
	}
      else
	{
	  *lenptr = sizeof (density_little_breakpoint);
	  return density_little_breakpoint;
	}
    }
  else
    {
      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
	{
	  *lenptr = sizeof (big_breakpoint);
	  return big_breakpoint;
	}
      else
	{
	  *lenptr = sizeof (little_breakpoint);
	  return little_breakpoint;
	}
    }
}

/* Call0 ABI support routines.  */

/* Call0 opcode class.  Opcodes are preclassified according to what they
   mean for Call0 prologue analysis, and their number of significant operands.
   The purpose of this is to simplify prologue analysis by separating 
   instruction decoding (libisa) from the semantics of prologue analysis.  */

typedef enum {
  c0opc_illegal,       /* Unknown to libisa (invalid) or 'ill' opcode.  */
  c0opc_uninteresting, /* Not interesting for Call0 prologue analysis.  */
  c0opc_flow,	       /* Flow control insn.  */
  c0opc_entry,	       /* ENTRY indicates non-Call0 prologue.  */
  c0opc_break,	       /* Debugger software breakpoints.  */
  c0opc_add,	       /* Adding two registers.  */
  c0opc_addi,	       /* Adding a register and an immediate.  */
  c0opc_sub,	       /* Subtracting a register from a register.  */
  c0opc_mov,	       /* Moving a register to a register.  */
  c0opc_movi,	       /* Moving an immediate to a register.  */
  c0opc_l32r,	       /* Loading a literal.  */
  c0opc_s32i,	       /* Storing word at fixed offset from a base register.  */
  c0opc_NrOf	       /* Number of opcode classifications.  */
} xtensa_insn_kind;


/* Classify an opcode based on what it means for Call0 prologue analysis.  */

static xtensa_insn_kind
call0_classify_opcode (xtensa_isa isa, xtensa_opcode opc)
{
  const char *opcname;
  xtensa_insn_kind opclass = c0opc_uninteresting;

  DEBUGTRACE ("call0_classify_opcode (..., opc = %d)\n", opc);

  /* Get opcode name and handle special classifications.  */

  opcname = xtensa_opcode_name (isa, opc);

  if (opcname == NULL 
      || strcasecmp (opcname, "ill") == 0
      || strcasecmp (opcname, "ill.n") == 0)
    opclass = c0opc_illegal;
  else if (strcasecmp (opcname, "break") == 0
	   || strcasecmp (opcname, "break.n") == 0)
     opclass = c0opc_break;
  else if (strcasecmp (opcname, "entry") == 0)
    opclass = c0opc_entry;
  else if (xtensa_opcode_is_branch (isa, opc) > 0
	   || xtensa_opcode_is_jump   (isa, opc) > 0
	   || xtensa_opcode_is_loop   (isa, opc) > 0
	   || xtensa_opcode_is_call   (isa, opc) > 0
	   || strcasecmp (opcname, "simcall") == 0
	   || strcasecmp (opcname, "syscall") == 0)
    opclass = c0opc_flow;

  /* Also, classify specific opcodes that need to be tracked.  */
  else if (strcasecmp (opcname, "add") == 0 
	   || strcasecmp (opcname, "add.n") == 0)
    opclass = c0opc_add;
  else if (strcasecmp (opcname, "addi") == 0 
	   || strcasecmp (opcname, "addi.n") == 0
	   || strcasecmp (opcname, "addmi") == 0)
    opclass = c0opc_addi;
  else if (strcasecmp (opcname, "sub") == 0)
    opclass = c0opc_sub;
  else if (strcasecmp (opcname, "mov.n") == 0
	   || strcasecmp (opcname, "or") == 0) /* Could be 'mov' asm macro.  */
    opclass = c0opc_mov;
  else if (strcasecmp (opcname, "movi") == 0 
	   || strcasecmp (opcname, "movi.n") == 0)
    opclass = c0opc_movi;
  else if (strcasecmp (opcname, "l32r") == 0)
    opclass = c0opc_l32r;
  else if (strcasecmp (opcname, "s32i") == 0 
	   || strcasecmp (opcname, "s32i.n") == 0)
    opclass = c0opc_s32i;

  return opclass;
}

/* Tracks register movement/mutation for a given operation, which may
   be within a bundle.  Updates the destination register tracking info
   accordingly.  The pc is needed only for pc-relative load instructions
   (eg. l32r).  The SP register number is needed to identify stores to
   the stack frame.  */

static void
call0_track_op (struct gdbarch *gdbarch,
		xtensa_c0reg_t dst[], xtensa_c0reg_t src[],
		xtensa_insn_kind opclass, int nods, unsigned odv[],
		CORE_ADDR pc, CORE_ADDR litbase, int spreg)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  unsigned litaddr, litval;

  switch (opclass)
    {
    case c0opc_addi:
      /* 3 operands: dst, src, imm.  */
      gdb_assert (nods == 3);
      dst[odv[0]].fr_reg = src[odv[1]].fr_reg;
      dst[odv[0]].fr_ofs = src[odv[1]].fr_ofs + odv[2];
      break;
    case c0opc_add:
      /* 3 operands: dst, src1, src2.  */
      gdb_assert (nods == 3);
      if      (src[odv[1]].fr_reg == C0_CONST)
        {
	  dst[odv[0]].fr_reg = src[odv[2]].fr_reg;
	  dst[odv[0]].fr_ofs = src[odv[2]].fr_ofs + src[odv[1]].fr_ofs;
	}
      else if (src[odv[2]].fr_reg == C0_CONST)
        {
	  dst[odv[0]].fr_reg = src[odv[1]].fr_reg;
	  dst[odv[0]].fr_ofs = src[odv[1]].fr_ofs + src[odv[2]].fr_ofs;
	}
      else dst[odv[0]].fr_reg = C0_INEXP;
      break;
    case c0opc_sub:
      /* 3 operands: dst, src1, src2.  */
      gdb_assert (nods == 3);
      if      (src[odv[2]].fr_reg == C0_CONST)
        {
	  dst[odv[0]].fr_reg = src[odv[1]].fr_reg;
	  dst[odv[0]].fr_ofs = src[odv[1]].fr_ofs - src[odv[2]].fr_ofs;
	}
      else dst[odv[0]].fr_reg = C0_INEXP;
      break;
    case c0opc_mov:
      /* 2 operands: dst, src [, src].  */
      gdb_assert (nods == 2);
      dst[odv[0]].fr_reg = src[odv[1]].fr_reg;
      dst[odv[0]].fr_ofs = src[odv[1]].fr_ofs;
      break;
    case c0opc_movi:
      /* 2 operands: dst, imm.  */
      gdb_assert (nods == 2);
      dst[odv[0]].fr_reg = C0_CONST;
      dst[odv[0]].fr_ofs = odv[1];
      break;
    case c0opc_l32r:
      /* 2 operands: dst, literal offset.  */
      gdb_assert (nods == 2);
      litaddr = litbase & 1
		  ? (litbase & ~1) + (signed)odv[1]
		  : (pc + 3  + (signed)odv[1]) & ~3;
      litval = read_memory_integer (litaddr, 4, byte_order);
      dst[odv[0]].fr_reg = C0_CONST;
      dst[odv[0]].fr_ofs = litval;
      break;
    case c0opc_s32i:
      /* 3 operands: value, base, offset.  */
      gdb_assert (nods == 3 && spreg >= 0 && spreg < C0_NREGS);
      if (src[odv[1]].fr_reg == spreg	     /* Store to stack frame.  */
	  && (src[odv[1]].fr_ofs & 3) == 0   /* Alignment preserved.  */
	  &&  src[odv[0]].fr_reg >= 0	     /* Value is from a register.  */
	  &&  src[odv[0]].fr_ofs == 0	     /* Value hasn't been modified.  */
	  &&  src[src[odv[0]].fr_reg].to_stk == C0_NOSTK) /* First time.  */
        {
	  /* ISA encoding guarantees alignment.  But, check it anyway.  */
	  gdb_assert ((odv[2] & 3) == 0);
	  dst[src[odv[0]].fr_reg].to_stk = src[odv[1]].fr_ofs + odv[2];
	}
      break;
    default:
	gdb_assert (0);
    }
}

/* Analyze prologue of the function at start address to determine if it uses 
   the Call0 ABI, and if so track register moves and linear modifications
   in the prologue up to the PC or just beyond the prologue, whichever is first.
   An 'entry' instruction indicates non-Call0 ABI and the end of the prologue.
   The prologue may overlap non-prologue instructions but is guaranteed to end
   by the first flow-control instruction (jump, branch, call or return).
   Since an optimized function may move information around and change the
   stack frame arbitrarily during the prologue, the information is guaranteed
   valid only at the point in the function indicated by the PC.
   May be used to skip the prologue or identify the ABI, w/o tracking.

   Returns:   Address of first instruction after prologue, or PC (whichever 
	      is first), or 0, if decoding failed (in libisa).
   Input args:
      start   Start address of function/prologue.
      pc      Program counter to stop at.  Use 0 to continue to end of prologue.
	      If 0, avoids infinite run-on in corrupt code memory by bounding
	      the scan to the end of the function if that can be determined.
      nregs   Number of general registers to track (size of rt[] array).
   InOut args:
      rt[]    Array[nregs] of xtensa_c0reg structures for register tracking info.
	      If NULL, registers are not tracked.
   Output args:
      call0   If != NULL, *call0 is set non-zero if Call0 ABI used, else 0
	      (more accurately, non-zero until 'entry' insn is encountered).

      Note that these may produce useful results even if decoding fails
      because they begin with default assumptions that analysis may change.  */

static CORE_ADDR
call0_analyze_prologue (struct gdbarch *gdbarch,
			CORE_ADDR start, CORE_ADDR pc, CORE_ADDR litbase,
			int nregs, xtensa_c0reg_t rt[], int *call0)
{
  CORE_ADDR ia;		    /* Current insn address in prologue.  */
  CORE_ADDR ba = 0;	    /* Current address at base of insn buffer.  */
  CORE_ADDR bt;		    /* Current address at top+1 of insn buffer.  */
  char ibuf[XTENSA_ISA_BSZ];/* Instruction buffer for decoding prologue.  */
  xtensa_isa isa;	    /* libisa ISA handle.  */
  xtensa_insnbuf ins, slot; /* libisa handle to decoded insn, slot.  */
  xtensa_format ifmt;	    /* libisa instruction format.  */
  int ilen, islots, is;	    /* Instruction length, nbr slots, current slot.  */
  xtensa_opcode opc;	    /* Opcode in current slot.  */
  xtensa_insn_kind opclass; /* Opcode class for Call0 prologue analysis.  */
  int nods;		    /* Opcode number of operands.  */
  unsigned odv[C0_MAXOPDS]; /* Operand values in order provided by libisa.  */
  xtensa_c0reg_t *rtmp;	    /* Register tracking info snapshot.  */
  int j;		    /* General loop counter.  */
  int fail = 0;		    /* Set non-zero and exit, if decoding fails.  */
  CORE_ADDR body_pc;	    /* The PC for the first non-prologue insn.  */
  CORE_ADDR end_pc;	    /* The PC for the lust function insn.  */

  struct symtab_and_line prologue_sal;

  DEBUGTRACE ("call0_analyze_prologue (start = 0x%08x, pc = 0x%08x, ...)\n", 
	      (int)start, (int)pc);

  /* Try to limit the scan to the end of the function if a non-zero pc
     arg was not supplied to avoid probing beyond the end of valid memory.
     If memory is full of garbage that classifies as c0opc_uninteresting.
     If this fails (eg. if no symbols) pc ends up 0 as it was.
     Intialize the Call0 frame and register tracking info.
     Assume it's Call0 until an 'entry' instruction is encountered.
     Assume we may be in the prologue until we hit a flow control instr.  */

  rtmp = NULL;
  body_pc = UINT_MAX;
  end_pc = 0;

  /* Find out, if we have an information about the prologue from DWARF.  */
  prologue_sal = find_pc_line (start, 0);
  if (prologue_sal.line != 0) /* Found debug info.  */
    body_pc = prologue_sal.end;

  /* If we are going to analyze the prologue in general without knowing about
     the current PC, make the best assumtion for the end of the prologue.  */
  if (pc == 0)
    {
      find_pc_partial_function (start, 0, NULL, &end_pc);
      body_pc = min (end_pc, body_pc);
    }
  else
    body_pc = min (pc, body_pc);

  if (call0 != NULL)
      *call0 = 1;

  if (rt != NULL)
    {
      rtmp = (xtensa_c0reg_t*) alloca(nregs * sizeof(xtensa_c0reg_t));
      /* rt is already initialized in xtensa_alloc_frame_cache().  */
    }
  else nregs = 0;

  if (!xtensa_default_isa)
    xtensa_default_isa = xtensa_isa_init (0, 0);
  isa = xtensa_default_isa;
  gdb_assert (XTENSA_ISA_BSZ >= xtensa_isa_maxlength (isa));
  ins = xtensa_insnbuf_alloc (isa);
  slot = xtensa_insnbuf_alloc (isa);

  for (ia = start, bt = ia; ia < body_pc ; ia += ilen)
    {
      /* (Re)fill instruction buffer from memory if necessary, but do not
         read memory beyond PC to be sure we stay within text section
	 (this protection only works if a non-zero pc is supplied).  */

      if (ia + xtensa_isa_maxlength (isa) > bt)
        {
	  ba = ia;
	  bt = (ba + XTENSA_ISA_BSZ) < body_pc ? ba + XTENSA_ISA_BSZ : body_pc;
	  read_memory (ba, ibuf, bt - ba);
	  /* If there is a memory reading error read_memory () will report it
	     and then throw an exception, stopping command execution.  */
	}

      /* Decode format information.  */

      xtensa_insnbuf_from_chars (isa, ins, &ibuf[ia-ba], 0);
      ifmt = xtensa_format_decode (isa, ins);
      if (ifmt == XTENSA_UNDEFINED)
	{
	  fail = 1;
	  goto done;
	}
      ilen = xtensa_format_length (isa, ifmt);
      if (ilen == XTENSA_UNDEFINED)
	{
	  fail = 1;
	  goto done;
	}
      islots = xtensa_format_num_slots (isa, ifmt);
      if (islots == XTENSA_UNDEFINED)
	{
	  fail = 1;
	  goto done;
	}

      /* Analyze a bundle or a single instruction, using a snapshot of 
         the register tracking info as input for the entire bundle so that
	 register changes do not take effect within this bundle.  */

      for (j = 0; j < nregs; ++j)
	rtmp[j] = rt[j];

      for (is = 0; is < islots; ++is)
        {
	  /* Decode a slot and classify the opcode.  */

	  fail = xtensa_format_get_slot (isa, ifmt, is, ins, slot);
	  if (fail)
	    goto done;

	  opc = xtensa_opcode_decode (isa, ifmt, is, slot);
	  DEBUGVERB ("[call0_analyze_prologue] instr addr = 0x%08x, opc = %d\n", 
		     (unsigned)ia, opc);
	  if (opc == XTENSA_UNDEFINED) 
	    opclass = c0opc_illegal;
	  else
	    opclass = call0_classify_opcode (isa, opc);

	  /* Decide whether to track this opcode, ignore it, or bail out.  */

	  switch (opclass)
	    {
	    case c0opc_illegal:
	    case c0opc_break:
	      fail = 1;
	      goto done;

	    case c0opc_uninteresting:
	      continue;

	    case c0opc_flow:
	      goto done;

	    case c0opc_entry:
	      if (call0 != NULL)
		*call0 = 0;
	      ia += ilen;	       	/* Skip over 'entry' insn.  */
	      goto done;

	    default:
	      if (call0 != NULL)
		*call0 = 1;
	    }

	  /* Only expected opcodes should get this far.  */
	  if (rt == NULL)
	    continue;

	  /* Extract and decode the operands.  */
	  nods = xtensa_opcode_num_operands (isa, opc);
	  if (nods == XTENSA_UNDEFINED)
	    {
	      fail = 1;
	      goto done;
	    }

	  for (j = 0; j < nods && j < C0_MAXOPDS; ++j)
	    {
	      fail = xtensa_operand_get_field (isa, opc, j, ifmt, 
					       is, slot, &odv[j]);
	      if (fail)
		goto done;

	      fail = xtensa_operand_decode (isa, opc, j, &odv[j]);
	      if (fail)
		goto done;
	    }

	  /* Check operands to verify use of 'mov' assembler macro.  */
	  if (opclass == c0opc_mov && nods == 3)
	    {
	      if (odv[2] == odv[1])
		nods = 2;
	      else
		{
		  opclass = c0opc_uninteresting;
		  continue;
		}
	    }

	  /* Track register movement and modification for this operation.  */
	  call0_track_op (gdbarch, rt, rtmp, opclass,
			  nods, odv, ia, litbase, 1);
	}
    }
done:
  DEBUGVERB ("[call0_analyze_prologue] stopped at instr addr 0x%08x, %s\n",
	     (unsigned)ia, fail ? "failed" : "succeeded");
  xtensa_insnbuf_free(isa, slot);
  xtensa_insnbuf_free(isa, ins);
  return fail ? XTENSA_ISA_BADPC : ia;
}

/* Initialize frame cache for the current frame in CALL0 ABI.  */

static void
call0_frame_cache (struct frame_info *this_frame,
		   xtensa_frame_cache_t *cache, CORE_ADDR pc, CORE_ADDR litbase)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR start_pc;		/* The beginning of the function.  */
  CORE_ADDR body_pc=UINT_MAX;	/* PC, where prologue analysis stopped.  */
  CORE_ADDR sp, fp, ra;
  int fp_regnum, c0_hasfp, c0_frmsz, prev_sp, to_stk;
 
  /* Find the beginning of the prologue of the function containing the PC
     and analyze it up to the PC or the end of the prologue.  */

  if (find_pc_partial_function (pc, NULL, &start_pc, NULL))
    {
      body_pc = call0_analyze_prologue (gdbarch, start_pc, pc, litbase,
					C0_NREGS,
					&cache->c0.c0_rt[0],
					&cache->call0);

      if (body_pc == XTENSA_ISA_BADPC)
	error (_("Xtensa-specific internal error: CALL0 prologue \
analysis failed in this frame. GDB command execution stopped."));
    }
  
  sp = get_frame_register_unsigned
    (this_frame, gdbarch_tdep (gdbarch)->a0_base + 1);
  fp = sp; /* Assume FP == SP until proven otherwise.  */

  /* Get the frame information and FP (if used) at the current PC.
     If PC is in the prologue, the prologue analysis is more reliable
     than DWARF info.  We don't not know for sure if PC is in the prologue,
     but we know no calls have yet taken place, so we can almost
     certainly rely on the prologue analysis.  */

  if (body_pc <= pc)
    {
      /* Prologue analysis was successful up to the PC.
         It includes the cases when PC == START_PC.  */
      c0_hasfp = cache->c0.c0_rt[C0_FP].fr_reg == C0_SP;
      /* c0_hasfp == true means there is a frame pointer because
	 we analyzed the prologue and found that cache->c0.c0_rt[C0_FP]
	 was derived from SP.  Otherwise, it would be C0_FP.  */
      fp_regnum = c0_hasfp ? C0_FP : C0_SP;
      c0_frmsz = - cache->c0.c0_rt[fp_regnum].fr_ofs;
      fp_regnum += gdbarch_tdep (gdbarch)->a0_base;
    }
  else  /* No data from the prologue analysis.  */
    {
      c0_hasfp = 0;
      fp_regnum = gdbarch_tdep (gdbarch)->a0_base + C0_SP;
      c0_frmsz = 0;
      start_pc = pc;
   }

  prev_sp = fp + c0_frmsz;

  /* Frame size from debug info or prologue tracking does not account for 
     alloca() and other dynamic allocations.  Adjust frame size by FP - SP.  */
  if (c0_hasfp)
    {
      fp = get_frame_register_unsigned (this_frame, fp_regnum);

      /* Recalculate previous SP.  */
      prev_sp = fp + c0_frmsz;
      /* Update the stack frame size.  */
      c0_frmsz += fp - sp;
    }

  /* Get the return address (RA) from the stack if saved,
     or try to get it from a register.  */

  to_stk = cache->c0.c0_rt[C0_RA].to_stk;
  if (to_stk != C0_NOSTK)
    ra = (CORE_ADDR) 
      read_memory_integer (sp + c0_frmsz + cache->c0.c0_rt[C0_RA].to_stk,
			   4, byte_order);

  else if (cache->c0.c0_rt[C0_RA].fr_reg == C0_CONST
	   && cache->c0.c0_rt[C0_RA].fr_ofs == 0)
    {
      /* Special case for terminating backtrace at a function that wants to
	 be seen as the outermost.  Such a function will clear it's RA (A0)
	 register to 0 in the prologue instead of saving its original value.  */
      ra = 0;
    }
  else
    {
      /* RA was copied to another register or (before any function call) may
	 still be in the original RA register.  This is not always reliable:
	 even in a leaf function, register tracking stops after prologue, and
	 even in prologue, non-prologue instructions (not tracked) may overwrite
	 RA or any register it was copied to.  If likely in prologue or before
	 any call, use retracking info and hope for the best (compiler should
	 have saved RA in stack if not in a leaf function).  If not in prologue,
	 too bad.  */

      int i;
      for (i = 0; 
	   (i < C0_NREGS) &&
	     (i == C0_RA || cache->c0.c0_rt[i].fr_reg != C0_RA);
	   ++i);
      if (i >= C0_NREGS && cache->c0.c0_rt[C0_RA].fr_reg == C0_RA)
	i = C0_RA;
      if (i < C0_NREGS)
	{
	  ra = get_frame_register_unsigned
	    (this_frame,
	     gdbarch_tdep (gdbarch)->a0_base + cache->c0.c0_rt[i].fr_reg);
	}
      else ra = 0;
    }
  
  cache->pc = start_pc;
  cache->ra = ra;
  /* RA == 0 marks the outermost frame.  Do not go past it.  */
  cache->prev_sp = (ra != 0) ?  prev_sp : 0;
  cache->c0.fp_regnum = fp_regnum;
  cache->c0.c0_frmsz = c0_frmsz;
  cache->c0.c0_hasfp = c0_hasfp;
  cache->c0.c0_fp = fp;
}


/* Skip function prologue.

   Return the pc of the first instruction after prologue.  GDB calls this to
   find the address of the first line of the function or (if there is no line
   number information) to skip the prologue for planting breakpoints on 
   function entries.  Use debug info (if present) or prologue analysis to skip 
   the prologue to achieve reliable debugging behavior.  For windowed ABI, 
   only the 'entry' instruction is skipped.  It is not strictly necessary to 
   skip the prologue (Call0) or 'entry' (Windowed) because xt-gdb knows how to
   backtrace at any point in the prologue, however certain potential hazards 
   are avoided and a more "normal" debugging experience is ensured by 
   skipping the prologue (can be disabled by defining DONT_SKIP_PROLOG).
   For example, if we don't skip the prologue:
   - Some args may not yet have been saved to the stack where the debug
     info expects to find them (true anyway when only 'entry' is skipped);
   - Software breakpoints ('break' instrs) may not have been unplanted 
     when the prologue analysis is done on initializing the frame cache, 
     and breaks in the prologue will throw off the analysis.

   If we have debug info ( line-number info, in particular ) we simply skip
   the code associated with the first function line effectively skipping
   the prologue code.  It works even in cases like

   int main()
   {	int local_var = 1;
   	....
   }

   because, for this source code, both Xtensa compilers will generate two
   separate entries ( with the same line number ) in dwarf line-number
   section to make sure there is a boundary between the prologue code and
   the rest of the function.

   If there is no debug info, we need to analyze the code.  */

/* #define DONT_SKIP_PROLOGUE  */

static CORE_ADDR
xtensa_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
{
  struct symtab_and_line prologue_sal;
  CORE_ADDR body_pc;

  DEBUGTRACE ("xtensa_skip_prologue (start_pc = 0x%08x)\n", (int) start_pc);

#if DONT_SKIP_PROLOGUE
  return start_pc;
#endif

 /* Try to find first body line from debug info.  */

  prologue_sal = find_pc_line (start_pc, 0);
  if (prologue_sal.line != 0) /* Found debug info.  */
    {
      /* In Call0, it is possible to have a function with only one instruction
	 ('ret') resulting from a 1-line optimized function that does nothing.
	 In that case, prologue_sal.end may actually point to the start of the
	 next function in the text section, causing a breakpoint to be set at
	 the wrong place.  Check if the end address is in a different function,
	 and if so return the start PC.  We know we have symbol info.  */

      CORE_ADDR end_func;

      find_pc_partial_function (prologue_sal.end, NULL, &end_func, NULL);
      if (end_func != start_pc)
	return start_pc;

      return prologue_sal.end;
    }

  /* No debug line info.  Analyze prologue for Call0 or simply skip ENTRY.  */
  body_pc = call0_analyze_prologue (gdbarch, start_pc, 0, 0, 0, NULL, NULL);
  return body_pc != 0 ? body_pc : start_pc;
}

/* Verify the current configuration.  */
static void
xtensa_verify_config (struct gdbarch *gdbarch)
{
  struct ui_file *log;
  struct cleanup *cleanups;
  struct gdbarch_tdep *tdep;
  long length;
  char *buf;

  tdep = gdbarch_tdep (gdbarch);
  log = mem_fileopen ();
  cleanups = make_cleanup_ui_file_delete (log);

  /* Verify that we got a reasonable number of AREGS.  */
  if ((tdep->num_aregs & -tdep->num_aregs) != tdep->num_aregs)
    fprintf_unfiltered (log, _("\
\n\tnum_aregs: Number of AR registers (%d) is not a power of two!"),
			tdep->num_aregs);

  /* Verify that certain registers exist.  */

  if (tdep->pc_regnum == -1)
    fprintf_unfiltered (log, _("\n\tpc_regnum: No PC register"));
  if (tdep->isa_use_exceptions && tdep->ps_regnum == -1)
    fprintf_unfiltered (log, _("\n\tps_regnum: No PS register"));

  if (tdep->isa_use_windowed_registers)
    {
      if (tdep->wb_regnum == -1)
	fprintf_unfiltered (log, _("\n\twb_regnum: No WB register"));
      if (tdep->ws_regnum == -1)
	fprintf_unfiltered (log, _("\n\tws_regnum: No WS register"));
      if (tdep->ar_base == -1)
	fprintf_unfiltered (log, _("\n\tar_base: No AR registers"));
    }

  if (tdep->a0_base == -1)
    fprintf_unfiltered (log, _("\n\ta0_base: No Ax registers"));

  buf = ui_file_xstrdup (log, &length);
  make_cleanup (xfree, buf);
  if (length > 0)
    internal_error (__FILE__, __LINE__,
		    _("the following are invalid: %s"), buf);
  do_cleanups (cleanups);
}


/* Derive specific register numbers from the array of registers.  */

static void
xtensa_derive_tdep (struct gdbarch_tdep *tdep)
{
  xtensa_register_t* rmap;
  int n, max_size = 4;

  tdep->num_regs = 0;
  tdep->num_nopriv_regs = 0;

/* Special registers 0..255 (core).  */
#define XTENSA_DBREGN_SREG(n)  (0x0200+(n))

  for (rmap = tdep->regmap, n = 0; rmap->target_number != -1; n++, rmap++)
    {
      if (rmap->target_number == 0x0020)
	tdep->pc_regnum = n;
      else if (rmap->target_number == 0x0100)
	tdep->ar_base = n;
      else if (rmap->target_number == 0x0000)
	tdep->a0_base = n;
      else if (rmap->target_number == XTENSA_DBREGN_SREG(72))
	tdep->wb_regnum = n;
      else if (rmap->target_number == XTENSA_DBREGN_SREG(73))
	tdep->ws_regnum = n;
      else if (rmap->target_number == XTENSA_DBREGN_SREG(233))
	tdep->debugcause_regnum = n;
      else if (rmap->target_number == XTENSA_DBREGN_SREG(232))
	tdep->exccause_regnum = n;
      else if (rmap->target_number == XTENSA_DBREGN_SREG(238))
	tdep->excvaddr_regnum = n;
      else if (rmap->target_number == XTENSA_DBREGN_SREG(0))
	tdep->lbeg_regnum = n;
      else if (rmap->target_number == XTENSA_DBREGN_SREG(1))
	tdep->lend_regnum = n;
      else if (rmap->target_number == XTENSA_DBREGN_SREG(2))
	tdep->lcount_regnum = n;
      else if (rmap->target_number == XTENSA_DBREGN_SREG(3))
	tdep->sar_regnum = n;
      else if (rmap->target_number == XTENSA_DBREGN_SREG(5))
	tdep->litbase_regnum = n;
      else if (rmap->target_number == XTENSA_DBREGN_SREG(230))
	tdep->ps_regnum = n;
#if 0
      else if (rmap->target_number == XTENSA_DBREGN_SREG(226))
	tdep->interrupt_regnum = n;
      else if (rmap->target_number == XTENSA_DBREGN_SREG(227))
	tdep->interrupt2_regnum = n;
      else if (rmap->target_number == XTENSA_DBREGN_SREG(224))
	tdep->cpenable_regnum = n;
#endif

      if (rmap->byte_size > max_size)
	max_size = rmap->byte_size;
      if (rmap->mask != 0 && tdep->num_regs == 0)
	tdep->num_regs = n;
      /* Find out out how to deal with priveleged registers.

         if ((rmap->flags & XTENSA_REGISTER_FLAGS_PRIVILEGED) != 0
              && tdep->num_nopriv_regs == 0)
           tdep->num_nopriv_regs = n;
      */
      if ((rmap->flags & XTENSA_REGISTER_FLAGS_PRIVILEGED) != 0
	  && tdep->num_regs == 0)
	tdep->num_regs = n;
    }

  /* Number of pseudo registers.  */
  tdep->num_pseudo_regs = n - tdep->num_regs;

  /* Empirically determined maximum sizes.  */
  tdep->max_register_raw_size = max_size;
  tdep->max_register_virtual_size = max_size;
}

/* Module "constructor" function.  */

extern struct gdbarch_tdep xtensa_tdep;

static struct gdbarch *
xtensa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  struct gdbarch_tdep *tdep;
  struct gdbarch *gdbarch;
  struct xtensa_abi_handler *abi_handler;

  DEBUGTRACE ("gdbarch_init()\n");

  /* We have to set the byte order before we call gdbarch_alloc.  */
  info.byte_order = XCHAL_HAVE_BE ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE;

  tdep = &xtensa_tdep;
  gdbarch = gdbarch_alloc (&info, tdep);
  xtensa_derive_tdep (tdep);

  /* Verify our configuration.  */
  xtensa_verify_config (gdbarch);

  /* Pseudo-Register read/write.  */
  set_gdbarch_pseudo_register_read (gdbarch, xtensa_pseudo_register_read);
  set_gdbarch_pseudo_register_write (gdbarch, xtensa_pseudo_register_write);

  /* Set target information.  */
  set_gdbarch_num_regs (gdbarch, tdep->num_regs);
  set_gdbarch_num_pseudo_regs (gdbarch, tdep->num_pseudo_regs);
  set_gdbarch_sp_regnum (gdbarch, tdep->a0_base + 1);
  set_gdbarch_pc_regnum (gdbarch, tdep->pc_regnum);
  set_gdbarch_ps_regnum (gdbarch, tdep->ps_regnum);

  /* Renumber registers for known formats (stabs and dwarf2).  */
  set_gdbarch_stab_reg_to_regnum (gdbarch, xtensa_reg_to_regnum);
  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, xtensa_reg_to_regnum);

  /* We provide our own function to get register information.  */
  set_gdbarch_register_name (gdbarch, xtensa_register_name);
  set_gdbarch_register_type (gdbarch, xtensa_register_type);

  /* To call functions from GDB using dummy frame */
  set_gdbarch_push_dummy_call (gdbarch, xtensa_push_dummy_call);

  set_gdbarch_believe_pcc_promotion (gdbarch, 1);

  set_gdbarch_return_value (gdbarch, xtensa_return_value);

  /* Advance PC across any prologue instructions to reach "real" code.  */
  set_gdbarch_skip_prologue (gdbarch, xtensa_skip_prologue);

  /* Stack grows downward.  */
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);

  /* Set breakpoints.  */
  set_gdbarch_breakpoint_from_pc (gdbarch, xtensa_breakpoint_from_pc);

  /* After breakpoint instruction or illegal instruction, pc still
     points at break instruction, so don't decrement.  */
  set_gdbarch_decr_pc_after_break (gdbarch, 0);

  /* We don't skip args.  */
  set_gdbarch_frame_args_skip (gdbarch, 0);

  set_gdbarch_unwind_pc (gdbarch, xtensa_unwind_pc);

  set_gdbarch_frame_align (gdbarch, xtensa_frame_align);

  set_gdbarch_dummy_id (gdbarch, xtensa_dummy_id);

  /* Frame handling.  */
  frame_base_set_default (gdbarch, &xtensa_frame_base);
  frame_unwind_append_unwinder (gdbarch, &xtensa_unwind);
  dwarf2_append_unwinders (gdbarch);

  set_gdbarch_print_insn (gdbarch, print_insn_xtensa);

  set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);

  xtensa_add_reggroups (gdbarch);
  set_gdbarch_register_reggroup_p (gdbarch, xtensa_register_reggroup_p);

  set_gdbarch_regset_from_core_section (gdbarch,
					xtensa_regset_from_core_section);

  set_solib_svr4_fetch_link_map_offsets
    (gdbarch, svr4_ilp32_fetch_link_map_offsets);

  return gdbarch;
}

static void
xtensa_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
{
  error (_("xtensa_dump_tdep(): not implemented"));
}

/* Provide a prototype to silence -Wmissing-prototypes.  */
extern initialize_file_ftype _initialize_xtensa_tdep;

void
_initialize_xtensa_tdep (void)
{
  struct cmd_list_element *c;

  gdbarch_register (bfd_arch_xtensa, xtensa_gdbarch_init, xtensa_dump_tdep);
  xtensa_init_reggroups ();

  add_setshow_zinteger_cmd ("xtensa",
			    class_maintenance,
			    &xtensa_debug_level, _("\
Set Xtensa debugging."), _("\
Show Xtensa debugging."), _("\
When non-zero, Xtensa-specific debugging is enabled. \
Can be 1, 2, 3, or 4 indicating the level of debugging."),
			    NULL,
			    NULL,
			    &setdebuglist, &showdebuglist);
}
