--- a/components/gdb/patches/gdb.features.sparc64-fpu.xml.patch Mon Dec 05 15:47:44 2016 -0800
+++ b/components/gdb/patches/gdb.features.sparc64-fpu.xml.patch Tue Dec 06 15:59:27 2016 -0800
@@ -3,7 +3,7 @@
+++ gdb-7.6/gdb/features/sparc64-fpu.xml 2013-08-28 00:21:33.000000000 -0700
@@ -0,0 +1,60 @@
+<?xml version="1.0"?>
-+<!-- Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
++<!-- Copyright (C) 2007-2013 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gdb/patches/gdb.gdb.sparc-tdep.c.patch Tue Dec 06 15:59:27 2016 -0800
@@ -0,0 +1,239 @@
+Support for target descriptions layered on top of sparc32/sparc64
+which describe more registers than native ones.
+Pseudo registers always come after the real registers.
+One more step forward to modernize sparc tdep's.
+Submitted to upstream as:
+https://sourceware.org/bugzilla/show_bug.cgi?id=20936
+
+--- gdb-7.11/gdb/sparc-tdep.c.orig 2016-11-18 06:00:18.299687730 -0800
++++ gdb-7.11/gdb/sparc-tdep.c 2016-11-18 06:01:36.293409472 -0800
+@@ -33,6 +33,7 @@
+ #include "osabi.h"
+ #include "regcache.h"
+ #include "target.h"
++#include "target-descriptions.h"
+ #include "value.h"
+
+ #include "sparc-tdep.h"
+@@ -295,20 +296,23 @@
+ }
+
+ /* Register information. */
++#define SPARC32_FPU_REGISTERS \
++ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
++ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
++ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
++ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"
++#define SPARC32_CP0_REGISTERS \
++ "y", "psr", "wim", "tbr", "pc", "npc", "fsr", "csr"
+
++static const char *sparc_core_register_names[] = { SPARC_CORE_REGISTERS };
++static const char *sparc32_fpu_register_names[] = { SPARC32_FPU_REGISTERS };
++static const char *sparc32_cp0_register_names[] = { SPARC32_CP0_REGISTERS };
++
+ static const char *sparc32_register_names[] =
+ {
+- "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
+- "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
+- "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
+- "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
+-
+- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+- "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+- "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+- "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+-
+- "y", "psr", "wim", "tbr", "pc", "npc", "fsr", "csr"
++ SPARC_CORE_REGISTERS,
++ SPARC32_FPU_REGISTERS,
++ SPARC32_CP0_REGISTERS
+ };
+
+ /* Total number of registers. */
+@@ -327,7 +331,19 @@
+ #define SPARC32_NUM_PSEUDO_REGS ARRAY_SIZE (sparc32_pseudo_register_names)
+
+ /* Return the name of register REGNUM. */
++static const char *
++sparc32_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
++{
++ regnum -= gdbarch_num_regs (gdbarch);
+
++ if (regnum < SPARC32_NUM_PSEUDO_REGS)
++ return sparc32_pseudo_register_names[regnum];
++
++ internal_error (__FILE__, __LINE__,
++ _("sparc32_pseudo_register_name: bad register number %d"),
++ regnum);
++}
++
+ static const char *
+ sparc32_register_name (struct gdbarch *gdbarch, int regnum)
+ {
+@@ -334,10 +350,10 @@
+ if (regnum >= 0 && regnum < SPARC32_NUM_REGS)
+ return sparc32_register_names[regnum];
+
+- if (regnum < SPARC32_NUM_REGS + SPARC32_NUM_PSEUDO_REGS)
+- return sparc32_pseudo_register_names[regnum - SPARC32_NUM_REGS];
++ if (regnum >= gdbarch_num_regs (gdbarch))
++ return sparc32_pseudo_register_name (gdbarch, regnum);
+
+- return NULL;
++ return tdesc_register_name (gdbarch, regnum);
+ }
+
+ /* Construct types for ISA-specific registers. */
+@@ -399,7 +415,19 @@
+
+ /* Return the GDB type object for the "standard" data type of data in
+ register REGNUM. */
++static struct type *
++sparc32_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
++{
++ regnum -= gdbarch_num_regs (gdbarch);
+
++ if (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM)
++ return builtin_type (gdbarch)->builtin_double;
++
++ internal_error (__FILE__, __LINE__,
++ _("sparc32_pseudo_register_type: bad register number %d"),
++ regnum);
++}
++
+ static struct type *
+ sparc32_register_type (struct gdbarch *gdbarch, int regnum)
+ {
+@@ -406,9 +434,6 @@
+ if (regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM)
+ return builtin_type (gdbarch)->builtin_float;
+
+- if (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM)
+- return builtin_type (gdbarch)->builtin_double;
+-
+ if (regnum == SPARC_SP_REGNUM || regnum == SPARC_FP_REGNUM)
+ return builtin_type (gdbarch)->builtin_data_ptr;
+
+@@ -421,6 +446,9 @@
+ if (regnum == SPARC32_FSR_REGNUM)
+ return sparc_fsr_type (gdbarch);
+
++ if (regnum >= gdbarch_num_regs (gdbarch))
++ return sparc32_pseudo_register_type (gdbarch, regnum);
++
+ return builtin_type (gdbarch)->builtin_int32;
+ }
+
+@@ -431,6 +459,7 @@
+ {
+ enum register_status status;
+
++ regnum -= gdbarch_num_regs (gdbarch);
+ gdb_assert (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM);
+
+ regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC32_D0_REGNUM);
+@@ -445,6 +474,7 @@
+ struct regcache *regcache,
+ int regnum, const gdb_byte *buf)
+ {
++ regnum -= gdbarch_num_regs (gdbarch);
+ gdb_assert (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM);
+
+ regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC32_D0_REGNUM);
+@@ -1660,11 +1690,36 @@
+ }
+
+
++static int
++validate_tdesc_registers (const struct target_desc *tdesc,
++ struct tdesc_arch_data *tdesc_data,
++ const char *feature_name,
++ const char *register_names[],
++ unsigned int registers_num,
++ unsigned int reg_start)
++{
++ int valid_p = 1;
++ const struct tdesc_feature *feature;
++
++ feature = tdesc_find_feature (tdesc, feature_name);
++ if (feature == NULL)
++ return 0;
++
++ for (unsigned int i = 0; i < registers_num; i++)
++ valid_p &= tdesc_numbered_register (feature, tdesc_data,
++ reg_start + i,
++ register_names[i]);
++
++ return valid_p;
++}
++
+ static struct gdbarch *
+ sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+ {
+ struct gdbarch_tdep *tdep;
++ const struct target_desc *tdesc = info.target_desc;
+ struct gdbarch *gdbarch;
++ int valid_p = 1;
+
+ /* If there is already a candidate, use it. */
+ arches = gdbarch_list_lookup_by_info (arches, &info);
+@@ -1678,6 +1733,10 @@
+ tdep->pc_regnum = SPARC32_PC_REGNUM;
+ tdep->npc_regnum = SPARC32_NPC_REGNUM;
+ tdep->step_trap = sparc_step_trap;
++ tdep->fpu_register_names = sparc32_fpu_register_names;
++ tdep->fpu_registers_num = ARRAY_SIZE (sparc32_fpu_register_names);
++ tdep->cp0_register_names = sparc32_cp0_register_names;
++ tdep->cp0_registers_num = ARRAY_SIZE (sparc32_cp0_register_names);
+
+ set_gdbarch_long_double_bit (gdbarch, 128);
+ set_gdbarch_long_double_format (gdbarch, floatformats_sparc_quad);
+@@ -1686,6 +1745,8 @@
+ set_gdbarch_register_name (gdbarch, sparc32_register_name);
+ set_gdbarch_register_type (gdbarch, sparc32_register_type);
+ set_gdbarch_num_pseudo_regs (gdbarch, SPARC32_NUM_PSEUDO_REGS);
++ set_tdesc_pseudo_register_name (gdbarch, sparc32_pseudo_register_name);
++ set_tdesc_pseudo_register_type (gdbarch, sparc32_pseudo_register_type);
+ set_gdbarch_pseudo_register_read (gdbarch, sparc32_pseudo_register_read);
+ set_gdbarch_pseudo_register_write (gdbarch, sparc32_pseudo_register_write);
+
+@@ -1734,6 +1795,39 @@
+
+ frame_unwind_append_unwinder (gdbarch, &sparc32_frame_unwind);
+
++ if (tdesc_has_registers (tdesc))
++ {
++ struct tdesc_arch_data *tdesc_data = tdesc_data_alloc ();
++
++ /* Validate that the descriptor provides the mandatory registers
++ and allocate their numbers. */
++ valid_p &= validate_tdesc_registers (tdesc, tdesc_data,
++ "org.gnu.gdb.sparc.cpu",
++ sparc_core_register_names,
++ ARRAY_SIZE (sparc_core_register_names),
++ SPARC_G0_REGNUM);
++ valid_p &= validate_tdesc_registers (tdesc, tdesc_data,
++ "org.gnu.gdb.sparc.fpu",
++ tdep->fpu_register_names,
++ tdep->fpu_registers_num,
++ SPARC_F0_REGNUM);
++ valid_p &= validate_tdesc_registers (tdesc, tdesc_data,
++ "org.gnu.gdb.sparc.cp0",
++ tdep->cp0_register_names,
++ tdep->cp0_registers_num,
++ SPARC_F0_REGNUM +
++ tdep->fpu_registers_num);
++ if (!valid_p)
++ {
++ tdesc_data_cleanup (tdesc_data);
++ return NULL;
++ }
++
++ /* Target description may have changed. */
++ info.tdep_info = tdesc_data;
++ tdesc_use_registers (gdbarch, tdesc, tdesc_data);
++ }
++
+ /* If we have register sets, enable the generic core file support. */
+ if (tdep->gregset)
+ set_gdbarch_iterate_over_regset_sections
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gdb/patches/gdb.gdb.sparc-tdep.h-2.patch Tue Dec 06 15:59:27 2016 -0800
@@ -0,0 +1,48 @@
+Support for target descriptions layered on top of sparc32/sparc64
+which describe more registers than native ones.
+Pseudo registers always come after the real registers.
+One more step forward to modernize sparc tdep's.
+Submitted to upstream as:
+https://sourceware.org/bugzilla/show_bug.cgi?id=20936
+
+--- gdb-7.11/gdb/sparc-tdep.h.orig 2016-11-13 21:25:35.998594039 -0800
++++ gdb-7.11/gdb/sparc-tdep.h 2016-11-13 21:26:09.714151047 -0800
+@@ -20,6 +20,12 @@
+ #ifndef SPARC_TDEP_H
+ #define SPARC_TDEP_H 1
+
++#define SPARC_CORE_REGISTERS \
++ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", \
++ "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", \
++ "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", \
++ "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7"
++
+ struct frame_info;
+ struct gdbarch;
+ struct regcache;
+@@ -57,6 +63,12 @@
+ int pc_regnum;
+ int npc_regnum;
+
++ /* Register names specific for architecture (sparc32 vs. sparc64) */
++ const char **fpu_register_names;
++ size_t fpu_registers_num;
++ const char **cp0_register_names;
++ size_t cp0_registers_num;
++
+ /* Register sets. */
+ const struct regset *gregset;
+ size_t sizeof_gregset;
+@@ -141,8 +153,11 @@
+ SPARC32_NPC_REGNUM, /* %npc */
+ SPARC32_FSR_REGNUM, /* %fsr */
+ SPARC32_CSR_REGNUM, /* %csr */
++};
+
+- /* Pseudo registers. */
++/* Pseudo registers. */
++enum sparc32_pseudo_regnum
++{
+ SPARC32_D0_REGNUM, /* %d0 */
+ SPARC32_D30_REGNUM /* %d30 */
+ = SPARC32_D0_REGNUM + 15
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gdb/patches/gdb.gdb.sparc64-tdep.c-2.patch Tue Dec 06 15:59:27 2016 -0800
@@ -0,0 +1,328 @@
+Support for target descriptions layered on top of sparc32/sparc64
+which describe more registers than native ones.
+Pseudo registers always come after the real registers.
+One more step forward to modernize sparc tdep's.
+Submitted to upstream as:
+https://sourceware.org/bugzilla/show_bug.cgi?id=20936
+
+--- gdb-7.11/gdb/sparc64-tdep.c.orig 2016-11-13 22:23:36.747445049 -0800
++++ gdb-7.11/gdb/sparc64-tdep.c 2016-11-13 22:23:47.678340579 -0800
+@@ -31,6 +31,7 @@
+ #include "objfiles.h"
+ #include "osabi.h"
+ #include "regcache.h"
++#include "target-descriptions.h"
+ #include "target.h"
+ #include "value.h"
+
+@@ -251,28 +252,29 @@
+
+
+ /* Register information. */
++#define SPARC64_FPU_REGISTERS \
++ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
++ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
++ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
++ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
++ "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", \
++ "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62"
++#define SPARC64_CP0_REGISTERS \
++ "pc", "npc", \
++ /* FIXME: Give "state" a name until we start using register groups. */ \
++ "state", \
++ "fsr", \
++ "fprs", \
++ "y"
+
++static const char *sparc64_fpu_register_names[] = { SPARC64_FPU_REGISTERS };
++static const char *sparc64_cp0_register_names[] = { SPARC64_CP0_REGISTERS };
++
+ static const char *sparc64_register_names[] =
+ {
+- "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
+- "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
+- "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
+- "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
+-
+- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+- "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+- "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+- "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+- "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46",
+- "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62",
+-
+- "pc", "npc",
+-
+- /* FIXME: Give "state" a name until we start using register groups. */
+- "state",
+- "fsr",
+- "fprs",
+- "y",
++ SPARC_CORE_REGISTERS,
++ SPARC64_FPU_REGISTERS,
++ SPARC64_CP0_REGISTERS
+ };
+
+ /* Total number of registers. */
+@@ -298,7 +300,19 @@
+ #define SPARC64_NUM_PSEUDO_REGS ARRAY_SIZE (sparc64_pseudo_register_names)
+
+ /* Return the name of register REGNUM. */
++static const char *
++sparc64_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
++{
++ regnum -= gdbarch_num_regs (gdbarch);
+
++ if (regnum < SPARC64_NUM_PSEUDO_REGS)
++ return sparc64_pseudo_register_names[regnum];
++
++ internal_error (__FILE__, __LINE__,
++ _("sparc64_pseudo_register_name: bad register number %d"),
++ regnum);
++}
++
+ static const char *
+ sparc64_register_name (struct gdbarch *gdbarch, int regnum)
+ {
+@@ -305,9 +319,8 @@
+ if (regnum >= 0 && regnum < SPARC64_NUM_REGS)
+ return sparc64_register_names[regnum];
+
+- if (regnum >= SPARC64_NUM_REGS
+- && regnum < SPARC64_NUM_REGS + SPARC64_NUM_PSEUDO_REGS)
+- return sparc64_pseudo_register_names[regnum - SPARC64_NUM_REGS];
++ if (regnum >= gdbarch_num_regs (gdbarch))
++ return sparc64_pseudo_register_name (gdbarch, regnum);
+
+ return NULL;
+ }
+@@ -314,7 +327,29 @@
+
+ /* Return the GDB type object for the "standard" data type of data in
+ register REGNUM. */
++static struct type *
++sparc64_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
++{
++ regnum -= gdbarch_num_regs (gdbarch);
+
++ if (regnum == SPARC64_CWP_REGNUM)
++ return builtin_type (gdbarch)->builtin_int64;
++ if (regnum == SPARC64_PSTATE_REGNUM)
++ return sparc64_pstate_type (gdbarch);
++ if (regnum == SPARC64_ASI_REGNUM)
++ return builtin_type (gdbarch)->builtin_int64;
++ if (regnum == SPARC64_CCR_REGNUM)
++ return sparc64_ccr_type (gdbarch);
++ if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D62_REGNUM)
++ return builtin_type (gdbarch)->builtin_double;
++ if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q60_REGNUM)
++ return builtin_type (gdbarch)->builtin_long_double;
++
++ internal_error (__FILE__, __LINE__,
++ _("sparc64_pseudo_register_type: bad register number %d"),
++ regnum);
++}
++
+ static struct type *
+ sparc64_register_type (struct gdbarch *gdbarch, int regnum)
+ {
+@@ -344,20 +379,9 @@
+ return builtin_type (gdbarch)->builtin_int64;
+
+ /* Pseudo registers. */
++ if (regnum >= gdbarch_num_regs (gdbarch))
++ return sparc64_pseudo_register_type (gdbarch, regnum);
+
+- if (regnum == SPARC64_CWP_REGNUM)
+- return builtin_type (gdbarch)->builtin_int64;
+- if (regnum == SPARC64_PSTATE_REGNUM)
+- return sparc64_pstate_type (gdbarch);
+- if (regnum == SPARC64_ASI_REGNUM)
+- return builtin_type (gdbarch)->builtin_int64;
+- if (regnum == SPARC64_CCR_REGNUM)
+- return sparc64_ccr_type (gdbarch);
+- if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D62_REGNUM)
+- return builtin_type (gdbarch)->builtin_double;
+- if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q60_REGNUM)
+- return builtin_type (gdbarch)->builtin_long_double;
+-
+ internal_error (__FILE__, __LINE__, _("invalid regnum"));
+ }
+
+@@ -369,7 +393,7 @@
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ enum register_status status;
+
+- gdb_assert (regnum >= SPARC64_NUM_REGS);
++ regnum -= gdbarch_num_regs (gdbarch);
+
+ if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D30_REGNUM)
+ {
+@@ -446,8 +470,9 @@
+ int regnum, const gdb_byte *buf)
+ {
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+- gdb_assert (regnum >= SPARC64_NUM_REGS);
+
++ regnum -= gdbarch_num_regs (gdbarch);
++
+ if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D30_REGNUM)
+ {
+ regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC64_D0_REGNUM);
+@@ -663,6 +688,7 @@
+ sparc64_store_floating_fields (struct regcache *regcache, struct type *type,
+ const gdb_byte *valbuf, int element, int bitpos)
+ {
++ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ int len = TYPE_LENGTH (type);
+
+ gdb_assert (element < 16);
+@@ -677,7 +703,7 @@
+ gdb_assert (bitpos == 0);
+ gdb_assert ((element % 2) == 0);
+
+- regnum = SPARC64_Q0_REGNUM + element / 2;
++ regnum = gdbarch_num_regs (gdbarch) + SPARC64_Q0_REGNUM + element / 2;
+ regcache_cooked_write (regcache, regnum, valbuf);
+ }
+ else if (len == 8)
+@@ -684,7 +710,8 @@
+ {
+ gdb_assert (bitpos == 0 || bitpos == 64);
+
+- regnum = SPARC64_D0_REGNUM + element + bitpos / 64;
++ regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM
++ + element + bitpos / 64;
+ regcache_cooked_write (regcache, regnum, valbuf + (bitpos / 8));
+ }
+ else
+@@ -737,6 +764,8 @@
+ sparc64_extract_floating_fields (struct regcache *regcache, struct type *type,
+ gdb_byte *valbuf, int bitpos)
+ {
++ struct gdbarch *gdbarch = get_regcache_arch (regcache);
++
+ if (sparc64_floating_p (type))
+ {
+ int len = TYPE_LENGTH (type);
+@@ -746,7 +775,8 @@
+ {
+ gdb_assert (bitpos == 0 || bitpos == 128);
+
+- regnum = SPARC64_Q0_REGNUM + bitpos / 128;
++ regnum = gdbarch_num_regs (gdbarch) + SPARC64_Q0_REGNUM
++ + bitpos / 128;
+ regcache_cooked_read (regcache, regnum, valbuf + (bitpos / 8));
+ }
+ else if (len == 8)
+@@ -753,7 +783,7 @@
+ {
+ gdb_assert (bitpos % 64 == 0 && bitpos >= 0 && bitpos < 256);
+
+- regnum = SPARC64_D0_REGNUM + bitpos / 64;
++ regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM + bitpos / 64;
+ regcache_cooked_read (regcache, regnum, valbuf + (bitpos / 8));
+ }
+ else
+@@ -936,13 +966,13 @@
+ /* Float Complex or double Complex arguments. */
+ if (element < 16)
+ {
+- regnum = SPARC64_D0_REGNUM + element;
++ regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM + element;
+
+ if (len == 16)
+ {
+- if (regnum < SPARC64_D30_REGNUM)
++ if (regnum < gdbarch_num_regs (gdbarch) + SPARC64_D30_REGNUM)
+ regcache_cooked_write (regcache, regnum + 1, valbuf + 8);
+- if (regnum < SPARC64_D10_REGNUM)
++ if (regnum < gdbarch_num_regs (gdbarch) + SPARC64_D10_REGNUM)
+ regcache_cooked_write (regcache,
+ SPARC_O0_REGNUM + element + 1,
+ valbuf + 8);
+@@ -957,12 +987,14 @@
+ if (element % 2)
+ element++;
+ if (element < 16)
+- regnum = SPARC64_Q0_REGNUM + element / 2;
++ regnum = gdbarch_num_regs (gdbarch) + SPARC64_Q0_REGNUM
++ + element / 2;
+ }
+ else if (len == 8)
+ {
+ if (element < 16)
+- regnum = SPARC64_D0_REGNUM + element;
++ regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM
++ + element;
+ }
+ else if (len == 4)
+ {
+@@ -977,7 +1009,8 @@
+ valbuf = buf;
+ len = 8;
+ if (element < 16)
+- regnum = SPARC64_D0_REGNUM + element;
++ regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM
++ + element;
+ }
+ }
+ else
+@@ -994,19 +1027,24 @@
+
+ /* If we're storing the value in a floating-point register,
+ also store it in the corresponding %0 register(s). */
+- if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D10_REGNUM)
+- {
+- gdb_assert (element < 6);
+- regnum = SPARC_O0_REGNUM + element;
+- regcache_cooked_write (regcache, regnum, valbuf);
+- }
+- else if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q8_REGNUM)
+- {
+- gdb_assert (element < 5);
+- regnum = SPARC_O0_REGNUM + element;
+- regcache_cooked_write (regcache, regnum, valbuf);
+- regcache_cooked_write (regcache, regnum + 1, valbuf + 8);
+- }
++ if (regnum >= gdbarch_num_regs (gdbarch))
++ {
++ regnum -= gdbarch_num_regs (gdbarch);
++
++ if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D10_REGNUM)
++ {
++ gdb_assert (element < 6);
++ regnum = SPARC_O0_REGNUM + element;
++ regcache_cooked_write (regcache, regnum, valbuf);
++ }
++ else if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q8_REGNUM)
++ {
++ gdb_assert (element < 5);
++ regnum = SPARC_O0_REGNUM + element;
++ regcache_cooked_write (regcache, regnum, valbuf);
++ regcache_cooked_write (regcache, regnum + 1, valbuf + 8);
++ }
++ }
+ }
+
+ /* Always store the argument in memory. */
+@@ -1210,6 +1248,10 @@
+
+ tdep->pc_regnum = SPARC64_PC_REGNUM;
+ tdep->npc_regnum = SPARC64_NPC_REGNUM;
++ tdep->fpu_register_names = sparc64_fpu_register_names;
++ tdep->fpu_registers_num = ARRAY_SIZE (sparc64_fpu_register_names);
++ tdep->cp0_register_names = sparc64_cp0_register_names;
++ tdep->cp0_registers_num = ARRAY_SIZE (sparc64_cp0_register_names);
+
+ /* This is what all the fuss is about. */
+ set_gdbarch_long_bit (gdbarch, 64);
+@@ -1220,6 +1262,8 @@
+ set_gdbarch_register_name (gdbarch, sparc64_register_name);
+ set_gdbarch_register_type (gdbarch, sparc64_register_type);
+ set_gdbarch_num_pseudo_regs (gdbarch, SPARC64_NUM_PSEUDO_REGS);
++ set_tdesc_pseudo_register_name (gdbarch, sparc64_pseudo_register_name);
++ set_tdesc_pseudo_register_type (gdbarch, sparc64_pseudo_register_type);
+ set_gdbarch_pseudo_register_read (gdbarch, sparc64_pseudo_register_read);
+ set_gdbarch_pseudo_register_write (gdbarch, sparc64_pseudo_register_write);
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gdb/patches/gdb.gdb.sparc64-tdep.h.patch Tue Dec 06 15:59:27 2016 -0800
@@ -0,0 +1,22 @@
+Support for target descriptions layered on top of sparc32/sparc64
+which describe more registers than native ones.
+Pseudo registers always come after the real registers.
+One more step forward to modernize sparc tdep's.
+Submitted to upstream as:
+https://sourceware.org/bugzilla/show_bug.cgi?id=20936
+
+--- gdb-7.11/gdb/sparc64-tdep.h.orig 2016-11-13 21:26:01.870566687 -0800
++++ gdb-7.11/gdb/sparc64-tdep.h 2016-11-13 21:26:21.157185579 -0800
+@@ -56,8 +56,11 @@
+ SPARC64_FSR_REGNUM, /* %fsr */
+ SPARC64_FPRS_REGNUM, /* %fprs */
+ SPARC64_Y_REGNUM, /* %y */
++};
+
+- /* Pseudo registers. */
++/* Pseudo registers. */
++enum sparc64_pseudo_regnum
++{
+ SPARC64_CWP_REGNUM, /* %cwp */
+ SPARC64_PSTATE_REGNUM, /* %pstate */
+ SPARC64_ASI_REGNUM, /* %asi */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/gdb/patches/gdb.testsuite.tdesc-regs.exp.patch Tue Dec 06 15:59:27 2016 -0800
@@ -0,0 +1,22 @@
+Support for target descriptions layered on top of sparc32/sparc64
+which describe more registers than native ones.
+Pseudo registers always come after the real registers.
+One more step forward to modernize sparc tdep's.
+Submitted to upstream as:
+https://sourceware.org/bugzilla/show_bug.cgi?id=20936
+
+--- gdb-7.11/gdb/testsuite/gdb.xml/tdesc-regs.exp.orig 2016-11-19 07:32:42.820444427 -0800
++++ gdb-7.11/gdb/testsuite/gdb.xml/tdesc-regs.exp 2016-11-19 07:35:44.085215333 -0800
+@@ -49,6 +49,12 @@
+ "s390*-*-*" {
+ set core-regs {s390-core32.xml s390-acr.xml s390-fpr.xml}
+ }
++ "sparc-*-*" {
++ set core-regs {sparc-cpu.xml sparc-fpu.xml sparc-cp0.xml}
++ }
++ "sparc64-*-*" {
++ set core-regs {sparc64-cpu.xml sparc64-fpu.xml sparc64-cp0.xml}
++ }
+ "spu*-*-*" {
+ # This may be either the spu-linux-nat target, or the Cell/B.E.
+ # multi-architecture debugger in SPU standalone executable mode.
--- a/components/gdb/test/results-sparc-64.master Mon Dec 05 15:47:44 2016 -0800
+++ b/components/gdb/test/results-sparc-64.master Tue Dec 06 15:59:27 2016 -0800
@@ -24370,14 +24370,25 @@
PASS: gdb.xml/tdesc-errors.exp: set tdesc filename gdb.xml/tdesc-bogus.xml
PASS: gdb.xml/tdesc-errors.exp: set tdesc filename gdb.xml/tdesc-unknown.xml
PASS: gdb.xml/tdesc-regs.exp: set tdesc file single-reg.xml
-UNSUPPORTED: gdb.xml/tdesc-regs.exp: register tests
+PASS: gdb.xml/tdesc-regs.exp: cd to directory holding xml
+PASS: gdb.xml/tdesc-regs.exp: set tdesc filename regs.xml - from extra-regs.xml
+PASS: gdb.xml/tdesc-regs.exp: ptype $extrareg
+PASS: gdb.xml/tdesc-regs.exp: ptype $uintreg
+PASS: gdb.xml/tdesc-regs.exp: ptype $vecreg
+PASS: gdb.xml/tdesc-regs.exp: ptype $unionreg
+PASS: gdb.xml/tdesc-regs.exp: ptype $unionreg.v4
+PASS: gdb.xml/tdesc-regs.exp: ptype $structreg
+PASS: gdb.xml/tdesc-regs.exp: ptype $structreg.v4
+PASS: gdb.xml/tdesc-regs.exp: ptype $bitfields
+PASS: gdb.xml/tdesc-regs.exp: set tdesc filename regs.xml - from core-only.xml
+PASS: gdb.xml/tdesc-regs.exp: ptype $extrareg
PASS: gdb.xml/tdesc-xinclude.exp: set tdesc filename gdb.xml/includes.xml
PASS: gdb.xml/tdesc-xinclude.exp: set tdesc filename gdb.xml/bad-include.xml
PASS: gdb.xml/tdesc-xinclude.exp: set tdesc filename gdb.xml/loop.xml
-# of expected passes 22561
+# of expected passes 22574
# of unexpected failures 1228
# of expected failures 36
# of known failures 51
# of unresolved testcases 177
# of untested testcases 104
-# of unsupported tests 219
+# of unsupported tests 218