From patchwork Wed Jan 4 17:42:27 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivo Raisr X-Patchwork-Id: 18786 Received: (qmail 62252 invoked by alias); 4 Jan 2017 17:43:52 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 62239 invoked by uid 89); 4 Jan 2017 17:43:50 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.2 required=5.0 tests=BAYES_50, KAM_MANYCOMMENTS, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 spammy=15000000000, numbered, 00000000000, be X-HELO: userp1040.oracle.com Received: from userp1040.oracle.com (HELO userp1040.oracle.com) (156.151.31.81) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 04 Jan 2017 17:43:40 +0000 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id v04Hhagd006059 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 4 Jan 2017 17:43:36 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0022.oracle.com (8.14.4/8.14.4) with ESMTP id v04HhZAN032044 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 4 Jan 2017 17:43:35 GMT Received: from abhmp0011.oracle.com (abhmp0011.oracle.com [141.146.116.17]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id v04HhX7P028242; Wed, 4 Jan 2017 17:43:34 GMT Received: from [10.163.45.69] (/10.163.45.69) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 04 Jan 2017 09:43:32 -0800 Subject: Re: [PATCH] Bug 20936 - provide sparc and sparcv9 target description XML files To: Yao Qi References: <46200a1e-29f7-8e20-c0b5-3f6f25c82d45@oracle.com> <20161206152616.GC28789@E107787-LIN> <83d4c58d-0834-4fc2-6194-72408510aa8a@oracle.com> <20161212125331.GB25542@E107787-LIN> Cc: gdb-patches@sourceware.org From: Ivo Raisr Message-ID: <082f9ac8-3e46-42cd-198d-91866d83ebb8@oracle.com> Date: Wed, 4 Jan 2017 18:42:27 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.5.1 MIME-Version: 1.0 In-Reply-To: <20161212125331.GB25542@E107787-LIN> 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, Thank you for looking into my changes. I think I can see your motivation behind splitting the patch into two, for better readability and manageability. However my intention was only to provide support for registers supplied by target description (Valgrind shadow registers in addition to sparc real hardware ones). Pseudo register changes were just a necessity to get this done because Valgrind shadow registers are considered as "real" registers and thus they are numbered before any pseudo registers. This also means I cannot draw a clear line between your suggested patch #1 and #2. Can you take my whole patch as is? > 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); Yes, it does. Fixed also in other functions returning register names and types. >> - /* Pseudo registers. */ >> +/* Pseudo registers. */ >> +enum sparc32_pseudo_regnum >> +{ >> SPARC32_D0_REGNUM, /* %d0 */ > Explicitly set it to zero. Fixed. >> @@ -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. Indeed, just looking at the patch it does. This is because the code mixes spaces and tabs and I wanted to preserve as much of existing code as possible, to keep the patch size down. Please look at the resulting file - indentation is ok. > >> /* 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/"' Fixed. > >> * 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/" Fixed. >> * 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. Fixed. > >> * gdb.texinfo: New node "Sparc Features". > This should go to a separated entry, > > gdb/doc: > > 2016-12-07 Ivo Raisr > > * gdb.texinfo (Standard Target Features): Document SPARC features. > (Sparc Features): New node. Fixed. > >> * tdesc-regs.exp: Provide sparc core registers for the tests. > Likewise, > > gdb/testsuite: > > 2016-12-07 Ivo Raisr > > * gdb.xml/tdesc-regs.exp: Provide sparc core registers for > the tests. Fixed. Please find a new patch and 3 new ChangeLog entries. Let me know your comments. I. ChangeLog entry: 2017-01-04 Ivo Raisr PR tdep/20936 * gdb.texinfo: (Standard Target Features): Document SPARC features. (Sparc Features): New node. ChangeLog entry: 2017-01-04 Ivo Raisr PR tdep/20936 Provide and use sparc32 and sparc64 target description XML files. * feature/sparc/sparc32-cp0.xml, feature/sparc/sparc32-cpu.xml, feature/sparc/sparc32-fpu.xml: New files for sparc 32-bit. * feature/sparc/sparc64-cp0.xml, feature/sparc/sparc64-cpu.xml, feature/sparc/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. * sparc64-tdep.h: Separate real and pseudo registers. * sparc-tdep.c (sparc32_pseudo_register_name): New function returning pseudo register names on sparc 32-bit. (sparc32_register_name): Account for register names provided by the target description. (sparc32_pseudo_register_type): New function returning pseudo register types on sparc 32-bit. (sparc32_register_type): Account for register types provided by the target description. (sparc32_pseudo_register_read, sparc32_pseudo_register_write): Pseudo registers may have different numbers based on the target description. (validate_tdesc_registers): Validate registers provided by the target description. (sparc32_gdbarch_init): Use new functions sparc32_pseudo_register_name and sparc32_pseudo_register_type. Validate and use registers provided by the target description. * sparc64-tdep.c (sparc64_pseudo_register_name): New function returning pseudo register names on sparc 64-bit. (sparc64_register_name): Account for register names provided by the target description. (sparc64_pseudo_register_type): New function returning pseudo register types on sparc 64-bit. (sparc64_register_type): Account for register types provided by the target description. (sparc64_pseudo_register_read, sparc64_pseudo_register_write): Pseudo registers may have different numbers based on the target description. (sparc64_store_floating_fields, sparc64_extract_floating_fields, sparc64_store_arguments): Pseudo registers may have different numbers based on the target description; deal with it. (sparc64_init_abi): Use new functions sparc64_pseudo_register_name and sparc64_pseudo_register_type. ChangeLog entry: 2017-01-04 Ivo Raisr PR tdep/20936 * gdb.xml/tdesc-regs.exp: Provide sparc core registers for the tests. --- a/gdb/doc/gdb.texinfo 2016-02-24 01:55:15.000000000 +0000 +++ b/gdb/doc/gdb.texinfo 2017-01-04 08:01:20.143769402 +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 2017-01-04 08:01:20.403989230 +0000 @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + 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 2017-01-04 08:01:20.403460252 +0000 @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 2017-01-04 08:01:20.400357652 +0000 @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 2017-01-04 08:01:20.402170320 +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 2017-01-04 08:01:20.404673057 +0000 @@ -0,0 +1,15 @@ + + + + + + sparc + Solaris + + + + 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 2017-01-04 08:01:20.403112335 +0000 @@ -0,0 +1,17 @@ + + + + + + + + + + + + + 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 2017-01-04 08:01:20.404329025 +0000 @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 2017-01-04 08:01:20.401648620 +0000 @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 2017-01-04 08:01:20.400706657 +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 2017-01-04 08:01:20.403803055 +0000 @@ -0,0 +1,15 @@ + + + + + + sparc:v9 + Solaris + + + + --- a/gdb/sparc-tdep.c 2016-02-09 19:19:39.000000000 +0000 +++ b/gdb/sparc-tdep.c 2017-01-04 08:01:20.482416587 +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,17 +331,29 @@ 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) { - if (regnum >= 0 && regnum < SPARC32_NUM_REGS) - return sparc32_register_names[regnum]; + if (tdesc_has_registers (gdbarch_target_desc (gdbarch))) + return tdesc_register_name (gdbarch, regnum); - if (regnum < SPARC32_NUM_REGS + SPARC32_NUM_PSEUDO_REGS) - return sparc32_pseudo_register_names[regnum - SPARC32_NUM_REGS]; + if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch)) + return sparc32_register_names[regnum]; - return NULL; + return sparc32_pseudo_register_name (gdbarch, regnum); } /* Construct types for ISA-specific registers. */ @@ -399,16 +415,28 @@ 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) { + 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; - 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 +449,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 +462,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 +477,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 +1693,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 +1736,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 +1748,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 +1798,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 --- a/gdb/sparc-tdep.h 2016-02-09 19:19:39.000000000 +0000 +++ b/gdb/sparc-tdep.h 2017-01-04 08:01:19.909195097 +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; @@ -85,7 +97,7 @@ struct gdbarch_tdep enum sparc_regnum { - SPARC_G0_REGNUM, /* %g0 */ + SPARC_G0_REGNUM = 0, /* %g0 */ SPARC_G1_REGNUM, SPARC_G2_REGNUM, SPARC_G3_REGNUM, @@ -140,9 +152,12 @@ enum sparc32_regnum SPARC32_NPC_REGNUM, /* %npc */ SPARC32_FSR_REGNUM, /* %fsr */ SPARC32_CSR_REGNUM, /* %csr */ +}; - /* Pseudo registers. */ - SPARC32_D0_REGNUM, /* %d0 */ +/* Pseudo registers. */ +enum sparc32_pseudo_regnum +{ + SPARC32_D0_REGNUM = 0, /* %d0 */ SPARC32_D30_REGNUM /* %d30 */ = SPARC32_D0_REGNUM + 15 }; --- a/gdb/sparc64-tdep.c 2016-02-09 19:19:39.000000000 +0000 +++ b/gdb/sparc64-tdep.c 2017-01-04 08:01:19.824420960 +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,28 +275,63 @@ 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) { - if (regnum >= 0 && regnum < SPARC64_NUM_REGS) - return sparc64_register_names[regnum]; + if (tdesc_has_registers (gdbarch_target_desc (gdbarch))) + return tdesc_register_name (gdbarch, 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 >= 0 && regnum < gdbarch_num_regs (gdbarch)) + return sparc64_register_names[regnum]; - return NULL; + return sparc64_pseudo_register_name (gdbarch, regnum); } /* 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 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; + + internal_error (__FILE__, __LINE__, + _("sparc64_pseudo_register_type: bad register number %d"), + regnum); +} static struct type * sparc64_register_type (struct gdbarch *gdbarch, int regnum) { - /* Raw registers. */ + 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; if (regnum >= SPARC_G0_REGNUM && regnum <= SPARC_I7_REGNUM) @@ -319,19 +356,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 +370,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 +447,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 +665,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 +680,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 +741,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 +752,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 +943,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 +964,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 +986,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 +1004,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 +1225,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 +1239,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); --- a/gdb/sparc64-tdep.h 2016-02-09 19:19:39.000000000 +0000 +++ b/gdb/sparc64-tdep.h 2017-01-04 08:01:20.035725052 +0000 @@ -56,9 +56,12 @@ enum sparc64_regnum SPARC64_FSR_REGNUM, /* %fsr */ SPARC64_FPRS_REGNUM, /* %fprs */ SPARC64_Y_REGNUM, /* %y */ +}; - /* Pseudo registers. */ - SPARC64_CWP_REGNUM, /* %cwp */ +/* Pseudo registers. */ +enum sparc64_pseudo_regnum +{ + SPARC64_CWP_REGNUM = 0, /* %cwp */ SPARC64_PSTATE_REGNUM, /* %pstate */ SPARC64_ASI_REGNUM, /* %asi */ SPARC64_CCR_REGNUM, /* %ccr */ --- a/gdb/testsuite/gdb.xml/tdesc-regs.exp 2016-02-09 19:19:39.000000000 +0000 +++ b/gdb/testsuite/gdb.xml/tdesc-regs.exp 2017-01-04 08:01:19.548047632 +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.