Bug 20936 - provide sparc and sparcv9 target description XML files

Message ID 83d4c58d-0834-4fc2-6194-72408510aa8a@oracle.com
State New
Headers show

Commit Message

Ivo Raisr Dec. 6, 2016, 11:57 p.m.
For some strange reason, test suite changes have not been included in my 
last patch. Please see the latest version of the patch and ChangeLog 
entry. Kind regards, I.
ChangeLog entry:
2016-12-07  Ivo Raisr  <ivo.raisr@oracle.com>

	PR tdep/20936
	Provide and use sparc32 and sparc64 target description XML files.
	* sparc32-cp0.xml, sparc32-cpu.xml, sparc32-fpu.xml: New files for
	sparc 32-bit.
	* sparc64-cp0.xml, sparc64-cpu.xml, sparc64-fpu.xml: New files
	for sparc 64-bit.
	* sparc32-solaris.xml, sparc64-solaris.xml: New files for sparc32
	and sparc64 on Solaris.
	* sparc-solaris.c, sparc64-solaris.c: Generated.
	* sparc-tdep.h: Deal with sparc32 and sparc64 differences
	in target descriptions. Separate real and pseudo registers.
	* sparc-tdep.c: Validate and use registers of the target description.
	Pseudo registers are numbered after all real registers from the target
	description; deal with it.
	* sparc64-tdep.h: Separate real and pseudo registers.
	* sparc64-tdep.c: Pseudo registers are numbered after all real
	registers from the target description; deal with it.
	* gdb.texinfo: New node "Sparc Features".
	* tdesc-regs.exp: Provide sparc core registers for the tests.

Comments

Yao Qi Dec. 12, 2016, 12:53 p.m. | #1
On 16-12-06 23:57:58, Ivo Raisr wrote:
> For some strange reason, test suite changes have not been included

> in my last patch. Please see the latest version of the patch and

> ChangeLog entry. Kind regards, I.

> 


Hi Ivo,
Your patch does two orthogonal things IMO,

 - Pseudo register support enhancement, patch #1
 - XML target description support and sparc*-tdep.c updates, patch #2,

Can you split them to two patches?

> @@ -327,6 +331,18 @@ static const char *sparc32_pseudo_regist

>  #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 @@ sparc32_register_name (struct gdbarch *g

>    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);

>  }


I prefer to using register names provided by target description, does
the code below work for you?

  if (tdesc_has_registers (gdbarch_target_desc (gdbarch)))
    return tdesc_register_name (gdbarch, rawnum);
  else if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch))
    return sparc32_register_names[regnum];
  else
    return sparc32_pseudo_register_name (gdbarch, regnum);


>  static struct type *

>  sparc32_register_type (struct gdbarch *gdbarch, int regnum)

> @@ -406,9 +434,6 @@ sparc32_register_type (struct gdbarch *g

>    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 @@ sparc32_register_type (struct gdbarch *g

>    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;

>  }


This can be moved to patch #1.  In patch #2, we can prefer register
types from target description, at the start of sparc32_register_type,
we can add this,

  /* If the XML description has register information, use that to
     determine the register type.  */
  if (tdesc_has_registers (gdbarch_target_desc (gdbarch)))
    return tdesc_register_type (gdbarch, regno);

>  

> @@ -431,6 +459,7 @@ sparc32_pseudo_register_read (struct gdb

>  {

>    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 @@ sparc32_pseudo_register_write (struct gd

>  			       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 @@ sparc_iterate_over_regset_sections (stru

>  }

>  


They can be moved to patch #1.

>  

> -  /* Pseudo registers.  */

> +/* Pseudo registers.  */

> +enum sparc32_pseudo_regnum

> +{

>    SPARC32_D0_REGNUM,		/* %d0 */


Explicitly set it to zero.

>    SPARC32_D30_REGNUM		/* %d30 */

>    = SPARC32_D0_REGNUM + 15

> diff -Npur a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c

> --- a/gdb/sparc64-tdep.c	2016-02-09 19:19:39.000000000 +0000

> +++ b/gdb/sparc64-tdep.c	2016-12-06 13:53:05.174301647 +0000

> @@ -31,6 +31,7 @@

>  #include "objfiles.h"

>  #include "osabi.h"

>  #include "regcache.h"

> +#include "target-descriptions.h"

>  #include "target.h"

>  #include "value.h"

>  

> @@ -226,28 +227,29 @@ sparc64_fprs_type (struct gdbarch *gdbar

>  

>  

>  /* 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.  */

> @@ -273,6 +275,18 @@ static const char *sparc64_pseudo_regist

>  #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)

> @@ -280,15 +294,36 @@ sparc64_register_name (struct gdbarch *g

>    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);

>  


Change like this can be moved to patch #1.

>    return NULL;

>  }

>  

>  /* 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)

> @@ -319,19 +354,8 @@ sparc64_register_type (struct gdbarch *g

>      return builtin_type (gdbarch)->builtin_int64;

>  

>    /* Pseudo registers.  */

> -

> -  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 builtin_type (gdbarch)->builtin_int64;

> -  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;

> +  if (regnum >= gdbarch_num_regs (gdbarch))

> +    return sparc64_pseudo_register_type (gdbarch, regnum);

>  

>    internal_error (__FILE__, __LINE__, _("invalid regnum"));

>  }

> @@ -344,7 +368,7 @@ sparc64_pseudo_register_read (struct gdb

>    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)

>      {

> @@ -421,7 +445,8 @@ sparc64_pseudo_register_write (struct gd

>  			       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)

>      {

> @@ -638,6 +663,7 @@ static void

>  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);

> @@ -652,14 +678,15 @@ sparc64_store_floating_fields (struct re

>  	  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)

>  	{

>  	  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

> @@ -712,6 +739,8 @@ static void

>  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);

> @@ -721,14 +750,15 @@ sparc64_extract_floating_fields (struct

>  	{

>  	  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)

>  	{

>  	  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

> @@ -911,13 +941,13 @@ sparc64_store_arguments (struct regcache

>  	  /* 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);

> @@ -932,12 +962,14 @@ sparc64_store_arguments (struct regcache

>  	      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)

>  	    {

> @@ -952,7 +984,8 @@ sparc64_store_arguments (struct regcache

>  	      valbuf = buf;

>  	      len = 8;

>  	      if (element < 16)

> -		regnum = SPARC64_D0_REGNUM + element;

> +		regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM

> +                         + element;

>  	    }

>  	}

>        else

> @@ -969,19 +1002,24 @@ sparc64_store_arguments (struct regcache

>  

>  	  /* 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))

> +            {


The indentation looks odd to me.

> +              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);

> +	        }

> +            }

>  	}


Looks all these changes can be moved to patch #1.

>  

>        /* Always store the argument in memory.  */

> diff -Npur a/gdb/testsuite/gdb.xml/tdesc-regs.exp b/gdb/testsuite/gdb.xml/tdesc-regs.exp

> --- a/gdb/testsuite/gdb.xml/tdesc-regs.exp	2016-02-09 19:19:39.000000000 +0000

> +++ b/gdb/testsuite/gdb.xml/tdesc-regs.exp	2016-12-06 15:53:35.418621207 +0000

> @@ -49,6 +49,12 @@ switch -glob -- [istarget] {

>      "s390*-*-*" {

>  	set core-regs {s390-core32.xml s390-acr.xml s390-fpr.xml}

>      }

> +    "sparc-*-*" {

> +        set core-regs {sparc32-cpu.xml sparc32-fpu.xml sparc32-cp0.xml}

> +    }

> +    "sparc64-*-*" {

> +        set core-regs {sparc64-cpu.xml sparc64-fpu.xml sparc64-cp0.xml}

> +    }


You need 'set regdir "sparc/"'

>      "spu*-*-*" {

>  	# This may be either the spu-linux-nat target, or the Cell/B.E.

>  	# multi-architecture debugger in SPU standalone executable mode.


> ChangeLog entry:

> 2016-12-07  Ivo Raisr  <ivo.raisr@oracle.com>

> 

> 	PR tdep/20936

> 	Provide and use sparc32 and sparc64 target description XML files.

> 	* sparc32-cp0.xml, sparc32-cpu.xml, sparc32-fpu.xml: New files for

> 	sparc 32-bit.

> 	* sparc64-cp0.xml, sparc64-cpu.xml, sparc64-fpu.xml: New files

> 	for sparc 64-bit.

> 	* sparc32-solaris.xml, sparc64-solaris.xml: New files for sparc32

> 	and sparc64 on Solaris.

> 	* sparc-solaris.c, sparc64-solaris.c: Generated.


These file names should be prefixed with "feature/sparc/"

> 	* sparc-tdep.h: Deal with sparc32 and sparc64 differences

> 	in target descriptions. Separate real and pseudo registers.

> 	* sparc-tdep.c: Validate and use registers of the target description.

> 	Pseudo registers are numbered after all real registers from the target

> 	description; deal with it.

> 	* sparc64-tdep.h: Separate real and pseudo registers.

> 	* sparc64-tdep.c: Pseudo registers are numbered after all real

> 	registers from the target description; deal with it.


Please describe the change on the function level, take a look at
https://sourceware.org/gdb/wiki/ContributionChecklist there are two
sections about ChangeLog.

> 	* gdb.texinfo: New node "Sparc Features".


This should go to a separated entry,

gdb/doc:

2016-12-07  Ivo Raisr  <ivo.raisr@oracle.com>

	* gdb.texinfo (Standard Target Features): Document SPARC features.
	(Sparc Features): New node.

> 	* tdesc-regs.exp: Provide sparc core registers for the tests.


Likewise,

gdb/testsuite:

2016-12-07  Ivo Raisr  <ivo.raisr@oracle.com>

	* gdb.xml/tdesc-regs.exp: Provide sparc core registers for
	the tests.

-- 
Yao (齐尧)
Ivo Raisr Jan. 17, 2017, 9:37 p.m. | #2
On 12.12.2016 13:53, Yao Qi wrote:
> Hi Ivo,

> Your patch does two orthogonal things IMO,

>

>   - Pseudo register support enhancement, patch #1

>   - XML target description support and sparc*-tdep.c updates, patch #2,

>

> Can you split them to two patches?


Hi Yao,

The first patch #1 has been pushed yesterday by Jose Marchesi.
I've prepared the second patch #2 and ChangeLog entries.
Please can you have a look (all attached).

Thank you,
I.

ChangeLog entry:
2017-01-17  Ivo Raisr  <ivo.raisr@oracle.com>

	PR tdep/20936
	* gdb.texinfo: (Standard Target Features): Document SPARC features.
	(Sparc Features): New node.
ChangeLog entry:
2017-01-17  Ivo Raisr  <ivo.raisr@oracle.com>

	PR tdep/20936
	Provide and use sparc32 and sparc64 target description XML files.
	* features/sparc/sparc32-cp0.xml, features/sparc/sparc32-cpu.xml,
	features/sparc/sparc32-fpu.xml: New files for sparc 32-bit.
	* features/sparc/sparc64-cp0.xml, features/sparc/sparc64-cpu.xml,
	features/sparc/sparc64-fpu.xml: New files for sparc 64-bit.
	* features/sparc/sparc32-solaris.xml: New file.
	* features/sparc/sparc64-solaris.xml: New file.
	* features/sparc/sparc32-solaris.c: Generated.
	* features/sparc/sparc64-solaris.c: Generated.
	* sparc-tdep.h: Account for differences in target descriptions.
	* sparc-tdep.c (sparc32_register_name): Use target provided registers.
	(sparc32_register_type): Use target provided registers.
	(validate_tdesc_registers): New function.
	(sparc32_gdbarch_init): Use tdesc_has_registers.
	Set pseudoregister functions.
	* sparc64-tdep.c (sparc64_register_name): Use target provided registers.
	(sparc64_register_type): Use target provided registers.
	(sparc64_init_abi): Set pseudoregister functions.
ChangeLog entry:
2017-01-17  Ivo Raisr  <ivo.raisr@oracle.com>

	PR tdep/20936
	* gdb.xml/tdesc-regs.exp: Provide sparc core registers for the tests.diff -Nupr a/gdb/doc/gdb.texinfo gdb-7.11/gdb/doc/gdb.texinfo
--- a/gdb/doc/gdb.texinfo	2016-02-24 01:55:15.000000000 +0000
+++ gdb-7.11/gdb/doc/gdb.texinfo	2017-01-17 04:51:21.533190029 +0000
@@ -40658,6 +40658,7 @@ registers using the capitalization used
 * Nios II Features::
 * PowerPC Features::
 * S/390 and System z Features::
+* Sparc Features::
 * TIC6x Features::
 @end menu
 
@@ -40945,6 +40946,48 @@ through @samp{f15} to present the 128-bi
 contain the 128-bit wide vector registers @samp{v16} through
 @samp{v31}.
 
+@node Sparc Features
+@subsection Sparc Features
+@cindex target descriptions, sparc32 features
+@cindex target descriptions, sparc64 features
+The @samp{org.gnu.gdb.sparc.cpu} feature is required for sparc32/sparc64
+targets.  It should describe the following registers:
+
+@itemize @minus
+@item
+@samp{g0} through @samp{g7}
+@item
+@samp{o0} through @samp{o7}
+@item
+@samp{l0} through @samp{l7}
+@item
+@samp{i0} through @samp{i7}
+@end itemize
+
+They may be 32-bit or 64-bit depending on the target.
+
+Also the @samp{org.gnu.gdb.sparc.fpu} feature is required for sparc32/sparc64
+targets.  It should describe the following registers:
+
+@itemize @minus
+@item
+@samp{f0} through @samp{f31}
+@item
+@samp{f32} through @samp{f62} for sparc64
+@end itemize
+
+The @samp{org.gnu.gdb.sparc.cp0} feature is required for sparc32/sparc64
+targets.  It should describe the following registers:
+
+@itemize @minus
+@item
+@samp{y}, @samp{psr}, @samp{wim}, @samp{tbr}, @samp{pc}, @samp{npc},
+@samp{fsr}, and @samp{csr} for sparc32
+@item
+@samp{pc}, @samp{npc}, @samp{state}, @samp{fsr}, @samp{fprs}, and @samp{y}
+for sparc64
+@end itemize
+
 @node TIC6x Features
 @subsection TMS320C6x Features
 @cindex target descriptions, TIC6x features
diff -Nupr a/gdb/features/sparc/sparc32-cp0.xml gdb-7.11/gdb/features/sparc/sparc32-cp0.xml
--- a/gdb/features/sparc/sparc32-cp0.xml	1969-12-31 16:00:00.000000000 +0000
+++ gdb-7.11/gdb/features/sparc/sparc32-cp0.xml	2017-01-17 04:51:21.534235184 +0000
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.sparc.cp0">
+  <reg name="y" bitsize="32" type="uint32" regnum="64"/>
+  <reg name="psr" bitsize="32" type="uint32" regnum="65"/>
+  <reg name="wim" bitsize="32" type="uint32" regnum="66"/>
+  <reg name="tbr" bitsize="32" type="uint32" regnum="67"/>
+  <reg name="pc" bitsize="32" type="code_ptr" regnum="68"/>
+  <reg name="npc" bitsize="32" type="code_ptr" regnum="69"/>
+  <reg name="fsr" bitsize="32" type="uint32" regnum="70"/>
+  <reg name="csr" bitsize="32" type="uint32" regnum="71"/>
+</feature>
+
diff -Nupr a/gdb/features/sparc/sparc32-cpu.xml gdb-7.11/gdb/features/sparc/sparc32-cpu.xml
--- a/gdb/features/sparc/sparc32-cpu.xml	1969-12-31 16:00:00.000000000 +0000
+++ gdb-7.11/gdb/features/sparc/sparc32-cpu.xml	2017-01-17 04:51:21.534750652 +0000
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.sparc.cpu">
+  <reg name="g0" bitsize="32" type="uint32" regnum="0"/>
+  <reg name="g1" bitsize="32" type="uint32" regnum="1"/>
+  <reg name="g2" bitsize="32" type="uint32" regnum="2"/>
+  <reg name="g3" bitsize="32" type="uint32" regnum="3"/>
+  <reg name="g4" bitsize="32" type="uint32" regnum="4"/>
+  <reg name="g5" bitsize="32" type="uint32" regnum="5"/>
+  <reg name="g6" bitsize="32" type="uint32" regnum="6"/>
+  <reg name="g7" bitsize="32" type="uint32" regnum="7"/>
+  <reg name="o0" bitsize="32" type="uint32" regnum="8"/>
+  <reg name="o1" bitsize="32" type="uint32" regnum="9"/>
+  <reg name="o2" bitsize="32" type="uint32" regnum="10"/>
+  <reg name="o3" bitsize="32" type="uint32" regnum="11"/>
+  <reg name="o4" bitsize="32" type="uint32" regnum="12"/>
+  <reg name="o5" bitsize="32" type="uint32" regnum="13"/>
+  <reg name="sp" bitsize="32" type="uint32" regnum="14"/>
+  <reg name="o7" bitsize="32" type="uint32" regnum="15"/>
+  <reg name="l0" bitsize="32" type="uint32" regnum="16"/>
+  <reg name="l1" bitsize="32" type="uint32" regnum="17"/>
+  <reg name="l2" bitsize="32" type="uint32" regnum="18"/>
+  <reg name="l3" bitsize="32" type="uint32" regnum="19"/>
+  <reg name="l4" bitsize="32" type="uint32" regnum="20"/>
+  <reg name="l5" bitsize="32" type="uint32" regnum="21"/>
+  <reg name="l6" bitsize="32" type="uint32" regnum="22"/>
+  <reg name="l7" bitsize="32" type="uint32" regnum="23"/>
+  <reg name="i0" bitsize="32" type="uint32" regnum="24"/>
+  <reg name="i1" bitsize="32" type="uint32" regnum="25"/>
+  <reg name="i2" bitsize="32" type="uint32" regnum="26"/>
+  <reg name="i3" bitsize="32" type="uint32" regnum="27"/>
+  <reg name="i4" bitsize="32" type="uint32" regnum="28"/>
+  <reg name="i5" bitsize="32" type="uint32" regnum="29"/>
+  <reg name="fp" bitsize="32" type="uint32" regnum="30"/>
+  <reg name="i7" bitsize="32" type="uint32" regnum="31"/>
+</feature>
diff -Nupr a/gdb/features/sparc/sparc32-fpu.xml gdb-7.11/gdb/features/sparc/sparc32-fpu.xml
--- a/gdb/features/sparc/sparc32-fpu.xml	1969-12-31 16:00:00.000000000 +0000
+++ gdb-7.11/gdb/features/sparc/sparc32-fpu.xml	2017-01-17 04:51:21.535246657 +0000
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.sparc.fpu">
+  <reg name="f0" bitsize="32" type="ieee_single" regnum="32"/>
+  <reg name="f1" bitsize="32" type="ieee_single" regnum="33"/>
+  <reg name="f2" bitsize="32" type="ieee_single" regnum="34"/>
+  <reg name="f3" bitsize="32" type="ieee_single" regnum="35"/>
+  <reg name="f4" bitsize="32" type="ieee_single" regnum="36"/>
+  <reg name="f5" bitsize="32" type="ieee_single" regnum="37"/>
+  <reg name="f6" bitsize="32" type="ieee_single" regnum="38"/>
+  <reg name="f7" bitsize="32" type="ieee_single" regnum="39"/>
+  <reg name="f8" bitsize="32" type="ieee_single" regnum="40"/>
+  <reg name="f9" bitsize="32" type="ieee_single" regnum="41"/>
+  <reg name="f10" bitsize="32" type="ieee_single" regnum="42"/>
+  <reg name="f11" bitsize="32" type="ieee_single" regnum="43"/>
+  <reg name="f12" bitsize="32" type="ieee_single" regnum="44"/>
+  <reg name="f13" bitsize="32" type="ieee_single" regnum="45"/>
+  <reg name="f14" bitsize="32" type="ieee_single" regnum="46"/>
+  <reg name="f15" bitsize="32" type="ieee_single" regnum="47"/>
+  <reg name="f16" bitsize="32" type="ieee_single" regnum="48"/>
+  <reg name="f17" bitsize="32" type="ieee_single" regnum="49"/>
+  <reg name="f18" bitsize="32" type="ieee_single" regnum="50"/>
+  <reg name="f19" bitsize="32" type="ieee_single" regnum="51"/>
+  <reg name="f20" bitsize="32" type="ieee_single" regnum="52"/>
+  <reg name="f21" bitsize="32" type="ieee_single" regnum="53"/>
+  <reg name="f22" bitsize="32" type="ieee_single" regnum="54"/>
+  <reg name="f23" bitsize="32" type="ieee_single" regnum="55"/>
+  <reg name="f24" bitsize="32" type="ieee_single" regnum="56"/>
+  <reg name="f25" bitsize="32" type="ieee_single" regnum="57"/>
+  <reg name="f26" bitsize="32" type="ieee_single" regnum="58"/>
+  <reg name="f27" bitsize="32" type="ieee_single" regnum="59"/>
+  <reg name="f28" bitsize="32" type="ieee_single" regnum="60"/>
+  <reg name="f29" bitsize="32" type="ieee_single" regnum="61"/>
+  <reg name="f30" bitsize="32" type="ieee_single" regnum="62"/>
+  <reg name="f31" bitsize="32" type="ieee_single" regnum="63"/>
+</feature>
+
diff -Nupr a/gdb/features/sparc/sparc32-solaris.c gdb-7.11/gdb/features/sparc/sparc32-solaris.c
--- a/gdb/features/sparc/sparc32-solaris.c	1969-12-31 16:00:00.000000000 +0000
+++ gdb-7.11/gdb/features/sparc/sparc32-solaris.c	2017-01-17 04:51:21.535796032 +0000
@@ -0,0 +1,98 @@
+/* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
+  Original: sparc32-solaris.xml */
+
+#include "defs.h"
+#include "osabi.h"
+#include "target-descriptions.h"
+
+struct target_desc *tdesc_sparc32_solaris;
+static void
+initialize_tdesc_sparc32_solaris (void)
+{
+  struct target_desc *result = allocate_target_description ();
+  struct tdesc_feature *feature;
+
+  set_tdesc_architecture (result, bfd_scan_arch ("sparc"));
+
+  set_tdesc_osabi (result, osabi_from_tdesc_string ("Solaris"));
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.sparc.cpu");
+  tdesc_create_reg (feature, "g0", 0, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "g1", 1, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "g2", 2, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "g3", 3, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "g4", 4, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "g5", 5, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "g6", 6, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "g7", 7, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "o0", 8, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "o1", 9, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "o2", 10, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "o3", 11, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "o4", 12, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "o5", 13, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "sp", 14, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "o7", 15, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l0", 16, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l1", 17, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l2", 18, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l3", 19, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l4", 20, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l5", 21, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l6", 22, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l7", 23, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "i0", 24, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "i1", 25, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "i2", 26, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "i3", 27, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "i4", 28, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "i5", 29, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "fp", 30, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "i7", 31, 1, NULL, 32, "uint32");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.sparc.cp0");
+  tdesc_create_reg (feature, "y", 64, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "psr", 65, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "wim", 66, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "tbr", 67, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "pc", 68, 1, NULL, 32, "code_ptr");
+  tdesc_create_reg (feature, "npc", 69, 1, NULL, 32, "code_ptr");
+  tdesc_create_reg (feature, "fsr", 70, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "csr", 71, 1, NULL, 32, "uint32");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.sparc.fpu");
+  tdesc_create_reg (feature, "f0", 32, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f1", 33, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f2", 34, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f3", 35, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f4", 36, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f5", 37, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f6", 38, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f7", 39, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f8", 40, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f9", 41, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f10", 42, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f11", 43, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f12", 44, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f13", 45, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f14", 46, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f15", 47, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f16", 48, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f17", 49, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f18", 50, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f19", 51, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f20", 52, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f21", 53, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f22", 54, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f23", 55, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f24", 56, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f25", 57, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f26", 58, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f27", 59, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f28", 60, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f29", 61, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f30", 62, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f31", 63, 1, NULL, 32, "ieee_single");
+
+  tdesc_sparc_solaris = result;
+}
diff -Nupr a/gdb/features/sparc/sparc32-solaris.xml gdb-7.11/gdb/features/sparc/sparc32-solaris.xml
--- a/gdb/features/sparc/sparc32-solaris.xml	1969-12-31 16:00:00.000000000 +0000
+++ gdb-7.11/gdb/features/sparc/sparc32-solaris.xml	2017-01-17 04:51:21.536253577 +0000
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+  <architecture>sparc</architecture>
+  <osabi>Solaris</osabi>
+  <xi:include href="sparc32-cpu.xml"/>
+  <xi:include href="sparc32-cp0.xml"/>
+  <xi:include href="sparc32-fpu.xml"/>
+</target>
diff -Nupr a/gdb/features/sparc/sparc64-cp0.xml gdb-7.11/gdb/features/sparc/sparc64-cp0.xml
--- a/gdb/features/sparc/sparc64-cp0.xml	1969-12-31 16:00:00.000000000 +0000
+++ gdb-7.11/gdb/features/sparc/sparc64-cp0.xml	2017-01-17 04:51:21.536709179 +0000
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.sparc.cp0">
+  <reg name="pc" bitsize="64" type="code_ptr" regnum="80"/>
+  <reg name="npc" bitsize="64" type="code_ptr" regnum="81"/>
+  <reg name="state" bitsize="64" type="uint64" regnum="82"/>
+  <reg name="fsr" bitsize="64" type="uint64" regnum="83"/>
+  <reg name="fprs" bitsize="64" type="uint64" regnum="84"/>
+  <reg name="y" bitsize="64" type="uint64" regnum="85"/>
+</feature>
+
diff -Nupr a/gdb/features/sparc/sparc64-cpu.xml gdb-7.11/gdb/features/sparc/sparc64-cpu.xml
--- a/gdb/features/sparc/sparc64-cpu.xml	1969-12-31 16:00:00.000000000 +0000
+++ gdb-7.11/gdb/features/sparc/sparc64-cpu.xml	2017-01-17 04:51:21.537183089 +0000
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.sparc.cpu">
+  <reg name="g0" bitsize="64" type="uint64" regnum="0"/>
+  <reg name="g1" bitsize="64" type="uint64" regnum="1"/>
+  <reg name="g2" bitsize="64" type="uint64" regnum="2"/>
+  <reg name="g3" bitsize="64" type="uint64" regnum="3"/>
+  <reg name="g4" bitsize="64" type="uint64" regnum="4"/>
+  <reg name="g5" bitsize="64" type="uint64" regnum="5"/>
+  <reg name="g6" bitsize="64" type="uint64" regnum="6"/>
+  <reg name="g7" bitsize="64" type="uint64" regnum="7"/>
+  <reg name="o0" bitsize="64" type="uint64" regnum="8"/>
+  <reg name="o1" bitsize="64" type="uint64" regnum="9"/>
+  <reg name="o2" bitsize="64" type="uint64" regnum="10"/>
+  <reg name="o3" bitsize="64" type="uint64" regnum="11"/>
+  <reg name="o4" bitsize="64" type="uint64" regnum="12"/>
+  <reg name="o5" bitsize="64" type="uint64" regnum="13"/>
+  <reg name="sp" bitsize="64" type="uint64" regnum="14"/>
+  <reg name="o7" bitsize="64" type="uint64" regnum="15"/>
+  <reg name="l0" bitsize="64" type="uint64" regnum="16"/>
+  <reg name="l1" bitsize="64" type="uint64" regnum="17"/>
+  <reg name="l2" bitsize="64" type="uint64" regnum="18"/>
+  <reg name="l3" bitsize="64" type="uint64" regnum="19"/>
+  <reg name="l4" bitsize="64" type="uint64" regnum="20"/>
+  <reg name="l5" bitsize="64" type="uint64" regnum="21"/>
+  <reg name="l6" bitsize="64" type="uint64" regnum="22"/>
+  <reg name="l7" bitsize="64" type="uint64" regnum="23"/>
+  <reg name="i0" bitsize="64" type="uint64" regnum="24"/>
+  <reg name="i1" bitsize="64" type="uint64" regnum="25"/>
+  <reg name="i2" bitsize="64" type="uint64" regnum="26"/>
+  <reg name="i3" bitsize="64" type="uint64" regnum="27"/>
+  <reg name="i4" bitsize="64" type="uint64" regnum="28"/>
+  <reg name="i5" bitsize="64" type="uint64" regnum="29"/>
+  <reg name="fp" bitsize="64" type="uint64" regnum="30"/>
+  <reg name="i7" bitsize="64" type="uint64" regnum="31"/>
+</feature>
diff -Nupr a/gdb/features/sparc/sparc64-fpu.xml gdb-7.11/gdb/features/sparc/sparc64-fpu.xml
--- a/gdb/features/sparc/sparc64-fpu.xml	1969-12-31 16:00:00.000000000 +0000
+++ gdb-7.11/gdb/features/sparc/sparc64-fpu.xml	2017-01-17 04:51:21.537853135 +0000
@@ -0,0 +1,60 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.sparc.fpu">
+  <reg name="f0" bitsize="32" type="ieee_single" regnum="32"/>
+  <reg name="f1" bitsize="32" type="ieee_single" regnum="33"/>
+  <reg name="f2" bitsize="32" type="ieee_single" regnum="34"/>
+  <reg name="f3" bitsize="32" type="ieee_single" regnum="35"/>
+  <reg name="f4" bitsize="32" type="ieee_single" regnum="36"/>
+  <reg name="f5" bitsize="32" type="ieee_single" regnum="37"/>
+  <reg name="f6" bitsize="32" type="ieee_single" regnum="38"/>
+  <reg name="f7" bitsize="32" type="ieee_single" regnum="39"/>
+  <reg name="f8" bitsize="32" type="ieee_single" regnum="40"/>
+  <reg name="f9" bitsize="32" type="ieee_single" regnum="41"/>
+  <reg name="f10" bitsize="32" type="ieee_single" regnum="42"/>
+  <reg name="f11" bitsize="32" type="ieee_single" regnum="43"/>
+  <reg name="f12" bitsize="32" type="ieee_single" regnum="44"/>
+  <reg name="f13" bitsize="32" type="ieee_single" regnum="45"/>
+  <reg name="f14" bitsize="32" type="ieee_single" regnum="46"/>
+  <reg name="f15" bitsize="32" type="ieee_single" regnum="47"/>
+  <reg name="f16" bitsize="32" type="ieee_single" regnum="48"/>
+  <reg name="f17" bitsize="32" type="ieee_single" regnum="49"/>
+  <reg name="f18" bitsize="32" type="ieee_single" regnum="50"/>
+  <reg name="f19" bitsize="32" type="ieee_single" regnum="51"/>
+  <reg name="f20" bitsize="32" type="ieee_single" regnum="52"/>
+  <reg name="f21" bitsize="32" type="ieee_single" regnum="53"/>
+  <reg name="f22" bitsize="32" type="ieee_single" regnum="54"/>
+  <reg name="f23" bitsize="32" type="ieee_single" regnum="55"/>
+  <reg name="f24" bitsize="32" type="ieee_single" regnum="56"/>
+  <reg name="f25" bitsize="32" type="ieee_single" regnum="57"/>
+  <reg name="f26" bitsize="32" type="ieee_single" regnum="58"/>
+  <reg name="f27" bitsize="32" type="ieee_single" regnum="59"/>
+  <reg name="f28" bitsize="32" type="ieee_single" regnum="60"/>
+  <reg name="f29" bitsize="32" type="ieee_single" regnum="61"/>
+  <reg name="f30" bitsize="32" type="ieee_single" regnum="62"/>
+  <reg name="f31" bitsize="32" type="ieee_single" regnum="63"/>
+
+  <reg name="f32" bitsize="64" type="ieee_double" regnum="64"/>
+  <reg name="f34" bitsize="64" type="ieee_double" regnum="65"/>
+  <reg name="f36" bitsize="64" type="ieee_double" regnum="66"/>
+  <reg name="f38" bitsize="64" type="ieee_double" regnum="67"/>
+  <reg name="f40" bitsize="64" type="ieee_double" regnum="68"/>
+  <reg name="f42" bitsize="64" type="ieee_double" regnum="69"/>
+  <reg name="f44" bitsize="64" type="ieee_double" regnum="70"/>
+  <reg name="f46" bitsize="64" type="ieee_double" regnum="71"/>
+  <reg name="f48" bitsize="64" type="ieee_double" regnum="72"/>
+  <reg name="f50" bitsize="64" type="ieee_double" regnum="73"/>
+  <reg name="f52" bitsize="64" type="ieee_double" regnum="74"/>
+  <reg name="f54" bitsize="64" type="ieee_double" regnum="75"/>
+  <reg name="f56" bitsize="64" type="ieee_double" regnum="76"/>
+  <reg name="f58" bitsize="64" type="ieee_double" regnum="77"/>
+  <reg name="f60" bitsize="64" type="ieee_double" regnum="78"/>
+  <reg name="f62" bitsize="64" type="ieee_double" regnum="79"/>
+</feature>
+
diff -Nupr a/gdb/features/sparc/sparc64-solaris.c gdb-7.11/gdb/features/sparc/sparc64-solaris.c
--- a/gdb/features/sparc/sparc64-solaris.c	1969-12-31 16:00:00.000000000 +0000
+++ gdb-7.11/gdb/features/sparc/sparc64-solaris.c	2017-01-17 04:51:21.538424830 +0000
@@ -0,0 +1,112 @@
+/* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
+  Original: sparc64-solaris.xml */
+
+#include "defs.h"
+#include "osabi.h"
+#include "target-descriptions.h"
+
+struct target_desc *tdesc_sparc64_solaris;
+static void
+initialize_tdesc_sparc64_solaris (void)
+{
+  struct target_desc *result = allocate_target_description ();
+  struct tdesc_feature *feature;
+
+  set_tdesc_architecture (result, bfd_scan_arch ("sparc"));
+
+  set_tdesc_osabi (result, osabi_from_tdesc_string ("Solaris"));
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.sparc.cpu");
+  tdesc_create_reg (feature, "g0", 0, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "g1", 1, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "g2", 2, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "g3", 3, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "g4", 4, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "g5", 5, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "g6", 6, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "g7", 7, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "o0", 8, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "o1", 9, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "o2", 10, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "o3", 11, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "o4", 12, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "o5", 13, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "sp", 14, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "o7", 15, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l0", 16, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l1", 17, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l2", 18, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l3", 19, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l4", 20, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l5", 21, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l6", 22, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l7", 23, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "i0", 24, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "i1", 25, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "i2", 26, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "i3", 27, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "i4", 28, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "i5", 29, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "fp", 30, 1, NULL, 32, "uint64");
+  tdesc_create_reg (feature, "i7", 31, 1, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.sparc.cp0");
+  tdesc_create_reg (feature, "pc", 80, 1, NULL, 64, "code_ptr");
+  tdesc_create_reg (feature, "npc", 81, 1, NULL, 64, "code_ptr");
+  tdesc_create_reg (feature, "state", 82, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "fsr", 83, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "fprs", 84, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "y", 85, 1, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.sparc.fpu");
+  tdesc_create_reg (feature, "f0", 32, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f1", 33, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f2", 34, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f3", 35, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f4", 36, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f5", 37, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f6", 38, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f7", 39, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f8", 40, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f9", 41, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f10", 42, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f11", 43, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f12", 44, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f13", 45, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f14", 46, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f15", 47, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f16", 48, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f17", 49, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f18", 50, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f19", 51, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f20", 52, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f21", 53, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f22", 54, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f23", 55, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f24", 56, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f25", 57, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f26", 58, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f27", 59, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f28", 60, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f29", 61, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f30", 62, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f31", 63, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f32", 64, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f34", 65, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f36", 66, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f38", 67, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f40", 68, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f42", 69, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f44", 70, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f46", 71, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f48", 72, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f50", 73, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f52", 74, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f54", 75, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f56", 76, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f58", 77, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f60", 78, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f62", 79, 1, NULL, 64, "ieee_double");
+
+  tdesc_sparc64_solaris = result;
+}
diff -Nupr a/gdb/features/sparc/sparc64-solaris.xml gdb-7.11/gdb/features/sparc/sparc64-solaris.xml
--- a/gdb/features/sparc/sparc64-solaris.xml	1969-12-31 16:00:00.000000000 +0000
+++ gdb-7.11/gdb/features/sparc/sparc64-solaris.xml	2017-01-17 04:51:21.538886762 +0000
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+  <architecture>sparc:v9</architecture>
+  <osabi>Solaris</osabi>
+  <xi:include href="sparc64-cpu.xml"/>
+  <xi:include href="sparc64-cp0.xml"/>
+  <xi:include href="sparc64-fpu.xml"/>
+</target>
diff -Nupr a/gdb/sparc-tdep.c gdb-7.11/gdb/sparc-tdep.c
--- a/gdb/sparc-tdep.c	2017-01-17 04:50:50.555502887 +0000
+++ gdb-7.11/gdb/sparc-tdep.c	2017-01-17 10:15:24.207990332 +0000
@@ -33,6 +33,7 @@
 #include "osabi.h"
 #include "regcache.h"
 #include "target.h"
+#include "target-descriptions.h"
 #include "value.h"
 
 #include "sparc-tdep.h"
@@ -303,6 +304,10 @@ sparc_structure_or_union_p (const struct
 #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[] =
 {
   SPARC_CORE_REGISTERS,
@@ -345,6 +350,9 @@ sparc32_pseudo_register_name (struct gdb
 static const char *
 sparc32_register_name (struct gdbarch *gdbarch, int regnum)
 {
+  if (tdesc_has_registers (gdbarch_target_desc (gdbarch)))
+    return tdesc_register_name (gdbarch, regnum);
+
   if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch))
     return sparc32_register_names[regnum];
 
@@ -430,6 +438,9 @@ sparc32_pseudo_register_type (struct gdb
 static struct type *
 sparc32_register_type (struct gdbarch *gdbarch, int regnum)
 {
+  if (tdesc_has_registers (gdbarch_target_desc (gdbarch)))
+    return tdesc_register_type (gdbarch, regnum);
+
   if (regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM)
     return builtin_type (gdbarch)->builtin_float;
 
@@ -1689,11 +1700,36 @@ sparc_iterate_over_regset_sections (stru
 }
 
 
+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);
@@ -1707,6 +1743,10 @@ sparc32_gdbarch_init (struct gdbarch_inf
   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);
@@ -1715,6 +1755,8 @@ sparc32_gdbarch_init (struct gdbarch_inf
   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);
 
@@ -1763,6 +1805,39 @@ sparc32_gdbarch_init (struct gdbarch_inf
 
   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
diff -Nupr a/gdb/sparc-tdep.h gdb-7.11/gdb/sparc-tdep.h
--- a/gdb/sparc-tdep.h	2017-01-17 04:50:50.552703625 +0000
+++ gdb-7.11/gdb/sparc-tdep.h	2017-01-17 04:51:21.541536782 +0000
@@ -63,6 +63,12 @@ struct gdbarch_tdep
   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;
diff -Nupr a/gdb/sparc64-tdep.c gdb-7.11/gdb/sparc64-tdep.c
--- a/gdb/sparc64-tdep.c	2017-01-17 04:50:50.557105452 +0000
+++ gdb-7.11/gdb/sparc64-tdep.c	2017-01-17 10:16:27.515890909 +0000
@@ -31,6 +31,7 @@
 #include "objfiles.h"
 #include "osabi.h"
 #include "regcache.h"
+#include "target-descriptions.h"
 #include "target.h"
 #include "value.h"
 
@@ -241,6 +242,9 @@ sparc64_fprs_type (struct gdbarch *gdbar
   "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[] =
 {
   SPARC_CORE_REGISTERS,
@@ -290,6 +294,9 @@ sparc64_pseudo_register_name (struct gdb
 static const char *
 sparc64_register_name (struct gdbarch *gdbarch, int regnum)
 {
+  if (tdesc_has_registers (gdbarch_target_desc (gdbarch)))
+    return tdesc_register_name (gdbarch, regnum);
+
   if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch))
     return sparc64_register_names[regnum];
 
@@ -328,6 +335,9 @@ sparc64_pseudo_register_type (struct gdb
 static struct type *
 sparc64_register_type (struct gdbarch *gdbarch, int regnum)
 {
+  if (tdesc_has_registers (gdbarch_target_desc (gdbarch)))
+    return tdesc_register_type (gdbarch, regnum);
+
   /* Raw registers.  */
   if (regnum == SPARC_SP_REGNUM || regnum == SPARC_FP_REGNUM)
     return builtin_type (gdbarch)->builtin_data_ptr;
@@ -1222,6 +1232,10 @@ sparc64_init_abi (struct gdbarch_info in
 
   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);
@@ -1232,6 +1246,8 @@ sparc64_init_abi (struct gdbarch_info in
   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);
 
diff -Nupr a/gdb/testsuite/gdb.xml/tdesc-regs.exp gdb-7.11/gdb/testsuite/gdb.xml/tdesc-regs.exp
--- a/gdb/testsuite/gdb.xml/tdesc-regs.exp	2016-02-09 19:19:39.000000000 +0000
+++ gdb-7.11/gdb/testsuite/gdb.xml/tdesc-regs.exp	2017-01-17 04:51:21.544945232 +0000
@@ -49,6 +49,14 @@ switch -glob -- [istarget] {
     "s390*-*-*" {
 	set core-regs {s390-core32.xml s390-acr.xml s390-fpr.xml}
     }
+    "sparc-*-*" {
+	set regdir "sparc/"
+        set core-regs {sparc32-cpu.xml sparc32-fpu.xml sparc32-cp0.xml}
+    }
+    "sparc64-*-*" {
+	set regdir "sparc/"
+        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.

Ivo Raisr Jan. 25, 2017, 5:46 a.m. | #3
Any news here?
I.


-------- Forwarded Message --------
Subject: Re: [PATCH] Bug 20936 - provide sparc and sparcv9 target 
description XML files
Date: Tue, 17 Jan 2017 22:37:59 +0100
From: Ivo Raisr <ivo.raisr@oracle.com>

To: Yao Qi <qiyaoltc@gmail.com>
CC: gdb-patches@sourceware.org



On 12.12.2016 13:53, Yao Qi wrote:
> Hi Ivo,

> Your patch does two orthogonal things IMO,

>

>   - Pseudo register support enhancement, patch #1

>   - XML target description support and sparc*-tdep.c updates, patch #2,

>

> Can you split them to two patches?


Hi Yao,

The first patch #1 has been pushed yesterday by Jose Marchesi.
I've prepared the second patch #2 and ChangeLog entries.
Please can you have a look (all attached).

Thank you,
I.

ChangeLog entry:
2017-01-17  Ivo Raisr  <ivo.raisr@oracle.com>

	PR tdep/20936
	* gdb.texinfo: (Standard Target Features): Document SPARC features.
	(Sparc Features): New node.
ChangeLog entry:
2017-01-17  Ivo Raisr  <ivo.raisr@oracle.com>

	PR tdep/20936
	Provide and use sparc32 and sparc64 target description XML files.
	* features/sparc/sparc32-cp0.xml, features/sparc/sparc32-cpu.xml,
	features/sparc/sparc32-fpu.xml: New files for sparc 32-bit.
	* features/sparc/sparc64-cp0.xml, features/sparc/sparc64-cpu.xml,
	features/sparc/sparc64-fpu.xml: New files for sparc 64-bit.
	* features/sparc/sparc32-solaris.xml: New file.
	* features/sparc/sparc64-solaris.xml: New file.
	* features/sparc/sparc32-solaris.c: Generated.
	* features/sparc/sparc64-solaris.c: Generated.
	* sparc-tdep.h: Account for differences in target descriptions.
	* sparc-tdep.c (sparc32_register_name): Use target provided registers.
	(sparc32_register_type): Use target provided registers.
	(validate_tdesc_registers): New function.
	(sparc32_gdbarch_init): Use tdesc_has_registers.
	Set pseudoregister functions.
	* sparc64-tdep.c (sparc64_register_name): Use target provided registers.
	(sparc64_register_type): Use target provided registers.
	(sparc64_init_abi): Set pseudoregister functions.
ChangeLog entry:
2017-01-17  Ivo Raisr  <ivo.raisr@oracle.com>

	PR tdep/20936
	* gdb.xml/tdesc-regs.exp: Provide sparc core registers for the tests.diff -Nupr a/gdb/doc/gdb.texinfo gdb-7.11/gdb/doc/gdb.texinfo
--- a/gdb/doc/gdb.texinfo	2016-02-24 01:55:15.000000000 +0000
+++ gdb-7.11/gdb/doc/gdb.texinfo	2017-01-17 04:51:21.533190029 +0000
@@ -40658,6 +40658,7 @@ registers using the capitalization used
 * Nios II Features::
 * PowerPC Features::
 * S/390 and System z Features::
+* Sparc Features::
 * TIC6x Features::
 @end menu
 
@@ -40945,6 +40946,48 @@ through @samp{f15} to present the 128-bi
 contain the 128-bit wide vector registers @samp{v16} through
 @samp{v31}.
 
+@node Sparc Features
+@subsection Sparc Features
+@cindex target descriptions, sparc32 features
+@cindex target descriptions, sparc64 features
+The @samp{org.gnu.gdb.sparc.cpu} feature is required for sparc32/sparc64
+targets.  It should describe the following registers:
+
+@itemize @minus
+@item
+@samp{g0} through @samp{g7}
+@item
+@samp{o0} through @samp{o7}
+@item
+@samp{l0} through @samp{l7}
+@item
+@samp{i0} through @samp{i7}
+@end itemize
+
+They may be 32-bit or 64-bit depending on the target.
+
+Also the @samp{org.gnu.gdb.sparc.fpu} feature is required for sparc32/sparc64
+targets.  It should describe the following registers:
+
+@itemize @minus
+@item
+@samp{f0} through @samp{f31}
+@item
+@samp{f32} through @samp{f62} for sparc64
+@end itemize
+
+The @samp{org.gnu.gdb.sparc.cp0} feature is required for sparc32/sparc64
+targets.  It should describe the following registers:
+
+@itemize @minus
+@item
+@samp{y}, @samp{psr}, @samp{wim}, @samp{tbr}, @samp{pc}, @samp{npc},
+@samp{fsr}, and @samp{csr} for sparc32
+@item
+@samp{pc}, @samp{npc}, @samp{state}, @samp{fsr}, @samp{fprs}, and @samp{y}
+for sparc64
+@end itemize
+
 @node TIC6x Features
 @subsection TMS320C6x Features
 @cindex target descriptions, TIC6x features
diff -Nupr a/gdb/features/sparc/sparc32-cp0.xml gdb-7.11/gdb/features/sparc/sparc32-cp0.xml
--- a/gdb/features/sparc/sparc32-cp0.xml	1969-12-31 16:00:00.000000000 +0000
+++ gdb-7.11/gdb/features/sparc/sparc32-cp0.xml	2017-01-17 04:51:21.534235184 +0000
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.sparc.cp0">
+  <reg name="y" bitsize="32" type="uint32" regnum="64"/>
+  <reg name="psr" bitsize="32" type="uint32" regnum="65"/>
+  <reg name="wim" bitsize="32" type="uint32" regnum="66"/>
+  <reg name="tbr" bitsize="32" type="uint32" regnum="67"/>
+  <reg name="pc" bitsize="32" type="code_ptr" regnum="68"/>
+  <reg name="npc" bitsize="32" type="code_ptr" regnum="69"/>
+  <reg name="fsr" bitsize="32" type="uint32" regnum="70"/>
+  <reg name="csr" bitsize="32" type="uint32" regnum="71"/>
+</feature>
+
diff -Nupr a/gdb/features/sparc/sparc32-cpu.xml gdb-7.11/gdb/features/sparc/sparc32-cpu.xml
--- a/gdb/features/sparc/sparc32-cpu.xml	1969-12-31 16:00:00.000000000 +0000
+++ gdb-7.11/gdb/features/sparc/sparc32-cpu.xml	2017-01-17 04:51:21.534750652 +0000
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.sparc.cpu">
+  <reg name="g0" bitsize="32" type="uint32" regnum="0"/>
+  <reg name="g1" bitsize="32" type="uint32" regnum="1"/>
+  <reg name="g2" bitsize="32" type="uint32" regnum="2"/>
+  <reg name="g3" bitsize="32" type="uint32" regnum="3"/>
+  <reg name="g4" bitsize="32" type="uint32" regnum="4"/>
+  <reg name="g5" bitsize="32" type="uint32" regnum="5"/>
+  <reg name="g6" bitsize="32" type="uint32" regnum="6"/>
+  <reg name="g7" bitsize="32" type="uint32" regnum="7"/>
+  <reg name="o0" bitsize="32" type="uint32" regnum="8"/>
+  <reg name="o1" bitsize="32" type="uint32" regnum="9"/>
+  <reg name="o2" bitsize="32" type="uint32" regnum="10"/>
+  <reg name="o3" bitsize="32" type="uint32" regnum="11"/>
+  <reg name="o4" bitsize="32" type="uint32" regnum="12"/>
+  <reg name="o5" bitsize="32" type="uint32" regnum="13"/>
+  <reg name="sp" bitsize="32" type="uint32" regnum="14"/>
+  <reg name="o7" bitsize="32" type="uint32" regnum="15"/>
+  <reg name="l0" bitsize="32" type="uint32" regnum="16"/>
+  <reg name="l1" bitsize="32" type="uint32" regnum="17"/>
+  <reg name="l2" bitsize="32" type="uint32" regnum="18"/>
+  <reg name="l3" bitsize="32" type="uint32" regnum="19"/>
+  <reg name="l4" bitsize="32" type="uint32" regnum="20"/>
+  <reg name="l5" bitsize="32" type="uint32" regnum="21"/>
+  <reg name="l6" bitsize="32" type="uint32" regnum="22"/>
+  <reg name="l7" bitsize="32" type="uint32" regnum="23"/>
+  <reg name="i0" bitsize="32" type="uint32" regnum="24"/>
+  <reg name="i1" bitsize="32" type="uint32" regnum="25"/>
+  <reg name="i2" bitsize="32" type="uint32" regnum="26"/>
+  <reg name="i3" bitsize="32" type="uint32" regnum="27"/>
+  <reg name="i4" bitsize="32" type="uint32" regnum="28"/>
+  <reg name="i5" bitsize="32" type="uint32" regnum="29"/>
+  <reg name="fp" bitsize="32" type="uint32" regnum="30"/>
+  <reg name="i7" bitsize="32" type="uint32" regnum="31"/>
+</feature>
diff -Nupr a/gdb/features/sparc/sparc32-fpu.xml gdb-7.11/gdb/features/sparc/sparc32-fpu.xml
--- a/gdb/features/sparc/sparc32-fpu.xml	1969-12-31 16:00:00.000000000 +0000
+++ gdb-7.11/gdb/features/sparc/sparc32-fpu.xml	2017-01-17 04:51:21.535246657 +0000
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.sparc.fpu">
+  <reg name="f0" bitsize="32" type="ieee_single" regnum="32"/>
+  <reg name="f1" bitsize="32" type="ieee_single" regnum="33"/>
+  <reg name="f2" bitsize="32" type="ieee_single" regnum="34"/>
+  <reg name="f3" bitsize="32" type="ieee_single" regnum="35"/>
+  <reg name="f4" bitsize="32" type="ieee_single" regnum="36"/>
+  <reg name="f5" bitsize="32" type="ieee_single" regnum="37"/>
+  <reg name="f6" bitsize="32" type="ieee_single" regnum="38"/>
+  <reg name="f7" bitsize="32" type="ieee_single" regnum="39"/>
+  <reg name="f8" bitsize="32" type="ieee_single" regnum="40"/>
+  <reg name="f9" bitsize="32" type="ieee_single" regnum="41"/>
+  <reg name="f10" bitsize="32" type="ieee_single" regnum="42"/>
+  <reg name="f11" bitsize="32" type="ieee_single" regnum="43"/>
+  <reg name="f12" bitsize="32" type="ieee_single" regnum="44"/>
+  <reg name="f13" bitsize="32" type="ieee_single" regnum="45"/>
+  <reg name="f14" bitsize="32" type="ieee_single" regnum="46"/>
+  <reg name="f15" bitsize="32" type="ieee_single" regnum="47"/>
+  <reg name="f16" bitsize="32" type="ieee_single" regnum="48"/>
+  <reg name="f17" bitsize="32" type="ieee_single" regnum="49"/>
+  <reg name="f18" bitsize="32" type="ieee_single" regnum="50"/>
+  <reg name="f19" bitsize="32" type="ieee_single" regnum="51"/>
+  <reg name="f20" bitsize="32" type="ieee_single" regnum="52"/>
+  <reg name="f21" bitsize="32" type="ieee_single" regnum="53"/>
+  <reg name="f22" bitsize="32" type="ieee_single" regnum="54"/>
+  <reg name="f23" bitsize="32" type="ieee_single" regnum="55"/>
+  <reg name="f24" bitsize="32" type="ieee_single" regnum="56"/>
+  <reg name="f25" bitsize="32" type="ieee_single" regnum="57"/>
+  <reg name="f26" bitsize="32" type="ieee_single" regnum="58"/>
+  <reg name="f27" bitsize="32" type="ieee_single" regnum="59"/>
+  <reg name="f28" bitsize="32" type="ieee_single" regnum="60"/>
+  <reg name="f29" bitsize="32" type="ieee_single" regnum="61"/>
+  <reg name="f30" bitsize="32" type="ieee_single" regnum="62"/>
+  <reg name="f31" bitsize="32" type="ieee_single" regnum="63"/>
+</feature>
+
diff -Nupr a/gdb/features/sparc/sparc32-solaris.c gdb-7.11/gdb/features/sparc/sparc32-solaris.c
--- a/gdb/features/sparc/sparc32-solaris.c	1969-12-31 16:00:00.000000000 +0000
+++ gdb-7.11/gdb/features/sparc/sparc32-solaris.c	2017-01-17 04:51:21.535796032 +0000
@@ -0,0 +1,98 @@
+/* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
+  Original: sparc32-solaris.xml */
+
+#include "defs.h"
+#include "osabi.h"
+#include "target-descriptions.h"
+
+struct target_desc *tdesc_sparc32_solaris;
+static void
+initialize_tdesc_sparc32_solaris (void)
+{
+  struct target_desc *result = allocate_target_description ();
+  struct tdesc_feature *feature;
+
+  set_tdesc_architecture (result, bfd_scan_arch ("sparc"));
+
+  set_tdesc_osabi (result, osabi_from_tdesc_string ("Solaris"));
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.sparc.cpu");
+  tdesc_create_reg (feature, "g0", 0, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "g1", 1, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "g2", 2, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "g3", 3, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "g4", 4, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "g5", 5, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "g6", 6, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "g7", 7, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "o0", 8, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "o1", 9, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "o2", 10, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "o3", 11, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "o4", 12, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "o5", 13, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "sp", 14, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "o7", 15, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l0", 16, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l1", 17, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l2", 18, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l3", 19, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l4", 20, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l5", 21, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l6", 22, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l7", 23, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "i0", 24, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "i1", 25, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "i2", 26, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "i3", 27, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "i4", 28, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "i5", 29, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "fp", 30, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "i7", 31, 1, NULL, 32, "uint32");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.sparc.cp0");
+  tdesc_create_reg (feature, "y", 64, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "psr", 65, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "wim", 66, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "tbr", 67, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "pc", 68, 1, NULL, 32, "code_ptr");
+  tdesc_create_reg (feature, "npc", 69, 1, NULL, 32, "code_ptr");
+  tdesc_create_reg (feature, "fsr", 70, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "csr", 71, 1, NULL, 32, "uint32");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.sparc.fpu");
+  tdesc_create_reg (feature, "f0", 32, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f1", 33, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f2", 34, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f3", 35, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f4", 36, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f5", 37, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f6", 38, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f7", 39, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f8", 40, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f9", 41, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f10", 42, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f11", 43, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f12", 44, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f13", 45, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f14", 46, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f15", 47, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f16", 48, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f17", 49, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f18", 50, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f19", 51, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f20", 52, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f21", 53, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f22", 54, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f23", 55, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f24", 56, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f25", 57, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f26", 58, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f27", 59, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f28", 60, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f29", 61, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f30", 62, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f31", 63, 1, NULL, 32, "ieee_single");
+
+  tdesc_sparc_solaris = result;
+}
diff -Nupr a/gdb/features/sparc/sparc32-solaris.xml gdb-7.11/gdb/features/sparc/sparc32-solaris.xml
--- a/gdb/features/sparc/sparc32-solaris.xml	1969-12-31 16:00:00.000000000 +0000
+++ gdb-7.11/gdb/features/sparc/sparc32-solaris.xml	2017-01-17 04:51:21.536253577 +0000
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+  <architecture>sparc</architecture>
+  <osabi>Solaris</osabi>
+  <xi:include href="sparc32-cpu.xml"/>
+  <xi:include href="sparc32-cp0.xml"/>
+  <xi:include href="sparc32-fpu.xml"/>
+</target>
diff -Nupr a/gdb/features/sparc/sparc64-cp0.xml gdb-7.11/gdb/features/sparc/sparc64-cp0.xml
--- a/gdb/features/sparc/sparc64-cp0.xml	1969-12-31 16:00:00.000000000 +0000
+++ gdb-7.11/gdb/features/sparc/sparc64-cp0.xml	2017-01-17 04:51:21.536709179 +0000
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.sparc.cp0">
+  <reg name="pc" bitsize="64" type="code_ptr" regnum="80"/>
+  <reg name="npc" bitsize="64" type="code_ptr" regnum="81"/>
+  <reg name="state" bitsize="64" type="uint64" regnum="82"/>
+  <reg name="fsr" bitsize="64" type="uint64" regnum="83"/>
+  <reg name="fprs" bitsize="64" type="uint64" regnum="84"/>
+  <reg name="y" bitsize="64" type="uint64" regnum="85"/>
+</feature>
+
diff -Nupr a/gdb/features/sparc/sparc64-cpu.xml gdb-7.11/gdb/features/sparc/sparc64-cpu.xml
--- a/gdb/features/sparc/sparc64-cpu.xml	1969-12-31 16:00:00.000000000 +0000
+++ gdb-7.11/gdb/features/sparc/sparc64-cpu.xml	2017-01-17 04:51:21.537183089 +0000
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.sparc.cpu">
+  <reg name="g0" bitsize="64" type="uint64" regnum="0"/>
+  <reg name="g1" bitsize="64" type="uint64" regnum="1"/>
+  <reg name="g2" bitsize="64" type="uint64" regnum="2"/>
+  <reg name="g3" bitsize="64" type="uint64" regnum="3"/>
+  <reg name="g4" bitsize="64" type="uint64" regnum="4"/>
+  <reg name="g5" bitsize="64" type="uint64" regnum="5"/>
+  <reg name="g6" bitsize="64" type="uint64" regnum="6"/>
+  <reg name="g7" bitsize="64" type="uint64" regnum="7"/>
+  <reg name="o0" bitsize="64" type="uint64" regnum="8"/>
+  <reg name="o1" bitsize="64" type="uint64" regnum="9"/>
+  <reg name="o2" bitsize="64" type="uint64" regnum="10"/>
+  <reg name="o3" bitsize="64" type="uint64" regnum="11"/>
+  <reg name="o4" bitsize="64" type="uint64" regnum="12"/>
+  <reg name="o5" bitsize="64" type="uint64" regnum="13"/>
+  <reg name="sp" bitsize="64" type="uint64" regnum="14"/>
+  <reg name="o7" bitsize="64" type="uint64" regnum="15"/>
+  <reg name="l0" bitsize="64" type="uint64" regnum="16"/>
+  <reg name="l1" bitsize="64" type="uint64" regnum="17"/>
+  <reg name="l2" bitsize="64" type="uint64" regnum="18"/>
+  <reg name="l3" bitsize="64" type="uint64" regnum="19"/>
+  <reg name="l4" bitsize="64" type="uint64" regnum="20"/>
+  <reg name="l5" bitsize="64" type="uint64" regnum="21"/>
+  <reg name="l6" bitsize="64" type="uint64" regnum="22"/>
+  <reg name="l7" bitsize="64" type="uint64" regnum="23"/>
+  <reg name="i0" bitsize="64" type="uint64" regnum="24"/>
+  <reg name="i1" bitsize="64" type="uint64" regnum="25"/>
+  <reg name="i2" bitsize="64" type="uint64" regnum="26"/>
+  <reg name="i3" bitsize="64" type="uint64" regnum="27"/>
+  <reg name="i4" bitsize="64" type="uint64" regnum="28"/>
+  <reg name="i5" bitsize="64" type="uint64" regnum="29"/>
+  <reg name="fp" bitsize="64" type="uint64" regnum="30"/>
+  <reg name="i7" bitsize="64" type="uint64" regnum="31"/>
+</feature>
diff -Nupr a/gdb/features/sparc/sparc64-fpu.xml gdb-7.11/gdb/features/sparc/sparc64-fpu.xml
--- a/gdb/features/sparc/sparc64-fpu.xml	1969-12-31 16:00:00.000000000 +0000
+++ gdb-7.11/gdb/features/sparc/sparc64-fpu.xml	2017-01-17 04:51:21.537853135 +0000
@@ -0,0 +1,60 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.sparc.fpu">
+  <reg name="f0" bitsize="32" type="ieee_single" regnum="32"/>
+  <reg name="f1" bitsize="32" type="ieee_single" regnum="33"/>
+  <reg name="f2" bitsize="32" type="ieee_single" regnum="34"/>
+  <reg name="f3" bitsize="32" type="ieee_single" regnum="35"/>
+  <reg name="f4" bitsize="32" type="ieee_single" regnum="36"/>
+  <reg name="f5" bitsize="32" type="ieee_single" regnum="37"/>
+  <reg name="f6" bitsize="32" type="ieee_single" regnum="38"/>
+  <reg name="f7" bitsize="32" type="ieee_single" regnum="39"/>
+  <reg name="f8" bitsize="32" type="ieee_single" regnum="40"/>
+  <reg name="f9" bitsize="32" type="ieee_single" regnum="41"/>
+  <reg name="f10" bitsize="32" type="ieee_single" regnum="42"/>
+  <reg name="f11" bitsize="32" type="ieee_single" regnum="43"/>
+  <reg name="f12" bitsize="32" type="ieee_single" regnum="44"/>
+  <reg name="f13" bitsize="32" type="ieee_single" regnum="45"/>
+  <reg name="f14" bitsize="32" type="ieee_single" regnum="46"/>
+  <reg name="f15" bitsize="32" type="ieee_single" regnum="47"/>
+  <reg name="f16" bitsize="32" type="ieee_single" regnum="48"/>
+  <reg name="f17" bitsize="32" type="ieee_single" regnum="49"/>
+  <reg name="f18" bitsize="32" type="ieee_single" regnum="50"/>
+  <reg name="f19" bitsize="32" type="ieee_single" regnum="51"/>
+  <reg name="f20" bitsize="32" type="ieee_single" regnum="52"/>
+  <reg name="f21" bitsize="32" type="ieee_single" regnum="53"/>
+  <reg name="f22" bitsize="32" type="ieee_single" regnum="54"/>
+  <reg name="f23" bitsize="32" type="ieee_single" regnum="55"/>
+  <reg name="f24" bitsize="32" type="ieee_single" regnum="56"/>
+  <reg name="f25" bitsize="32" type="ieee_single" regnum="57"/>
+  <reg name="f26" bitsize="32" type="ieee_single" regnum="58"/>
+  <reg name="f27" bitsize="32" type="ieee_single" regnum="59"/>
+  <reg name="f28" bitsize="32" type="ieee_single" regnum="60"/>
+  <reg name="f29" bitsize="32" type="ieee_single" regnum="61"/>
+  <reg name="f30" bitsize="32" type="ieee_single" regnum="62"/>
+  <reg name="f31" bitsize="32" type="ieee_single" regnum="63"/>
+
+  <reg name="f32" bitsize="64" type="ieee_double" regnum="64"/>
+  <reg name="f34" bitsize="64" type="ieee_double" regnum="65"/>
+  <reg name="f36" bitsize="64" type="ieee_double" regnum="66"/>
+  <reg name="f38" bitsize="64" type="ieee_double" regnum="67"/>
+  <reg name="f40" bitsize="64" type="ieee_double" regnum="68"/>
+  <reg name="f42" bitsize="64" type="ieee_double" regnum="69"/>
+  <reg name="f44" bitsize="64" type="ieee_double" regnum="70"/>
+  <reg name="f46" bitsize="64" type="ieee_double" regnum="71"/>
+  <reg name="f48" bitsize="64" type="ieee_double" regnum="72"/>
+  <reg name="f50" bitsize="64" type="ieee_double" regnum="73"/>
+  <reg name="f52" bitsize="64" type="ieee_double" regnum="74"/>
+  <reg name="f54" bitsize="64" type="ieee_double" regnum="75"/>
+  <reg name="f56" bitsize="64" type="ieee_double" regnum="76"/>
+  <reg name="f58" bitsize="64" type="ieee_double" regnum="77"/>
+  <reg name="f60" bitsize="64" type="ieee_double" regnum="78"/>
+  <reg name="f62" bitsize="64" type="ieee_double" regnum="79"/>
+</feature>
+
diff -Nupr a/gdb/features/sparc/sparc64-solaris.c gdb-7.11/gdb/features/sparc/sparc64-solaris.c
--- a/gdb/features/sparc/sparc64-solaris.c	1969-12-31 16:00:00.000000000 +0000
+++ gdb-7.11/gdb/features/sparc/sparc64-solaris.c	2017-01-17 04:51:21.538424830 +0000
@@ -0,0 +1,112 @@
+/* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
+  Original: sparc64-solaris.xml */
+
+#include "defs.h"
+#include "osabi.h"
+#include "target-descriptions.h"
+
+struct target_desc *tdesc_sparc64_solaris;
+static void
+initialize_tdesc_sparc64_solaris (void)
+{
+  struct target_desc *result = allocate_target_description ();
+  struct tdesc_feature *feature;
+
+  set_tdesc_architecture (result, bfd_scan_arch ("sparc"));
+
+  set_tdesc_osabi (result, osabi_from_tdesc_string ("Solaris"));
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.sparc.cpu");
+  tdesc_create_reg (feature, "g0", 0, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "g1", 1, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "g2", 2, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "g3", 3, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "g4", 4, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "g5", 5, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "g6", 6, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "g7", 7, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "o0", 8, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "o1", 9, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "o2", 10, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "o3", 11, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "o4", 12, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "o5", 13, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "sp", 14, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "o7", 15, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l0", 16, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l1", 17, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l2", 18, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l3", 19, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l4", 20, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l5", 21, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l6", 22, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l7", 23, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "i0", 24, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "i1", 25, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "i2", 26, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "i3", 27, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "i4", 28, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "i5", 29, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "fp", 30, 1, NULL, 32, "uint64");
+  tdesc_create_reg (feature, "i7", 31, 1, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.sparc.cp0");
+  tdesc_create_reg (feature, "pc", 80, 1, NULL, 64, "code_ptr");
+  tdesc_create_reg (feature, "npc", 81, 1, NULL, 64, "code_ptr");
+  tdesc_create_reg (feature, "state", 82, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "fsr", 83, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "fprs", 84, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "y", 85, 1, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.sparc.fpu");
+  tdesc_create_reg (feature, "f0", 32, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f1", 33, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f2", 34, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f3", 35, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f4", 36, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f5", 37, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f6", 38, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f7", 39, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f8", 40, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f9", 41, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f10", 42, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f11", 43, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f12", 44, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f13", 45, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f14", 46, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f15", 47, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f16", 48, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f17", 49, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f18", 50, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f19", 51, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f20", 52, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f21", 53, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f22", 54, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f23", 55, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f24", 56, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f25", 57, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f26", 58, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f27", 59, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f28", 60, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f29", 61, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f30", 62, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f31", 63, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f32", 64, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f34", 65, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f36", 66, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f38", 67, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f40", 68, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f42", 69, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f44", 70, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f46", 71, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f48", 72, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f50", 73, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f52", 74, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f54", 75, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f56", 76, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f58", 77, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f60", 78, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f62", 79, 1, NULL, 64, "ieee_double");
+
+  tdesc_sparc64_solaris = result;
+}
diff -Nupr a/gdb/features/sparc/sparc64-solaris.xml gdb-7.11/gdb/features/sparc/sparc64-solaris.xml
--- a/gdb/features/sparc/sparc64-solaris.xml	1969-12-31 16:00:00.000000000 +0000
+++ gdb-7.11/gdb/features/sparc/sparc64-solaris.xml	2017-01-17 04:51:21.538886762 +0000
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+  <architecture>sparc:v9</architecture>
+  <osabi>Solaris</osabi>
+  <xi:include href="sparc64-cpu.xml"/>
+  <xi:include href="sparc64-cp0.xml"/>
+  <xi:include href="sparc64-fpu.xml"/>
+</target>
diff -Nupr a/gdb/sparc-tdep.c gdb-7.11/gdb/sparc-tdep.c
--- a/gdb/sparc-tdep.c	2017-01-17 04:50:50.555502887 +0000
+++ gdb-7.11/gdb/sparc-tdep.c	2017-01-17 10:15:24.207990332 +0000
@@ -33,6 +33,7 @@
 #include "osabi.h"
 #include "regcache.h"
 #include "target.h"
+#include "target-descriptions.h"
 #include "value.h"
 
 #include "sparc-tdep.h"
@@ -303,6 +304,10 @@ sparc_structure_or_union_p (const struct
 #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[] =
 {
   SPARC_CORE_REGISTERS,
@@ -345,6 +350,9 @@ sparc32_pseudo_register_name (struct gdb
 static const char *
 sparc32_register_name (struct gdbarch *gdbarch, int regnum)
 {
+  if (tdesc_has_registers (gdbarch_target_desc (gdbarch)))
+    return tdesc_register_name (gdbarch, regnum);
+
   if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch))
     return sparc32_register_names[regnum];
 
@@ -430,6 +438,9 @@ sparc32_pseudo_register_type (struct gdb
 static struct type *
 sparc32_register_type (struct gdbarch *gdbarch, int regnum)
 {
+  if (tdesc_has_registers (gdbarch_target_desc (gdbarch)))
+    return tdesc_register_type (gdbarch, regnum);
+
   if (regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM)
     return builtin_type (gdbarch)->builtin_float;
 
@@ -1689,11 +1700,36 @@ sparc_iterate_over_regset_sections (stru
 }
 
 
+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);
@@ -1707,6 +1743,10 @@ sparc32_gdbarch_init (struct gdbarch_inf
   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);
@@ -1715,6 +1755,8 @@ sparc32_gdbarch_init (struct gdbarch_inf
   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);
 
@@ -1763,6 +1805,39 @@ sparc32_gdbarch_init (struct gdbarch_inf
 
   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
diff -Nupr a/gdb/sparc-tdep.h gdb-7.11/gdb/sparc-tdep.h
--- a/gdb/sparc-tdep.h	2017-01-17 04:50:50.552703625 +0000
+++ gdb-7.11/gdb/sparc-tdep.h	2017-01-17 04:51:21.541536782 +0000
@@ -63,6 +63,12 @@ struct gdbarch_tdep
   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;
diff -Nupr a/gdb/sparc64-tdep.c gdb-7.11/gdb/sparc64-tdep.c
--- a/gdb/sparc64-tdep.c	2017-01-17 04:50:50.557105452 +0000
+++ gdb-7.11/gdb/sparc64-tdep.c	2017-01-17 10:16:27.515890909 +0000
@@ -31,6 +31,7 @@
 #include "objfiles.h"
 #include "osabi.h"
 #include "regcache.h"
+#include "target-descriptions.h"
 #include "target.h"
 #include "value.h"
 
@@ -241,6 +242,9 @@ sparc64_fprs_type (struct gdbarch *gdbar
   "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[] =
 {
   SPARC_CORE_REGISTERS,
@@ -290,6 +294,9 @@ sparc64_pseudo_register_name (struct gdb
 static const char *
 sparc64_register_name (struct gdbarch *gdbarch, int regnum)
 {
+  if (tdesc_has_registers (gdbarch_target_desc (gdbarch)))
+    return tdesc_register_name (gdbarch, regnum);
+
   if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch))
     return sparc64_register_names[regnum];
 
@@ -328,6 +335,9 @@ sparc64_pseudo_register_type (struct gdb
 static struct type *
 sparc64_register_type (struct gdbarch *gdbarch, int regnum)
 {
+  if (tdesc_has_registers (gdbarch_target_desc (gdbarch)))
+    return tdesc_register_type (gdbarch, regnum);
+
   /* Raw registers.  */
   if (regnum == SPARC_SP_REGNUM || regnum == SPARC_FP_REGNUM)
     return builtin_type (gdbarch)->builtin_data_ptr;
@@ -1222,6 +1232,10 @@ sparc64_init_abi (struct gdbarch_info in
 
   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);
@@ -1232,6 +1246,8 @@ sparc64_init_abi (struct gdbarch_info in
   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);
 
diff -Nupr a/gdb/testsuite/gdb.xml/tdesc-regs.exp gdb-7.11/gdb/testsuite/gdb.xml/tdesc-regs.exp
--- a/gdb/testsuite/gdb.xml/tdesc-regs.exp	2016-02-09 19:19:39.000000000 +0000
+++ gdb-7.11/gdb/testsuite/gdb.xml/tdesc-regs.exp	2017-01-17 04:51:21.544945232 +0000
@@ -49,6 +49,14 @@ switch -glob -- [istarget] {
     "s390*-*-*" {
 	set core-regs {s390-core32.xml s390-acr.xml s390-fpr.xml}
     }
+    "sparc-*-*" {
+	set regdir "sparc/"
+        set core-regs {sparc32-cpu.xml sparc32-fpu.xml sparc32-cp0.xml}
+    }
+    "sparc64-*-*" {
+	set regdir "sparc/"
+        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.

Yao Qi Jan. 25, 2017, 10:42 p.m. | #4
On 17-01-17 22:37:59, Ivo Raisr wrote:
> diff -Nupr a/gdb/doc/gdb.texinfo gdb-7.11/gdb/doc/gdb.texinfo

> --- a/gdb/doc/gdb.texinfo	2016-02-24 01:55:15.000000000 +0000

> +++ gdb-7.11/gdb/doc/gdb.texinfo	2017-01-17 04:51:21.533190029 +0000

> @@ -40658,6 +40658,7 @@ registers using the capitalization used

>  * Nios II Features::

>  * PowerPC Features::

>  * S/390 and System z Features::

> +* Sparc Features::

>  * TIC6x Features::

>  @end menu

>  

> @@ -40945,6 +40946,48 @@ through @samp{f15} to present the 128-bi

>  contain the 128-bit wide vector registers @samp{v16} through

>  @samp{v31}.

>  

> +@node Sparc Features

> +@subsection Sparc Features

> +@cindex target descriptions, sparc32 features

> +@cindex target descriptions, sparc64 features

> +The @samp{org.gnu.gdb.sparc.cpu} feature is required for sparc32/sparc64

> +targets.  It should describe the following registers:

> +

> +@itemize @minus

> +@item

> +@samp{g0} through @samp{g7}

> +@item

> +@samp{o0} through @samp{o7}

> +@item

> +@samp{l0} through @samp{l7}

> +@item

> +@samp{i0} through @samp{i7}

> +@end itemize

> +

> +They may be 32-bit or 64-bit depending on the target.

> +

> +Also the @samp{org.gnu.gdb.sparc.fpu} feature is required for sparc32/sparc64

> +targets.  It should describe the following registers:

> +

> +@itemize @minus

> +@item

> +@samp{f0} through @samp{f31}

> +@item

> +@samp{f32} through @samp{f62} for sparc64

> +@end itemize

> +

> +The @samp{org.gnu.gdb.sparc.cp0} feature is required for sparc32/sparc64

> +targets.  It should describe the following registers:

> +

> +@itemize @minus

> +@item

> +@samp{y}, @samp{psr}, @samp{wim}, @samp{tbr}, @samp{pc}, @samp{npc},

> +@samp{fsr}, and @samp{csr} for sparc32

> +@item

> +@samp{pc}, @samp{npc}, @samp{state}, @samp{fsr}, @samp{fprs}, and @samp{y}

> +for sparc64

> +@end itemize

> +

>  @node TIC6x Features

>  @subsection TMS320C6x Features

>  @cindex target descriptions, TIC6x features


If the doc hasn't been reviewed before, it needs a doc review.

> diff -Nupr a/gdb/features/sparc/sparc32-cp0.xml gdb-7.11/gdb/features/sparc/sparc32-cp0.xml

> --- a/gdb/features/sparc/sparc32-cp0.xml	1969-12-31 16:00:00.000000000 +0000

> +++ gdb-7.11/gdb/features/sparc/sparc32-cp0.xml	2017-01-17 04:51:21.534235184 +0000

> @@ -0,0 +1,19 @@

> +<?xml version="1.0"?>

> +<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.


Why does the year range start from 2013?  It should end on 2017, anyway.

> +

> +     Copying and distribution of this file, with or without modification,

> +     are permitted in any medium without royalty provided the copyright

> +     notice and this notice are preserved.  -->

> +


non-doc bits of this patch look good to me.

-- 
Yao
Ivo Raisr Jan. 26, 2017, 11:23 a.m. | #5
On 25.1.2017 23:42, Yao Qi wrote:
> On 17-01-17 22:37:59, Ivo Raisr wrote:

>> diff -Nupr a/gdb/doc/gdb.texinfo gdb-7.11/gdb/doc/gdb.texinfo

>> --- a/gdb/doc/gdb.texinfo	2016-02-24 01:55:15.000000000 +0000

>> +++ gdb-7.11/gdb/doc/gdb.texinfo	2017-01-17 04:51:21.533190029 +0000

>

> If the doc hasn't been reviewed before, it needs a doc review.


I have looked all around gdb website and could not find a description of 
documentation review. What is the process here?

>

>> diff -Nupr a/gdb/features/sparc/sparc32-cp0.xml gdb-7.11/gdb/features/sparc/sparc32-cp0.xml

>> --- a/gdb/features/sparc/sparc32-cp0.xml	1969-12-31 16:00:00.000000000 +0000

>> +++ gdb-7.11/gdb/features/sparc/sparc32-cp0.xml	2017-01-17 04:51:21.534235184 +0000

>> @@ -0,0 +1,19 @@

>> +<?xml version="1.0"?>

>> +<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.

>

> Why does the year range start from 2013?  It should end on 2017, anyway.


It starts from 2013 because that's the year when these files were 
internally developed. It took that long to bundle this up into patches 
and send upstream. I will fix year 2016 to 2017.

Thank you,
I.

Patch hide | download patch | download mbox

diff -Npur a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
--- a/gdb/doc/gdb.texinfo	2016-02-24 01:55:15.000000000 +0000
+++ b/gdb/doc/gdb.texinfo	2016-12-06 15:13:58.642188517 +0000
@@ -40658,6 +40658,7 @@  registers using the capitalization used
 * Nios II Features::
 * PowerPC Features::
 * S/390 and System z Features::
+* Sparc Features::
 * TIC6x Features::
 @end menu
 
@@ -40945,6 +40946,48 @@  through @samp{f15} to present the 128-bi
 contain the 128-bit wide vector registers @samp{v16} through
 @samp{v31}.
 
+@node Sparc Features
+@subsection Sparc Features
+@cindex target descriptions, sparc32 features
+@cindex target descriptions, sparc64 features
+The @samp{org.gnu.gdb.sparc.cpu} feature is required for sparc32/sparc64
+targets.  It should describe the following registers:
+
+@itemize @minus
+@item
+@samp{g0} through @samp{g7}
+@item
+@samp{o0} through @samp{o7}
+@item
+@samp{l0} through @samp{l7}
+@item
+@samp{i0} through @samp{i7}
+@end itemize
+
+They may be 32-bit or 64-bit depending on the target.
+
+Also the @samp{org.gnu.gdb.sparc.fpu} feature is required for sparc32/sparc64
+targets.  It should describe the following registers:
+
+@itemize @minus
+@item
+@samp{f0} through @samp{f31}
+@item
+@samp{f32} through @samp{f62} for sparc64
+@end itemize
+
+The @samp{org.gnu.gdb.sparc.cp0} feature is required for sparc32/sparc64
+targets.  It should describe the following registers:
+
+@itemize @minus
+@item
+@samp{y}, @samp{psr}, @samp{wim}, @samp{tbr}, @samp{pc}, @samp{npc},
+@samp{fsr}, and @samp{csr} for sparc32
+@item
+@samp{pc}, @samp{npc}, @samp{state}, @samp{fsr}, @samp{fprs}, and @samp{y}
+for sparc64
+@end itemize
+
 @node TIC6x Features
 @subsection TMS320C6x Features
 @cindex target descriptions, TIC6x features
diff -Npur a/gdb/features/sparc/sparc32-cp0.xml b/gdb/features/sparc/sparc32-cp0.xml
--- a/gdb/features/sparc/sparc32-cp0.xml	1969-12-31 16:00:00.000000000 +0000
+++ b/gdb/features/sparc/sparc32-cp0.xml	2016-12-06 14:32:38.315180859 +0000
@@ -0,0 +1,19 @@ 
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.sparc.cp0">
+  <reg name="y" bitsize="32" type="uint32" regnum="64"/>
+  <reg name="psr" bitsize="32" type="uint32" regnum="65"/>
+  <reg name="wim" bitsize="32" type="uint32" regnum="66"/>
+  <reg name="tbr" bitsize="32" type="uint32" regnum="67"/>
+  <reg name="pc" bitsize="32" type="code_ptr" regnum="68"/>
+  <reg name="npc" bitsize="32" type="code_ptr" regnum="69"/>
+  <reg name="fsr" bitsize="32" type="uint32" regnum="70"/>
+  <reg name="csr" bitsize="32" type="uint32" regnum="71"/>
+</feature>
+
diff -Npur a/gdb/features/sparc/sparc32-cpu.xml b/gdb/features/sparc/sparc32-cpu.xml
--- a/gdb/features/sparc/sparc32-cpu.xml	1969-12-31 16:00:00.000000000 +0000
+++ b/gdb/features/sparc/sparc32-cpu.xml	2016-12-06 03:07:50.656613925 +0000
@@ -0,0 +1,42 @@ 
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.sparc.cpu">
+  <reg name="g0" bitsize="32" type="uint32" regnum="0"/>
+  <reg name="g1" bitsize="32" type="uint32" regnum="1"/>
+  <reg name="g2" bitsize="32" type="uint32" regnum="2"/>
+  <reg name="g3" bitsize="32" type="uint32" regnum="3"/>
+  <reg name="g4" bitsize="32" type="uint32" regnum="4"/>
+  <reg name="g5" bitsize="32" type="uint32" regnum="5"/>
+  <reg name="g6" bitsize="32" type="uint32" regnum="6"/>
+  <reg name="g7" bitsize="32" type="uint32" regnum="7"/>
+  <reg name="o0" bitsize="32" type="uint32" regnum="8"/>
+  <reg name="o1" bitsize="32" type="uint32" regnum="9"/>
+  <reg name="o2" bitsize="32" type="uint32" regnum="10"/>
+  <reg name="o3" bitsize="32" type="uint32" regnum="11"/>
+  <reg name="o4" bitsize="32" type="uint32" regnum="12"/>
+  <reg name="o5" bitsize="32" type="uint32" regnum="13"/>
+  <reg name="sp" bitsize="32" type="uint32" regnum="14"/>
+  <reg name="o7" bitsize="32" type="uint32" regnum="15"/>
+  <reg name="l0" bitsize="32" type="uint32" regnum="16"/>
+  <reg name="l1" bitsize="32" type="uint32" regnum="17"/>
+  <reg name="l2" bitsize="32" type="uint32" regnum="18"/>
+  <reg name="l3" bitsize="32" type="uint32" regnum="19"/>
+  <reg name="l4" bitsize="32" type="uint32" regnum="20"/>
+  <reg name="l5" bitsize="32" type="uint32" regnum="21"/>
+  <reg name="l6" bitsize="32" type="uint32" regnum="22"/>
+  <reg name="l7" bitsize="32" type="uint32" regnum="23"/>
+  <reg name="i0" bitsize="32" type="uint32" regnum="24"/>
+  <reg name="i1" bitsize="32" type="uint32" regnum="25"/>
+  <reg name="i2" bitsize="32" type="uint32" regnum="26"/>
+  <reg name="i3" bitsize="32" type="uint32" regnum="27"/>
+  <reg name="i4" bitsize="32" type="uint32" regnum="28"/>
+  <reg name="i5" bitsize="32" type="uint32" regnum="29"/>
+  <reg name="fp" bitsize="32" type="uint32" regnum="30"/>
+  <reg name="i7" bitsize="32" type="uint32" regnum="31"/>
+</feature>
diff -Npur a/gdb/features/sparc/sparc32-fpu.xml b/gdb/features/sparc/sparc32-fpu.xml
--- a/gdb/features/sparc/sparc32-fpu.xml	1969-12-31 16:00:00.000000000 +0000
+++ b/gdb/features/sparc/sparc32-fpu.xml	2016-12-06 03:12:29.787543070 +0000
@@ -0,0 +1,43 @@ 
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.sparc.fpu">
+  <reg name="f0" bitsize="32" type="ieee_single" regnum="32"/>
+  <reg name="f1" bitsize="32" type="ieee_single" regnum="33"/>
+  <reg name="f2" bitsize="32" type="ieee_single" regnum="34"/>
+  <reg name="f3" bitsize="32" type="ieee_single" regnum="35"/>
+  <reg name="f4" bitsize="32" type="ieee_single" regnum="36"/>
+  <reg name="f5" bitsize="32" type="ieee_single" regnum="37"/>
+  <reg name="f6" bitsize="32" type="ieee_single" regnum="38"/>
+  <reg name="f7" bitsize="32" type="ieee_single" regnum="39"/>
+  <reg name="f8" bitsize="32" type="ieee_single" regnum="40"/>
+  <reg name="f9" bitsize="32" type="ieee_single" regnum="41"/>
+  <reg name="f10" bitsize="32" type="ieee_single" regnum="42"/>
+  <reg name="f11" bitsize="32" type="ieee_single" regnum="43"/>
+  <reg name="f12" bitsize="32" type="ieee_single" regnum="44"/>
+  <reg name="f13" bitsize="32" type="ieee_single" regnum="45"/>
+  <reg name="f14" bitsize="32" type="ieee_single" regnum="46"/>
+  <reg name="f15" bitsize="32" type="ieee_single" regnum="47"/>
+  <reg name="f16" bitsize="32" type="ieee_single" regnum="48"/>
+  <reg name="f17" bitsize="32" type="ieee_single" regnum="49"/>
+  <reg name="f18" bitsize="32" type="ieee_single" regnum="50"/>
+  <reg name="f19" bitsize="32" type="ieee_single" regnum="51"/>
+  <reg name="f20" bitsize="32" type="ieee_single" regnum="52"/>
+  <reg name="f21" bitsize="32" type="ieee_single" regnum="53"/>
+  <reg name="f22" bitsize="32" type="ieee_single" regnum="54"/>
+  <reg name="f23" bitsize="32" type="ieee_single" regnum="55"/>
+  <reg name="f24" bitsize="32" type="ieee_single" regnum="56"/>
+  <reg name="f25" bitsize="32" type="ieee_single" regnum="57"/>
+  <reg name="f26" bitsize="32" type="ieee_single" regnum="58"/>
+  <reg name="f27" bitsize="32" type="ieee_single" regnum="59"/>
+  <reg name="f28" bitsize="32" type="ieee_single" regnum="60"/>
+  <reg name="f29" bitsize="32" type="ieee_single" regnum="61"/>
+  <reg name="f30" bitsize="32" type="ieee_single" regnum="62"/>
+  <reg name="f31" bitsize="32" type="ieee_single" regnum="63"/>
+</feature>
+
diff -Npur a/gdb/features/sparc/sparc32-solaris.c b/gdb/features/sparc/sparc32-solaris.c
--- a/gdb/features/sparc/sparc32-solaris.c	1969-12-31 16:00:00.000000000 +0000
+++ b/gdb/features/sparc/sparc32-solaris.c	2016-12-06 15:23:01.740280980 +0000
@@ -0,0 +1,98 @@ 
+/* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
+  Original: sparc32-solaris.xml */
+
+#include "defs.h"
+#include "osabi.h"
+#include "target-descriptions.h"
+
+struct target_desc *tdesc_sparc32_solaris;
+static void
+initialize_tdesc_sparc32_solaris (void)
+{
+  struct target_desc *result = allocate_target_description ();
+  struct tdesc_feature *feature;
+
+  set_tdesc_architecture (result, bfd_scan_arch ("sparc"));
+
+  set_tdesc_osabi (result, osabi_from_tdesc_string ("Solaris"));
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.sparc.cpu");
+  tdesc_create_reg (feature, "g0", 0, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "g1", 1, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "g2", 2, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "g3", 3, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "g4", 4, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "g5", 5, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "g6", 6, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "g7", 7, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "o0", 8, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "o1", 9, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "o2", 10, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "o3", 11, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "o4", 12, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "o5", 13, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "sp", 14, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "o7", 15, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l0", 16, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l1", 17, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l2", 18, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l3", 19, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l4", 20, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l5", 21, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l6", 22, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "l7", 23, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "i0", 24, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "i1", 25, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "i2", 26, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "i3", 27, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "i4", 28, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "i5", 29, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "fp", 30, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "i7", 31, 1, NULL, 32, "uint32");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.sparc.cp0");
+  tdesc_create_reg (feature, "y", 64, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "psr", 65, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "wim", 66, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "tbr", 67, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "pc", 68, 1, NULL, 32, "code_ptr");
+  tdesc_create_reg (feature, "npc", 69, 1, NULL, 32, "code_ptr");
+  tdesc_create_reg (feature, "fsr", 70, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "csr", 71, 1, NULL, 32, "uint32");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.sparc.fpu");
+  tdesc_create_reg (feature, "f0", 32, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f1", 33, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f2", 34, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f3", 35, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f4", 36, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f5", 37, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f6", 38, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f7", 39, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f8", 40, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f9", 41, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f10", 42, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f11", 43, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f12", 44, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f13", 45, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f14", 46, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f15", 47, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f16", 48, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f17", 49, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f18", 50, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f19", 51, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f20", 52, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f21", 53, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f22", 54, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f23", 55, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f24", 56, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f25", 57, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f26", 58, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f27", 59, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f28", 60, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f29", 61, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f30", 62, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f31", 63, 1, NULL, 32, "ieee_single");
+
+  tdesc_sparc_solaris = result;
+}
diff -Npur a/gdb/features/sparc/sparc32-solaris.xml b/gdb/features/sparc/sparc32-solaris.xml
--- a/gdb/features/sparc/sparc32-solaris.xml	1969-12-31 16:00:00.000000000 +0000
+++ b/gdb/features/sparc/sparc32-solaris.xml	2016-12-06 15:19:12.901856952 +0000
@@ -0,0 +1,15 @@ 
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+  <architecture>sparc</architecture>
+  <osabi>Solaris</osabi>
+  <xi:include href="sparc32-cpu.xml"/>
+  <xi:include href="sparc32-cp0.xml"/>
+  <xi:include href="sparc32-fpu.xml"/>
+</target>
diff -Npur a/gdb/features/sparc/sparc64-cp0.xml b/gdb/features/sparc/sparc64-cp0.xml
--- a/gdb/features/sparc/sparc64-cp0.xml	1969-12-31 16:00:00.000000000 +0000
+++ b/gdb/features/sparc/sparc64-cp0.xml	2016-12-06 14:35:22.736677522 +0000
@@ -0,0 +1,17 @@ 
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.sparc.cp0">
+  <reg name="pc" bitsize="64" type="code_ptr" regnum="80"/>
+  <reg name="npc" bitsize="64" type="code_ptr" regnum="81"/>
+  <reg name="state" bitsize="64" type="uint64" regnum="82"/>
+  <reg name="fsr" bitsize="64" type="uint64" regnum="83"/>
+  <reg name="fprs" bitsize="64" type="uint64" regnum="84"/>
+  <reg name="y" bitsize="64" type="uint64" regnum="85"/>
+</feature>
+
diff -Npur a/gdb/features/sparc/sparc64-cpu.xml b/gdb/features/sparc/sparc64-cpu.xml
--- a/gdb/features/sparc/sparc64-cpu.xml	1969-12-31 16:00:00.000000000 +0000
+++ b/gdb/features/sparc/sparc64-cpu.xml	2016-12-06 03:10:00.965714367 +0000
@@ -0,0 +1,42 @@ 
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.sparc.cpu">
+  <reg name="g0" bitsize="64" type="uint64" regnum="0"/>
+  <reg name="g1" bitsize="64" type="uint64" regnum="1"/>
+  <reg name="g2" bitsize="64" type="uint64" regnum="2"/>
+  <reg name="g3" bitsize="64" type="uint64" regnum="3"/>
+  <reg name="g4" bitsize="64" type="uint64" regnum="4"/>
+  <reg name="g5" bitsize="64" type="uint64" regnum="5"/>
+  <reg name="g6" bitsize="64" type="uint64" regnum="6"/>
+  <reg name="g7" bitsize="64" type="uint64" regnum="7"/>
+  <reg name="o0" bitsize="64" type="uint64" regnum="8"/>
+  <reg name="o1" bitsize="64" type="uint64" regnum="9"/>
+  <reg name="o2" bitsize="64" type="uint64" regnum="10"/>
+  <reg name="o3" bitsize="64" type="uint64" regnum="11"/>
+  <reg name="o4" bitsize="64" type="uint64" regnum="12"/>
+  <reg name="o5" bitsize="64" type="uint64" regnum="13"/>
+  <reg name="sp" bitsize="64" type="uint64" regnum="14"/>
+  <reg name="o7" bitsize="64" type="uint64" regnum="15"/>
+  <reg name="l0" bitsize="64" type="uint64" regnum="16"/>
+  <reg name="l1" bitsize="64" type="uint64" regnum="17"/>
+  <reg name="l2" bitsize="64" type="uint64" regnum="18"/>
+  <reg name="l3" bitsize="64" type="uint64" regnum="19"/>
+  <reg name="l4" bitsize="64" type="uint64" regnum="20"/>
+  <reg name="l5" bitsize="64" type="uint64" regnum="21"/>
+  <reg name="l6" bitsize="64" type="uint64" regnum="22"/>
+  <reg name="l7" bitsize="64" type="uint64" regnum="23"/>
+  <reg name="i0" bitsize="64" type="uint64" regnum="24"/>
+  <reg name="i1" bitsize="64" type="uint64" regnum="25"/>
+  <reg name="i2" bitsize="64" type="uint64" regnum="26"/>
+  <reg name="i3" bitsize="64" type="uint64" regnum="27"/>
+  <reg name="i4" bitsize="64" type="uint64" regnum="28"/>
+  <reg name="i5" bitsize="64" type="uint64" regnum="29"/>
+  <reg name="fp" bitsize="64" type="uint64" regnum="30"/>
+  <reg name="i7" bitsize="64" type="uint64" regnum="31"/>
+</feature>
diff -Npur a/gdb/features/sparc/sparc64-fpu.xml b/gdb/features/sparc/sparc64-fpu.xml
--- a/gdb/features/sparc/sparc64-fpu.xml	1969-12-31 16:00:00.000000000 +0000
+++ b/gdb/features/sparc/sparc64-fpu.xml	2016-12-06 03:10:14.508504295 +0000
@@ -0,0 +1,60 @@ 
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.sparc.fpu">
+  <reg name="f0" bitsize="32" type="ieee_single" regnum="32"/>
+  <reg name="f1" bitsize="32" type="ieee_single" regnum="33"/>
+  <reg name="f2" bitsize="32" type="ieee_single" regnum="34"/>
+  <reg name="f3" bitsize="32" type="ieee_single" regnum="35"/>
+  <reg name="f4" bitsize="32" type="ieee_single" regnum="36"/>
+  <reg name="f5" bitsize="32" type="ieee_single" regnum="37"/>
+  <reg name="f6" bitsize="32" type="ieee_single" regnum="38"/>
+  <reg name="f7" bitsize="32" type="ieee_single" regnum="39"/>
+  <reg name="f8" bitsize="32" type="ieee_single" regnum="40"/>
+  <reg name="f9" bitsize="32" type="ieee_single" regnum="41"/>
+  <reg name="f10" bitsize="32" type="ieee_single" regnum="42"/>
+  <reg name="f11" bitsize="32" type="ieee_single" regnum="43"/>
+  <reg name="f12" bitsize="32" type="ieee_single" regnum="44"/>
+  <reg name="f13" bitsize="32" type="ieee_single" regnum="45"/>
+  <reg name="f14" bitsize="32" type="ieee_single" regnum="46"/>
+  <reg name="f15" bitsize="32" type="ieee_single" regnum="47"/>
+  <reg name="f16" bitsize="32" type="ieee_single" regnum="48"/>
+  <reg name="f17" bitsize="32" type="ieee_single" regnum="49"/>
+  <reg name="f18" bitsize="32" type="ieee_single" regnum="50"/>
+  <reg name="f19" bitsize="32" type="ieee_single" regnum="51"/>
+  <reg name="f20" bitsize="32" type="ieee_single" regnum="52"/>
+  <reg name="f21" bitsize="32" type="ieee_single" regnum="53"/>
+  <reg name="f22" bitsize="32" type="ieee_single" regnum="54"/>
+  <reg name="f23" bitsize="32" type="ieee_single" regnum="55"/>
+  <reg name="f24" bitsize="32" type="ieee_single" regnum="56"/>
+  <reg name="f25" bitsize="32" type="ieee_single" regnum="57"/>
+  <reg name="f26" bitsize="32" type="ieee_single" regnum="58"/>
+  <reg name="f27" bitsize="32" type="ieee_single" regnum="59"/>
+  <reg name="f28" bitsize="32" type="ieee_single" regnum="60"/>
+  <reg name="f29" bitsize="32" type="ieee_single" regnum="61"/>
+  <reg name="f30" bitsize="32" type="ieee_single" regnum="62"/>
+  <reg name="f31" bitsize="32" type="ieee_single" regnum="63"/>
+
+  <reg name="f32" bitsize="64" type="ieee_double" regnum="64"/>
+  <reg name="f34" bitsize="64" type="ieee_double" regnum="65"/>
+  <reg name="f36" bitsize="64" type="ieee_double" regnum="66"/>
+  <reg name="f38" bitsize="64" type="ieee_double" regnum="67"/>
+  <reg name="f40" bitsize="64" type="ieee_double" regnum="68"/>
+  <reg name="f42" bitsize="64" type="ieee_double" regnum="69"/>
+  <reg name="f44" bitsize="64" type="ieee_double" regnum="70"/>
+  <reg name="f46" bitsize="64" type="ieee_double" regnum="71"/>
+  <reg name="f48" bitsize="64" type="ieee_double" regnum="72"/>
+  <reg name="f50" bitsize="64" type="ieee_double" regnum="73"/>
+  <reg name="f52" bitsize="64" type="ieee_double" regnum="74"/>
+  <reg name="f54" bitsize="64" type="ieee_double" regnum="75"/>
+  <reg name="f56" bitsize="64" type="ieee_double" regnum="76"/>
+  <reg name="f58" bitsize="64" type="ieee_double" regnum="77"/>
+  <reg name="f60" bitsize="64" type="ieee_double" regnum="78"/>
+  <reg name="f62" bitsize="64" type="ieee_double" regnum="79"/>
+</feature>
+
diff -Npur a/gdb/features/sparc/sparc64-solaris.c b/gdb/features/sparc/sparc64-solaris.c
--- a/gdb/features/sparc/sparc64-solaris.c	1969-12-31 16:00:00.000000000 +0000
+++ b/gdb/features/sparc/sparc64-solaris.c	2016-12-06 14:36:22.923302527 +0000
@@ -0,0 +1,112 @@ 
+/* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
+  Original: sparc64-solaris.xml */
+
+#include "defs.h"
+#include "osabi.h"
+#include "target-descriptions.h"
+
+struct target_desc *tdesc_sparc64_solaris;
+static void
+initialize_tdesc_sparc64_solaris (void)
+{
+  struct target_desc *result = allocate_target_description ();
+  struct tdesc_feature *feature;
+
+  set_tdesc_architecture (result, bfd_scan_arch ("sparc"));
+
+  set_tdesc_osabi (result, osabi_from_tdesc_string ("Solaris"));
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.sparc.cpu");
+  tdesc_create_reg (feature, "g0", 0, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "g1", 1, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "g2", 2, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "g3", 3, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "g4", 4, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "g5", 5, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "g6", 6, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "g7", 7, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "o0", 8, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "o1", 9, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "o2", 10, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "o3", 11, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "o4", 12, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "o5", 13, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "sp", 14, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "o7", 15, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l0", 16, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l1", 17, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l2", 18, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l3", 19, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l4", 20, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l5", 21, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l6", 22, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "l7", 23, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "i0", 24, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "i1", 25, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "i2", 26, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "i3", 27, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "i4", 28, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "i5", 29, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "fp", 30, 1, NULL, 32, "uint64");
+  tdesc_create_reg (feature, "i7", 31, 1, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.sparc.cp0");
+  tdesc_create_reg (feature, "pc", 80, 1, NULL, 64, "code_ptr");
+  tdesc_create_reg (feature, "npc", 81, 1, NULL, 64, "code_ptr");
+  tdesc_create_reg (feature, "state", 82, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "fsr", 83, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "fprs", 84, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "y", 85, 1, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.sparc.fpu");
+  tdesc_create_reg (feature, "f0", 32, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f1", 33, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f2", 34, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f3", 35, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f4", 36, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f5", 37, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f6", 38, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f7", 39, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f8", 40, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f9", 41, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f10", 42, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f11", 43, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f12", 44, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f13", 45, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f14", 46, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f15", 47, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f16", 48, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f17", 49, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f18", 50, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f19", 51, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f20", 52, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f21", 53, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f22", 54, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f23", 55, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f24", 56, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f25", 57, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f26", 58, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f27", 59, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f28", 60, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f29", 61, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f30", 62, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f31", 63, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f32", 64, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f34", 65, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f36", 66, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f38", 67, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f40", 68, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f42", 69, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f44", 70, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f46", 71, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f48", 72, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f50", 73, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f52", 74, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f54", 75, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f56", 76, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f58", 77, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f60", 78, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f62", 79, 1, NULL, 64, "ieee_double");
+
+  tdesc_sparc64_solaris = result;
+}
diff -Npur a/gdb/features/sparc/sparc64-solaris.xml b/gdb/features/sparc/sparc64-solaris.xml
--- a/gdb/features/sparc/sparc64-solaris.xml	1969-12-31 16:00:00.000000000 +0000
+++ b/gdb/features/sparc/sparc64-solaris.xml	2016-12-06 03:10:40.182027442 +0000
@@ -0,0 +1,15 @@ 
+<?xml version="1.0"?>
+<!-- Copyright (C) 2013-2016 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+  <architecture>sparc:v9</architecture>
+  <osabi>Solaris</osabi>
+  <xi:include href="sparc64-cpu.xml"/>
+  <xi:include href="sparc64-cp0.xml"/>
+  <xi:include href="sparc64-fpu.xml"/>
+</target>
diff -Npur a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
--- a/gdb/sparc-tdep.c	2016-02-09 19:19:39.000000000 +0000
+++ b/gdb/sparc-tdep.c	2016-12-06 13:50:53.926722079 +0000
@@ -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 @@  sparc_structure_or_union_p (const struct
 }
 
 /* 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,6 +331,18 @@  static const char *sparc32_pseudo_regist
 #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 @@  sparc32_register_name (struct gdbarch *g
   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,6 +415,18 @@  sparc_fsr_type (struct gdbarch *gdbarch)
 
 /* 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 @@  sparc32_register_type (struct gdbarch *g
   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 @@  sparc32_register_type (struct gdbarch *g
   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 @@  sparc32_pseudo_register_read (struct gdb
 {
   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 @@  sparc32_pseudo_register_write (struct gd
 			       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 @@  sparc_iterate_over_regset_sections (stru
 }
 
 
+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 @@  sparc32_gdbarch_init (struct gdbarch_inf
   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 @@  sparc32_gdbarch_init (struct gdbarch_inf
   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 @@  sparc32_gdbarch_init (struct gdbarch_inf
 
   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
diff -Npur a/gdb/sparc-tdep.h b/gdb/sparc-tdep.h
--- a/gdb/sparc-tdep.h	2016-02-09 19:19:39.000000000 +0000
+++ b/gdb/sparc-tdep.h	2016-12-06 13:51:01.379658192 +0000
@@ -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 @@  struct gdbarch_tdep
   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;
@@ -140,8 +152,11 @@  enum sparc32_regnum
   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
diff -Npur a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c
--- a/gdb/sparc64-tdep.c	2016-02-09 19:19:39.000000000 +0000
+++ b/gdb/sparc64-tdep.c	2016-12-06 13:53:05.174301647 +0000
@@ -31,6 +31,7 @@ 
 #include "objfiles.h"
 #include "osabi.h"
 #include "regcache.h"
+#include "target-descriptions.h"
 #include "target.h"
 #include "value.h"
 
@@ -226,28 +227,29 @@  sparc64_fprs_type (struct gdbarch *gdbar
 
 
 /* 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.  */
@@ -273,6 +275,18 @@  static const char *sparc64_pseudo_regist
 #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)
@@ -280,15 +294,36 @@  sparc64_register_name (struct gdbarch *g
   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;
 }
 
 /* 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)
@@ -319,19 +354,8 @@  sparc64_register_type (struct gdbarch *g
     return builtin_type (gdbarch)->builtin_int64;
 
   /* Pseudo registers.  */
-
-  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 builtin_type (gdbarch)->builtin_int64;
-  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;
+  if (regnum >= gdbarch_num_regs (gdbarch))
+    return sparc64_pseudo_register_type (gdbarch, regnum);
 
   internal_error (__FILE__, __LINE__, _("invalid regnum"));
 }
@@ -344,7 +368,7 @@  sparc64_pseudo_register_read (struct gdb
   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)
     {
@@ -421,7 +445,8 @@  sparc64_pseudo_register_write (struct gd
 			       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)
     {
@@ -638,6 +663,7 @@  static void
 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);
@@ -652,14 +678,15 @@  sparc64_store_floating_fields (struct re
 	  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)
 	{
 	  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
@@ -712,6 +739,8 @@  static void
 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);
@@ -721,14 +750,15 @@  sparc64_extract_floating_fields (struct
 	{
 	  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)
 	{
 	  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
@@ -911,13 +941,13 @@  sparc64_store_arguments (struct regcache
 	  /* 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);
@@ -932,12 +962,14 @@  sparc64_store_arguments (struct regcache
 	      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)
 	    {
@@ -952,7 +984,8 @@  sparc64_store_arguments (struct regcache
 	      valbuf = buf;
 	      len = 8;
 	      if (element < 16)
-		regnum = SPARC64_D0_REGNUM + element;
+		regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM
+                         + element;
 	    }
 	}
       else
@@ -969,19 +1002,24 @@  sparc64_store_arguments (struct regcache
 
 	  /* 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.  */
@@ -1185,6 +1223,10 @@  sparc64_init_abi (struct gdbarch_info in
 
   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);
@@ -1195,6 +1237,8 @@  sparc64_init_abi (struct gdbarch_info in
   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);
 
diff -Npur a/gdb/sparc64-tdep.h b/gdb/sparc64-tdep.h
--- a/gdb/sparc64-tdep.h	2016-02-09 19:19:39.000000000 +0000
+++ b/gdb/sparc64-tdep.h	2016-12-06 13:51:24.047892455 +0000
@@ -56,8 +56,11 @@  enum sparc64_regnum
   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 */
diff -Npur a/gdb/testsuite/gdb.xml/tdesc-regs.exp b/gdb/testsuite/gdb.xml/tdesc-regs.exp
--- a/gdb/testsuite/gdb.xml/tdesc-regs.exp	2016-02-09 19:19:39.000000000 +0000
+++ b/gdb/testsuite/gdb.xml/tdesc-regs.exp	2016-12-06 15:53:35.418621207 +0000
@@ -49,6 +49,12 @@  switch -glob -- [istarget] {
     "s390*-*-*" {
 	set core-regs {s390-core32.xml s390-acr.xml s390-fpr.xml}
     }
+    "sparc-*-*" {
+        set core-regs {sparc32-cpu.xml sparc32-fpu.xml sparc32-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.