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

   Copyright (C) 2003-2021 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 "gdbtypes.h"
#include "gdbcore.h"
#include "value.h"
#include "osabi.h"
#include "regcache.h"
#include "reggroups.h"
#include "regset.h"

#include "dwarf2/frame.h"
#include "frame-base.h"
#include "frame-unwind.h"

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

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

#include "xtensa-isa.h"
#include "xtensa-tdep.h"
#include "xtensa-config.h"
#include <algorithm>


static unsigned 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))

/* On TX,  hardware can be configured without Exception Option.
   There is no PS register in this case.  Inside XT-GDB,  let us treat
   it as a virtual read-only register always holding the same value.  */
#define TX_PS			0x20

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

/* Big enough to hold the size of the largest register in bytes.  */
#define XTENSA_MAX_REGISTER_SIZE	64

static int
windowing_enabled (struct gdbarch *gdbarch, unsigned int ps)
{
  /* If we know CALL0 ABI is set explicitly,  say it is Call0.  */
  if (gdbarch_tdep (gdbarch)->call_abi == CallAbiCall0Only)
    return 0;

  return ((ps & PS_EXC) == 0 && (ps & PS_WOE) != 0);
}

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

/* Read Xtensa register directly from the hardware.  */ 
static unsigned long
xtensa_read_register (int regnum)
{
  ULONGEST value;

  regcache_raw_read_unsigned (get_current_regcache (), regnum, &value);
  return (unsigned long) value;
}

/* Write Xtensa register directly to the hardware.  */ 
static void
xtensa_write_register (int regnum, ULONGEST value)
{
  regcache_raw_write_unsigned (get_current_regcache (), regnum, value);
}

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

/* Find register by name.  */
static int
xtensa_find_register_by_name (struct gdbarch *gdbarch, const char *name)
{
  int i;

  for (i = 0; i < gdbarch_num_cooked_regs (gdbarch); i++)

    if (strcasecmp (gdbarch_tdep (gdbarch)->regmap[i].name, name) == 0)
      return i;

  return -1;
}

/* 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_cooked_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_cooked_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)
		{
		  std::string name = string_printf ("int%d", size * 8);

		  tp = XNEW (struct ctype_cache);
		  tp->next = tdep->type_entries;
		  tdep->type_entries = tp;
		  tp->size = size;
		  tp->virtual_type
		    = arch_integer_type (gdbarch, size * 8, 1, name.c_str ());
		}

	      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_cooked_regs (gdbarch); i++)
    if (regnum == gdbarch_tdep (gdbarch)->regmap[i].target_number)
      return i;

  return -1;
}


/* 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[(XTENSA_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 (regcache->arch ()) == 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 enum register_status
xtensa_register_read_masked (readable_regcache *regcache,
			     xtensa_register_t *reg, gdb_byte *buffer)
{
  unsigned int value[(XTENSA_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)
	{
	  enum register_status status;
	  ULONGEST val;

	  status = regcache->cooked_read (r, &val);
	  if (status != REG_VALID)
	    return status;
	  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 (regcache->arch ()) == 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;
      }

  return REG_VALID;
}


/* Read pseudo registers.  */

static enum register_status
xtensa_pseudo_register_read (struct gdbarch *gdbarch,
			     readable_regcache *regcache,
			     int regnum,
			     gdb_byte *buffer)
{
  DEBUGTRACE ("xtensa_pseudo_register_read (... regnum = %d (%s) ...)\n",
	      regnum, xtensa_register_name (gdbarch, regnum));

  /* 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))
    {
      ULONGEST value;
      enum register_status status;

      status = regcache->raw_read (gdbarch_tdep (gdbarch)->wb_regnum,
				   &value);
      if (status != REG_VALID)
	return status;
      regnum = arreg_number (gdbarch, regnum, value);
    }

  /* We can always read non-pseudo registers.  */
  if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch))
    return regcache->raw_read (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 (gdbarch_tdep (gdbarch)->call_abi == CallAbiCall0Only
	   || 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;
      return REG_VALID;
    }
  /* Pseudo registers.  */
  else if (regnum >= 0 && regnum < gdbarch_num_cooked_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 REG_VALID;
	    }
	}

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

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

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

      /* Assume that we can read the register.  */
      return regcache->raw_read (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)
{
  DEBUGTRACE ("xtensa_pseudo_register_write (... regnum = %d (%s) ...)\n",
	      regnum, xtensa_register_name (gdbarch, regnum));

  /* Renumber register, if aliases 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))
    {
      ULONGEST value;
      regcache_raw_read_unsigned (regcache,
				  gdbarch_tdep (gdbarch)->wb_regnum, &value);
      regnum = arreg_number (gdbarch, regnum, value);
    }

  /* We can always write 'core' registers.
     Note: We might have converted Ax->ARy.  */
  if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch))
    regcache->raw_write (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_cooked_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 (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)
{
  int i;

  xtensa_ar_reggroup = reggroup_new ("ar", USER_REGGROUP);
  xtensa_user_reggroup = reggroup_new ("user", USER_REGGROUP);
  xtensa_vectra_reggroup = reggroup_new ("vectra", USER_REGGROUP);

  for (i = 0; i < XTENSA_MAX_COPROCESSOR; i++)
    xtensa_cp[i] = reggroup_new (xstrprintf ("cp%d", i), 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;

  if (group == save_reggroup)
    /* Every single register should be included into the list of registers
       to be watched for changes while using -data-list-changed-registers.  */
    return 1;

  /* 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 == system_reggroup)
    return rg & xtRegisterGroupState;
  if (group == vector_reggroup || group == xtensa_vectra_reggroup)
    return rg & xtRegisterGroupVectra;
  if (group == restore_reggroup)
    return (regnum < gdbarch_num_regs (gdbarch)
	    && (reg->flags & SAVE_REST_FLAGS) == SAVE_REST_VALID);
  cp_number = xtensa_coprocessor_register_group (group);
  if (cp_number >= 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 = (const xtensa_elf_gregset_t *) gregs;
  struct gdbarch *gdbarch = rc->arch ();
  int i;

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

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


/* Xtensa register set.  */

static struct regset
xtensa_gregset =
{
  NULL,
  xtensa_supply_gregset
};


/* Iterate over supported core file register note sections. */

static void
xtensa_iterate_over_regset_sections (struct gdbarch *gdbarch,
				     iterate_over_regset_sections_cb *cb,
				     void *cb_data,
				     const struct regcache *regcache)
{
  DEBUGTRACE ("xtensa_iterate_over_regset_sections\n");

  cb (".reg", sizeof (xtensa_elf_gregset_t), sizeof (xtensa_elf_gregset_t),
      &xtensa_gregset, NULL, cb_data);
}


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

   /* Addresses of spilled A-registers.
      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_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 original 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.  */
  int c0_fpalign;		   /* Dynamic adjustment for the stack
				      pointer. It's an AND mask. Zero,
				      if alignment was not adjusted.  */
  int c0_old_sp;		   /* In case of dynamic adjustment, it is
				      a register holding unaligned sp. 
				      C0_INEXP, when undefined.  */
  int c0_sp_ofs;		   /* If "c0_old_sp" was spilled it's a
				      stack offset. C0_NOSTK otherwise.  */
					   
  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 of this frame at the function entry point.  */
  CORE_ADDR ra;		/* The raw return address of this frame.  */
  CORE_ADDR ps;		/* The PS register of the previous (older) frame.  */
  CORE_ADDR prev_sp;	/* Stack Pointer of the previous (older) 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;
      cache->c0.c0_fpalign =  0;
      cache->c0.c0_old_sp  =  C0_INEXP;
      cache->c0.c0_sp_ofs  =  C0_NOSTK;

      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 true,  if instruction to execute next is unique to Xtensa Window
   Interrupt Handlers.  It can only be one of L32E,  S32E,  RFWO,  or RFWU.  */

static int
xtensa_window_interrupt_insn (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  unsigned int insn = read_memory_integer (pc, 4, byte_order);
  unsigned int code;

  if (byte_order == BFD_ENDIAN_BIG)
    {
      /* Check, if this is L32E or S32E.  */
      code = insn & 0xf000ff00;
      if ((code == 0x00009000) || (code == 0x00009400))
	return 1;
      /* Check, if this is RFWU or RFWO.  */
      code = insn & 0xffffff00;
      return ((code == 0x00430000) || (code == 0x00530000));
    }
  else
    {
      /* Check, if this is L32E or S32E.  */
      code = insn & 0x00ff000f;
      if ((code == 0x090000) || (code == 0x490000))
	return 1;
      /* Check, if this is RFWU or RFWO.  */
      code = insn & 0x00ffffff;
      return ((code == 0x00003400) || (code == 0x00003500));
    }
}

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

  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);

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

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;
  int  windowed, ps_regnum;

  if (*this_cache)
    return (struct xtensa_frame_cache *) *this_cache;

  pc = get_frame_register_unsigned (this_frame, gdbarch_pc_regnum (gdbarch));
  ps_regnum = gdbarch_ps_regnum (gdbarch);
  ps = (ps_regnum >= 0
	? get_frame_register_unsigned (this_frame, ps_regnum) : TX_PS);

  windowed = windowing_enabled (gdbarch, ps);

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

  if (windowed)
    {
      LONGEST op1;

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

      if (safe_read_memory_integer (pc, 1, byte_order, &op1)
	  && 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 location.  */
	      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 = xtensa_read_register (regnum);
	    }
	}
    }
  else if (xtensa_window_interrupt_insn (gdbarch, pc))
    {
      /* Execution stopped inside Xtensa Window Interrupt Handler.  */

      xtensa_window_interrupt_frame_cache (this_frame, cache, pc);
      /* Everything was set already,  including cache->base.  */
      return cache;
    }
  else	/* Call0 framework.  */
    {
      call0_frame_cache (this_frame, cache, pc);  
      fp_regnum = cache->c0.fp_regnum;
    }

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

  return cache;
}

static int xtensa_session_once_reported = 1;

/* Report a problem with prologue analysis while doing backtracing.
   But, do it only once to avoid annoying repeated messages.  */

static void
warning_once (void)
{
  if (xtensa_session_once_reported == 0)
    warning (_("\
\nUnrecognised function prologue. Stack trace cannot be resolved. \
This message will not be repeated in this session.\n"));

  xtensa_session_once_reported = 1;
}


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 = (struct xtensa_frame_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 =
{
  "xtensa prologue",
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  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 = regcache->arch ();
  bfd_byte *valbuf = (bfd_byte *) 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 (areg, offset, len, valbuf);
      else
	regcache->raw_read (areg, valbuf);
    }
}


static void
xtensa_store_return_value (struct type *type,
			   struct regcache *regcache,
			   const void *dst)
{
  struct gdbarch *gdbarch = regcache->arch ();
  const bfd_byte *valbuf = (const bfd_byte *) 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: %s"),
			pulongest (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 (areg, offset, len, valbuf);
      else
	regcache->raw_write (areg, valbuf);
    }
}


static enum return_value_convention
xtensa_return_value (struct gdbarch *gdbarch,
		     struct value *function,
		     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 = ((valtype->code () == TYPE_CODE_STRUCT
			|| valtype->code () == TYPE_CODE_UNION
			|| valtype->code () == 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,
			function_call_return_method return_method,
			CORE_ADDR struct_addr)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  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)
    {
      DEBUGINFO ("[xtensa_push_dummy_call] nargs = %d\n", nargs);
      DEBUGINFO ("[xtensa_push_dummy_call] sp=0x%x, return_method=%d, "
		 "struct_addr=0x%x\n",
		 (int) sp, (int) return_method, (int) struct_addr);

      for (int i = 0; i < nargs; i++)
	{
	  struct value *arg = args[i];
	  struct type *arg_type = check_typedef (value_type (arg));
	  fprintf_unfiltered (gdb_stdlog, "%2d: %s %3s ", i,
			      host_address_to_string (arg),
			      pulongest (TYPE_LENGTH (arg_type)));
	  switch (arg_type->code ())
	    {
	    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", arg_type->code ());
	      break;
	    }
	  fprintf_unfiltered (gdb_stdlog, " %s\n",
			      host_address_to_string (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;

  if (return_method == return_method_struct)
    size = REGISTER_SIZE;

  for (int 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 (arg_type->code ())
	{
	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 (return_method == return_method_struct)
    {
      store_unsigned_integer (buf, REGISTER_SIZE, byte_order, struct_addr);
      regcache->cooked_write (ARG_1ST (gdbarch), buf);
    }

  for (int 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 (r, buf);

	      cp += REGISTER_SIZE;
	      n -= REGISTER_SIZE;
	      r++;
	    }
	  else
	    while (n > 0)
	      {
		regcache->cooked_write (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 safely overwrite A0 here.  */

  if (gdbarch_tdep (gdbarch)->call_abi != CallAbiCall0Only)
    {
      ULONGEST val;

      ra = (bp_addr & 0x3fffffff) | 0x40000000;
      regcache_raw_read_unsigned (regcache, gdbarch_ps_regnum (gdbarch), &val);
      ps = (unsigned long) val & ~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 (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;
}

/* Implement the breakpoint_kind_from_pc gdbarch method.  */

static int
xtensa_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
{
  if (gdbarch_tdep (gdbarch)->isa_use_density_instructions)
    return 2;
  else
    return 4;
}

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

/* Implement the sw_breakpoint_from_kind gdbarch method.  */

static const gdb_byte *
xtensa_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
{
  *size = kind;

  if (kind == 4)
    {
      static unsigned char big_breakpoint[] = BIG_BREAKPOINT;
      static unsigned char little_breakpoint[] = LITTLE_BREAKPOINT;

      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
	return big_breakpoint;
      else
	return little_breakpoint;
    }
  else
    {
      static unsigned char density_big_breakpoint[] = DENSITY_BIG_BREAKPOINT;
      static unsigned char density_little_breakpoint[]
	= DENSITY_LITTLE_BREAKPOINT;

      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
	return density_big_breakpoint;
      else
	return density_little_breakpoint;
    }
}

/* Call0 ABI support routines.  */

/* Return true, if PC points to "ret" or "ret.n".  */ 

static int
call0_ret (CORE_ADDR start_pc, CORE_ADDR finish_pc)
{
#define RETURN_RET goto done
  xtensa_isa isa;
  xtensa_insnbuf ins, slot;
  gdb_byte ibuf[XTENSA_ISA_BSZ];
  CORE_ADDR ia, bt, ba;
  xtensa_format ifmt;
  int ilen, islots, is;
  xtensa_opcode opc;
  const char *opcname;
  int found_ret = 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_pc, bt = ia; ia < finish_pc ; ia += ilen)
    {
      if (ia + xtensa_isa_maxlength (isa) > bt)
	{
	  ba = ia;
	  bt = (ba + XTENSA_ISA_BSZ) < finish_pc
	    ? ba + XTENSA_ISA_BSZ : finish_pc;
	  if (target_read_memory (ba, ibuf, bt - ba) != 0 )
	    RETURN_RET;
	}

      xtensa_insnbuf_from_chars (isa, ins, &ibuf[ia-ba], 0);
      ifmt = xtensa_format_decode (isa, ins);
      if (ifmt == XTENSA_UNDEFINED)
	RETURN_RET;
      ilen = xtensa_format_length (isa, ifmt);
      if (ilen == XTENSA_UNDEFINED)
	RETURN_RET;
      islots = xtensa_format_num_slots (isa, ifmt);
      if (islots == XTENSA_UNDEFINED)
	RETURN_RET;
      
      for (is = 0; is < islots; ++is)
	{
	  if (xtensa_format_get_slot (isa, ifmt, is, ins, slot))
	    RETURN_RET;
	  
	  opc = xtensa_opcode_decode (isa, ifmt, is, slot);
	  if (opc == XTENSA_UNDEFINED) 
	    RETURN_RET;
	  
	  opcname = xtensa_opcode_name (isa, opc);
	  
	  if ((strcasecmp (opcname, "ret.n") == 0)
	      || (strcasecmp (opcname, "ret") == 0))
	    {
	      found_ret = 1;
	      RETURN_RET;
	    }
	}
    }
 done:
  xtensa_insnbuf_free(isa, slot);
  xtensa_insnbuf_free(isa, ins);
  return found_ret;
}

/* 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_and,	       /* Bitwise "and"-ing two registers.  */
  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_rwxsr,	       /* RSR, WRS, or XSR instructions.  */
  c0opc_l32e,          /* L32E instruction.  */
  c0opc_s32e,          /* S32E instruction.  */
  c0opc_rfwo,          /* RFWO instruction.  */
  c0opc_rfwu,          /* RFWU instruction.  */
  c0opc_NrOf	       /* Number of opcode classifications.  */
} xtensa_insn_kind;

/* Return true,  if OPCNAME is RSR,  WRS,  or XSR instruction.  */

static int
rwx_special_register (const char *opcname)
{
  char ch = *opcname++;
  
  if ((ch != 'r') && (ch != 'w') && (ch != 'x'))
    return 0;
  if (*opcname++ != 's')
    return 0;
  if (*opcname++ != 'r')
    return 0;
  if (*opcname++ != '.')
    return 0;

  return 1;
}

/* 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 (strcasecmp (opcname, "rfwo") == 0)
    opclass = c0opc_rfwo;
  else if (strcasecmp (opcname, "rfwu") == 0)
    opclass = c0opc_rfwu;
  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, "and") == 0)
    opclass = c0opc_and;
  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;
  else if (strcasecmp (opcname, "l32e") == 0)
    opclass = c0opc_l32e;
  else if (strcasecmp (opcname, "s32e") == 0)
    opclass = c0opc_s32e;
  else if (rwx_special_register (opcname))
    opclass = c0opc_rwxsr;

  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.  Returns 0, if analysis was successful, non-zero
   otherwise.  */

static int
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, int spreg, xtensa_frame_cache_t *cache)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  unsigned litbase, 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_and:
      /* 3 operands:  dst, src1, src2.  */
      gdb_assert (nods == 3);
      if (cache->c0.c0_fpalign == 0)
	{
	  /* Handle dynamic stack alignment.  */
	  if ((src[odv[0]].fr_reg == spreg) && (src[odv[1]].fr_reg == spreg))
	    {
	      if (src[odv[2]].fr_reg == C0_CONST)
		cache->c0.c0_fpalign = src[odv[2]].fr_ofs;
	      break;
	    }
	  else if ((src[odv[0]].fr_reg == spreg)
		   && (src[odv[2]].fr_reg == spreg))
	    {
	      if (src[odv[1]].fr_reg == C0_CONST)
		cache->c0.c0_fpalign = src[odv[1]].fr_ofs;
	      break;
	    }
	  /* else fall through.  */
	}
      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);
      /* First, check if it's a special case of saving unaligned SP
	 to a spare register in case of dynamic stack adjustment.
	 But, only do it one time.  The second time could be initializing
	 frame pointer.  We don't want to overwrite the first one.  */
      if ((odv[1] == spreg) && (cache->c0.c0_old_sp == C0_INEXP))
	cache->c0.c0_old_sp = odv[0];

      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);
      /* litbase = xtensa_get_litbase (pc);  can be also used.  */
      litbase = (gdbarch_tdep (gdbarch)->litbase_regnum == -1)
	? 0 : xtensa_read_register
		(gdbarch_tdep (gdbarch)->litbase_regnum);
      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);
      /* First, check if it's a spill for saved unaligned SP,
	 when dynamic stack adjustment was applied to this frame.  */
      if ((cache->c0.c0_fpalign != 0)		/* Dynamic stack adjustment.  */
	  && (odv[1] == spreg)			/* SP usage indicates spill.  */
	  && (odv[0] == cache->c0.c0_old_sp))	/* Old SP register spilled.  */
	cache->c0.c0_sp_ofs = odv[2];

      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;
      /* If we end up inside Window Overflow / Underflow interrupt handler
	 report an error because these handlers should have been handled
	 already in a different way.  */
    case c0opc_l32e:
    case c0opc_s32e:
    case c0opc_rfwo:
    case c0opc_rfwu:
      return 1;
    default:
      return 1;
    }
  return 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.
   InOut args:
      cache   Xtensa frame cache.

      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,
			int nregs, xtensa_frame_cache_t *cache)
{
  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.  */
  gdb_byte 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.
     Initialize 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 assumption for the end of the prologue.  */
  if (pc == 0)
    {
      find_pc_partial_function (start, 0, NULL, &end_pc);
      body_pc = std::min (end_pc, body_pc);
    }
  else
    body_pc = std::min (pc, body_pc);

  cache->call0 = 1;
  rtmp = (xtensa_c0reg_t*) alloca(nregs * sizeof(xtensa_c0reg_t));

  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;
	  if (target_read_memory (ba, ibuf, bt - ba) != 0 )
	    error (_("Unable to read target memory ..."));
	}

      /* 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] = cache->c0.c0_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:  /* Flow control instructions stop analysis.  */
	    case c0opc_rwxsr: /* RSR, WSR, XSR instructions stop analysis.  */
	      goto done;

	    case c0opc_entry:
	      cache->call0 = 0;
	      ia += ilen;	       	/* Skip over 'entry' insn.  */
	      goto done;

	    default:
	      cache->call0 = 1;
	    }

	  /* Only expected opcodes should get this far.  */

	  /* 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;
		  if ((odv[0] == 1) && (odv[1] != 1))
		    /* OR  A1, An, An  , where n != 1.
		       This means we are inside epilogue already.  */
		    goto done;
		}
	      else
		{
		  opclass = c0opc_uninteresting;
		  continue;
		}
	    }

	  /* Track register movement and modification for this operation.  */
	  fail = call0_track_op (gdbarch, cache->c0.c0_rt, rtmp,
				 opclass, nods, odv, ia, 1, cache);
	  if (fail)
	    goto done;
	}
    }
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)
{
  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_SP, c0_hasfp = 0, c0_frmsz = 0, prev_sp = 0, to_stk;
 
  sp = get_frame_register_unsigned
    (this_frame, gdbarch_tdep (gdbarch)->a0_base + 1);
  fp = sp; /* Assume FP == SP until proven otherwise.  */

  /* 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, C0_NREGS, cache);

      if (body_pc == XTENSA_ISA_BADPC)
	{
	  warning_once ();
	  ra = 0;
	  goto finish_frame_analysis;
	}
    }
  
  /* 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 do 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;
   }

  if (cache->c0.c0_fpalign)
    {
      /* This frame has a special prologue with a dynamic stack adjustment
	 to force an alignment, which is bigger than standard 16 bytes.  */

      CORE_ADDR unaligned_sp;

      if (cache->c0.c0_old_sp == C0_INEXP)
	/* This can't be.  Prologue code should be consistent.
	   Unaligned stack pointer should be saved in a spare register.  */
	{
	  warning_once ();
	  ra = 0;
	  goto finish_frame_analysis;
	}

      if (cache->c0.c0_sp_ofs == C0_NOSTK)
	/* Saved unaligned value of SP is kept in a register.  */
	unaligned_sp = get_frame_register_unsigned
	  (this_frame, gdbarch_tdep (gdbarch)->a0_base + cache->c0.c0_old_sp);
      else
	/* Get the value from stack.  */
	unaligned_sp = (CORE_ADDR)
	  read_memory_integer (fp + cache->c0.c0_sp_ofs, 4, byte_order);

      prev_sp = unaligned_sp + c0_frmsz;
    }
  else
    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);

      /* 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 one.  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;
    }
  
 finish_frame_analysis:
  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;
}

static CORE_ADDR a0_saved;
static CORE_ADDR a7_saved;
static CORE_ADDR a11_saved;
static int a0_was_saved;
static int a7_was_saved;
static int a11_was_saved;

/* Simulate L32E instruction:  AT <-- ref (AS + offset).  */
static void
execute_l32e (struct gdbarch *gdbarch, int at, int as, int offset, CORE_ADDR wb)
{
  int atreg = arreg_number (gdbarch, gdbarch_tdep (gdbarch)->a0_base + at, wb);
  int asreg = arreg_number (gdbarch, gdbarch_tdep (gdbarch)->a0_base + as, wb);
  CORE_ADDR addr = xtensa_read_register (asreg) + offset;
  unsigned int spilled_value
    = read_memory_unsigned_integer (addr, 4, gdbarch_byte_order (gdbarch));

  if ((at == 0) && !a0_was_saved)
    {
      a0_saved = xtensa_read_register (atreg);
      a0_was_saved = 1;
    }
  else if ((at == 7) && !a7_was_saved)
    {
      a7_saved = xtensa_read_register (atreg);
      a7_was_saved = 1;
    }
  else if ((at == 11) && !a11_was_saved)
    {
      a11_saved = xtensa_read_register (atreg);
      a11_was_saved = 1;
    }

  xtensa_write_register (atreg, spilled_value);
}

/* Simulate S32E instruction:  AT --> ref (AS + offset).  */
static void
execute_s32e (struct gdbarch *gdbarch, int at, int as, int offset, CORE_ADDR wb)
{
  int atreg = arreg_number (gdbarch, gdbarch_tdep (gdbarch)->a0_base + at, wb);
  int asreg = arreg_number (gdbarch, gdbarch_tdep (gdbarch)->a0_base + as, wb);
  CORE_ADDR addr = xtensa_read_register (asreg) + offset;
  ULONGEST spilled_value = xtensa_read_register (atreg);

  write_memory_unsigned_integer (addr, 4,
				 gdbarch_byte_order (gdbarch),
				 spilled_value);
}

#define XTENSA_MAX_WINDOW_INTERRUPT_HANDLER_LEN  200

typedef enum
{
  xtWindowOverflow,
  xtWindowUnderflow,
  xtNoExceptionHandler
} xtensa_exception_handler_t;

/* Execute instruction stream from current PC until hitting RFWU or RFWO.
   Return type of Xtensa Window Interrupt Handler on success.  */
static xtensa_exception_handler_t
execute_code (struct gdbarch *gdbarch, CORE_ADDR current_pc, CORE_ADDR wb)
{
  xtensa_isa isa;
  xtensa_insnbuf ins, slot;
  gdb_byte ibuf[XTENSA_ISA_BSZ];
  CORE_ADDR ia, bt, ba;
  xtensa_format ifmt;
  int ilen, islots, is;
  xtensa_opcode opc;
  int insn_num = 0;
  void (*func) (struct gdbarch *, int, int, int, CORE_ADDR);

  uint32_t at, as, offset;

  /* WindowUnderflow12 = true, when inside _WindowUnderflow12.  */ 
  int WindowUnderflow12 = (current_pc & 0x1ff) >= 0x140; 

  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;
  ia = current_pc;
  bt = ia;

  a0_was_saved = 0;
  a7_was_saved = 0;
  a11_was_saved = 0;

  while (insn_num++ < XTENSA_MAX_WINDOW_INTERRUPT_HANDLER_LEN)
    {
      if (ia + xtensa_isa_maxlength (isa) > bt)
	{
	  ba = ia;
	  bt = (ba + XTENSA_ISA_BSZ);
	  if (target_read_memory (ba, ibuf, bt - ba) != 0)
	    return xtNoExceptionHandler;
	}
      xtensa_insnbuf_from_chars (isa, ins, &ibuf[ia-ba], 0);
      ifmt = xtensa_format_decode (isa, ins);
      if (ifmt == XTENSA_UNDEFINED)
	return xtNoExceptionHandler;
      ilen = xtensa_format_length (isa, ifmt);
      if (ilen == XTENSA_UNDEFINED)
	return xtNoExceptionHandler;
      islots = xtensa_format_num_slots (isa, ifmt);
      if (islots == XTENSA_UNDEFINED)
	return xtNoExceptionHandler;
      for (is = 0; is < islots; ++is)
	{
	  if (xtensa_format_get_slot (isa, ifmt, is, ins, slot))
	    return xtNoExceptionHandler;
	  opc = xtensa_opcode_decode (isa, ifmt, is, slot);
	  if (opc == XTENSA_UNDEFINED) 
	    return xtNoExceptionHandler;
	  switch (call0_classify_opcode (isa, opc))
	    {
	    case c0opc_illegal:
	    case c0opc_flow:
	    case c0opc_entry:
	    case c0opc_break:
	      /* We expect none of them here.  */
	      return xtNoExceptionHandler;
	    case c0opc_l32e:
	      func = execute_l32e;
	      break;
	    case c0opc_s32e:
	      func = execute_s32e;
	      break;
	    case c0opc_rfwo: /* RFWO.  */
	      /* Here, we return from WindowOverflow handler and,
		 if we stopped at the very beginning, which means
		 A0 was saved, we have to restore it now.  */
	      if (a0_was_saved)
		{
		  int arreg = arreg_number (gdbarch,
					    gdbarch_tdep (gdbarch)->a0_base,
					    wb);
		  xtensa_write_register (arreg, a0_saved);
		}
	      return xtWindowOverflow;
	    case c0opc_rfwu: /* RFWU.  */
	      /* Here, we return from WindowUnderflow handler.
		 Let's see if either A7 or A11 has to be restored.  */
	      if (WindowUnderflow12)
		{
		  if (a11_was_saved)
		    {
		      int arreg = arreg_number (gdbarch,
						gdbarch_tdep (gdbarch)->a0_base + 11,
						wb);
		      xtensa_write_register (arreg, a11_saved);
		    }
		}
	      else if (a7_was_saved)
		{
		  int arreg = arreg_number (gdbarch,
					    gdbarch_tdep (gdbarch)->a0_base + 7,
					    wb);
		  xtensa_write_register (arreg, a7_saved);
		}
	      return xtWindowUnderflow;
	    default: /* Simply skip this insns.  */
	      continue;
	    }

	  /* Decode arguments for L32E / S32E and simulate their execution.  */
	  if ( xtensa_opcode_num_operands (isa, opc) != 3 )
	    return xtNoExceptionHandler;
	  if (xtensa_operand_get_field (isa, opc, 0, ifmt, is, slot, &at))
	    return xtNoExceptionHandler;
	  if (xtensa_operand_decode (isa, opc, 0, &at))
	    return xtNoExceptionHandler;
	  if (xtensa_operand_get_field (isa, opc, 1, ifmt, is, slot, &as))
	    return xtNoExceptionHandler;
	  if (xtensa_operand_decode (isa, opc, 1, &as))
	    return xtNoExceptionHandler;
	  if (xtensa_operand_get_field (isa, opc, 2, ifmt, is, slot, &offset))
	    return xtNoExceptionHandler;
	  if (xtensa_operand_decode (isa, opc, 2, &offset))
	    return xtNoExceptionHandler;

	  (*func) (gdbarch, at, as, offset, wb);
	}

      ia += ilen;
    }
  return xtNoExceptionHandler;
}

/* Handle Window Overflow / Underflow exception frames.  */

static void
xtensa_window_interrupt_frame_cache (struct frame_info *this_frame,
				     xtensa_frame_cache_t *cache,
				     CORE_ADDR pc)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  CORE_ADDR ps, wb, ws, ra;
  int epc1_regnum, i, regnum;
  xtensa_exception_handler_t eh_type;

  /* Read PS, WB, and WS from the hardware. Note that PS register
     must be present, if Windowed ABI is supported.  */
  ps = xtensa_read_register (gdbarch_ps_regnum (gdbarch));
  wb = xtensa_read_register (gdbarch_tdep (gdbarch)->wb_regnum);
  ws = xtensa_read_register (gdbarch_tdep (gdbarch)->ws_regnum);

  /* Execute all the remaining instructions from Window Interrupt Handler
     by simulating them on the remote protocol level.  On return, set the
     type of Xtensa Window Interrupt Handler, or report an error.  */
  eh_type = execute_code (gdbarch, pc, wb);
  if (eh_type == xtNoExceptionHandler)
    error (_("\
Unable to decode Xtensa Window Interrupt Handler's code."));

  cache->ps = ps ^ PS_EXC;	/* Clear the exception bit in PS.  */
  cache->call0 = 0;		/* It's Windowed ABI.  */

  /* All registers for the cached frame will be alive.  */
  for (i = 0; i < XTENSA_NUM_SAVED_AREGS; i++)
    cache->wd.aregs[i] = -1;

  if (eh_type == xtWindowOverflow)
    cache->wd.ws = ws ^ (1 << wb);
  else /* eh_type == xtWindowUnderflow.  */
    cache->wd.ws = ws | (1 << wb);

  cache->wd.wb = (ps & 0xf00) >> 8; /* Set WB to OWB.  */
  regnum = arreg_number (gdbarch, gdbarch_tdep (gdbarch)->a0_base,
			 cache->wd.wb);
  ra = xtensa_read_register (regnum);
  cache->wd.callsize = WINSIZE (ra);
  cache->prev_sp = xtensa_read_register (regnum + 1);
  /* Set regnum to a frame pointer of the frame being cached.  */
  regnum = xtensa_scan_prologue (gdbarch, pc);
  regnum = arreg_number (gdbarch,
			 gdbarch_tdep (gdbarch)->a0_base + regnum,
			 cache->wd.wb);
  cache->base = get_frame_register_unsigned (this_frame, regnum);

  /* Read PC of interrupted function from EPC1 register.  */
  epc1_regnum = xtensa_find_register_by_name (gdbarch,"epc1");
  if (epc1_regnum < 0)
    error(_("Unable to read Xtensa register EPC1"));
  cache->ra = xtensa_read_register (epc1_regnum);
  cache->pc = get_frame_func (this_frame);
}


/* 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 one-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 within a different
	 function,  and if so return the start PC.  We know we have symbol
	 information.  */

      CORE_ADDR end_func;

      if ((gdbarch_tdep (gdbarch)->call_abi == CallAbiCall0Only)
	  && call0_ret (start_pc, prologue_sal.end))
	return start_pc;

      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,
				    xtensa_alloc_frame_cache (0));
  return body_pc != 0 ? body_pc : start_pc;
}

/* Verify the current configuration.  */
static void
xtensa_verify_config (struct gdbarch *gdbarch)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  string_file log;

  /* Verify that we got a reasonable number of AREGS.  */
  if ((tdep->num_aregs & -tdep->num_aregs) != tdep->num_aregs)
    log.printf (_("\
\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)
    log.printf (_("\n\tpc_regnum: No PC register"));
  if (tdep->isa_use_exceptions && tdep->ps_regnum == -1)
    log.printf (_("\n\tps_regnum: No PS register"));

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

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

  if (!log.empty ())
    internal_error (__FILE__, __LINE__,
		    _("the following are invalid: %s"), log.c_str ());
}


/* 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))
/* User registers 0..255.  */
#define XTENSA_DBREGN_UREG(n)  (0x0300+(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;
      else if (rmap->target_number == XTENSA_DBREGN_UREG(231))
	tdep->threadptr_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;
      if ((rmap->flags & XTENSA_REGISTER_FLAGS_PRIVILEGED) != 0
	  && tdep->num_nopriv_regs == 0)
	tdep->num_nopriv_regs = n;
    }
  if (tdep->num_regs == 0)
    tdep->num_regs = tdep->num_nopriv_regs;

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

  DEBUGTRACE ("gdbarch_init()\n");

  if (!xtensa_default_isa)
    xtensa_default_isa = xtensa_isa_init (0, 0);

  /* 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);
  xtensa_session_once_reported = 0;

  set_gdbarch_wchar_bit (gdbarch, 2 * TARGET_CHAR_BIT);
  set_gdbarch_wchar_signed (gdbarch, 0);

  /* 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_kind_from_pc (gdbarch,
				       xtensa_breakpoint_kind_from_pc);
  set_gdbarch_sw_breakpoint_from_kind (gdbarch,
				       xtensa_sw_breakpoint_from_kind);

  /* 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_have_nonsteppable_watchpoint (gdbarch, 1);

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

  set_gdbarch_iterate_over_regset_sections
    (gdbarch, xtensa_iterate_over_regset_sections);

  set_solib_svr4_fetch_link_map_offsets
    (gdbarch, svr4_ilp32_fetch_link_map_offsets);

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

  return gdbarch;
}

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

void _initialize_xtensa_tdep ();
void
_initialize_xtensa_tdep ()
{
  gdbarch_register (bfd_arch_xtensa, xtensa_gdbarch_init, xtensa_dump_tdep);
  xtensa_init_reggroups ();

  add_setshow_zuinteger_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);
}
