Automatic date update in version.in
[deliverable/binutils-gdb.git] / gdb / xtensa-tdep.c
index 19a59b98f6912676257359a74f5c146ff302491c..2a430bf527f30bbc45e9671600e6760a8e564118 100644 (file)
@@ -1,7 +1,6 @@
 /* Target-dependent code for the Xtensa port of GDB, the GNU debugger.
 
-   Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2011
-   Free Software Foundation, Inc.
+   Copyright (C) 2003-2019 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -29,7 +28,7 @@
 #include "value.h"
 #include "dis-asm.h"
 #include "inferior.h"
-#include "floatformat.h"
+#include "osabi.h"
 #include "regcache.h"
 #include "reggroups.h"
 #include "regset.h"
@@ -38,7 +37,6 @@
 #include "dwarf2.h"
 #include "dwarf2-frame.h"
 #include "dwarf2loc.h"
-#include "frame.h"
 #include "frame-base.h"
 #include "frame-unwind.h"
 
 
 #include "command.h"
 #include "gdbcmd.h"
-#include "gdb_assert.h"
 
 #include "xtensa-isa.h"
 #include "xtensa-tdep.h"
 #include "xtensa-config.h"
+#include <algorithm>
 
 
-static int xtensa_debug_level = 0;
+static unsigned int xtensa_debug_level = 0;
 
 #define DEBUGWARN(args...) \
   if (xtensa_debug_level > 0) \
@@ -121,7 +119,10 @@ static int xtensa_debug_level = 0;
 #define PS_WOE                 (1<<18)
 #define PS_EXC                 (1<<4)
 
-static inline int
+/* 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.  */
@@ -161,7 +162,8 @@ areg_number (struct gdbarch *gdbarch, int ar_regnum, unsigned int wb)
   return (areg > 15) ? -1 : areg;
 }
 
-static inline unsigned long
+/* Read Xtensa register directly from the hardware.  */ 
+static unsigned long
 xtensa_read_register (int regnum)
 {
   ULONGEST value;
@@ -170,7 +172,8 @@ xtensa_read_register (int regnum)
   return (unsigned long) value;
 }
 
-static inline void
+/* 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);
@@ -227,13 +230,11 @@ extract_call_winsize (struct gdbarch *gdbarch, CORE_ADDR pc)
 
 /* Find register by name.  */
 static int
-xtensa_find_register_by_name (struct gdbarch *gdbarch, char *name)
+xtensa_find_register_by_name (struct gdbarch *gdbarch, const char *name)
 {
   int i;
 
-  for (i = 0; i < gdbarch_num_regs (gdbarch)
-        + gdbarch_num_pseudo_regs (gdbarch);
-       i++)
+  for (i = 0; i < gdbarch_num_cooked_regs (gdbarch); i++)
 
     if (strcasecmp (gdbarch_tdep (gdbarch)->regmap[i].name, name) == 0)
       return i;
@@ -246,8 +247,7 @@ static const char *
 xtensa_register_name (struct gdbarch *gdbarch, int regnum)
 {
   /* Return the name stored in the register map.  */
-  if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch)
-                             + gdbarch_num_pseudo_regs (gdbarch))
+  if (regnum >= 0 && regnum < gdbarch_num_cooked_regs (gdbarch))
     return gdbarch_tdep (gdbarch)->regmap[regnum].name;
 
   internal_error (__FILE__, __LINE__, _("invalid register %d"), regnum);
@@ -273,8 +273,7 @@ xtensa_register_type (struct gdbarch *gdbarch, int regnum)
     return builtin_type (gdbarch)->builtin_data_ptr;
 
   /* Return the stored type for all other registers.  */
-  else if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch)
-                                  + gdbarch_num_pseudo_regs (gdbarch))
+  else if (regnum >= 0 && regnum < gdbarch_num_cooked_regs (gdbarch))
     {
       xtensa_register_t* reg = &tdep->regmap[regnum];
 
@@ -316,15 +315,14 @@ xtensa_register_type (struct gdbarch *gdbarch, int regnum)
 
              if (tp == NULL)
                {
-                 char *name = xmalloc (16);
-                 tp = xmalloc (sizeof (struct ctype_cache));
+                 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;
-
-                 sprintf (name, "int%d", size * 8);
                  tp->virtual_type
-                   = arch_integer_type (gdbarch, size * 8, 1, xstrdup (name));
+                   = arch_integer_type (gdbarch, size * 8, 1, name.c_str ());
                }
 
              reg->ctype = tp->virtual_type;
@@ -350,15 +348,11 @@ xtensa_reg_to_regnum (struct gdbarch *gdbarch, int regnum)
   if (regnum >= 0 && regnum < 16)
     return gdbarch_tdep (gdbarch)->a0_base + regnum;
 
-  for (i = 0;
-       i < gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
-       i++)
+  for (i = 0; i < gdbarch_num_cooked_regs (gdbarch); i++)
     if (regnum == gdbarch_tdep (gdbarch)->regmap[i].target_number)
       return i;
 
-  internal_error (__FILE__, __LINE__,
-                 _("invalid dwarf/stabs register number %d"), regnum);
-  return 0;
+  return -1;
 }
 
 
@@ -371,7 +365,7 @@ static void
 xtensa_register_write_masked (struct regcache *regcache,
                              xtensa_register_t *reg, const gdb_byte *buffer)
 {
-  unsigned int value[(MAX_REGISTER_SIZE + 3) / 4];
+  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).  */
@@ -387,7 +381,7 @@ xtensa_register_write_masked (struct regcache *regcache,
   DEBUGTRACE ("xtensa_register_write_masked ()\n");
 
   /* Copy the masked register to host byte-order.  */
-  if (gdbarch_byte_order (get_regcache_arch (regcache)) == BFD_ENDIAN_BIG)
+  if (gdbarch_byte_order (regcache->arch ()) == BFD_ENDIAN_BIG)
     for (i = 0; i < bytesize; i++)
       {
        mem >>= 8;
@@ -451,11 +445,11 @@ xtensa_register_write_masked (struct regcache *regcache,
 /* Read a tie state or mapped registers.  Read the masked areas
    of the registers and assemble them into a single value.  */
 
-static void
-xtensa_register_read_masked (struct regcache *regcache,
+static enum register_status
+xtensa_register_read_masked (readable_regcache *regcache,
                             xtensa_register_t *reg, gdb_byte *buffer)
 {
-  unsigned int value[(MAX_REGISTER_SIZE + 3) / 4];
+  unsigned int value[(XTENSA_MAX_REGISTER_SIZE + 3) / 4];
   const xtensa_mask_t *mask = reg->mask;
 
   int shift = 0;
@@ -477,8 +471,12 @@ xtensa_register_read_masked (struct regcache *regcache,
       int r = mask->mask[i].reg_num;
       if (r >= 0)
        {
+         enum register_status status;
          ULONGEST val;
-         regcache_cooked_read_unsigned (regcache, r, &val);
+
+         status = regcache->cooked_read (r, &val);
+         if (status != REG_VALID)
+           return status;
          regval = (unsigned int) val;
        }
       else
@@ -517,7 +515,7 @@ xtensa_register_read_masked (struct regcache *regcache,
   ptr = value;
   mem = *ptr;
 
-  if (gdbarch_byte_order (get_regcache_arch (regcache)) == BFD_ENDIAN_BIG)
+  if (gdbarch_byte_order (regcache->arch ()) == BFD_ENDIAN_BIG)
     for (i = 0; i < bytesize; i++)
       {
        if ((i & 3) == 0)
@@ -533,57 +531,55 @@ xtensa_register_read_masked (struct regcache *regcache,
        buffer[i] = mem & 0xff;
        mem >>= 8;
       }
+
+  return REG_VALID;
 }
 
 
 /* Read pseudo registers.  */
 
-static void
+static enum register_status
 xtensa_pseudo_register_read (struct gdbarch *gdbarch,
-                            struct regcache *regcache,
+                            readable_regcache *regcache,
                             int regnum,
                             gdb_byte *buffer)
 {
-  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-
   DEBUGTRACE ("xtensa_pseudo_register_read (... regnum = %d (%s) ...)\n",
              regnum, xtensa_register_name (gdbarch, regnum));
 
-  if (regnum == gdbarch_num_regs (gdbarch)
-               + gdbarch_num_pseudo_regs (gdbarch) - 1)
-     regnum = gdbarch_tdep (gdbarch)->a0_base + 1;
-
   /* Read aliases a0..a15, if this is a Windowed ABI.  */
   if (gdbarch_tdep (gdbarch)->isa_use_windowed_registers
       && (regnum >= gdbarch_tdep (gdbarch)->a0_base)
       && (regnum <= gdbarch_tdep (gdbarch)->a0_base + 15))
     {
-      gdb_byte *buf = (gdb_byte *) alloca (MAX_REGISTER_SIZE);
-
-      regcache_raw_read (regcache, gdbarch_tdep (gdbarch)->wb_regnum, buf);
-      regnum = arreg_number (gdbarch, regnum,
-                            extract_unsigned_integer (buf, 4, byte_order));
+      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))
-    regcache_raw_read (regcache, regnum, buffer);
-
+    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 (regnum < gdbarch_tdep (gdbarch)->a0_base)
+  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_regs (gdbarch)
-                       + gdbarch_num_pseudo_regs (gdbarch))
+  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;
@@ -596,7 +592,7 @@ xtensa_pseudo_register_read (struct gdbarch *gdbarch,
            {
              warning (_("cannot read register %s"),
                       xtensa_register_name (gdbarch, regnum));
-             return;
+             return REG_VALID;
            }
        }
 
@@ -607,26 +603,23 @@ xtensa_pseudo_register_read (struct gdbarch *gdbarch,
          if (flags & xtTargetFlagsUseFetchStore)
            {
              warning (_("cannot read register"));
-             return;
+             return REG_VALID;
            }
 
          /* On some targets (esp. simulators), we can always read the reg.  */
          else if ((flags & xtTargetFlagsNonVisibleRegs) == 0)
            {
              warning (_("cannot read register"));
-             return;
+             return REG_VALID;
            }
        }
 
       /* We can always read mapped registers.  */
       else if (type == xtRegisterTypeMapped || type == xtRegisterTypeTieState)
-        {
-         xtensa_register_read_masked (regcache, reg, buffer);
-         return;
-       }
+       return xtensa_register_read_masked (regcache, reg, buffer);
 
       /* Assume that we can read the register.  */
-      regcache_raw_read (regcache, regnum, buffer);
+      return regcache->raw_read (regnum, buffer);
     }
   else
     internal_error (__FILE__, __LINE__,
@@ -642,33 +635,24 @@ xtensa_pseudo_register_write (struct gdbarch *gdbarch,
                              int regnum,
                              const gdb_byte *buffer)
 {
-  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-
   DEBUGTRACE ("xtensa_pseudo_register_write (... regnum = %d (%s) ...)\n",
              regnum, xtensa_register_name (gdbarch, regnum));
 
-  if (regnum == gdbarch_num_regs (gdbarch)
-               + gdbarch_num_pseudo_regs (gdbarch) -1)
-     regnum = gdbarch_tdep (gdbarch)->a0_base + 1;
-
-  /* Renumber register, if aliase a0..a15 on Windowed ABI.  */
+  /* 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))
     {
-      gdb_byte *buf = (gdb_byte *) alloca (MAX_REGISTER_SIZE);
-      unsigned int wb;
-
-      regcache_raw_read (regcache,
-                        gdbarch_tdep (gdbarch)->wb_regnum, buf);
-      regnum = arreg_number (gdbarch, regnum,
-                            extract_unsigned_integer (buf, 4, byte_order));
+      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 (regcache, regnum, buffer);
+    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.  */
@@ -678,9 +662,7 @@ xtensa_pseudo_register_write (struct gdbarch *gdbarch,
       return;
     }
   /* Pseudo registers.  */
-  else if (regnum >= 0
-          && regnum < gdbarch_num_regs (gdbarch)
-                      + gdbarch_num_pseudo_regs (gdbarch))
+  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;
@@ -725,20 +707,13 @@ xtensa_pseudo_register_write (struct gdbarch *gdbarch,
        }
 
       /* Assume that we can write the register.  */
-      regcache_raw_write (regcache, regnum, buffer);
+      regcache->raw_write (regnum, buffer);
     }
   else
     internal_error (__FILE__, __LINE__,
                    _("invalid register number %d"), regnum);
 }
 
-static inline char xtensa_hextochar (int xdigit)
-{
-  static char hex[]="0123456789abcdef";
-
-  return hex[xdigit & 0x0f];
-}
-
 static struct reggroup *xtensa_ar_reggroup;
 static struct reggroup *xtensa_user_reggroup;
 static struct reggroup *xtensa_vectra_reggroup;
@@ -748,17 +723,13 @@ static void
 xtensa_init_reggroups (void)
 {
   int i;
-  char cpname[] = "cp0";
 
   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++)
-    {
-      cpname[2] = xtensa_hextochar (i);
-      xtensa_cp[i] = reggroup_new (cpname, USER_REGGROUP);
-    }
+    xtensa_cp[i] = reggroup_new (xstrprintf ("cp%d", i), USER_REGGROUP);
 }
 
 static void
@@ -840,7 +811,8 @@ xtensa_register_reggroup_p (struct gdbarch *gdbarch,
   if (group == restore_reggroup)
     return (regnum < gdbarch_num_regs (gdbarch)
            && (reg->flags & SAVE_REST_FLAGS) == SAVE_REST_VALID);
-  if ((cp_number = xtensa_coprocessor_register_group (group)) >= 0)
+  cp_number = xtensa_coprocessor_register_group (group);
+  if (cp_number >= 0)
     return rg & (xtRegisterGroupCP0 << cp_number);
   else
     return 1;
@@ -858,45 +830,44 @@ xtensa_supply_gregset (const struct regset *regset,
                       const void *gregs,
                       size_t len)
 {
-  const xtensa_elf_gregset_t *regs = gregs;
-  struct gdbarch *gdbarch = get_regcache_arch (rc);
+  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)
-    regcache_raw_supply (rc, gdbarch_pc_regnum (gdbarch), (char *) &regs->pc);
+    rc->raw_supply (gdbarch_pc_regnum (gdbarch), (char *) &regs->pc);
   if (regnum == gdbarch_ps_regnum (gdbarch) || regnum == -1)
-    regcache_raw_supply (rc, gdbarch_ps_regnum (gdbarch), (char *) &regs->ps);
+    rc->raw_supply (gdbarch_ps_regnum (gdbarch), (char *) &regs->ps);
   if (regnum == gdbarch_tdep (gdbarch)->wb_regnum || regnum == -1)
-    regcache_raw_supply (rc, gdbarch_tdep (gdbarch)->wb_regnum,
-                        (char *) &regs->windowbase);
+    rc->raw_supply (gdbarch_tdep (gdbarch)->wb_regnum,
+                   (char *) &regs->windowbase);
   if (regnum == gdbarch_tdep (gdbarch)->ws_regnum || regnum == -1)
-    regcache_raw_supply (rc, gdbarch_tdep (gdbarch)->ws_regnum,
-                        (char *) &regs->windowstart);
+    rc->raw_supply (gdbarch_tdep (gdbarch)->ws_regnum,
+                   (char *) &regs->windowstart);
   if (regnum == gdbarch_tdep (gdbarch)->lbeg_regnum || regnum == -1)
-    regcache_raw_supply (rc, gdbarch_tdep (gdbarch)->lbeg_regnum,
-                        (char *) &regs->lbeg);
+    rc->raw_supply (gdbarch_tdep (gdbarch)->lbeg_regnum,
+                   (char *) &regs->lbeg);
   if (regnum == gdbarch_tdep (gdbarch)->lend_regnum || regnum == -1)
-    regcache_raw_supply (rc, gdbarch_tdep (gdbarch)->lend_regnum,
-                        (char *) &regs->lend);
+    rc->raw_supply (gdbarch_tdep (gdbarch)->lend_regnum,
+                   (char *) &regs->lend);
   if (regnum == gdbarch_tdep (gdbarch)->lcount_regnum || regnum == -1)
-    regcache_raw_supply (rc, gdbarch_tdep (gdbarch)->lcount_regnum,
-                        (char *) &regs->lcount);
+    rc->raw_supply (gdbarch_tdep (gdbarch)->lcount_regnum,
+                   (char *) &regs->lcount);
   if (regnum == gdbarch_tdep (gdbarch)->sar_regnum || regnum == -1)
-    regcache_raw_supply (rc, gdbarch_tdep (gdbarch)->sar_regnum,
-                        (char *) &regs->sar);
+    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)
-    regcache_raw_supply (rc, regnum,
-                        (char *) &regs->ar[regnum - gdbarch_tdep
-                          (gdbarch)->ar_base]);
+    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)
-       regcache_raw_supply (rc, gdbarch_tdep (gdbarch)->ar_base + i,
-                            (char *) &regs->ar[i]);
+       rc->raw_supply (gdbarch_tdep (gdbarch)->ar_base + i,
+                       (char *) &regs->ar[i]);
     }
 }
 
@@ -911,23 +882,18 @@ xtensa_gregset =
 };
 
 
-/* Return the appropriate register set for the core
-   section identified by SECT_NAME and SECT_SIZE.  */
+/* Iterate over supported core file register note sections. */
 
-static const struct regset *
-xtensa_regset_from_core_section (struct gdbarch *core_arch,
-                                const char *sect_name,
-                                size_t sect_size)
+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_regset_from_core_section "
-             "(..., sect_name==\"%s\", sect_size==%x)\n",
-             sect_name, (unsigned int) sect_size);
+  DEBUGTRACE ("xtensa_iterate_over_regset_sections\n");
 
-  if (strcmp (sect_name, ".reg") == 0
-      && sect_size >= sizeof(xtensa_elf_gregset_t))
-    return &xtensa_gregset;
-
-  return NULL;
+  cb (".reg", sizeof (xtensa_elf_gregset_t), sizeof (xtensa_elf_gregset_t),
+      &xtensa_gregset, NULL, cb_data);
 }
 
 
@@ -955,7 +921,6 @@ typedef struct xtensa_windowed_frame_cache
 
 #define C0_MAXOPDS  3  /* Maximum number of operands for prologue
                           analysis.  */
-#define C0_NREGS   16  /* Number of A-registers to track.  */
 #define C0_CLESV   12  /* Callee-saved registers are here and up.  */
 #define C0_SP      1   /* Register used as SP.  */
 #define C0_FP     15   /* Register used as FP.  */
@@ -966,7 +931,7 @@ typedef struct xtensa_windowed_frame_cache
 /* Each element of xtensa_call0_frame_cache.c0_rt[] describes for each
    A-register where the current content of the reg came from (in terms
    of an original reg and a constant).  Negative values of c0_rt[n].fp_reg
-   mean that the orignal content of the register was saved to the stack.
+   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.  */
 
@@ -978,24 +943,30 @@ 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.  */
+  int fr_reg;  /* original register from which register content
+                 is derived, or C0_CONST, or C0_INEXP.  */
+  int fr_ofs;  /* constant offset from reg, or immediate value.  */
+  int to_stk;  /* offset from original SP to register (4-byte aligned),
+                 or C0_NOSTK if register has not been saved.  */
 } xtensa_c0reg_t;
 
-
 /* Frame cache part for Call0 ABI.  */
 typedef struct xtensa_call0_frame_cache
 {
-  int c0_frmsz;                                /* Stack frame size.  */
-  int c0_hasfp;                                /* Current frame uses frame
-                                          pointer.  */
-  int fp_regnum;                       /* A-register used as FP.  */
-  int c0_fp;                           /* Actual value of frame pointer.  */
-  xtensa_c0reg_t c0_rt[C0_NREGS];      /* Register tracking information.  */
+  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
@@ -1036,6 +1007,9 @@ xtensa_alloc_frame_cache (int windowed)
       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++)
        {
@@ -1144,7 +1118,7 @@ xtensa_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR current_pc)
   CORE_ADDR start_addr;
   xtensa_isa isa;
   xtensa_insnbuf ins, slot;
-  char ibuf[XTENSA_ISA_BSZ];
+  gdb_byte ibuf[XTENSA_ISA_BSZ];
   CORE_ADDR ia, bt, ba;
   xtensa_format ifmt;
   int ilen, islots, is;
@@ -1155,8 +1129,6 @@ xtensa_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR current_pc)
   if (start_addr == 0)
     return fp_regnum;
 
-  if (!xtensa_default_isa)
-    xtensa_default_isa = xtensa_isa_init (0, 0);
   isa = xtensa_default_isa;
   gdb_assert (XTENSA_ISA_BSZ >= xtensa_isa_maxlength (isa));
   ins = xtensa_insnbuf_alloc (isa);
@@ -1257,8 +1229,7 @@ done:
 
 static void
 call0_frame_cache (struct frame_info *this_frame,
-                  xtensa_frame_cache_t *cache,
-                  CORE_ADDR pc, CORE_ADDR litbase);
+                  xtensa_frame_cache_t *cache, CORE_ADDR pc);
 
 static void
 xtensa_window_interrupt_frame_cache (struct frame_info *this_frame,
@@ -1276,12 +1247,12 @@ xtensa_frame_cache (struct frame_info *this_frame, void **this_cache)
   int  windowed, ps_regnum;
 
   if (*this_cache)
-    return *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;
+  ps = (ps_regnum >= 0
+       ? get_frame_register_unsigned (this_frame, ps_regnum) : TX_PS);
 
   windowed = windowing_enabled (gdbarch, ps);
 
@@ -1291,7 +1262,7 @@ xtensa_frame_cache (struct frame_info *this_frame, void **this_cache)
 
   if (windowed)
     {
-      char op1;
+      LONGEST op1;
 
       /* Get WINDOWBASE, WINDOWSTART, and PS registers.  */
       wb = get_frame_register_unsigned (this_frame, 
@@ -1299,8 +1270,8 @@ xtensa_frame_cache (struct frame_info *this_frame, void **this_cache)
       ws = get_frame_register_unsigned (this_frame,
                                        gdbarch_tdep (gdbarch)->ws_regnum);
 
-      op1 = read_memory_integer (pc, 1, byte_order);
-      if (XTENSA_IS_ENTRY (gdbarch, op1))
+      if (safe_read_memory_integer (pc, 1, byte_order, &op1)
+         && XTENSA_IS_ENTRY (gdbarch, op1))
        {
          int callinc = CALLINC (ps);
          ra = get_frame_register_unsigned
@@ -1378,7 +1349,7 @@ xtensa_frame_cache (struct frame_info *this_frame, void **this_cache)
          if ((cache->wd.ws & (1 << cache->wd.wb)) == 0)
            {
              /* Register window overflow already happened.
-                We can read caller's SP from the proper spill loction.  */
+                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);
@@ -1404,11 +1375,7 @@ xtensa_frame_cache (struct frame_info *this_frame, void **this_cache)
     }
   else /* Call0 framework.  */
     {
-      unsigned int litbase_regnum = gdbarch_tdep (gdbarch)->litbase_regnum;
-      CORE_ADDR litbase = (litbase_regnum == -1)
-       ? 0 : get_frame_register_unsigned (this_frame, litbase_regnum);
-
-      call0_frame_cache (this_frame, cache, pc, litbase);
+      call0_frame_cache (this_frame, cache, pc);  
       fp_regnum = cache->c0.fp_regnum;
     }
 
@@ -1417,6 +1384,23 @@ xtensa_frame_cache (struct frame_info *this_frame, void **this_cache)
   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,
@@ -1443,7 +1427,7 @@ xtensa_frame_prev_register (struct frame_info *this_frame,
 
   if (*this_cache == NULL)
     *this_cache = xtensa_frame_cache (this_frame, this_cache);
-  cache = *this_cache;
+  cache = (struct xtensa_frame_cache *) *this_cache;
 
   if (regnum ==gdbarch_pc_regnum (gdbarch))
     saved_reg = cache->ra;
@@ -1525,6 +1509,7 @@ static const struct frame_unwind
 xtensa_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   xtensa_frame_this_id,
   xtensa_frame_prev_register,
   NULL,
@@ -1555,8 +1540,8 @@ xtensa_extract_return_value (struct type *type,
                             struct regcache *regcache,
                             void *dst)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  bfd_byte *valbuf = dst;
+  struct gdbarch *gdbarch = regcache->arch ();
+  bfd_byte *valbuf = (bfd_byte *) dst;
   int len = TYPE_LENGTH (type);
   ULONGEST pc, wb;
   int callsize, areg;
@@ -1599,9 +1584,9 @@ xtensa_extract_return_value (struct type *type,
   for (; len > 0; len -= 4, areg++, valbuf += 4)
     {
       if (len < 4)
-       regcache_raw_read_part (regcache, areg, offset, len, valbuf);
+       regcache->raw_read_part (areg, offset, len, valbuf);
       else
-       regcache_raw_read (regcache, areg, valbuf);
+       regcache->raw_read (areg, valbuf);
     }
 }
 
@@ -1611,8 +1596,8 @@ xtensa_store_return_value (struct type *type,
                           struct regcache *regcache,
                           const void *dst)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  const bfd_byte *valbuf = dst;
+  struct gdbarch *gdbarch = regcache->arch ();
+  const bfd_byte *valbuf = (const bfd_byte *) dst;
   unsigned int areg;
   ULONGEST pc, wb;
   int callsize;
@@ -1630,8 +1615,8 @@ xtensa_store_return_value (struct type *type,
 
       if (len > (callsize > 8 ? 8 : 16))
        internal_error (__FILE__, __LINE__,
-                       _("unimplemented for this length: %d"),
-                       TYPE_LENGTH (type));
+                       _("unimplemented for this length: %s"),
+                       pulongest (TYPE_LENGTH (type)));
       areg = arreg_number (gdbarch,
                           gdbarch_tdep (gdbarch)->a0_base + 2 + callsize, wb);
 
@@ -1649,16 +1634,16 @@ xtensa_store_return_value (struct type *type,
   for (; len > 0; len -= 4, areg++, valbuf += 4)
     {
       if (len < 4)
-       regcache_raw_write_part (regcache, areg, offset, len, valbuf);
+       regcache->raw_write_part (areg, offset, len, valbuf);
       else
-       regcache_raw_write (regcache, areg, valbuf);
+       regcache->raw_write (areg, valbuf);
     }
 }
 
 
 static enum return_value_convention
 xtensa_return_value (struct gdbarch *gdbarch,
-                    struct type *func_type,
+                    struct value *function,
                     struct type *valtype,
                     struct regcache *regcache,
                     gdb_byte *readbuf,
@@ -1700,11 +1685,10 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch,
                        int nargs,
                        struct value **args,
                        CORE_ADDR sp,
-                       int struct_return,
+                       function_call_return_method return_method,
                        CORE_ADDR struct_addr)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  int i;
   int size, onstack_size;
   gdb_byte *buf = (gdb_byte *) alloca (16);
   CORE_ADDR ra, ps;
@@ -1730,19 +1714,18 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch,
 
   if (xtensa_debug_level > 3)
     {
-      int i;
       DEBUGINFO ("[xtensa_push_dummy_call] nargs = %d\n", nargs);
-      DEBUGINFO ("[xtensa_push_dummy_call] sp=0x%x, struct_return=%d, "
+      DEBUGINFO ("[xtensa_push_dummy_call] sp=0x%x, return_method=%d, "
                 "struct_addr=0x%x\n",
-                (int) sp, (int) struct_return, (int) struct_addr);
+                (int) sp, (int) return_method, (int) struct_addr);
 
-      for (i = 0; i < nargs; i++)
+      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 %3d ", i,
+         fprintf_unfiltered (gdb_stdlog, "%2d: %s %3s ", i,
                              host_address_to_string (arg),
-                             TYPE_LENGTH (arg_type));
+                             pulongest (TYPE_LENGTH (arg_type)));
          switch (TYPE_CODE (arg_type))
            {
            case TYPE_CODE_INT:
@@ -1767,12 +1750,11 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch,
 
   size = 0;
   onstack_size = 0;
-  i = 0;
 
-  if (struct_return)
+  if (return_method == return_method_struct)
     size = REGISTER_SIZE;
 
-  for (i = 0; i < nargs; i++)
+  for (int i = 0; i < nargs; i++)
     {
       struct argument_info *info = &arg_info[i];
       struct value *arg = args[i];
@@ -1846,13 +1828,13 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch,
 
   /* Second Loop: Load arguments.  */
 
-  if (struct_return)
+  if (return_method == return_method_struct)
     {
       store_unsigned_integer (buf, REGISTER_SIZE, byte_order, struct_addr);
-      regcache_cooked_write (regcache, ARG_1ST (gdbarch), buf);
+      regcache->cooked_write (ARG_1ST (gdbarch), buf);
     }
 
-  for (i = 0; i < nargs; i++)
+  for (int i = 0; i < nargs; i++)
     {
       struct argument_info *info = &arg_info[i];
 
@@ -1891,7 +1873,7 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch,
              v = v >> ((REGISTER_SIZE - n) * TARGET_CHAR_BIT);
 
              store_unsigned_integer (buf, REGISTER_SIZE, byte_order, v);
-             regcache_cooked_write (regcache, r, buf);
+             regcache->cooked_write (r, buf);
 
              cp += REGISTER_SIZE;
              n -= REGISTER_SIZE;
@@ -1900,7 +1882,7 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch,
          else
            while (n > 0)
              {
-               regcache_cooked_write (regcache, r, cp);
+               regcache->cooked_write (r, cp);
 
                cp += REGISTER_SIZE;
                n -= REGISTER_SIZE;
@@ -1911,11 +1893,12 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch,
 
   /* Set the return address of dummy frame to the dummy address.
      The return address for the current function (in A0) is
-     saved in the dummy frame, so we can savely overwrite A0 here.  */
+     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;
@@ -1930,7 +1913,7 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch,
         to modify WINDOWSTART register to make it look like there
         is only one register window corresponding to WINDOWEBASE.  */
 
-      regcache_raw_read (regcache, gdbarch_tdep (gdbarch)->wb_regnum, buf);
+      regcache->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));
@@ -1949,6 +1932,16 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch,
   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
@@ -1959,42 +1952,33 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch,
 #define DENSITY_BIG_BREAKPOINT { 0xd2, 0x0f }
 #define DENSITY_LITTLE_BREAKPOINT { 0x2d, 0xf0 }
 
-static const unsigned char *
-xtensa_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
-                          int *lenptr)
-{
-  static unsigned char big_breakpoint[] = BIG_BREAKPOINT;
-  static unsigned char little_breakpoint[] = LITTLE_BREAKPOINT;
-  static unsigned char density_big_breakpoint[] = DENSITY_BIG_BREAKPOINT;
-  static unsigned char density_little_breakpoint[] = DENSITY_LITTLE_BREAKPOINT;
+/* Implement the sw_breakpoint_from_kind gdbarch method.  */
 
-  DEBUGTRACE ("xtensa_breakpoint_from_pc (pc = 0x%08x)\n", (int) *pcptr);
+static const gdb_byte *
+xtensa_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
+{
+  *size = kind;
 
-  if (gdbarch_tdep (gdbarch)->isa_use_density_instructions)
+  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)
-       {
-         *lenptr = sizeof (density_big_breakpoint);
-         return density_big_breakpoint;
-       }
+       return big_breakpoint;
       else
-       {
-         *lenptr = sizeof (density_little_breakpoint);
-         return density_little_breakpoint;
-       }
+       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)
-       {
-         *lenptr = sizeof (big_breakpoint);
-         return big_breakpoint;
-       }
+       return density_big_breakpoint;
       else
-       {
-         *lenptr = sizeof (little_breakpoint);
-         return little_breakpoint;
-       }
+       return density_little_breakpoint;
     }
 }
 
@@ -2008,7 +1992,7 @@ call0_ret (CORE_ADDR start_pc, CORE_ADDR finish_pc)
 #define RETURN_RET goto done
   xtensa_isa isa;
   xtensa_insnbuf ins, slot;
-  char ibuf[XTENSA_ISA_BSZ];
+  gdb_byte ibuf[XTENSA_ISA_BSZ];
   CORE_ADDR ia, bt, ba;
   xtensa_format ifmt;
   int ilen, islots, is;
@@ -2074,7 +2058,8 @@ call0_ret (CORE_ADDR start_pc, CORE_ADDR finish_pc)
    The purpose of this is to simplify prologue analysis by separating 
    instruction decoding (libisa) from the semantics of prologue analysis.  */
 
-typedef enum {
+typedef enum
+{
   c0opc_illegal,       /* Unknown to libisa (invalid) or 'ill' opcode.  */
   c0opc_uninteresting, /* Not interesting for Call0 prologue analysis.  */
   c0opc_flow,         /* Flow control insn.  */
@@ -2082,6 +2067,7 @@ typedef enum {
   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.  */
@@ -2153,6 +2139,8 @@ call0_classify_opcode (xtensa_isa isa, xtensa_opcode opc)
   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)
@@ -2184,16 +2172,16 @@ call0_classify_opcode (xtensa_isa isa, xtensa_opcode opc)
    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.  */
+   the stack frame.  Returns 0, if analysis was successful, non-zero
+   otherwise.  */
 
-static void
-call0_track_op (struct gdbarch *gdbarch,
-               xtensa_c0reg_t dst[], xtensa_c0reg_t src[],
+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, CORE_ADDR litbase, int spreg)
+               CORE_ADDR pc, int spreg, xtensa_frame_cache_t *cache)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  unsigned litaddr, litval;
+  unsigned litbase, litaddr, litval;
 
   switch (opclass)
     {
@@ -2218,6 +2206,39 @@ call0_track_op (struct gdbarch *gdbarch,
        }
       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);
@@ -2231,6 +2252,13 @@ call0_track_op (struct gdbarch *gdbarch,
     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;
@@ -2243,6 +2271,10 @@ call0_track_op (struct gdbarch *gdbarch,
     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;
@@ -2253,6 +2285,13 @@ call0_track_op (struct gdbarch *gdbarch,
     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.  */
@@ -2264,20 +2303,29 @@ call0_track_op (struct gdbarch *gdbarch,
          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:
-       gdb_assert_not_reached ("unexpected instruction kind");
+      return 1;
     }
+  return 0;
 }
 
-/* Analyze prologue of the function at start address to determine if it uses 
+/* 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.
+   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 
@@ -2287,26 +2335,22 @@ call0_track_op (struct gdbarch *gdbarch,
       pc      Program counter to stop at.  Use 0 to continue to end of prologue.
              If 0, avoids infinite run-on in corrupt code memory by bounding
              the scan to the end of the function if that can be determined.
-      nregs   Number of general registers to track (size of rt[] array).
+      nregs   Number of general registers to track.
    InOut args:
-      rt[]    Array[nregs] of xtensa_c0reg structures for register tracking info.
-             If NULL, registers are not tracked.
-   Output args:
-      call0   If != NULL, *call0 is set non-zero if Call0 ABI used, else 0
-             (more accurately, non-zero until 'entry' insn is encountered).
+      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, CORE_ADDR litbase,
-                       int nregs, xtensa_c0reg_t rt[], int *call0)
+                       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.  */
-  char ibuf[XTENSA_ISA_BSZ];/* Instruction buffer for decoding prologue.  */
+  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.  */
@@ -2330,7 +2374,7 @@ call0_analyze_prologue (struct gdbarch *gdbarch,
      arg was not supplied to avoid probing beyond the end of valid memory.
      If memory is full of garbage that classifies as c0opc_uninteresting.
      If this fails (eg. if no symbols) pc ends up 0 as it was.
-     Intialize the Call0 frame and register tracking info.
+     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.  */
 
@@ -2344,27 +2388,18 @@ call0_analyze_prologue (struct gdbarch *gdbarch,
     body_pc = prologue_sal.end;
 
   /* If we are going to analyze the prologue in general without knowing about
-     the current PC, make the best assumtion for the end of the prologue.  */
+     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 = min (end_pc, body_pc);
+      body_pc = std::min (end_pc, body_pc);
     }
   else
-    body_pc = min (pc, body_pc);
-
-  if (call0 != NULL)
-      *call0 = 1;
+    body_pc = std::min (pc, body_pc);
 
-  if (rt != NULL)
-    {
-      rtmp = (xtensa_c0reg_t*) alloca(nregs * sizeof(xtensa_c0reg_t));
-      /* rt is already initialized in xtensa_alloc_frame_cache().  */
-    }
-  else nregs = 0;
+  cache->call0 = 1;
+  rtmp = (xtensa_c0reg_t*) alloca(nregs * sizeof(xtensa_c0reg_t));
 
-  if (!xtensa_default_isa)
-    xtensa_default_isa = xtensa_isa_init (0, 0);
   isa = xtensa_default_isa;
   gdb_assert (XTENSA_ISA_BSZ >= xtensa_isa_maxlength (isa));
   ins = xtensa_insnbuf_alloc (isa);
@@ -2380,9 +2415,8 @@ call0_analyze_prologue (struct gdbarch *gdbarch,
         {
          ba = ia;
          bt = (ba + XTENSA_ISA_BSZ) < body_pc ? ba + XTENSA_ISA_BSZ : body_pc;
-         read_memory (ba, ibuf, bt - ba);
-         /* If there is a memory reading error read_memory () will report it
-            and then throw an exception, stopping command execution.  */
+         if (target_read_memory (ba, ibuf, bt - ba) != 0 )
+           error (_("Unable to read target memory ..."));
        }
 
       /* Decode format information.  */
@@ -2412,7 +2446,7 @@ call0_analyze_prologue (struct gdbarch *gdbarch,
         register changes do not take effect within this bundle.  */
 
       for (j = 0; j < nregs; ++j)
-       rtmp[j] = rt[j];
+       rtmp[j] = cache->c0.c0_rt[j];
 
       for (is = 0; is < islots; ++is)
         {
@@ -2423,8 +2457,7 @@ call0_analyze_prologue (struct gdbarch *gdbarch,
            goto done;
 
          opc = xtensa_opcode_decode (isa, ifmt, is, slot);
-         DEBUGVERB ("[call0_analyze_prologue] instr "
-                    "addr = 0x%08x, opc = %d\n", 
+         DEBUGVERB ("[call0_analyze_prologue] instr addr = 0x%08x, opc = %d\n", 
                     (unsigned)ia, opc);
          if (opc == XTENSA_UNDEFINED) 
            opclass = c0opc_illegal;
@@ -2443,23 +2476,20 @@ call0_analyze_prologue (struct gdbarch *gdbarch,
            case c0opc_uninteresting:
              continue;
 
-           case c0opc_flow:
+           case c0opc_flow:  /* Flow control instructions stop analysis.  */
+           case c0opc_rwxsr: /* RSR, WSR, XSR instructions stop analysis.  */
              goto done;
 
            case c0opc_entry:
-             if (call0 != NULL)
-               *call0 = 0;
+             cache->call0 = 0;
              ia += ilen;               /* Skip over 'entry' insn.  */
              goto done;
 
            default:
-             if (call0 != NULL)
-               *call0 = 1;
+             cache->call0 = 1;
            }
 
          /* Only expected opcodes should get this far.  */
-         if (rt == NULL)
-           continue;
 
          /* Extract and decode the operands.  */
          nods = xtensa_opcode_num_operands (isa, opc);
@@ -2485,7 +2515,13 @@ call0_analyze_prologue (struct gdbarch *gdbarch,
          if (opclass == c0opc_mov && nods == 3)
            {
              if (odv[2] == odv[1])
-               nods = 2;
+               {
+                 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;
@@ -2494,8 +2530,10 @@ call0_analyze_prologue (struct gdbarch *gdbarch,
            }
 
          /* Track register movement and modification for this operation.  */
-         call0_track_op (gdbarch, rt, rtmp, opclass,
-                         nods, odv, ia, litbase, 1);
+         fail = call0_track_op (gdbarch, cache->c0.c0_rt, rtmp,
+                                opclass, nods, odv, ia, 1, cache);
+         if (fail)
+           goto done;
        }
     }
 done:
@@ -2510,39 +2548,38 @@ done:
 
 static void
 call0_frame_cache (struct frame_info *this_frame,
-                  xtensa_frame_cache_t *cache,
-                  CORE_ADDR pc, CORE_ADDR litbase)
+                  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_hasfp, c0_frmsz, prev_sp, to_stk;
+  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, litbase,
-                                       C0_NREGS,
-                                       &cache->c0.c0_rt[0],
-                                       &cache->call0);
+      body_pc = call0_analyze_prologue (gdbarch, start_pc, pc, C0_NREGS, cache);
 
       if (body_pc == XTENSA_ISA_BADPC)
-       error (_("Xtensa-specific internal error: CALL0 prologue \
-analysis failed in this frame. GDB command execution stopped."));
+       {
+         warning_once ();
+         ra = 0;
+         goto finish_frame_analysis;
+       }
     }
   
-  sp = get_frame_register_unsigned
-    (this_frame, gdbarch_tdep (gdbarch)->a0_base + 1);
-  fp = sp; /* Assume FP == SP until proven otherwise.  */
-
   /* Get the frame information and FP (if used) at the current PC.
      If PC is in the prologue, the prologue analysis is more reliable
-     than DWARF info.  We don't not know for sure if PC is in the prologue,
-     but we know no calls have yet taken place, so we can almost
+     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)
@@ -2565,7 +2602,35 @@ analysis failed in this frame. GDB command execution stopped."));
       start_pc = pc;
    }
 
-  prev_sp = fp + c0_frmsz;
+  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.  */
@@ -2573,8 +2638,6 @@ analysis failed in this frame. GDB command execution stopped."));
     {
       fp = get_frame_register_unsigned (this_frame, fp_regnum);
 
-      /* Recalculate previous SP.  */
-      prev_sp = fp + c0_frmsz;
       /* Update the stack frame size.  */
       c0_frmsz += fp - sp;
     }
@@ -2591,28 +2654,26 @@ analysis failed in this frame. GDB command execution stopped."));
   else if (cache->c0.c0_rt[C0_RA].fr_reg == C0_CONST
           && cache->c0.c0_rt[C0_RA].fr_ofs == 0)
     {
-      /* Special case for terminating backtrace at a function that
-        wants to be seen as the outermost.  Such a function will
-        clear it's RA (A0) register to 0 in the prologue instead of
-        saving its original value.  */
+      /* 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.  */
+      /* 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);
+      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;
@@ -2625,6 +2686,7 @@ analysis failed in this frame. GDB command execution stopped."));
       else ra = 0;
     }
   
+ finish_frame_analysis:
   cache->pc = start_pc;
   cache->ra = ra;
   /* RA == 0 marks the outermost frame.  Do not go past it.  */
@@ -2642,7 +2704,7 @@ static int a0_was_saved;
 static int a7_was_saved;
 static int a11_was_saved;
 
-/* Simulate L32E insn:  AT <-- ref (AS + offset).  */
+/* Simulate L32E instruction:  AT <-- ref (AS + offset).  */
 static void
 execute_l32e (struct gdbarch *gdbarch, int at, int as, int offset, CORE_ADDR wb)
 {
@@ -2671,7 +2733,7 @@ execute_l32e (struct gdbarch *gdbarch, int at, int as, int offset, CORE_ADDR wb)
   xtensa_write_register (atreg, spilled_value);
 }
 
-/* Simulate S32E insn:  AT --> ref (AS + offset).  */
+/* Simulate S32E instruction:  AT --> ref (AS + offset).  */
 static void
 execute_s32e (struct gdbarch *gdbarch, int at, int as, int offset, CORE_ADDR wb)
 {
@@ -2687,30 +2749,29 @@ execute_s32e (struct gdbarch *gdbarch, int at, int as, int offset, CORE_ADDR wb)
 
 #define XTENSA_MAX_WINDOW_INTERRUPT_HANDLER_LEN  200
 
-typedef enum {
+typedef enum
+{
   xtWindowOverflow,
   xtWindowUnderflow,
   xtNoExceptionHandler
 } xtensa_exception_handler_t;
 
-/* Execute insn stream from current PC until hitting RFWU or RFWO.
+/* 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;
-  char ibuf[XTENSA_ISA_BSZ];
+  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;
-  int fail = 0;
   void (*func) (struct gdbarch *, int, int, int, CORE_ADDR);
 
-  int at, as, offset;
-  int num_operands;
+  uint32_t at, as, offset;
 
   /* WindowUnderflow12 = true, when inside _WindowUnderflow12.  */ 
   int WindowUnderflow12 = (current_pc & 0x1ff) >= 0x140; 
@@ -2964,7 +3025,8 @@ xtensa_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
     }
 
   /* No debug line info.  Analyze prologue for Call0 or simply skip ENTRY.  */
-  body_pc = call0_analyze_prologue (gdbarch, start_pc, 0, 0, 0, NULL, NULL);
+  body_pc = call0_analyze_prologue (gdbarch, start_pc, 0, 0,
+                                   xtensa_alloc_frame_cache (0));
   return body_pc != 0 ? body_pc : start_pc;
 }
 
@@ -2972,48 +3034,38 @@ xtensa_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
 static void
 xtensa_verify_config (struct gdbarch *gdbarch)
 {
-  struct ui_file *log;
-  struct cleanup *cleanups;
-  struct gdbarch_tdep *tdep;
-  long length;
-  char *buf;
-
-  tdep = gdbarch_tdep (gdbarch);
-  log = mem_fileopen ();
-  cleanups = make_cleanup_ui_file_delete (log);
+  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)
-    fprintf_unfiltered (log, _("\
+    log.printf (_("\
 \n\tnum_aregs: Number of AR registers (%d) is not a power of two!"),
-                       tdep->num_aregs);
+               tdep->num_aregs);
 
   /* Verify that certain registers exist.  */
 
   if (tdep->pc_regnum == -1)
-    fprintf_unfiltered (log, _("\n\tpc_regnum: No PC register"));
+    log.printf (_("\n\tpc_regnum: No PC register"));
   if (tdep->isa_use_exceptions && tdep->ps_regnum == -1)
-    fprintf_unfiltered (log, _("\n\tps_regnum: No PS register"));
+    log.printf (_("\n\tps_regnum: No PS register"));
 
   if (tdep->isa_use_windowed_registers)
     {
       if (tdep->wb_regnum == -1)
-       fprintf_unfiltered (log, _("\n\twb_regnum: No WB register"));
+       log.printf (_("\n\twb_regnum: No WB register"));
       if (tdep->ws_regnum == -1)
-       fprintf_unfiltered (log, _("\n\tws_regnum: No WS register"));
+       log.printf (_("\n\tws_regnum: No WS register"));
       if (tdep->ar_base == -1)
-       fprintf_unfiltered (log, _("\n\tar_base: No AR registers"));
+       log.printf (_("\n\tar_base: No AR registers"));
     }
 
   if (tdep->a0_base == -1)
-    fprintf_unfiltered (log, _("\n\ta0_base: No Ax registers"));
+    log.printf (_("\n\ta0_base: No Ax registers"));
 
-  buf = ui_file_xstrdup (log, &length);
-  make_cleanup (xfree, buf);
-  if (length > 0)
+  if (!log.empty ())
     internal_error (__FILE__, __LINE__,
-                   _("the following are invalid: %s"), buf);
-  do_cleanups (cleanups);
+                   _("the following are invalid: %s"), log.c_str ());
 }
 
 
@@ -3030,6 +3082,8 @@ xtensa_derive_tdep (struct gdbarch_tdep *tdep)
 
 /* 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++)
     {
@@ -3061,6 +3115,8 @@ xtensa_derive_tdep (struct gdbarch_tdep *tdep)
        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;
@@ -3074,16 +3130,12 @@ xtensa_derive_tdep (struct gdbarch_tdep *tdep)
        max_size = rmap->byte_size;
       if (rmap->mask != 0 && tdep->num_regs == 0)
        tdep->num_regs = n;
-      /* Find out out how to deal with priveleged registers.
-
-         if ((rmap->flags & XTENSA_REGISTER_FLAGS_PRIVILEGED) != 0
-              && tdep->num_nopriv_regs == 0)
-           tdep->num_nopriv_regs = n;
-      */
       if ((rmap->flags & XTENSA_REGISTER_FLAGS_PRIVILEGED) != 0
-         && tdep->num_regs == 0)
-       tdep->num_regs = n;
+         && 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;
@@ -3102,10 +3154,12 @@ xtensa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
   struct gdbarch_tdep *tdep;
   struct gdbarch *gdbarch;
-  struct xtensa_abi_handler *abi_handler;
 
   DEBUGTRACE ("gdbarch_init()\n");
 
+  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;
 
@@ -3115,6 +3169,10 @@ xtensa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* 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);
@@ -3149,7 +3207,10 @@ xtensa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
 
   /* Set breakpoints.  */
-  set_gdbarch_breakpoint_from_pc (gdbarch, xtensa_breakpoint_from_pc);
+  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.  */
@@ -3169,19 +3230,20 @@ xtensa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   frame_unwind_append_unwinder (gdbarch, &xtensa_unwind);
   dwarf2_append_unwinders (gdbarch);
 
-  set_gdbarch_print_insn (gdbarch, print_insn_xtensa);
-
   set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
 
   xtensa_add_reggroups (gdbarch);
   set_gdbarch_register_reggroup_p (gdbarch, xtensa_register_reggroup_p);
 
-  set_gdbarch_regset_from_core_section (gdbarch,
-                                       xtensa_regset_from_core_section);
+  set_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;
 }
 
@@ -3191,25 +3253,20 @@ xtensa_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
   error (_("xtensa_dump_tdep(): not implemented"));
 }
 
-/* Provide a prototype to silence -Wmissing-prototypes.  */
-extern initialize_file_ftype _initialize_xtensa_tdep;
-
 void
 _initialize_xtensa_tdep (void)
 {
-  struct cmd_list_element *c;
-
   gdbarch_register (bfd_arch_xtensa, xtensa_gdbarch_init, xtensa_dump_tdep);
   xtensa_init_reggroups ();
 
-  add_setshow_zinteger_cmd ("xtensa",
-                           class_maintenance,
-                           &xtensa_debug_level,
+  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);
+                            NULL,
+                            NULL,
+                            &setdebuglist, &showdebuglist);
 }
This page took 0.05125 seconds and 4 git commands to generate.