Automatic date update in version.in
[platform/upstream/binutils.git] / gdb / spu-tdep.c
index d42d94b..032f5de 100644 (file)
@@ -1,6 +1,5 @@
 /* SPU target-dependent code for GDB, the GNU debugger.
-   Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
-   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>.
@@ -25,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"
@@ -45,7 +42,8 @@
 #include "observer.h"
 #include "infcall.h"
 #include "dwarf2.h"
-#include "exceptions.h"
+#include "dwarf2-frame.h"
+#include "ax.h"
 #include "spu-tdep.h"
 
 
@@ -193,6 +191,7 @@ spu_pseudo_register_read_spu (struct regcache *regcache, const char *regname,
   gdb_byte reg[32];
   char annex[32];
   ULONGEST id;
+  ULONGEST ul;
 
   status = regcache_raw_read_unsigned (regcache, SPU_ID_REGNUM, &id);
   if (status != REG_VALID)
@@ -202,7 +201,8 @@ spu_pseudo_register_read_spu (struct regcache *regcache, const char *regname,
   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;
 }
 
@@ -255,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;
 
@@ -264,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
@@ -310,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)
@@ -350,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.  */
 
@@ -850,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.  */
@@ -1136,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));
@@ -1187,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);
@@ -1218,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;
@@ -1374,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.  */
@@ -1451,18 +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
-      && TYPE_CALLING_CONVENTION (func_type) == DW_CC_GDB_IBM_OpenCL
-      && TYPE_CODE (type) == TYPE_CODE_ARRAY
-      && TYPE_VECTOR (type))
-    opencl_vector = 1;
+  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;
@@ -1604,8 +1668,9 @@ spu_software_single_step (struct frame_info *frame)
          else
            {
              if (optim)
-               error (_("Could not determine address of "
-                        "single-step breakpoint."));
+               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 "
@@ -1736,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);
@@ -1749,19 +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)
+  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);
@@ -1887,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];
@@ -1907,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;
@@ -1935,12 +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 */,
                     bp_breakpoint /* type_wanted */,
                     0 /* ignore_count */,
                     AUTO_BOOLEAN_FALSE /* pending_break_support */,
                     &bkpt_breakpoint_ops /* ops */, 0 /* from_tty */,
-                    1 /* enabled */, 0 /* internal  */);
+                    1 /* enabled */, 0 /* internal  */, 0);
 }
 
 
@@ -1969,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 ())
@@ -1981,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;
@@ -1989,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);
     }
@@ -2023,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."));
@@ -2036,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,
@@ -2044,7 +2111,7 @@ 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 (current_uiout, "SPUInfoEvent");
 
@@ -2080,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."));
@@ -2103,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);
@@ -2121,7 +2188,7 @@ 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 (current_uiout, "SPUInfoSignal");
 
@@ -2201,7 +2268,7 @@ 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."));
@@ -2349,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;
 
@@ -2443,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."));
@@ -2522,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."));
@@ -2579,7 +2646,7 @@ 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);
+  help_list (infospucmdlist, "info spu ", all_commands, gdb_stdout);
 }
 
 
@@ -2646,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);
 
@@ -2666,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);
@@ -2704,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);