Automatic date update in version.in
[platform/upstream/binutils.git] / gdb / spu-tdep.c
index de5435c..032f5de 100644 (file)
@@ -1,5 +1,5 @@
 /* SPU target-dependent code for GDB, the GNU debugger.
-   Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2006-2014 Free Software Foundation, Inc.
 
    Contributed by Ulrich Weigand <uweigand@de.ibm.com>.
    Based on a port by Sid Manning <sid@us.ibm.com>.
@@ -24,8 +24,6 @@
 #include "gdbtypes.h"
 #include "gdbcmd.h"
 #include "gdbcore.h"
-#include "gdb_string.h"
-#include "gdb_assert.h"
 #include "frame.h"
 #include "frame-unwind.h"
 #include "frame-base.h"
@@ -43,7 +41,9 @@
 #include "block.h"
 #include "observer.h"
 #include "infcall.h"
-
+#include "dwarf2.h"
+#include "dwarf2-frame.h"
+#include "ax.h"
 #include "spu-tdep.h"
 
 
@@ -175,67 +175,74 @@ spu_register_type (struct gdbarch *gdbarch, int reg_nr)
       return builtin_type (gdbarch)->builtin_uint32;
 
     default:
-      internal_error (__FILE__, __LINE__, "invalid regnum");
+      internal_error (__FILE__, __LINE__, _("invalid regnum"));
     }
 }
 
 /* Pseudo registers for preferred slots - stack pointer.  */
 
-static void
+static enum register_status
 spu_pseudo_register_read_spu (struct regcache *regcache, const char *regname,
                              gdb_byte *buf)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  enum register_status status;
   gdb_byte reg[32];
   char annex[32];
   ULONGEST id;
+  ULONGEST ul;
 
-  regcache_raw_read_unsigned (regcache, SPU_ID_REGNUM, &id);
+  status = regcache_raw_read_unsigned (regcache, SPU_ID_REGNUM, &id);
+  if (status != REG_VALID)
+    return status;
   xsnprintf (annex, sizeof annex, "%d/%s", (int) id, regname);
   memset (reg, 0, sizeof reg);
   target_read (&current_target, TARGET_OBJECT_SPU, annex,
               reg, 0, sizeof reg);
 
-  store_unsigned_integer (buf, 4, byte_order, strtoulst (reg, NULL, 16));
+  ul = strtoulst ((char *) reg, NULL, 16);
+  store_unsigned_integer (buf, 4, byte_order, ul);
+  return REG_VALID;
 }
 
-static void
+static enum register_status
 spu_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
                           int regnum, gdb_byte *buf)
 {
   gdb_byte reg[16];
   char annex[32];
   ULONGEST id;
+  enum register_status status;
 
   switch (regnum)
     {
     case SPU_SP_REGNUM:
-      regcache_raw_read (regcache, SPU_RAW_SP_REGNUM, reg);
+      status = regcache_raw_read (regcache, SPU_RAW_SP_REGNUM, reg);
+      if (status != REG_VALID)
+       return status;
       memcpy (buf, reg, 4);
-      break;
+      return status;
 
     case SPU_FPSCR_REGNUM:
-      regcache_raw_read_unsigned (regcache, SPU_ID_REGNUM, &id);
+      status = regcache_raw_read_unsigned (regcache, SPU_ID_REGNUM, &id);
+      if (status != REG_VALID)
+       return status;
       xsnprintf (annex, sizeof annex, "%d/fpcr", (int) id);
       target_read (&current_target, TARGET_OBJECT_SPU, annex, buf, 0, 16);
-      break;
+      return status;
 
     case SPU_SRR0_REGNUM:
-      spu_pseudo_register_read_spu (regcache, "srr0", buf);
-      break;
+      return spu_pseudo_register_read_spu (regcache, "srr0", buf);
 
     case SPU_LSLR_REGNUM:
-      spu_pseudo_register_read_spu (regcache, "lslr", buf);
-      break;
+      return spu_pseudo_register_read_spu (regcache, "lslr", buf);
 
     case SPU_DECR_REGNUM:
-      spu_pseudo_register_read_spu (regcache, "decr", buf);
-      break;
+      return spu_pseudo_register_read_spu (regcache, "decr", buf);
 
     case SPU_DECR_STATUS_REGNUM:
-      spu_pseudo_register_read_spu (regcache, "decr_status", buf);
-      break;
+      return spu_pseudo_register_read_spu (regcache, "decr_status", buf);
 
     default:
       internal_error (__FILE__, __LINE__, _("invalid regnum"));
@@ -248,7 +255,7 @@ spu_pseudo_register_write_spu (struct regcache *regcache, const char *regname,
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  gdb_byte reg[32];
+  char reg[32];
   char annex[32];
   ULONGEST id;
 
@@ -257,7 +264,7 @@ spu_pseudo_register_write_spu (struct regcache *regcache, const char *regname,
   xsnprintf (reg, sizeof reg, "0x%s",
             phex_nz (extract_unsigned_integer (buf, 4, byte_order), 4));
   target_write (&current_target, TARGET_OBJECT_SPU, annex,
-               reg, 0, strlen (reg));
+               (gdb_byte *) reg, 0, strlen (reg));
 }
 
 static void
@@ -303,13 +310,59 @@ spu_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
     }
 }
 
+static int
+spu_ax_pseudo_register_collect (struct gdbarch *gdbarch,
+                               struct agent_expr *ax, int regnum)
+{
+  switch (regnum)
+    {
+    case SPU_SP_REGNUM:
+      ax_reg_mask (ax, SPU_RAW_SP_REGNUM);
+      return 0;
+
+    case SPU_FPSCR_REGNUM:
+    case SPU_SRR0_REGNUM:
+    case SPU_LSLR_REGNUM:
+    case SPU_DECR_REGNUM:
+    case SPU_DECR_STATUS_REGNUM:
+      return -1;
+
+    default:
+      internal_error (__FILE__, __LINE__, _("invalid regnum"));
+    }
+}
+
+static int
+spu_ax_pseudo_register_push_stack (struct gdbarch *gdbarch,
+                                  struct agent_expr *ax, int regnum)
+{
+  switch (regnum)
+    {
+    case SPU_SP_REGNUM:
+      ax_reg (ax, SPU_RAW_SP_REGNUM);
+      return 0;
+
+    case SPU_FPSCR_REGNUM:
+    case SPU_SRR0_REGNUM:
+    case SPU_LSLR_REGNUM:
+    case SPU_DECR_REGNUM:
+    case SPU_DECR_STATUS_REGNUM:
+      return -1;
+
+    default:
+      internal_error (__FILE__, __LINE__, _("invalid regnum"));
+    }
+}
+
+
 /* Value conversion -- access scalar values at the preferred slot.  */
 
 static struct value *
-spu_value_from_register (struct type *type, int regnum,
-                        struct frame_info *frame)
+spu_value_from_register (struct gdbarch *gdbarch, struct type *type,
+                        int regnum, struct frame_id frame_id)
 {
-  struct value *value = default_value_from_register (type, regnum, frame);
+  struct value *value = default_value_from_register (gdbarch, type,
+                                                    regnum, frame_id);
   int len = TYPE_LENGTH (type);
 
   if (regnum < SPU_NUM_GPRS && len < 16)
@@ -343,6 +396,15 @@ spu_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
   return default_register_reggroup_p (gdbarch, regnum, group);
 }
 
+/* DWARF-2 register numbers.  */
+
+static int
+spu_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
+{
+  /* Use cooked instead of raw SP.  */
+  return (reg == SPU_RAW_SP_REGNUM)? SPU_SP_REGNUM : reg;
+}
+
 
 /* Address handling.  */
 
@@ -353,7 +415,7 @@ spu_gdbarch_id (struct gdbarch *gdbarch)
   int id = tdep->id;
 
   /* The objfile architecture of a standalone SPU executable does not
-     provide an SPU ID.  Retrieve it from the the objfile's relocated
+     provide an SPU ID.  Retrieve it from the objfile's relocated
      address range in this special case.  */
   if (id == -1
       && symfile_objfile && symfile_objfile->obfd
@@ -449,7 +511,7 @@ enum
     op_a     = 0x0c0,
     op_ai    = 0x1c,
 
-    op_selb  = 0x4,
+    op_selb  = 0x8,
 
     op_br    = 0x64,
     op_bra   = 0x60,
@@ -813,7 +875,7 @@ spu_virtual_frame_pointer (struct gdbarch *gdbarch, CORE_ADDR pc,
     }
   else
     {
-      /* ??? We don't really know ... */
+      /* ??? We don't really know ...  */
       *reg = SPU_SP_REGNUM;
       *offset = 0;
     }
@@ -843,7 +905,7 @@ spu_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
   CORE_ADDR scan_pc, func_start, func_end, epilogue_start, epilogue_end;
   bfd_byte buf[4];
   unsigned int insn;
-  int rt, ra, rb, rc, immed;
+  int rt, ra, rb, immed;
 
   /* Find the search limits based on function boundaries and hard limit.
      We assume the epilogue can be up to 64 instructions long.  */
@@ -1006,7 +1068,8 @@ spu_frame_unwind_cache (struct frame_info *this_frame,
        {
          /* Assume the link register is saved into its slot.  */
          if (backchain + 16 <= lslr)
-           info->saved_regs[SPU_LR_REGNUM].addr = SPUADDR (id, backchain + 16);
+           info->saved_regs[SPU_LR_REGNUM].addr = SPUADDR (id,
+                                                           backchain + 16);
 
           /* Frame bases.  */
          info->frame_base = SPUADDR (id, backchain);
@@ -1074,6 +1137,7 @@ spu_frame_prev_register (struct frame_info *this_frame,
 
 static const struct frame_unwind spu_frame_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   spu_frame_this_id,
   spu_frame_prev_register,
   NULL,
@@ -1127,6 +1191,7 @@ spu_write_pc (struct regcache *regcache, CORE_ADDR pc)
 {
   /* Keep interrupt enabled state unchanged.  */
   ULONGEST old_pc;
+
   regcache_cooked_read_unsigned (regcache, SPU_PC_REGNUM, &old_pc);
   regcache_cooked_write_unsigned (regcache, SPU_PC_REGNUM,
                                  (SPUADDR_ADDR (pc) & -4) | (old_pc & 3));
@@ -1178,7 +1243,7 @@ spu2ppu_sniffer (const struct frame_unwind *self,
   CORE_ADDR base, func, backchain;
   gdb_byte buf[4];
 
-  if (gdbarch_bfd_arch_info (target_gdbarch)->arch == bfd_arch_spu)
+  if (gdbarch_bfd_arch_info (target_gdbarch ())->arch == bfd_arch_spu)
     return 0;
 
   base = get_frame_sp (this_frame);
@@ -1209,7 +1274,7 @@ spu2ppu_sniffer (const struct frame_unwind *self,
       else
        {
          struct regcache *regcache;
-         regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch);
+         regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
          cache->regcache = regcache_dup (regcache);
          *this_prologue_cache = cache;
          return 1;
@@ -1228,6 +1293,7 @@ spu2ppu_dealloc_cache (struct frame_info *self, void *this_cache)
 
 static const struct frame_unwind spu2ppu_unwind = {
   ARCH_FRAME,
+  default_frame_unwind_stop_reason,
   spu2ppu_this_id,
   spu2ppu_prev_register,
   NULL,
@@ -1364,8 +1430,7 @@ spu_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       struct value *arg = args[i];
       struct type *type = check_typedef (value_type (arg));
       const gdb_byte *contents = value_contents (arg);
-      int len = TYPE_LENGTH (type);
-      int n_regs = align_up (len, 16) / 16;
+      int n_regs = align_up (TYPE_LENGTH (type), 16) / 16;
 
       /* If the argument doesn't wholly fit into registers, it and
         all subsequent arguments go to the stack.  */
@@ -1441,11 +1506,27 @@ spu_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 /* Function return value access.  */
 
 static enum return_value_convention
-spu_return_value (struct gdbarch *gdbarch, struct type *func_type,
+spu_return_value (struct gdbarch *gdbarch, struct value *function,
                  struct type *type, struct regcache *regcache,
                  gdb_byte *out, const gdb_byte *in)
 {
+  struct type *func_type = function ? value_type (function) : NULL;
   enum return_value_convention rvc;
+  int opencl_vector = 0;
+
+  if (func_type)
+    {
+      func_type = check_typedef (func_type);
+
+      if (TYPE_CODE (func_type) == TYPE_CODE_PTR)
+       func_type = check_typedef (TYPE_TARGET_TYPE (func_type));
+
+      if (TYPE_CODE (func_type) == TYPE_CODE_FUNC
+         && TYPE_CALLING_CONVENTION (func_type) == DW_CC_GDB_IBM_OpenCL
+         && TYPE_CODE (type) == TYPE_CODE_ARRAY
+         && TYPE_VECTOR (type))
+       opencl_vector = 1;
+    }
 
   if (TYPE_LENGTH (type) <= (SPU_ARGN_REGNUM - SPU_ARG1_REGNUM + 1) * 16)
     rvc = RETURN_VALUE_REGISTER_CONVENTION;
@@ -1457,11 +1538,14 @@ spu_return_value (struct gdbarch *gdbarch, struct type *func_type,
       switch (rvc)
        {
        case RETURN_VALUE_REGISTER_CONVENTION:
-         spu_value_to_regcache (regcache, SPU_ARG1_REGNUM, type, in);
+         if (opencl_vector && TYPE_LENGTH (type) == 2)
+           regcache_cooked_write_part (regcache, SPU_ARG1_REGNUM, 2, 2, in);
+         else
+           spu_value_to_regcache (regcache, SPU_ARG1_REGNUM, type, in);
          break;
 
        case RETURN_VALUE_STRUCT_CONVENTION:
-         error ("Cannot set function return value.");
+         error (_("Cannot set function return value."));
          break;
        }
     }
@@ -1470,11 +1554,14 @@ spu_return_value (struct gdbarch *gdbarch, struct type *func_type,
       switch (rvc)
        {
        case RETURN_VALUE_REGISTER_CONVENTION:
-         spu_regcache_to_value (regcache, SPU_ARG1_REGNUM, type, out);
+         if (opencl_vector && TYPE_LENGTH (type) == 2)
+           regcache_cooked_read_part (regcache, SPU_ARG1_REGNUM, 2, 2, out);
+         else
+           spu_regcache_to_value (regcache, SPU_ARG1_REGNUM, type, out);
          break;
 
        case RETURN_VALUE_STRUCT_CONVENTION:
-         error ("Function return value unknown.");
+         error (_("Function return value unknown."));
          break;
        }
     }
@@ -1486,7 +1573,8 @@ spu_return_value (struct gdbarch *gdbarch, struct type *func_type,
 /* Breakpoints.  */
 
 static const gdb_byte *
-spu_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR * pcptr, int *lenptr)
+spu_breakpoint_from_pc (struct gdbarch *gdbarch,
+                       CORE_ADDR * pcptr, int *lenptr)
 {
   static const gdb_byte breakpoint[] = { 0x00, 0x00, 0x3f, 0xff };
 
@@ -1572,8 +1660,22 @@ spu_software_single_step (struct frame_info *frame)
        target += SPUADDR_ADDR (pc);
       else if (reg != -1)
        {
-         get_frame_register_bytes (frame, reg, 0, 4, buf);
-         target += extract_unsigned_integer (buf, 4, byte_order) & -4;
+         int optim, unavail;
+
+         if (get_frame_register_bytes (frame, reg, 0, 4, buf,
+                                        &optim, &unavail))
+           target += extract_unsigned_integer (buf, 4, byte_order) & -4;
+         else
+           {
+             if (optim)
+               throw_error (OPTIMIZED_OUT_ERROR,
+                            _("Could not determine address of "
+                              "single-step breakpoint."));
+             if (unavail)
+               throw_error (NOT_AVAILABLE_ERROR,
+                            _("Could not determine address of "
+                              "single-step breakpoint."));
+           }
        }
 
       target = target & lslr;
@@ -1596,9 +1698,13 @@ spu_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   gdb_byte buf[4];
   CORE_ADDR jb_addr;
+  int optim, unavail;
 
   /* Jump buffer is pointed to by the argument register $r3.  */
-  get_frame_register_bytes (frame, SPU_ARG1_REGNUM, 0, 4, buf);
+  if (!get_frame_register_bytes (frame, SPU_ARG1_REGNUM, 0, 4, buf,
+                                &optim, &unavail))
+    return 0;
+
   jb_addr = extract_unsigned_integer (buf, 4, byte_order);
   if (target_read_memory (SPUADDR (tdep->id, jb_addr), buf, 4))
     return 0;
@@ -1627,8 +1733,9 @@ spu_dis_asm_print_address (bfd_vma addr, struct disassemble_info *info)
 static int
 gdb_print_insn_spu (bfd_vma memaddr, struct disassemble_info *info)
 {
-  /* The opcodes disassembler does 18-bit address arithmetic.  Make sure the
-     SPU ID encoded in the high bits is added back when we call print_address.  */
+  /* The opcodes disassembler does 18-bit address arithmetic.  Make
+     sure the SPU ID encoded in the high bits is added back when we
+     call print_address.  */
   struct disassemble_info spu_info = *info;
   struct spu_dis_asm_data data;
   data.gdbarch = info->application_data;
@@ -1662,11 +1769,12 @@ gdb_print_insn_spu (bfd_vma memaddr, struct disassemble_info *info)
 
    _ovly_table should never change.
 
-   Both tables are aligned to a 16-byte boundary, the symbols _ovly_table
-   and _ovly_buf_table are of type STT_OBJECT and their size set to the size
-   of the respective array. buf in _ovly_table is an index into _ovly_buf_table.
+   Both tables are aligned to a 16-byte boundary, the symbols
+   _ovly_table and _ovly_buf_table are of type STT_OBJECT and their
+   size set to the size of the respective array. buf in _ovly_table is
+   an index into _ovly_buf_table.
 
-   mapped is an index into _ovly_table. Both the mapped and buf indices start
+   mapped is an index into _ovly_table.  Both the mapped and buf indices start
    from one to reference the first entry in their respective tables.  */
 
 /* Using the per-objfile private data mechanism, we store for each
@@ -1693,12 +1801,12 @@ spu_get_overlay_table (struct objfile *objfile)
 {
   enum bfd_endian byte_order = bfd_big_endian (objfile->obfd)?
                   BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE;
-  struct minimal_symbol *ovly_table_msym, *ovly_buf_table_msym;
+  struct bound_minimal_symbol ovly_table_msym, ovly_buf_table_msym;
   CORE_ADDR ovly_table_base, ovly_buf_table_base;
   unsigned ovly_table_size, ovly_buf_table_size;
   struct spu_overlay_table *tbl;
   struct obj_section *osect;
-  char *ovly_table;
+  gdb_byte *ovly_table;
   int i;
 
   tbl = objfile_data (objfile, spu_overlay_data);
@@ -1706,18 +1814,19 @@ spu_get_overlay_table (struct objfile *objfile)
     return tbl;
 
   ovly_table_msym = lookup_minimal_symbol ("_ovly_table", NULL, objfile);
-  if (!ovly_table_msym)
+  if (!ovly_table_msym.minsym)
     return NULL;
 
-  ovly_buf_table_msym = lookup_minimal_symbol ("_ovly_buf_table", NULL, objfile);
-  if (!ovly_buf_table_msym)
+  ovly_buf_table_msym = lookup_minimal_symbol ("_ovly_buf_table",
+                                              NULL, objfile);
+  if (!ovly_buf_table_msym.minsym)
     return NULL;
 
-  ovly_table_base = SYMBOL_VALUE_ADDRESS (ovly_table_msym);
-  ovly_table_size = MSYMBOL_SIZE (ovly_table_msym);
+  ovly_table_base = BMSYMBOL_VALUE_ADDRESS (ovly_table_msym);
+  ovly_table_size = MSYMBOL_SIZE (ovly_table_msym.minsym);
 
-  ovly_buf_table_base = SYMBOL_VALUE_ADDRESS (ovly_buf_table_msym);
-  ovly_buf_table_size = MSYMBOL_SIZE (ovly_buf_table_msym);
+  ovly_buf_table_base = BMSYMBOL_VALUE_ADDRESS (ovly_buf_table_msym);
+  ovly_buf_table_size = MSYMBOL_SIZE (ovly_buf_table_msym.minsym);
 
   ovly_table = xmalloc (ovly_table_size);
   read_memory (ovly_table_base, ovly_table, ovly_table_size);
@@ -1843,7 +1952,7 @@ spu_overlay_new_objfile (struct objfile *objfile)
 static void
 spu_catch_start (struct objfile *objfile)
 {
-  struct minimal_symbol *minsym;
+  struct bound_minimal_symbol minsym;
   struct symtab *symtab;
   CORE_ADDR pc;
   char buf[32];
@@ -1863,16 +1972,17 @@ spu_catch_start (struct objfile *objfile)
   /* There can be multiple symbols named "main".  Search for the
      "main" in *this* objfile.  */
   minsym = lookup_minimal_symbol ("main", NULL, objfile);
-  if (!minsym)
+  if (!minsym.minsym)
     return;
 
   /* If we have debugging information, try to use it -- this
      will allow us to properly skip the prologue.  */
-  pc = SYMBOL_VALUE_ADDRESS (minsym);
-  symtab = find_pc_sect_symtab (pc, SYMBOL_OBJ_SECTION (minsym));
+  pc = BMSYMBOL_VALUE_ADDRESS (minsym);
+  symtab = find_pc_sect_symtab (pc, MSYMBOL_OBJ_SECTION (minsym.objfile,
+                                                        minsym.minsym));
   if (symtab != NULL)
     {
-      struct blockvector *bv = BLOCKVECTOR (symtab);
+      const struct blockvector *bv = BLOCKVECTOR (symtab);
       struct block *block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
       struct symbol *sym;
       struct symtab_and_line sal;
@@ -1891,11 +2001,13 @@ spu_catch_start (struct objfile *objfile)
   xsnprintf (buf, sizeof buf, "*%s", core_addr_to_string (pc));
   create_breakpoint (get_objfile_arch (objfile), buf /* arg */,
                     NULL /* cond_string */, -1 /* thread */,
+                    NULL /* extra_string */,
                     0 /* parse_condition_and_thread */, 1 /* tempflag */,
-                    0 /* hardwareflag */, 0 /* traceflag */,
+                    bp_breakpoint /* type_wanted */,
                     0 /* ignore_count */,
                     AUTO_BOOLEAN_FALSE /* pending_break_support */,
-                    NULL /* ops */, 0 /* from_tty */, 1 /* enabled */);
+                    &bkpt_breakpoint_ops /* ops */, 0 /* from_tty */,
+                    1 /* enabled */, 0 /* internal  */, 0);
 }
 
 
@@ -1924,7 +2036,7 @@ spu_objfile_from_frame (struct frame_info *frame)
 static void
 flush_ea_cache (void)
 {
-  struct minimal_symbol *msymbol;
+  struct bound_minimal_symbol msymbol;
   struct objfile *obj;
 
   if (!has_stack_frames ())
@@ -1936,7 +2048,7 @@ flush_ea_cache (void)
 
   /* Lookup inferior function __cache_flush.  */
   msymbol = lookup_minimal_symbol ("__cache_flush", NULL, obj);
-  if (msymbol != NULL)
+  if (msymbol.minsym != NULL)
     {
       struct type *type;
       CORE_ADDR addr;
@@ -1944,7 +2056,7 @@ flush_ea_cache (void)
       type = objfile_type (obj)->builtin_void;
       type = lookup_function_type (type);
       type = lookup_pointer_type (type);
-      addr = SYMBOL_VALUE_ADDRESS (msymbol);
+      addr = BMSYMBOL_VALUE_ADDRESS (msymbol);
 
       call_function_by_hand (value_from_pointer (type, addr), 0, NULL);
     }
@@ -1978,7 +2090,7 @@ info_spu_event_command (char *args, int from_tty)
   gdb_byte buf[100];
   char annex[32];
   LONGEST len;
-  int rc, id;
+  int id;
 
   if (gdbarch_bfd_arch_info (get_frame_arch (frame))->arch != bfd_arch_spu)
     error (_("\"info spu\" is only supported on the SPU architecture."));
@@ -1991,7 +2103,7 @@ info_spu_event_command (char *args, int from_tty)
   if (len <= 0)
     error (_("Could not read event_status."));
   buf[len] = '\0';
-  event_status = strtoulst (buf, NULL, 16);
+  event_status = strtoulst ((char *) buf, NULL, 16);
  
   xsnprintf (annex, sizeof annex, "%d/event_mask", id);
   len = target_read (&current_target, TARGET_OBJECT_SPU, annex,
@@ -1999,15 +2111,15 @@ info_spu_event_command (char *args, int from_tty)
   if (len <= 0)
     error (_("Could not read event_mask."));
   buf[len] = '\0';
-  event_mask = strtoulst (buf, NULL, 16);
+  event_mask = strtoulst ((char *) buf, NULL, 16);
  
-  chain = make_cleanup_ui_out_tuple_begin_end (uiout, "SPUInfoEvent");
+  chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, "SPUInfoEvent");
 
-  if (ui_out_is_mi_like_p (uiout))
+  if (ui_out_is_mi_like_p (current_uiout))
     {
-      ui_out_field_fmt (uiout, "event_status",
+      ui_out_field_fmt (current_uiout, "event_status",
                        "0x%s", phex_nz (event_status, 4));
-      ui_out_field_fmt (uiout, "event_mask",
+      ui_out_field_fmt (current_uiout, "event_mask",
                        "0x%s", phex_nz (event_mask, 4));
     }
   else
@@ -2035,7 +2147,7 @@ info_spu_signal_command (char *args, int from_tty)
   char annex[32];
   gdb_byte buf[100];
   LONGEST len;
-  int rc, id;
+  int id;
 
   if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_spu)
     error (_("\"info spu\" is only supported on the SPU architecture."));
@@ -2058,7 +2170,7 @@ info_spu_signal_command (char *args, int from_tty)
   if (len <= 0)
     error (_("Could not read signal1_type."));
   buf[len] = '\0';
-  signal1_type = strtoulst (buf, NULL, 16);
+  signal1_type = strtoulst ((char *) buf, NULL, 16);
 
   xsnprintf (annex, sizeof annex, "%d/signal2", id);
   len = target_read (&current_target, TARGET_OBJECT_SPU, annex, buf, 0, 4);
@@ -2076,18 +2188,18 @@ info_spu_signal_command (char *args, int from_tty)
   if (len <= 0)
     error (_("Could not read signal2_type."));
   buf[len] = '\0';
-  signal2_type = strtoulst (buf, NULL, 16);
+  signal2_type = strtoulst ((char *) buf, NULL, 16);
 
-  chain = make_cleanup_ui_out_tuple_begin_end (uiout, "SPUInfoSignal");
+  chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, "SPUInfoSignal");
 
-  if (ui_out_is_mi_like_p (uiout))
+  if (ui_out_is_mi_like_p (current_uiout))
     {
-      ui_out_field_int (uiout, "signal1_pending", signal1_pending);
-      ui_out_field_fmt (uiout, "signal1", "0x%s", phex_nz (signal1, 4));
-      ui_out_field_int (uiout, "signal1_type", signal1_type);
-      ui_out_field_int (uiout, "signal2_pending", signal2_pending);
-      ui_out_field_fmt (uiout, "signal2", "0x%s", phex_nz (signal2, 4));
-      ui_out_field_int (uiout, "signal2_type", signal2_type);
+      ui_out_field_int (current_uiout, "signal1_pending", signal1_pending);
+      ui_out_field_fmt (current_uiout, "signal1", "0x%s", phex_nz (signal1, 4));
+      ui_out_field_int (current_uiout, "signal1_type", signal1_type);
+      ui_out_field_int (current_uiout, "signal2_pending", signal2_pending);
+      ui_out_field_fmt (current_uiout, "signal2", "0x%s", phex_nz (signal2, 4));
+      ui_out_field_int (current_uiout, "signal2_type", signal2_type);
     }
   else
     {
@@ -2125,21 +2237,21 @@ info_spu_mailbox_list (gdb_byte *buf, int nr, enum bfd_endian byte_order,
   if (nr <= 0)
     return;
 
-  chain = make_cleanup_ui_out_table_begin_end (uiout, 1, nr, "mbox");
+  chain = make_cleanup_ui_out_table_begin_end (current_uiout, 1, nr, "mbox");
 
-  ui_out_table_header (uiout, 32, ui_left, field, msg);
-  ui_out_table_body (uiout);
+  ui_out_table_header (current_uiout, 32, ui_left, field, msg);
+  ui_out_table_body (current_uiout);
 
   for (i = 0; i < nr; i++)
     {
       struct cleanup *val_chain;
       ULONGEST val;
-      val_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "mbox");
+      val_chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, "mbox");
       val = extract_unsigned_integer (buf + 4*i, 4, byte_order);
-      ui_out_field_fmt (uiout, field, "0x%s", phex (val, 4));
+      ui_out_field_fmt (current_uiout, field, "0x%s", phex (val, 4));
       do_cleanups (val_chain);
 
-      if (!ui_out_is_mi_like_p (uiout))
+      if (!ui_out_is_mi_like_p (current_uiout))
        printf_filtered ("\n");
     }
 
@@ -2156,14 +2268,14 @@ info_spu_mailbox_command (char *args, int from_tty)
   char annex[32];
   gdb_byte buf[1024];
   LONGEST len;
-  int i, id;
+  int id;
 
   if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_spu)
     error (_("\"info spu\" is only supported on the SPU architecture."));
 
   id = get_frame_register_unsigned (frame, SPU_ID_REGNUM);
 
-  chain = make_cleanup_ui_out_tuple_begin_end (uiout, "SPUInfoMailbox");
+  chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, "SPUInfoMailbox");
 
   xsnprintf (annex, sizeof annex, "%d/mbox_info", id);
   len = target_read (&current_target, TARGET_OBJECT_SPU, annex,
@@ -2281,20 +2393,21 @@ info_spu_dma_cmdlist (gdb_byte *buf, int nr, enum bfd_endian byte_order)
   nr = i;
 
 
-  chain = make_cleanup_ui_out_table_begin_end (uiout, 10, nr, "dma_cmd");
+  chain = make_cleanup_ui_out_table_begin_end (current_uiout, 10, nr,
+                                              "dma_cmd");
 
-  ui_out_table_header (uiout, 7, ui_left, "opcode", "Opcode");
-  ui_out_table_header (uiout, 3, ui_left, "tag", "Tag");
-  ui_out_table_header (uiout, 3, ui_left, "tid", "TId");
-  ui_out_table_header (uiout, 3, ui_left, "rid", "RId");
-  ui_out_table_header (uiout, 18, ui_left, "ea", "EA");
-  ui_out_table_header (uiout, 7, ui_left, "lsa", "LSA");
-  ui_out_table_header (uiout, 7, ui_left, "size", "Size");
-  ui_out_table_header (uiout, 7, ui_left, "lstaddr", "LstAddr");
-  ui_out_table_header (uiout, 7, ui_left, "lstsize", "LstSize");
-  ui_out_table_header (uiout, 1, ui_left, "error_p", "E");
+  ui_out_table_header (current_uiout, 7, ui_left, "opcode", "Opcode");
+  ui_out_table_header (current_uiout, 3, ui_left, "tag", "Tag");
+  ui_out_table_header (current_uiout, 3, ui_left, "tid", "TId");
+  ui_out_table_header (current_uiout, 3, ui_left, "rid", "RId");
+  ui_out_table_header (current_uiout, 18, ui_left, "ea", "EA");
+  ui_out_table_header (current_uiout, 7, ui_left, "lsa", "LSA");
+  ui_out_table_header (current_uiout, 7, ui_left, "size", "Size");
+  ui_out_table_header (current_uiout, 7, ui_left, "lstaddr", "LstAddr");
+  ui_out_table_header (current_uiout, 7, ui_left, "lstsize", "LstSize");
+  ui_out_table_header (current_uiout, 1, ui_left, "error_p", "E");
 
-  ui_out_table_body (uiout);
+  ui_out_table_body (current_uiout);
 
   for (i = 0; i < nr; i++)
     {
@@ -2303,7 +2416,7 @@ info_spu_dma_cmdlist (gdb_byte *buf, int nr, enum bfd_endian byte_order)
       ULONGEST mfc_cq_dw1;
       ULONGEST mfc_cq_dw2;
       int mfc_cmd_opcode, mfc_cmd_tag, rclass_id, tclass_id;
-      int lsa, size, list_lsa, list_size, mfc_lsa, mfc_size;
+      int list_lsa, list_size, mfc_lsa, mfc_size;
       ULONGEST mfc_ea;
       int list_valid_p, noop_valid_p, qw_valid_p, ea_valid_p, cmd_error_p;
 
@@ -2335,47 +2448,47 @@ info_spu_dma_cmdlist (gdb_byte *buf, int nr, enum bfd_endian byte_order)
       ea_valid_p = spu_mfc_get_bitfield (mfc_cq_dw2, 39, 39);
       cmd_error_p = spu_mfc_get_bitfield (mfc_cq_dw2, 40, 40);
 
-      cmd_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "cmd");
+      cmd_chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, "cmd");
 
       if (spu_mfc_opcode[mfc_cmd_opcode])
-       ui_out_field_string (uiout, "opcode", spu_mfc_opcode[mfc_cmd_opcode]);
+       ui_out_field_string (current_uiout, "opcode", spu_mfc_opcode[mfc_cmd_opcode]);
       else
-       ui_out_field_int (uiout, "opcode", mfc_cmd_opcode);
+       ui_out_field_int (current_uiout, "opcode", mfc_cmd_opcode);
 
-      ui_out_field_int (uiout, "tag", mfc_cmd_tag);
-      ui_out_field_int (uiout, "tid", tclass_id);
-      ui_out_field_int (uiout, "rid", rclass_id);
+      ui_out_field_int (current_uiout, "tag", mfc_cmd_tag);
+      ui_out_field_int (current_uiout, "tid", tclass_id);
+      ui_out_field_int (current_uiout, "rid", rclass_id);
 
       if (ea_valid_p)
-       ui_out_field_fmt (uiout, "ea", "0x%s", phex (mfc_ea, 8));
+       ui_out_field_fmt (current_uiout, "ea", "0x%s", phex (mfc_ea, 8));
       else
-       ui_out_field_skip (uiout, "ea");
+       ui_out_field_skip (current_uiout, "ea");
 
-      ui_out_field_fmt (uiout, "lsa", "0x%05x", mfc_lsa << 4);
+      ui_out_field_fmt (current_uiout, "lsa", "0x%05x", mfc_lsa << 4);
       if (qw_valid_p)
-       ui_out_field_fmt (uiout, "size", "0x%05x", mfc_size << 4);
+       ui_out_field_fmt (current_uiout, "size", "0x%05x", mfc_size << 4);
       else
-       ui_out_field_fmt (uiout, "size", "0x%05x", mfc_size);
+       ui_out_field_fmt (current_uiout, "size", "0x%05x", mfc_size);
 
       if (list_valid_p)
        {
-         ui_out_field_fmt (uiout, "lstaddr", "0x%05x", list_lsa << 3);
-         ui_out_field_fmt (uiout, "lstsize", "0x%05x", list_size << 3);
+         ui_out_field_fmt (current_uiout, "lstaddr", "0x%05x", list_lsa << 3);
+         ui_out_field_fmt (current_uiout, "lstsize", "0x%05x", list_size << 3);
        }
       else
        {
-         ui_out_field_skip (uiout, "lstaddr");
-         ui_out_field_skip (uiout, "lstsize");
+         ui_out_field_skip (current_uiout, "lstaddr");
+         ui_out_field_skip (current_uiout, "lstsize");
        }
 
       if (cmd_error_p)
-       ui_out_field_string (uiout, "error_p", "*");
+       ui_out_field_string (current_uiout, "error_p", "*");
       else
-       ui_out_field_skip (uiout, "error_p");
+       ui_out_field_skip (current_uiout, "error_p");
 
       do_cleanups (cmd_chain);
 
-      if (!ui_out_is_mi_like_p (uiout))
+      if (!ui_out_is_mi_like_p (current_uiout))
        printf_filtered ("\n");
     }
 
@@ -2397,7 +2510,7 @@ info_spu_dma_command (char *args, int from_tty)
   char annex[32];
   gdb_byte buf[1024];
   LONGEST len;
-  int i, id;
+  int id;
 
   if (gdbarch_bfd_arch_info (get_frame_arch (frame))->arch != bfd_arch_spu)
     error (_("\"info spu\" is only supported on the SPU architecture."));
@@ -2421,19 +2534,19 @@ info_spu_dma_command (char *args, int from_tty)
   dma_info_atomic_command_status
     = extract_unsigned_integer (buf + 32, 8, byte_order);
   
-  chain = make_cleanup_ui_out_tuple_begin_end (uiout, "SPUInfoDMA");
+  chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, "SPUInfoDMA");
 
-  if (ui_out_is_mi_like_p (uiout))
+  if (ui_out_is_mi_like_p (current_uiout))
     {
-      ui_out_field_fmt (uiout, "dma_info_type", "0x%s",
+      ui_out_field_fmt (current_uiout, "dma_info_type", "0x%s",
                        phex_nz (dma_info_type, 4));
-      ui_out_field_fmt (uiout, "dma_info_mask", "0x%s",
+      ui_out_field_fmt (current_uiout, "dma_info_mask", "0x%s",
                        phex_nz (dma_info_mask, 4));
-      ui_out_field_fmt (uiout, "dma_info_status", "0x%s",
+      ui_out_field_fmt (current_uiout, "dma_info_status", "0x%s",
                        phex_nz (dma_info_status, 4));
-      ui_out_field_fmt (uiout, "dma_info_stall_and_notify", "0x%s",
+      ui_out_field_fmt (current_uiout, "dma_info_stall_and_notify", "0x%s",
                        phex_nz (dma_info_stall_and_notify, 4));
-      ui_out_field_fmt (uiout, "dma_info_atomic_command_status", "0x%s",
+      ui_out_field_fmt (current_uiout, "dma_info_atomic_command_status", "0x%s",
                        phex_nz (dma_info_atomic_command_status, 4));
     }
   else
@@ -2476,7 +2589,7 @@ info_spu_proxydma_command (char *args, int from_tty)
   char annex[32];
   gdb_byte buf[1024];
   LONGEST len;
-  int i, id;
+  int id;
 
   if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_spu)
     error (_("\"info spu\" is only supported on the SPU architecture."));
@@ -2493,15 +2606,16 @@ info_spu_proxydma_command (char *args, int from_tty)
   dma_info_mask = extract_unsigned_integer (buf + 8, 8, byte_order);
   dma_info_status = extract_unsigned_integer (buf + 16, 8, byte_order);
   
-  chain = make_cleanup_ui_out_tuple_begin_end (uiout, "SPUInfoProxyDMA");
+  chain = make_cleanup_ui_out_tuple_begin_end (current_uiout,
+                                              "SPUInfoProxyDMA");
 
-  if (ui_out_is_mi_like_p (uiout))
+  if (ui_out_is_mi_like_p (current_uiout))
     {
-      ui_out_field_fmt (uiout, "proxydma_info_type", "0x%s",
+      ui_out_field_fmt (current_uiout, "proxydma_info_type", "0x%s",
                        phex_nz (dma_info_type, 4));
-      ui_out_field_fmt (uiout, "proxydma_info_mask", "0x%s",
+      ui_out_field_fmt (current_uiout, "proxydma_info_mask", "0x%s",
                        phex_nz (dma_info_mask, 4));
-      ui_out_field_fmt (uiout, "proxydma_info_status", "0x%s",
+      ui_out_field_fmt (current_uiout, "proxydma_info_status", "0x%s",
                        phex_nz (dma_info_status, 4));
     }
   else
@@ -2530,8 +2644,9 @@ info_spu_proxydma_command (char *args, int from_tty)
 static void
 info_spu_command (char *args, int from_tty)
 {
-  printf_unfiltered (_("\"info spu\" must be followed by the name of an SPU facility.\n"));
-  help_list (infospucmdlist, "info spu ", -1, gdb_stdout);
+  printf_unfiltered (_("\"info spu\" must be followed by "
+                      "the name of an SPU facility.\n"));
+  help_list (infospucmdlist, "info spu ", all_commands, gdb_stdout);
 }
 
 
@@ -2598,7 +2713,7 @@ spu_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     }
 
   /* None found, so create a new architecture.  */
-  tdep = XCALLOC (1, struct gdbarch_tdep);
+  tdep = XCNEW (struct gdbarch_tdep);
   tdep->id = id;
   gdbarch = gdbarch_alloc (&info, tdep);
 
@@ -2618,6 +2733,11 @@ spu_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_pseudo_register_write (gdbarch, spu_pseudo_register_write);
   set_gdbarch_value_from_register (gdbarch, spu_value_from_register);
   set_gdbarch_register_reggroup_p (gdbarch, spu_register_reggroup_p);
+  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, spu_dwarf_reg_to_regnum);
+  set_gdbarch_ax_pseudo_register_collect
+    (gdbarch, spu_ax_pseudo_register_collect);
+  set_gdbarch_ax_pseudo_register_push_stack
+    (gdbarch, spu_ax_pseudo_register_push_stack);
 
   /* Data types.  */
   set_gdbarch_char_signed (gdbarch, 0);
@@ -2656,6 +2776,7 @@ spu_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Frame handling.  */
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+  dwarf2_append_unwinders (gdbarch);
   frame_unwind_append_unwinder (gdbarch, &spu_frame_unwind);
   frame_base_set_default (gdbarch, &spu_frame_base);
   set_gdbarch_unwind_pc (gdbarch, spu_unwind_pc);