/* SPU target-dependent code for GDB, the GNU debugger.
- Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
Contributed by Ulrich Weigand <uweigand@de.ibm.com>.
Based on a port by Sid Manning <sid@us.ibm.com>.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "arch-utils.h"
#include "spu-tdep.h"
+
+/* The tdep structure. */
+struct gdbarch_tdep
+{
+ /* SPU-specific vector type. */
+ struct type *spu_builtin_type_vec128;
+};
+
+
/* SPU-specific vector type. */
-struct type *spu_builtin_type_vec128;
+static struct type *
+spu_builtin_type_vec128 (struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ if (!tdep->spu_builtin_type_vec128)
+ {
+ struct type *t;
+
+ t = init_composite_type ("__spu_builtin_type_vec128", TYPE_CODE_UNION);
+ append_composite_type_field (t, "uint128", builtin_type_int128);
+ append_composite_type_field (t, "v2_int64",
+ init_vector_type (builtin_type_int64, 2));
+ append_composite_type_field (t, "v4_int32",
+ init_vector_type (builtin_type_int32, 4));
+ append_composite_type_field (t, "v8_int16",
+ init_vector_type (builtin_type_int16, 8));
+ append_composite_type_field (t, "v16_int8",
+ init_vector_type (builtin_type_int8, 16));
+ append_composite_type_field (t, "v2_double",
+ init_vector_type (builtin_type_double, 2));
+ append_composite_type_field (t, "v4_float",
+ init_vector_type (builtin_type_float, 4));
+
+ TYPE_FLAGS (t) |= TYPE_FLAG_VECTOR;
+ TYPE_NAME (t) = "spu_builtin_type_vec128";
+
+ tdep->spu_builtin_type_vec128 = t;
+ }
+
+ return tdep->spu_builtin_type_vec128;
+}
+
/* The list of available "info spu " commands. */
static struct cmd_list_element *infospucmdlist = NULL;
/* Registers. */
static const char *
-spu_register_name (int reg_nr)
+spu_register_name (struct gdbarch *gdbarch, int reg_nr)
{
static char *register_names[] =
{
spu_register_type (struct gdbarch *gdbarch, int reg_nr)
{
if (reg_nr < SPU_NUM_GPRS)
- return spu_builtin_type_vec128;
+ return spu_builtin_type_vec128 (gdbarch);
switch (reg_nr)
{
return default_register_reggroup_p (gdbarch, regnum, group);
}
+/* Address conversion. */
+
+static CORE_ADDR
+spu_pointer_to_address (struct type *type, const gdb_byte *buf)
+{
+ ULONGEST addr = extract_unsigned_integer (buf, TYPE_LENGTH (type));
+ ULONGEST lslr = SPU_LS_SIZE - 1; /* Hard-wired LS size. */
+
+ if (target_has_registers && target_has_stack && target_has_memory)
+ lslr = get_frame_register_unsigned (get_selected_frame (NULL),
+ SPU_LSLR_REGNUM);
+
+ return addr & lslr;
+}
+
+static CORE_ADDR
+spu_integer_to_address (struct gdbarch *gdbarch,
+ struct type *type, const gdb_byte *buf)
+{
+ ULONGEST addr = unpack_long (type, buf);
+ ULONGEST lslr = SPU_LS_SIZE - 1; /* Hard-wired LS size. */
+
+ if (target_has_registers && target_has_stack && target_has_memory)
+ lslr = get_frame_register_unsigned (get_selected_frame (NULL),
+ SPU_LSLR_REGNUM);
+
+ return addr & lslr;
+}
+
/* Decoding SPU instructions. */
/* Return the frame pointer in use at address PC. */
static void
-spu_virtual_frame_pointer (CORE_ADDR pc, int *reg, LONGEST *offset)
+spu_virtual_frame_pointer (struct gdbarch *gdbarch, CORE_ADDR pc,
+ int *reg, LONGEST *offset)
{
struct spu_prologue_data data;
spu_analyze_prologue (pc, (CORE_ADDR)-1, &data);
/* Breakpoints. */
static const gdb_byte *
-spu_breakpoint_from_pc (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 };
printf_filtered (_("Signal 1 not pending "));
if (signal1_type)
- printf_filtered (_("(Type Overwrite)\n"));
- else
printf_filtered (_("(Type Or)\n"));
+ else
+ printf_filtered (_("(Type Overwrite)\n"));
if (signal2_pending)
printf_filtered (_("Signal 2 control word 0x%s "), phex (signal2, 4));
printf_filtered (_("Signal 2 not pending "));
if (signal2_type)
- printf_filtered (_("(Type Overwrite)\n"));
- else
printf_filtered (_("(Type Or)\n"));
+ else
+ printf_filtered (_("(Type Overwrite)\n"));
}
do_cleanups (chain);
spu_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
struct gdbarch *gdbarch;
+ struct gdbarch_tdep *tdep;
/* Find a candidate among the list of pre-declared architectures. */
arches = gdbarch_list_lookup_by_info (arches, &info);
return NULL;
/* Yes, create a new architecture. */
- gdbarch = gdbarch_alloc (&info, NULL);
+ tdep = XCALLOC (1, struct gdbarch_tdep);
+ gdbarch = gdbarch_alloc (&info, tdep);
/* Disassembler. */
set_gdbarch_print_insn (gdbarch, print_insn_spu);
set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
+ /* Address conversion. */
+ set_gdbarch_pointer_to_address (gdbarch, spu_pointer_to_address);
+ set_gdbarch_integer_to_address (gdbarch, spu_integer_to_address);
+
/* Inferior function calls. */
set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
set_gdbarch_frame_align (gdbarch, spu_frame_align);
return gdbarch;
}
-/* Implement a SPU-specific vector type as replacement
- for __gdb_builtin_type_vec128. */
-static void
-spu_init_vector_type (void)
-{
- struct type *type;
-
- type = init_composite_type ("__spu_builtin_type_vec128", TYPE_CODE_UNION);
- append_composite_type_field (type, "uint128", builtin_type_int128);
- append_composite_type_field (type, "v2_int64", builtin_type_v2_int64);
- append_composite_type_field (type, "v4_int32", builtin_type_v4_int32);
- append_composite_type_field (type, "v8_int16", builtin_type_v8_int16);
- append_composite_type_field (type, "v16_int8", builtin_type_v16_int8);
- append_composite_type_field (type, "v2_double", builtin_type_v2_double);
- append_composite_type_field (type, "v4_float", builtin_type_v4_float);
-
- TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
- TYPE_NAME (type) = "spu_builtin_type_vec128";
- spu_builtin_type_vec128 = type;
-}
-
void
_initialize_spu_tdep (void)
{
register_gdbarch_init (bfd_arch_spu, spu_gdbarch_init);
- spu_init_vector_type ();
-
/* Add ourselves to objfile event chain. */
observer_attach_new_objfile (spu_overlay_new_objfile);
spu_overlay_data = register_objfile_data ();