From patchwork Wed Aug 15 00:06:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pedro Franco de Carvalho X-Patchwork-Id: 28921 Received: (qmail 80534 invoked by alias); 15 Aug 2018 00:55: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 79834 invoked by uid 89); 15 Aug 2018 00:55:50 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-23.7 required=5.0 tests=GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW, SPF_PASS, TIME_LIMIT_EXCEEDED, UNSUBSCRIBE_BODY autolearn=unavailable version=3.3.2 spammy=2197, transactions X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0a-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.156.1) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 15 Aug 2018 00:55:39 +0000 Received: from pps.filterd (m0098404.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w7F04JJU128633 for ; Tue, 14 Aug 2018 20:07:11 -0400 Received: from e15.ny.us.ibm.com (e15.ny.us.ibm.com [129.33.205.205]) by mx0a-001b2d01.pphosted.com with ESMTP id 2kv51c2k48-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Tue, 14 Aug 2018 20:07:10 -0400 Received: from localhost by e15.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 14 Aug 2018 20:07:08 -0400 Received: from b01cxnp22034.gho.pok.ibm.com (9.57.198.24) by e15.ny.us.ibm.com (146.89.104.202) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Tue, 14 Aug 2018 20:07:06 -0400 Received: from b01ledav006.gho.pok.ibm.com (b01ledav006.gho.pok.ibm.com [9.57.199.111]) by b01cxnp22034.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w7F074Zk18284548 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 15 Aug 2018 00:07:04 GMT Received: from b01ledav006.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9F6BFAC05E; Tue, 14 Aug 2018 20:07:25 -0400 (EDT) Received: from b01ledav006.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id BEA66AC059; Tue, 14 Aug 2018 20:07:24 -0400 (EDT) Received: from pedro.localdomain (unknown [9.80.202.230]) by b01ledav006.gho.pok.ibm.com (Postfix) with ESMTP; Tue, 14 Aug 2018 20:07:24 -0400 (EDT) Received: by pedro.localdomain (Postfix, from userid 1000) id E71F13C0557; Tue, 14 Aug 2018 21:06:57 -0300 (-03) From: Pedro Franco de Carvalho To: gdb-patches@sourceware.org Cc: uweigand@de.ibm.com, edjunior@gmail.com Subject: [PATCH v4 12/12] [PowerPC] Add support for HTM registers Date: Tue, 14 Aug 2018 21:06:08 -0300 In-Reply-To: <20180815000608.26840-1-pedromfc@linux.ibm.com> References: <20180815000608.26840-1-pedromfc@linux.ibm.com> x-cbid: 18081500-0068-0000-0000-00000329217B X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00009545; HX=3.00000242; KW=3.00000007; PH=3.00000004; SC=3.00000266; SDB=6.01073610; UDB=6.00553198; IPR=6.00853568; MB=3.00022721; MTD=3.00000008; XFM=3.00000015; UTC=2018-08-15 00:07:07 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18081500-0069-0000-0000-000045646C05 Message-Id: <20180815000608.26840-13-pedromfc@linux.ibm.com> From: Edjunior Barbosa Machado This patch adds support for Hardware Transactional Memory registers for the powerpc linux native and core file targets, and for the pwoerpc linux server stub. These registers include both the HTM special-purpose registers (TFHAR, TEXASR and TFIAR) as well as the set of registers that are checkpointed (saved) when a transaction is initiated, which the processor restores in the event of a transaction failure. The set of checkpointed general-purpose registers is returned by the linux kernel in the same format as the regular general-purpose registers, defined in struct pt_regs. However, the architecture specifies that only some of the registers present in pt_regs are checkpointed (GPRs 0-31, CR, XER, LR and CTR). The kernel fills the slots for other registers with other info (e.g., nip is filled with the contents of TFHAR). GDB doesn't handle these other registers. This means that core files generated by GDB will show values of zero for these registers, while core files generated by the kernel will have other values. Core files generated by the kernel have a note section for checkpointed GPRs with the same size for both 32-bit and 64-bit threads, and the values for the registers of a 32-bit thread are squeezed in the first half, with no useful data in the second half. GDB generates a smaller note section for 32-bit threads, but can read both sizes. The checkpointed XER is required to be 32-bit in the target description documentation, even though the more recent ISAs define it as 64-bit wide, since the high-order 32-bits are reserved, and because in Linux there is no way to get a 64-bit checkpointed XER for 32-bit threads. If this changes in the future, the target description feature requirement can be relaxed to allow for a 64-bit checkpointed XER. Access to the checkpointed CR (condition register) can be confusing. The architecture only specifies that CR fields 1 to 7 (the 24 least significant bits) are checkpointed, but the kernel provides all 8 fields (32 bits). The value of field 0 is not masked by ptrace, so it will sometimes show the result of some kernel operation, probably treclaim., which sets this field. The checkpointed registers are marked not to be saved and restored. Inferior function calls during an active transaction don't work well, and it's unclear what should be done in this case. TEXASR and TFIAR can be altered asynchronously, during transaction failure recording, so they are also not saved and restored. For consistency neither is TFHAR. Record and replay also doesn't work well when transactions are involved. This patch doesn't address this, so the values of the HTM SPRs will sometimes be innacurate when the record/relay target is enabled. For instance, executing a "tbegin." alters TFHAR and TEXASR, but these changes are not currently recorded. Because the checkpointed registers are only available when a transaction is active (or suspended), ptrace can return ENODATA when gdb tries to read these registers and the inferior is not in a transactional state. The registers are set to the unavailable state when this happens. When gbd tries to write to one of these registers, and it is unavailable, an error is raised. When gdb tries to store to all registers in one go (when store_registers called with -1), the state of these registers is checked. If they are all unavailable, no write is attempted, so that writes to all the other registers are unaffected. If all are available, the write is attempted. Otherwise an internal_error is raised. The "fill" functions for checkpointed register sets in the server stub are not implemented for the same reason as for the EBB register set, since ptrace can also return ENODATA for checkpointed regsets. Just like for the EBB registers, tracepoints will not mark the checkpointed registers as unavailable if the inferior was not in a transaction, so their content will also show 0 instead of when inspecting trace data. The new tests record the values of the regular registers before stepping the inferior through a "tbegin." instruction to start a transaction, then the checkpointed registers are checked against the recorded pre-transactional values. New values are written to the checkpointed registers and recorded, the inferior continues until the transaction aborts (which is usually immediately when it is resumed), and the regular registers are checked against the recorded values, because the abort should have reverted the registers to these values. gdb/ChangeLog: YYYY-MM-DD Edjunior Barbosa Machado Pedro Franco de Carvalho * arch/ppc-linux-tdesc.h (tdesc_powerpc_isa207_htm_vsx32l) (tdesc_powerpc_isa207_htm_vsx64l): Declare. * arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_TM_SPRREGSET) (PPC32_LINUX_SIZEOF_CGPRREGSET, PPC64_LINUX_SIZEOF_CGPRREGSET) (PPC_LINUX_SIZEOF_CFPRREGSET, PPC_LINUX_SIZEOF_CVMXREGSET) (PPC_LINUX_SIZEOF_CVSXREGSET, PPC_LINUX_SIZEOF_CPPRREGSET) (PPC_LINUX_SIZEOF_CDSCRREGSET, PPC_LINUX_SIZEOF_CTARREGSET): Define. (struct ppc_linux_features) : New field. (ppc_linux_no_features): Add initializer for htm field. * arch/ppc-linux-common.c (ppc_linux_match_description): Return new tdescs. * nat/ppc-linux.h (PPC_FEATURE2_HTM, NT_PPC_TM_CGPR) (NT_PPC_TM_CFPR, NT_PPC_TM_CVMX, NT_PPC_TM_CVSX) (NT_PPC_TM_SPR, NT_PPC_TM_CTAR, NT_PPC_TM_CPPR, NT_PPC_TM_CDSCR): Define if not already defined. * features/Makefile (WHICH): Add rs6000/powerpc-isa207-htm-vsx32l and rs6000/powerpc-isa207-htm-vsx64l. (XMLTOC): Add rs6000/powerpc-isa207-htm-vsx32l.xml and rs6000/powerpc-isa207-htm-vsx64l.xml. * features/rs6000/power-htm-spr.xml: New file. * features/rs6000/power-htm-core.xml: New file. * features/rs6000/power64-htm-core.xml: New file. * features/rs6000/power-htm-fpu.xml: New file. * features/rs6000/power-htm-altivec.xml: New file. * features/rs6000/power-htm-vsx.xml: New file. * features/rs6000/power-htm-ppr.xml: New file. * features/rs6000/power-htm-dscr.xml: New file. * features/rs6000/power-htm-tar.xml: New file. * features/rs6000/powerpc-isa207-htm-vsx32l.xml: New file. * features/rs6000/powerpc-isa207-htm-vsx64l.xml: New file. * features/rs6000/powerpc-isa207-htm-vsx32l.c: Generate. * features/rs6000/powerpc-isa207-htm-vsx64l.c: Generate. * regformats/rs6000/powerpc-isa207-htm-vsx32l.dat: Generate. * regformats/rs6000/powerpc-isa207-htm-vsx64l.dat: Generate. * ppc-linux-nat.c (fetch_register, fetch_ppc_registers): Call fetch_regset with HTM regsets. (store_register, store_ppc_registers): Call store_regset with HTM regsets. (ppc_linux_nat_target::read_description): Set htm field in the features struct if needed. * ppc-linux-tdep.c: Include features/rs6000/powerpc-isa207-htm-vsx32l.c and features/rs6000/powerpc-isa207-htm-vsx64l.c. (ppc32_regmap_tm_spr, ppc32_regmap_cgpr, ppc64_le_regmap_cgpr) (ppc64_be_regmap_cgpr, ppc32_regmap_cfpr, ppc32_le_regmap_cvmx) (ppc32_be_regmap_cvmx, ppc32_regmap_cvsx, ppc32_regmap_cppr) (ppc32_regmap_cdscr, ppc32_regmap_ctar): New globals. (ppc32_linux_tm_sprregset, ppc32_linux_cgprregset) (ppc64_be_linux_cgprregset, ppc64_le_linux_cgprregset) (ppc32_linux_cfprregset, ppc32_le_linux_cvmxregset) (ppc32_be_linux_cvmxregset, ppc32_linux_cvsxregset) (ppc32_linux_cpprregset, ppc32_linux_cdscrregset) (ppc32_linux_ctarregset): New globals. (ppc_linux_cgprregset, ppc_linux_cvmxregset): New functions. (ppc_linux_iterate_over_regset_sections): Call back with the htm regsets. (ppc_linux_core_read_description): Check if the tm spr section is present and set htm in the features struct. (_initialize_ppc_linux_tdep): Call initialize_tdesc_powerpc_isa207_htm_vsx32l and initialize_tdesc_powerpc_isa207_htm_vsx64l. * ppc-linux-tdep.h (ppc_linux_cgprregset, ppc_linux_cvmxregset): Declare. (ppc32_linux_tm_sprregset, ppc32_linux_cfprregset) (ppc32_linux_cvsxregset, ppc32_linux_cpprregset) (ppc32_linux_cdscrregset, ppc32_linux_ctarregset): Declare. * ppc-tdep.h (struct gdbarch_tdep) : New fields. : Likewise. : Likewise. : Likewise. (enum) : New enum fields. : Likewise. : Likewise. : Likewise. : Likewise. : Likewise. : Likewise. (PPC_IS_TMSPR_REGNUM, PPC_IS_CKPTGP_REGNUM, PPC_IS_CKPTFP_REGNUM) (PPC_IS_CKPTVMX_REGNUM, PPC_IS_CKPTVSX_REGNUM): Define. * rs6000-tdep.c (IS_CDFP_PSEUDOREG, IS_CVSX_PSEUDOREG) (IS_CEFP_PSEUDOREG): Define. (rs6000_register_name): Hide the upper halves of checkpointed VSX registers. Return names for the checkpointed DFP, VSX, and EFP pseudo registers. (rs6000_pseudo_register_type): Remove initial assert and raise an internal error in the else clause instead. Return types for the checkpointed DFP, VSX, and EFP pseudo registers. (dfp_pseudo_register_read, dfp_pseudo_register_write): Handle checkpointed DFP pseudo registers. (vsx_pseudo_register_read, vsx_pseudo_register_write): Handle checkpointed VSX pseudo registers. (efp_pseudo_register_read, efp_pseudo_register_write): Rename from efpr_pseudo_register_read and efpr_pseudo_register_write. Handle checkpointed EFP pseudo registers. (rs6000_pseudo_register_read, rs6000_pseudo_register_write): Handle checkpointed DFP, VSX, and EFP registers. (dfp_ax_pseudo_register_collect, vsx_ax_pseudo_register_collect) (efp_ax_pseudo_register_collect): New functions. (rs6000_ax_pseudo_register_collect): Move DFP, VSX and EFP pseudo register logic to new functions. Handle checkpointed DFP, VSX, and EFP pseudo registers. (rs6000_gdbarch_init): Look for and validate the htm features. Include checkpointed DFP, VSX and EFP pseudo-registers. * NEWS: Mention access to PPR, DSCR, TAR, EBB/PMU registers and HTM registers. gdb/gdbserver/ChangeLog: YYYY-MM-DD Pedro Franco de Carvalho * configure.srv (ipa_ppc_linux_regobj): Add powerpc-isa207-htm-vsx32l-ipa.o and powerpc-isa207-htm-vsx64l-ipa.o. (powerpc*-*-linux*): Add powerpc-isa207-htm-vsx32l.o and powerpc-isa207-htm-vsx64l.o to srv_regobj. Add rs6000/power-htm-spr.xml, rs6000/power-htm-core.xml, rs6000/power64-htm-core.xml, rs6000/power-htm-fpu.xml, rs6000/power-htm-altivec.xml, rs6000/power-htm-vsx.xml, rs6000/power-htm-ppr.xml, rs6000/power-htm-dscr.xml, rs6000/power-htm-tar.xml, rs6000/powerpc-isa207-htm-vsx32l.xml, and rs6000/powerpc-isa207-htm-vsx64l.xml to srv_xmlfiles. * linux-ppc-tdesc-init.h (enum ppc_linux_tdesc) : New enum value. (init_registers_powerpc_isa207_htm_vsx32l) (init_registers_powerpc_isa207_htm_vsx64l): Declare. * linux-ppc-low.c (ppc_fill_tm_sprregset, ppc_store_tm_sprregset) (ppc_store_tm_cgprregset, ppc_store_tm_cfprregset) (ppc_store_tm_cvrregset, ppc_store_tm_cvsxregset) (ppc_store_tm_cpprregset, ppc_store_tm_cdscrregset) (ppc_store_tm_ctarregset): New functions. (ppc_regsets): Add entries for HTM regsets. (ppc_arch_setup): Set htm in features struct when needed. Set sizes for the HTM regsets. (ppc_get_ipa_tdesc_idx): Return PPC_TDESC_ISA207_HTM_VSX. (initialize_low_arch): Call init_registers_powerpc_isa207_htm_vsx32l and init_registers_powerpc_isa207_htm_vsx64l. * linux-ppc-ipa.c (get_ipa_tdesc): Handle PPC_TDESC_ISA207_HTM_VSX. (initialize_low_tracepoint): Call init_registers_powerpc_isa207_htm_vsx32l and init_registers_powerpc_isa207_htm_vsx64l. gdb/testsuite/ChangeLog: YYYY-MM-DD Pedro Franco de Carvalho * gdb.arch/powerpc-htm-regs.c: New file. * gdb.arch/powerpc-htm-regs.exp: New file. gdb/doc/ChangeLog: YYYY-MM-DD Pedro Franco de Carvalho * gdb.texinfo (PowerPC Features): Describe new features "org.gnu.gdb.power.htm.spr", "org.gnu.gdb.power.htm.core", "org.gnu.gdb.power.htm.fpu", "org.gnu.gdb.power.htm.altivec", "org.gnu.gdb.power.htm.vsx", "org.gnu.gdb.power.htm.ppr", "org.gnu.gdb.power.htm.dscr", "org.gnu.gdb.power.htm.tar". --- gdb/NEWS | 4 + gdb/arch/ppc-linux-common.c | 6 +- gdb/arch/ppc-linux-common.h | 11 + gdb/arch/ppc-linux-tdesc.h | 2 + gdb/doc/gdb.texinfo | 42 ++ gdb/features/Makefile | 4 + gdb/features/rs6000/power-htm-altivec.xml | 58 ++ gdb/features/rs6000/power-htm-core.xml | 48 ++ gdb/features/rs6000/power-htm-dscr.xml | 12 + gdb/features/rs6000/power-htm-fpu.xml | 45 ++ gdb/features/rs6000/power-htm-ppr.xml | 12 + gdb/features/rs6000/power-htm-spr.xml | 14 + gdb/features/rs6000/power-htm-tar.xml | 12 + gdb/features/rs6000/power-htm-vsx.xml | 43 ++ gdb/features/rs6000/power64-htm-core.xml | 48 ++ gdb/features/rs6000/powerpc-isa207-htm-vsx32l.c | 396 +++++++++++++ gdb/features/rs6000/powerpc-isa207-htm-vsx32l.xml | 29 + gdb/features/rs6000/powerpc-isa207-htm-vsx64l.c | 396 +++++++++++++ gdb/features/rs6000/powerpc-isa207-htm-vsx64l.xml | 29 + gdb/gdbserver/configure.srv | 15 +- gdb/gdbserver/linux-ppc-ipa.c | 6 + gdb/gdbserver/linux-ppc-low.c | 187 ++++++- gdb/gdbserver/linux-ppc-tdesc-init.h | 7 + gdb/nat/ppc-linux.h | 43 ++ gdb/ppc-linux-nat.c | 278 ++++++++- gdb/ppc-linux-tdep.c | 313 ++++++++++- gdb/ppc-linux-tdep.h | 14 + gdb/ppc-tdep.h | 53 ++ .../rs6000/powerpc-isa207-htm-vsx32l.dat | 296 ++++++++++ .../rs6000/powerpc-isa207-htm-vsx64l.dat | 296 ++++++++++ gdb/rs6000-tdep.c | 620 ++++++++++++++++++--- gdb/testsuite/gdb.arch/powerpc-htm-regs.c | 39 ++ gdb/testsuite/gdb.arch/powerpc-htm-regs.exp | 320 +++++++++++ 33 files changed, 3607 insertions(+), 91 deletions(-) create mode 100644 gdb/features/rs6000/power-htm-altivec.xml create mode 100644 gdb/features/rs6000/power-htm-core.xml create mode 100644 gdb/features/rs6000/power-htm-dscr.xml create mode 100644 gdb/features/rs6000/power-htm-fpu.xml create mode 100644 gdb/features/rs6000/power-htm-ppr.xml create mode 100644 gdb/features/rs6000/power-htm-spr.xml create mode 100644 gdb/features/rs6000/power-htm-tar.xml create mode 100644 gdb/features/rs6000/power-htm-vsx.xml create mode 100644 gdb/features/rs6000/power64-htm-core.xml create mode 100644 gdb/features/rs6000/powerpc-isa207-htm-vsx32l.c create mode 100644 gdb/features/rs6000/powerpc-isa207-htm-vsx32l.xml create mode 100644 gdb/features/rs6000/powerpc-isa207-htm-vsx64l.c create mode 100644 gdb/features/rs6000/powerpc-isa207-htm-vsx64l.xml create mode 100644 gdb/regformats/rs6000/powerpc-isa207-htm-vsx32l.dat create mode 100644 gdb/regformats/rs6000/powerpc-isa207-htm-vsx64l.dat create mode 100644 gdb/testsuite/gdb.arch/powerpc-htm-regs.c create mode 100644 gdb/testsuite/gdb.arch/powerpc-htm-regs.exp diff --git a/gdb/NEWS b/gdb/NEWS index 16d3d72589..04be95bd2f 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -3,6 +3,10 @@ *** Changes since GDB 8.2 +* GDB and GDBserver now support access to additional registers on + PowerPC GNU/Linux targets: PPR, DSCR, TAR, EBB/PMU registers, and + HTM registers. + * GDB and GDBserver now support IPv6 connections. IPv6 addresses can be passed using the '[ADDRESS]:PORT' notation, or the regular 'ADDRESS:PORT' method. diff --git a/gdb/arch/ppc-linux-common.c b/gdb/arch/ppc-linux-common.c index b8a7cdb2ad..cc4d164320 100644 --- a/gdb/arch/ppc-linux-common.c +++ b/gdb/arch/ppc-linux-common.c @@ -53,7 +53,8 @@ ppc_linux_match_description (struct ppc_linux_features features) if (features.cell) tdesc = tdesc_powerpc_cell64l; else if (features.vsx) - tdesc = (features.isa207? tdesc_powerpc_isa207_vsx64l + tdesc = (features.htm? tdesc_powerpc_isa207_htm_vsx64l + : features.isa207? tdesc_powerpc_isa207_vsx64l : features.ppr_dscr? tdesc_powerpc_isa205_ppr_dscr_vsx64l : features.isa205? tdesc_powerpc_isa205_vsx64l : tdesc_powerpc_vsx64l); @@ -71,7 +72,8 @@ ppc_linux_match_description (struct ppc_linux_features features) if (features.cell) tdesc = tdesc_powerpc_cell32l; else if (features.vsx) - tdesc = (features.isa207? tdesc_powerpc_isa207_vsx32l + tdesc = (features.htm? tdesc_powerpc_isa207_htm_vsx32l + : features.isa207? tdesc_powerpc_isa207_vsx32l : features.ppr_dscr? tdesc_powerpc_isa205_ppr_dscr_vsx32l : features.isa205? tdesc_powerpc_isa205_vsx32l : tdesc_powerpc_vsx32l); diff --git a/gdb/arch/ppc-linux-common.h b/gdb/arch/ppc-linux-common.h index 50e9e064d0..9ecb02bcf6 100644 --- a/gdb/arch/ppc-linux-common.h +++ b/gdb/arch/ppc-linux-common.h @@ -35,6 +35,15 @@ struct target_desc; #define PPC_LINUX_SIZEOF_TARREGSET 8 #define PPC_LINUX_SIZEOF_EBBREGSET (3*8) #define PPC_LINUX_SIZEOF_PMUREGSET (5*8) +#define PPC_LINUX_SIZEOF_TM_SPRREGSET (3*8) +#define PPC32_LINUX_SIZEOF_CGPRREGSET (48*4) +#define PPC64_LINUX_SIZEOF_CGPRREGSET (48*8) +#define PPC_LINUX_SIZEOF_CFPRREGSET (32*8+8) +#define PPC_LINUX_SIZEOF_CVMXREGSET (34*16) +#define PPC_LINUX_SIZEOF_CVSXREGSET (32*8) +#define PPC_LINUX_SIZEOF_CPPRREGSET 8 +#define PPC_LINUX_SIZEOF_CDSCRREGSET 8 +#define PPC_LINUX_SIZEOF_CTARREGSET 8 /* Check if the hwcap auxv entry indicates that isa205 is supported. */ bool ppc_linux_has_isa205 (CORE_ADDR hwcap); @@ -48,6 +57,7 @@ struct ppc_linux_features bool isa205; bool ppr_dscr; bool isa207; + bool htm; bool cell; }; @@ -60,6 +70,7 @@ const struct ppc_linux_features ppc_linux_no_features = { false, false, false, + false, }; /* Return a target description that matches FEATURES. */ diff --git a/gdb/arch/ppc-linux-tdesc.h b/gdb/arch/ppc-linux-tdesc.h index 9962879786..2716be7e53 100644 --- a/gdb/arch/ppc-linux-tdesc.h +++ b/gdb/arch/ppc-linux-tdesc.h @@ -31,6 +31,7 @@ extern struct target_desc *tdesc_powerpc_isa205_altivec32l; extern struct target_desc *tdesc_powerpc_isa205_vsx32l; extern struct target_desc *tdesc_powerpc_isa205_ppr_dscr_vsx32l; extern struct target_desc *tdesc_powerpc_isa207_vsx32l; +extern struct target_desc *tdesc_powerpc_isa207_htm_vsx32l; extern struct target_desc *tdesc_powerpc_e500l; extern struct target_desc *tdesc_powerpc_64l; @@ -42,5 +43,6 @@ extern struct target_desc *tdesc_powerpc_isa205_altivec64l; extern struct target_desc *tdesc_powerpc_isa205_vsx64l; extern struct target_desc *tdesc_powerpc_isa205_ppr_dscr_vsx64l; extern struct target_desc *tdesc_powerpc_isa207_vsx64l; +extern struct target_desc *tdesc_powerpc_isa207_htm_vsx64l; #endif /* ARCH_PPC_LINUX_TDESC_H */ diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index f30a459e9e..edafd39988 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -42800,6 +42800,48 @@ contain registers @samp{mmcr0}, @samp{mmcr2}, @samp{siar}, @samp{sdar} and @samp{sier}, all 64-bit wide. This is the subset of the isa 2.07 server PMU registers provided by @sc{gnu}/Linux. +The @samp{org.gnu.gdb.power.htm.spr} feature is optional. It should +contain registers @samp{tfhar}, @samp{texasr} and @samp{tfiar}, all +64-bit wide. + +The @samp{org.gnu.gdb.power.htm.core} feature is optional. It should +contain the checkpointed general-purpose registers @samp{cr0} through +@samp{cr31}, as well as the checkpointed registers @samp{clr} and +@samp{cctr}. These registers may all be either 32-bit or 64-bit +depending on the target. It should also contain the checkpointed +registers @samp{ccr} and @samp{cxer}, which should both be 32-bit +wide. + +The @samp{org.gnu.gdb.power.htm.fpu} feature is optional. It should +contain the checkpointed 64-bit floating-point registers @samp{cf0} +through @samp{cf31}, as well as the checkpointed 64-bit register +@samp{cfpscr}. + +The @samp{org.gnu.gdb.power.htm.altivec} feature is optional. It +should contain the checkpointed altivec registers @samp{cvr0} through +@samp{cvr31}, all 128-bit wide. It should also contain the +checkpointed registers @samp{cvscr} and @samp{cvrsave}, both 32-bit +wide. + +The @samp{org.gnu.gdb.power.htm.vsx} feature is optional. It should +contain registers @samp{cvs0h} through @samp{cvs31h}. @value{GDBN} +will combine these registers with the checkpointed floating point +registers (@samp{cf0} through @samp{cf31}) and the checkpointed +altivec registers (@samp{cvr0} through @samp{cvr31}) to present the +128-bit wide checkpointed vector-scalar registers @samp{cvs0} through +@samp{cvs63}. Therefore, this feature requires both +@samp{org.gnu.gdb.power.htm.altivec} and +@samp{org.gnu.gdb.power.htm.fpu}. + +The @samp{org.gnu.gdb.power.htm.ppr} feature is optional. It should +contain the 64-bit checkpointed register @samp{cppr}. + +The @samp{org.gnu.gdb.power.htm.dscr} feature is optional. It should +contain the 64-bit checkpointed register @samp{cdscr}. + +The @samp{org.gnu.gdb.power.htm.tar} feature is optional. It should +contain the 64-bit checkpointed register @samp{ctar}. + @node S/390 and System z Features @subsection S/390 and System z Features @cindex target descriptions, S/390 features diff --git a/gdb/features/Makefile b/gdb/features/Makefile index 6eaa7db05f..150fef23f0 100644 --- a/gdb/features/Makefile +++ b/gdb/features/Makefile @@ -76,6 +76,8 @@ WHICH = aarch64 \ rs6000/powerpc-isa205-ppr-dscr-vsx32l \ rs6000/powerpc-isa205-ppr-dscr-vsx64l \ rs6000/powerpc-isa207-vsx32l rs6000/powerpc-isa207-vsx64l \ + rs6000/powerpc-isa207-htm-vsx32l \ + rs6000/powerpc-isa207-htm-vsx64l \ s390-linux32 s390-linux64 s390x-linux64 \ s390-linux32v1 s390-linux64v1 s390x-linux64v1 \ s390-linux32v2 s390-linux64v2 s390x-linux64v2 \ @@ -174,6 +176,8 @@ XMLTOC = \ rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml \ rs6000/powerpc-isa207-vsx32l.xml \ rs6000/powerpc-isa207-vsx64l.xml \ + rs6000/powerpc-isa207-htm-vsx32l.xml \ + rs6000/powerpc-isa207-htm-vsx64l.xml \ rs6000/powerpc-vsx32.xml \ rs6000/powerpc-vsx32l.xml \ rs6000/powerpc-vsx64.xml \ diff --git a/gdb/features/rs6000/power-htm-altivec.xml b/gdb/features/rs6000/power-htm-altivec.xml new file mode 100644 index 0000000000..efc33b7def --- /dev/null +++ b/gdb/features/rs6000/power-htm-altivec.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb/features/rs6000/power-htm-core.xml b/gdb/features/rs6000/power-htm-core.xml new file mode 100644 index 0000000000..d067be842e --- /dev/null +++ b/gdb/features/rs6000/power-htm-core.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb/features/rs6000/power-htm-dscr.xml b/gdb/features/rs6000/power-htm-dscr.xml new file mode 100644 index 0000000000..9f218fadc6 --- /dev/null +++ b/gdb/features/rs6000/power-htm-dscr.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/gdb/features/rs6000/power-htm-fpu.xml b/gdb/features/rs6000/power-htm-fpu.xml new file mode 100644 index 0000000000..561a8c3c81 --- /dev/null +++ b/gdb/features/rs6000/power-htm-fpu.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb/features/rs6000/power-htm-ppr.xml b/gdb/features/rs6000/power-htm-ppr.xml new file mode 100644 index 0000000000..2725937b54 --- /dev/null +++ b/gdb/features/rs6000/power-htm-ppr.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/gdb/features/rs6000/power-htm-spr.xml b/gdb/features/rs6000/power-htm-spr.xml new file mode 100644 index 0000000000..e933439f1b --- /dev/null +++ b/gdb/features/rs6000/power-htm-spr.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/gdb/features/rs6000/power-htm-tar.xml b/gdb/features/rs6000/power-htm-tar.xml new file mode 100644 index 0000000000..bc6339d4f7 --- /dev/null +++ b/gdb/features/rs6000/power-htm-tar.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/gdb/features/rs6000/power-htm-vsx.xml b/gdb/features/rs6000/power-htm-vsx.xml new file mode 100644 index 0000000000..2dd14fe100 --- /dev/null +++ b/gdb/features/rs6000/power-htm-vsx.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb/features/rs6000/power64-htm-core.xml b/gdb/features/rs6000/power64-htm-core.xml new file mode 100644 index 0000000000..b8dd6aef59 --- /dev/null +++ b/gdb/features/rs6000/power64-htm-core.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb/features/rs6000/powerpc-isa207-htm-vsx32l.c b/gdb/features/rs6000/powerpc-isa207-htm-vsx32l.c new file mode 100644 index 0000000000..e1b933c8fb --- /dev/null +++ b/gdb/features/rs6000/powerpc-isa207-htm-vsx32l.c @@ -0,0 +1,396 @@ +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: + Original: powerpc-isa207-htm-vsx32l.xml */ + +#include "defs.h" +#include "osabi.h" +#include "target-descriptions.h" + +struct target_desc *tdesc_powerpc_isa207_htm_vsx32l; +static void +initialize_tdesc_powerpc_isa207_htm_vsx32l (void) +{ + struct target_desc *result = allocate_target_description (); + set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common")); + + struct tdesc_feature *feature; + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); + tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r2", 2, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r3", 3, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r4", 4, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r5", 5, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r6", 6, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r7", 7, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r8", 8, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r9", 9, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r10", 10, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r11", 11, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r12", 12, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r13", 13, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r14", 14, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r15", 15, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r16", 16, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r17", 17, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r18", 18, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r19", 19, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r20", 20, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r21", 21, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r22", 22, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r23", 23, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r24", 24, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r25", 25, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r26", 26, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r27", 27, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r28", 28, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r29", 29, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r30", 30, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r31", 31, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "pc", 64, 1, NULL, 32, "code_ptr"); + tdesc_create_reg (feature, "msr", 65, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr", 66, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "lr", 67, 1, NULL, 32, "code_ptr"); + tdesc_create_reg (feature, "ctr", 68, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "xer", 69, 1, NULL, 32, "uint32"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.fpu"); + tdesc_create_reg (feature, "f0", 32, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f1", 33, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f2", 34, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f3", 35, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f4", 36, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f5", 37, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f6", 38, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f7", 39, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f8", 40, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f9", 41, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f10", 42, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f11", 43, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f12", 44, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f13", 45, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f14", 46, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f15", 47, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f16", 48, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f17", 49, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f18", 50, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f19", 51, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f20", 52, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f21", 53, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f22", 54, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f23", 55, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f24", 56, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f25", 57, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f26", 58, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f27", 59, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f28", 60, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f29", 61, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f30", 62, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f31", 63, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "fpscr", 70, 1, "float", 64, "int"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux"); + tdesc_create_reg (feature, "orig_r3", 71, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "trap", 72, 1, NULL, 32, "int"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); + tdesc_type *element_type; + element_type = tdesc_named_type (feature, "ieee_single"); + tdesc_create_vector (feature, "v4f", element_type, 4); + + element_type = tdesc_named_type (feature, "int32"); + tdesc_create_vector (feature, "v4i32", element_type, 4); + + element_type = tdesc_named_type (feature, "int16"); + tdesc_create_vector (feature, "v8i16", element_type, 8); + + element_type = tdesc_named_type (feature, "int8"); + tdesc_create_vector (feature, "v16i8", element_type, 16); + + tdesc_type_with_fields *type_with_fields; + type_with_fields = tdesc_create_union (feature, "vec128"); + tdesc_type *field_type; + field_type = tdesc_named_type (feature, "uint128"); + tdesc_add_field (type_with_fields, "uint128", field_type); + field_type = tdesc_named_type (feature, "v4f"); + tdesc_add_field (type_with_fields, "v4_float", field_type); + field_type = tdesc_named_type (feature, "v4i32"); + tdesc_add_field (type_with_fields, "v4_int32", field_type); + field_type = tdesc_named_type (feature, "v8i16"); + tdesc_add_field (type_with_fields, "v8_int16", field_type); + field_type = tdesc_named_type (feature, "v16i8"); + tdesc_add_field (type_with_fields, "v16_int8", field_type); + + tdesc_create_reg (feature, "vr0", 73, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr1", 74, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr2", 75, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr3", 76, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr4", 77, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr5", 78, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr6", 79, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr7", 80, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr8", 81, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr9", 82, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr10", 83, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr11", 84, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr12", 85, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr13", 86, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr14", 87, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr15", 88, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr16", 89, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr17", 90, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr18", 91, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr19", 92, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr20", 93, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr21", 94, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr22", 95, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr23", 96, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr24", 97, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr25", 98, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr26", 99, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr27", 100, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr28", 101, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr29", 102, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr30", 103, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr31", 104, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vscr", 105, 1, "vector", 32, "int"); + tdesc_create_reg (feature, "vrsave", 106, 1, "vector", 32, "int"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.vsx"); + tdesc_create_reg (feature, "vs0h", 107, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs1h", 108, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs2h", 109, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs3h", 110, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs4h", 111, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs5h", 112, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs6h", 113, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs7h", 114, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs8h", 115, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs9h", 116, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs10h", 117, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs11h", 118, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs12h", 119, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs13h", 120, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs14h", 121, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs15h", 122, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs16h", 123, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs17h", 124, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs18h", 125, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs19h", 126, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs20h", 127, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs21h", 128, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs22h", 129, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs23h", 130, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs24h", 131, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs25h", 132, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs26h", 133, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs27h", 134, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs28h", 135, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs29h", 136, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs30h", 137, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs31h", 138, 1, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.ppr"); + tdesc_create_reg (feature, "ppr", 139, 1, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.dscr"); + tdesc_create_reg (feature, "dscr", 140, 1, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.tar"); + tdesc_create_reg (feature, "tar", 141, 1, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.ebb"); + tdesc_create_reg (feature, "bescr", 142, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "ebbhr", 143, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "ebbrr", 144, 0, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux.pmu"); + tdesc_create_reg (feature, "mmcr0", 145, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "mmcr2", 146, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "siar", 147, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "sdar", 148, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "sier", 149, 0, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.spr"); + tdesc_create_reg (feature, "tfhar", 150, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "texasr", 151, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "tfiar", 152, 0, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.core"); + tdesc_create_reg (feature, "cr0", 153, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr1", 154, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr2", 155, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr3", 156, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr4", 157, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr5", 158, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr6", 159, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr7", 160, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr8", 161, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr9", 162, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr10", 163, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr11", 164, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr12", 165, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr13", 166, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr14", 167, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr15", 168, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr16", 169, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr17", 170, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr18", 171, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr19", 172, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr20", 173, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr21", 174, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr22", 175, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr23", 176, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr24", 177, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr25", 178, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr26", 179, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr27", 180, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr28", 181, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr29", 182, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr30", 183, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr31", 184, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "ccr", 185, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cxer", 186, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "clr", 187, 0, NULL, 32, "code_ptr"); + tdesc_create_reg (feature, "cctr", 188, 0, NULL, 32, "uint32"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.fpu"); + tdesc_create_reg (feature, "cf0", 189, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf1", 190, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf2", 191, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf3", 192, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf4", 193, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf5", 194, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf6", 195, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf7", 196, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf8", 197, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf9", 198, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf10", 199, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf11", 200, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf12", 201, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf13", 202, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf14", 203, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf15", 204, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf16", 205, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf17", 206, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf18", 207, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf19", 208, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf20", 209, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf21", 210, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf22", 211, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf23", 212, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf24", 213, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf25", 214, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf26", 215, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf27", 216, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf28", 217, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf29", 218, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf30", 219, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf31", 220, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cfpscr", 221, 0, "float", 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.altivec"); + element_type = tdesc_named_type (feature, "ieee_single"); + tdesc_create_vector (feature, "v4f", element_type, 4); + + element_type = tdesc_named_type (feature, "int32"); + tdesc_create_vector (feature, "v4i32", element_type, 4); + + element_type = tdesc_named_type (feature, "int16"); + tdesc_create_vector (feature, "v8i16", element_type, 8); + + element_type = tdesc_named_type (feature, "int8"); + tdesc_create_vector (feature, "v16i8", element_type, 16); + + type_with_fields = tdesc_create_union (feature, "vec128"); + field_type = tdesc_named_type (feature, "uint128"); + tdesc_add_field (type_with_fields, "uint128", field_type); + field_type = tdesc_named_type (feature, "v4f"); + tdesc_add_field (type_with_fields, "v4_float", field_type); + field_type = tdesc_named_type (feature, "v4i32"); + tdesc_add_field (type_with_fields, "v4_int32", field_type); + field_type = tdesc_named_type (feature, "v8i16"); + tdesc_add_field (type_with_fields, "v8_int16", field_type); + field_type = tdesc_named_type (feature, "v16i8"); + tdesc_add_field (type_with_fields, "v16_int8", field_type); + + tdesc_create_reg (feature, "cvr0", 222, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr1", 223, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr2", 224, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr3", 225, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr4", 226, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr5", 227, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr6", 228, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr7", 229, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr8", 230, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr9", 231, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr10", 232, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr11", 233, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr12", 234, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr13", 235, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr14", 236, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr15", 237, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr16", 238, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr17", 239, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr18", 240, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr19", 241, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr20", 242, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr21", 243, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr22", 244, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr23", 245, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr24", 246, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr25", 247, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr26", 248, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr27", 249, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr28", 250, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr29", 251, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr30", 252, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr31", 253, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvscr", 254, 0, "vector", 32, "int"); + tdesc_create_reg (feature, "cvrsave", 255, 0, "vector", 32, "int"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.vsx"); + tdesc_create_reg (feature, "cvs0h", 256, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs1h", 257, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs2h", 258, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs3h", 259, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs4h", 260, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs5h", 261, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs6h", 262, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs7h", 263, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs8h", 264, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs9h", 265, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs10h", 266, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs11h", 267, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs12h", 268, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs13h", 269, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs14h", 270, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs15h", 271, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs16h", 272, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs17h", 273, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs18h", 274, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs19h", 275, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs20h", 276, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs21h", 277, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs22h", 278, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs23h", 279, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs24h", 280, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs25h", 281, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs26h", 282, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs27h", 283, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs28h", 284, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs29h", 285, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs30h", 286, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs31h", 287, 0, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.ppr"); + tdesc_create_reg (feature, "cppr", 288, 0, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.dscr"); + tdesc_create_reg (feature, "cdscr", 289, 0, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.tar"); + tdesc_create_reg (feature, "ctar", 290, 0, NULL, 64, "uint64"); + + tdesc_powerpc_isa207_htm_vsx32l = result; +} diff --git a/gdb/features/rs6000/powerpc-isa207-htm-vsx32l.xml b/gdb/features/rs6000/powerpc-isa207-htm-vsx32l.xml new file mode 100644 index 0000000000..6da85ad628 --- /dev/null +++ b/gdb/features/rs6000/powerpc-isa207-htm-vsx32l.xml @@ -0,0 +1,29 @@ + + + + + + powerpc:common + + + + + + + + + + + + + + + + + + + diff --git a/gdb/features/rs6000/powerpc-isa207-htm-vsx64l.c b/gdb/features/rs6000/powerpc-isa207-htm-vsx64l.c new file mode 100644 index 0000000000..0d818d0159 --- /dev/null +++ b/gdb/features/rs6000/powerpc-isa207-htm-vsx64l.c @@ -0,0 +1,396 @@ +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: + Original: powerpc-isa207-htm-vsx64l.xml */ + +#include "defs.h" +#include "osabi.h" +#include "target-descriptions.h" + +struct target_desc *tdesc_powerpc_isa207_htm_vsx64l; +static void +initialize_tdesc_powerpc_isa207_htm_vsx64l (void) +{ + struct target_desc *result = allocate_target_description (); + set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common64")); + + struct tdesc_feature *feature; + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); + tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r2", 2, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r3", 3, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r4", 4, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r5", 5, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r6", 6, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r7", 7, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r8", 8, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r9", 9, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r10", 10, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r11", 11, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r12", 12, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r13", 13, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r14", 14, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r15", 15, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r16", 16, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r17", 17, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r18", 18, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r19", 19, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r20", 20, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r21", 21, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r22", 22, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r23", 23, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r24", 24, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r25", 25, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r26", 26, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r27", 27, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r28", 28, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r29", 29, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r30", 30, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r31", 31, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "pc", 64, 1, NULL, 64, "code_ptr"); + tdesc_create_reg (feature, "msr", 65, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr", 66, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "lr", 67, 1, NULL, 64, "code_ptr"); + tdesc_create_reg (feature, "ctr", 68, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "xer", 69, 1, NULL, 32, "uint32"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.fpu"); + tdesc_create_reg (feature, "f0", 32, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f1", 33, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f2", 34, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f3", 35, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f4", 36, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f5", 37, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f6", 38, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f7", 39, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f8", 40, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f9", 41, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f10", 42, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f11", 43, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f12", 44, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f13", 45, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f14", 46, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f15", 47, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f16", 48, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f17", 49, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f18", 50, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f19", 51, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f20", 52, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f21", 53, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f22", 54, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f23", 55, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f24", 56, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f25", 57, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f26", 58, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f27", 59, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f28", 60, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f29", 61, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f30", 62, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f31", 63, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "fpscr", 70, 1, "float", 64, "int"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux"); + tdesc_create_reg (feature, "orig_r3", 71, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "trap", 72, 1, NULL, 64, "int"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); + tdesc_type *element_type; + element_type = tdesc_named_type (feature, "ieee_single"); + tdesc_create_vector (feature, "v4f", element_type, 4); + + element_type = tdesc_named_type (feature, "int32"); + tdesc_create_vector (feature, "v4i32", element_type, 4); + + element_type = tdesc_named_type (feature, "int16"); + tdesc_create_vector (feature, "v8i16", element_type, 8); + + element_type = tdesc_named_type (feature, "int8"); + tdesc_create_vector (feature, "v16i8", element_type, 16); + + tdesc_type_with_fields *type_with_fields; + type_with_fields = tdesc_create_union (feature, "vec128"); + tdesc_type *field_type; + field_type = tdesc_named_type (feature, "uint128"); + tdesc_add_field (type_with_fields, "uint128", field_type); + field_type = tdesc_named_type (feature, "v4f"); + tdesc_add_field (type_with_fields, "v4_float", field_type); + field_type = tdesc_named_type (feature, "v4i32"); + tdesc_add_field (type_with_fields, "v4_int32", field_type); + field_type = tdesc_named_type (feature, "v8i16"); + tdesc_add_field (type_with_fields, "v8_int16", field_type); + field_type = tdesc_named_type (feature, "v16i8"); + tdesc_add_field (type_with_fields, "v16_int8", field_type); + + tdesc_create_reg (feature, "vr0", 73, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr1", 74, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr2", 75, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr3", 76, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr4", 77, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr5", 78, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr6", 79, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr7", 80, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr8", 81, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr9", 82, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr10", 83, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr11", 84, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr12", 85, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr13", 86, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr14", 87, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr15", 88, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr16", 89, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr17", 90, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr18", 91, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr19", 92, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr20", 93, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr21", 94, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr22", 95, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr23", 96, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr24", 97, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr25", 98, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr26", 99, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr27", 100, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr28", 101, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr29", 102, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr30", 103, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr31", 104, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vscr", 105, 1, "vector", 32, "int"); + tdesc_create_reg (feature, "vrsave", 106, 1, "vector", 32, "int"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.vsx"); + tdesc_create_reg (feature, "vs0h", 107, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs1h", 108, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs2h", 109, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs3h", 110, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs4h", 111, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs5h", 112, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs6h", 113, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs7h", 114, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs8h", 115, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs9h", 116, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs10h", 117, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs11h", 118, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs12h", 119, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs13h", 120, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs14h", 121, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs15h", 122, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs16h", 123, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs17h", 124, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs18h", 125, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs19h", 126, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs20h", 127, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs21h", 128, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs22h", 129, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs23h", 130, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs24h", 131, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs25h", 132, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs26h", 133, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs27h", 134, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs28h", 135, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs29h", 136, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs30h", 137, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "vs31h", 138, 1, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.ppr"); + tdesc_create_reg (feature, "ppr", 139, 1, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.dscr"); + tdesc_create_reg (feature, "dscr", 140, 1, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.tar"); + tdesc_create_reg (feature, "tar", 141, 1, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.ebb"); + tdesc_create_reg (feature, "bescr", 142, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "ebbhr", 143, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "ebbrr", 144, 0, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux.pmu"); + tdesc_create_reg (feature, "mmcr0", 145, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "mmcr2", 146, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "siar", 147, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "sdar", 148, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "sier", 149, 0, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.spr"); + tdesc_create_reg (feature, "tfhar", 150, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "texasr", 151, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "tfiar", 152, 0, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.core"); + tdesc_create_reg (feature, "cr0", 153, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr1", 154, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr2", 155, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr3", 156, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr4", 157, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr5", 158, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr6", 159, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr7", 160, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr8", 161, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr9", 162, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr10", 163, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr11", 164, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr12", 165, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr13", 166, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr14", 167, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr15", 168, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr16", 169, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr17", 170, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr18", 171, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr19", 172, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr20", 173, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr21", 174, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr22", 175, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr23", 176, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr24", 177, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr25", 178, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr26", 179, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr27", 180, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr28", 181, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr29", 182, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr30", 183, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr31", 184, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "ccr", 185, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cxer", 186, 0, NULL, 32, "uint32"); + tdesc_create_reg (feature, "clr", 187, 0, NULL, 64, "code_ptr"); + tdesc_create_reg (feature, "cctr", 188, 0, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.fpu"); + tdesc_create_reg (feature, "cf0", 189, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf1", 190, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf2", 191, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf3", 192, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf4", 193, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf5", 194, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf6", 195, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf7", 196, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf8", 197, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf9", 198, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf10", 199, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf11", 200, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf12", 201, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf13", 202, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf14", 203, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf15", 204, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf16", 205, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf17", 206, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf18", 207, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf19", 208, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf20", 209, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf21", 210, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf22", 211, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf23", 212, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf24", 213, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf25", 214, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf26", 215, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf27", 216, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf28", 217, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf29", 218, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf30", 219, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cf31", 220, 0, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "cfpscr", 221, 0, "float", 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.altivec"); + element_type = tdesc_named_type (feature, "ieee_single"); + tdesc_create_vector (feature, "v4f", element_type, 4); + + element_type = tdesc_named_type (feature, "int32"); + tdesc_create_vector (feature, "v4i32", element_type, 4); + + element_type = tdesc_named_type (feature, "int16"); + tdesc_create_vector (feature, "v8i16", element_type, 8); + + element_type = tdesc_named_type (feature, "int8"); + tdesc_create_vector (feature, "v16i8", element_type, 16); + + type_with_fields = tdesc_create_union (feature, "vec128"); + field_type = tdesc_named_type (feature, "uint128"); + tdesc_add_field (type_with_fields, "uint128", field_type); + field_type = tdesc_named_type (feature, "v4f"); + tdesc_add_field (type_with_fields, "v4_float", field_type); + field_type = tdesc_named_type (feature, "v4i32"); + tdesc_add_field (type_with_fields, "v4_int32", field_type); + field_type = tdesc_named_type (feature, "v8i16"); + tdesc_add_field (type_with_fields, "v8_int16", field_type); + field_type = tdesc_named_type (feature, "v16i8"); + tdesc_add_field (type_with_fields, "v16_int8", field_type); + + tdesc_create_reg (feature, "cvr0", 222, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr1", 223, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr2", 224, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr3", 225, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr4", 226, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr5", 227, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr6", 228, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr7", 229, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr8", 230, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr9", 231, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr10", 232, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr11", 233, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr12", 234, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr13", 235, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr14", 236, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr15", 237, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr16", 238, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr17", 239, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr18", 240, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr19", 241, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr20", 242, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr21", 243, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr22", 244, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr23", 245, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr24", 246, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr25", 247, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr26", 248, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr27", 249, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr28", 250, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr29", 251, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr30", 252, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvr31", 253, 0, NULL, 128, "vec128"); + tdesc_create_reg (feature, "cvscr", 254, 0, "vector", 32, "int"); + tdesc_create_reg (feature, "cvrsave", 255, 0, "vector", 32, "int"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.vsx"); + tdesc_create_reg (feature, "cvs0h", 256, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs1h", 257, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs2h", 258, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs3h", 259, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs4h", 260, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs5h", 261, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs6h", 262, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs7h", 263, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs8h", 264, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs9h", 265, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs10h", 266, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs11h", 267, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs12h", 268, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs13h", 269, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs14h", 270, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs15h", 271, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs16h", 272, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs17h", 273, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs18h", 274, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs19h", 275, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs20h", 276, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs21h", 277, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs22h", 278, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs23h", 279, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs24h", 280, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs25h", 281, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs26h", 282, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs27h", 283, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs28h", 284, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs29h", 285, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs30h", 286, 0, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cvs31h", 287, 0, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.ppr"); + tdesc_create_reg (feature, "cppr", 288, 0, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.dscr"); + tdesc_create_reg (feature, "cdscr", 289, 0, NULL, 64, "uint64"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.tar"); + tdesc_create_reg (feature, "ctar", 290, 0, NULL, 64, "uint64"); + + tdesc_powerpc_isa207_htm_vsx64l = result; +} diff --git a/gdb/features/rs6000/powerpc-isa207-htm-vsx64l.xml b/gdb/features/rs6000/powerpc-isa207-htm-vsx64l.xml new file mode 100644 index 0000000000..28a8ea279b --- /dev/null +++ b/gdb/features/rs6000/powerpc-isa207-htm-vsx64l.xml @@ -0,0 +1,29 @@ + + + + + + powerpc:common64 + + + + + + + + + + + + + + + + + + + diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv index a18d7b6357..c324ae3447 100644 --- a/gdb/gdbserver/configure.srv +++ b/gdb/gdbserver/configure.srv @@ -32,7 +32,7 @@ else srv_amd64_linux_regobj="" fi -ipa_ppc_linux_regobj="powerpc-32l-ipa.o powerpc-altivec32l-ipa.o powerpc-cell32l-ipa.o powerpc-vsx32l-ipa.o powerpc-isa205-32l-ipa.o powerpc-isa205-altivec32l-ipa.o powerpc-isa205-vsx32l-ipa.o powerpc-isa205-ppr-dscr-vsx32l-ipa.o powerpc-isa207-vsx32l-ipa.o powerpc-e500l-ipa.o powerpc-64l-ipa.o powerpc-altivec64l-ipa.o powerpc-cell64l-ipa.o powerpc-vsx64l-ipa.o powerpc-isa205-64l-ipa.o powerpc-isa205-altivec64l-ipa.o powerpc-isa205-vsx64l-ipa.o powerpc-isa205-ppr-dscr-vsx64l-ipa.o powerpc-isa207-vsx64l-ipa.o" +ipa_ppc_linux_regobj="powerpc-32l-ipa.o powerpc-altivec32l-ipa.o powerpc-cell32l-ipa.o powerpc-vsx32l-ipa.o powerpc-isa205-32l-ipa.o powerpc-isa205-altivec32l-ipa.o powerpc-isa205-vsx32l-ipa.o powerpc-isa205-ppr-dscr-vsx32l-ipa.o powerpc-isa207-vsx32l-ipa.o powerpc-isa207-htm-vsx32l-ipa.o powerpc-e500l-ipa.o powerpc-64l-ipa.o powerpc-altivec64l-ipa.o powerpc-cell64l-ipa.o powerpc-vsx64l-ipa.o powerpc-isa205-64l-ipa.o powerpc-isa205-altivec64l-ipa.o powerpc-isa205-vsx64l-ipa.o powerpc-isa205-ppr-dscr-vsx64l-ipa.o powerpc-isa207-vsx64l-ipa.o powerpc-isa207-htm-vsx64l-ipa.o" # Linux object files. This is so we don't have to repeat # these files over and over again. @@ -219,6 +219,7 @@ case "${target}" in srv_regobj="${srv_regobj} powerpc-isa205-vsx32l.o" srv_regobj="${srv_regobj} powerpc-isa205-ppr-dscr-vsx32l.o" srv_regobj="${srv_regobj} powerpc-isa207-vsx32l.o" + srv_regobj="${srv_regobj} powerpc-isa207-htm-vsx32l.o" srv_regobj="${srv_regobj} powerpc-e500l.o" srv_regobj="${srv_regobj} powerpc-64l.o" srv_regobj="${srv_regobj} powerpc-altivec64l.o" @@ -229,6 +230,7 @@ case "${target}" in srv_regobj="${srv_regobj} powerpc-isa205-vsx64l.o" srv_regobj="${srv_regobj} powerpc-isa205-ppr-dscr-vsx64l.o" srv_regobj="${srv_regobj} powerpc-isa207-vsx64l.o" + srv_regobj="${srv_regobj} powerpc-isa207-htm-vsx64l.o" srv_tgtobj="$srv_linux_obj linux-ppc-low.o ppc-linux.o" srv_tgtobj="${srv_tgtobj} arch/ppc-linux-common.o" srv_xmlfiles="rs6000/powerpc-32l.xml" @@ -240,6 +242,7 @@ case "${target}" in srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-vsx32l.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa207-vsx32l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa207-htm-vsx32l.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/power-altivec.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/power-vsx.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/power-core.xml" @@ -251,6 +254,14 @@ case "${target}" in srv_xmlfiles="${srv_xmlfiles} rs6000/power-tar.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/power-ebb.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/power-linux-pmu.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-spr.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-core.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-fpu.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-altivec.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-vsx.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-ppr.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-dscr.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-tar.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-e500l.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/power-spe.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-64l.xml" @@ -262,8 +273,10 @@ case "${target}" in srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-vsx64l.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa207-vsx64l.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa207-htm-vsx64l.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/power64-core.xml" srv_xmlfiles="${srv_xmlfiles} rs6000/power64-linux.xml" + srv_xmlfiles="${srv_xmlfiles} rs6000/power64-htm-core.xml" srv_linux_usrregs=yes srv_linux_regsets=yes srv_linux_thread_db=yes diff --git a/gdb/gdbserver/linux-ppc-ipa.c b/gdb/gdbserver/linux-ppc-ipa.c index b543dceba5..348d455193 100644 --- a/gdb/gdbserver/linux-ppc-ipa.c +++ b/gdb/gdbserver/linux-ppc-ipa.c @@ -195,6 +195,8 @@ get_ipa_tdesc (int idx) return tdesc_powerpc_isa205_ppr_dscr_vsx64l; case PPC_TDESC_ISA207_VSX: return tdesc_powerpc_isa207_vsx64l; + case PPC_TDESC_ISA207_HTM_VSX: + return tdesc_powerpc_isa207_htm_vsx64l; #else case PPC_TDESC_BASE: return tdesc_powerpc_32l; @@ -214,6 +216,8 @@ get_ipa_tdesc (int idx) return tdesc_powerpc_isa205_ppr_dscr_vsx32l; case PPC_TDESC_ISA207_VSX: return tdesc_powerpc_isa207_vsx32l; + case PPC_TDESC_ISA207_HTM_VSX: + return tdesc_powerpc_isa207_htm_vsx32l; case PPC_TDESC_E500: return tdesc_powerpc_e500l; #endif @@ -244,6 +248,7 @@ initialize_low_tracepoint (void) init_registers_powerpc_isa205_vsx64l (); init_registers_powerpc_isa205_ppr_dscr_vsx64l (); init_registers_powerpc_isa207_vsx64l (); + init_registers_powerpc_isa207_htm_vsx64l (); #else init_registers_powerpc_32l (); init_registers_powerpc_altivec32l (); @@ -254,6 +259,7 @@ initialize_low_tracepoint (void) init_registers_powerpc_isa205_vsx32l (); init_registers_powerpc_isa205_ppr_dscr_vsx32l (); init_registers_powerpc_isa207_vsx32l (); + init_registers_powerpc_isa207_htm_vsx32l (); init_registers_powerpc_e500l (); #endif } diff --git a/gdb/gdbserver/linux-ppc-low.c b/gdb/gdbserver/linux-ppc-low.c index 261247861c..3cbcee17ae 100644 --- a/gdb/gdbserver/linux-ppc-low.c +++ b/gdb/gdbserver/linux-ppc-low.c @@ -564,6 +564,127 @@ ppc_store_pmuregset (struct regcache *regcache, const void *buf) } static void +ppc_fill_tm_sprregset (struct regcache *regcache, void *buf) +{ + int i, base; + char *regset = (char *) buf; + + base = find_regno (regcache->tdesc, "tfhar"); + for (i = 0; i < 3; i++) + collect_register (regcache, base + i, ®set[i * 8]); +} + +static void +ppc_store_tm_sprregset (struct regcache *regcache, const void *buf) +{ + int i, base; + const char *regset = (const char *) buf; + + base = find_regno (regcache->tdesc, "tfhar"); + for (i = 0; i < 3; i++) + supply_register (regcache, base + i, ®set[i * 8]); +} + +static void +ppc_store_tm_cgprregset (struct regcache *regcache, const void *buf) +{ + int i, base, size, endian_offset; + const char *regset = (const char *) buf; + + base = find_regno (regcache->tdesc, "cr0"); + size = register_size (regcache->tdesc, base); + + gdb_assert (size == 4 || size == 8); + + for (i = 0; i < 32; i++) + supply_register (regcache, base + i, ®set[i * size]); + + endian_offset = 0; + + if ((size == 8) && (__BYTE_ORDER == __BIG_ENDIAN)) + endian_offset = 4; + + supply_register_by_name (regcache, "ccr", + ®set[PT_CCR * size + endian_offset]); + + supply_register_by_name (regcache, "cxer", + ®set[PT_XER * size + endian_offset]); + + supply_register_by_name (regcache, "clr", ®set[PT_LNK * size]); + supply_register_by_name (regcache, "cctr", ®set[PT_CTR * size]); +} + +static void +ppc_store_tm_cfprregset (struct regcache *regcache, const void *buf) +{ + int i, base; + const char *regset = (const char *) buf; + + base = find_regno (regcache->tdesc, "cf0"); + + for (i = 0; i < 32; i++) + supply_register (regcache, base + i, ®set[i * 8]); + + supply_register_by_name (regcache, "cfpscr", ®set[32 * 8]); +} + +static void +ppc_store_tm_cvrregset (struct regcache *regcache, const void *buf) +{ + int i, base; + const char *regset = (const char *) buf; + int vscr_offset = 0; + + base = find_regno (regcache->tdesc, "cvr0"); + + for (i = 0; i < 32; i++) + supply_register (regcache, base + i, ®set[i * 16]); + + if (__BYTE_ORDER == __BIG_ENDIAN) + vscr_offset = 12; + + supply_register_by_name (regcache, "cvscr", + ®set[32 * 16 + vscr_offset]); + + supply_register_by_name (regcache, "cvrsave", ®set[33 * 16]); +} + +static void +ppc_store_tm_cvsxregset (struct regcache *regcache, const void *buf) +{ + int i, base; + const char *regset = (const char *) buf; + + base = find_regno (regcache->tdesc, "cvs0h"); + for (i = 0; i < 32; i++) + supply_register (regcache, base + i, ®set[i * 8]); +} + +static void +ppc_store_tm_cpprregset (struct regcache *regcache, const void *buf) +{ + const char *cppr = (const char *) buf; + + supply_register_by_name (regcache, "cppr", cppr); +} + +static void +ppc_store_tm_cdscrregset (struct regcache *regcache, const void *buf) +{ + const char *cdscr = (const char *) buf; + + supply_register_by_name (regcache, "cdscr", cdscr); +} + +static void +ppc_store_tm_ctarregset (struct regcache *regcache, const void *buf) +{ + const char *ctar = (const char *) buf; + + supply_register_by_name (regcache, "ctar", ctar); +} + +static void ppc_fill_vsxregset (struct regcache *regcache, void *buf) { int i, base; @@ -672,6 +793,22 @@ static struct regset_info ppc_regsets[] = { fetch them every time, but still fall back to PTRACE_PEEKUSER for the general registers. Some kernels support these, but not the newer PPC_PTRACE_GETREGS. */ + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CTAR, 0, EXTENDED_REGS, + NULL, ppc_store_tm_ctarregset }, + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CDSCR, 0, EXTENDED_REGS, + NULL, ppc_store_tm_cdscrregset }, + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CPPR, 0, EXTENDED_REGS, + NULL, ppc_store_tm_cpprregset }, + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CVSX, 0, EXTENDED_REGS, + NULL, ppc_store_tm_cvsxregset }, + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CVMX, 0, EXTENDED_REGS, + NULL, ppc_store_tm_cvrregset }, + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CFPR, 0, EXTENDED_REGS, + NULL, ppc_store_tm_cfprregset }, + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CGPR, 0, EXTENDED_REGS, + NULL, ppc_store_tm_cgprregset }, + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_SPR, 0, EXTENDED_REGS, + ppc_fill_tm_sprregset, ppc_store_tm_sprregset }, { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_EBB, 0, EXTENDED_REGS, NULL, ppc_store_ebbregset }, { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_PMU, 0, EXTENDED_REGS, @@ -763,7 +900,13 @@ ppc_arch_setup (void) PPC_LINUX_SIZEOF_EBBREGSET) && ppc_check_regset (tid, NT_PPC_PMU, PPC_LINUX_SIZEOF_PMUREGSET)) - features.isa207 = true; + { + features.isa207 = true; + if ((ppc_hwcap2 & PPC_FEATURE2_HTM) + && ppc_check_regset (tid, NT_PPC_TM_SPR, + PPC_LINUX_SIZEOF_TM_SPRREGSET)) + features.htm = true; + } } if (ppc_hwcap & PPC_FEATURE_CELL) @@ -833,6 +976,42 @@ ppc_arch_setup (void) regset->size = (features.isa207 ? PPC_LINUX_SIZEOF_PMUREGSET : 0); break; + case NT_PPC_TM_SPR: + regset->size = (features.htm ? + PPC_LINUX_SIZEOF_TM_SPRREGSET : 0); + break; + case NT_PPC_TM_CGPR: + if (features.wordsize == 4) + regset->size = (features.htm ? + PPC32_LINUX_SIZEOF_CGPRREGSET : 0); + else + regset->size = (features.htm ? + PPC64_LINUX_SIZEOF_CGPRREGSET : 0); + break; + case NT_PPC_TM_CFPR: + regset->size = (features.htm ? + PPC_LINUX_SIZEOF_CFPRREGSET : 0); + break; + case NT_PPC_TM_CVMX: + regset->size = (features.htm ? + PPC_LINUX_SIZEOF_CVMXREGSET : 0); + break; + case NT_PPC_TM_CVSX: + regset->size = (features.htm ? + PPC_LINUX_SIZEOF_CVSXREGSET : 0); + break; + case NT_PPC_TM_CPPR: + regset->size = (features.htm ? + PPC_LINUX_SIZEOF_CPPRREGSET : 0); + break; + case NT_PPC_TM_CDSCR: + regset->size = (features.htm ? + PPC_LINUX_SIZEOF_CDSCRREGSET : 0); + break; + case NT_PPC_TM_CTAR: + regset->size = (features.htm ? + PPC_LINUX_SIZEOF_CTARREGSET : 0); + break; default: break; } @@ -3216,6 +3395,8 @@ ppc_get_ipa_tdesc_idx (void) return PPC_TDESC_ISA205_PPR_DSCR_VSX; if (tdesc == tdesc_powerpc_isa207_vsx64l) return PPC_TDESC_ISA207_VSX; + if (tdesc == tdesc_powerpc_isa207_htm_vsx64l) + return PPC_TDESC_ISA207_HTM_VSX; #endif if (tdesc == tdesc_powerpc_32l) @@ -3236,6 +3417,8 @@ ppc_get_ipa_tdesc_idx (void) return PPC_TDESC_ISA205_PPR_DSCR_VSX; if (tdesc == tdesc_powerpc_isa207_vsx32l) return PPC_TDESC_ISA207_VSX; + if (tdesc == tdesc_powerpc_isa207_htm_vsx32l) + return PPC_TDESC_ISA207_HTM_VSX; if (tdesc == tdesc_powerpc_e500l) return PPC_TDESC_E500; @@ -3296,6 +3479,7 @@ initialize_low_arch (void) init_registers_powerpc_isa205_vsx32l (); init_registers_powerpc_isa205_ppr_dscr_vsx32l (); init_registers_powerpc_isa207_vsx32l (); + init_registers_powerpc_isa207_htm_vsx32l (); init_registers_powerpc_e500l (); #if __powerpc64__ init_registers_powerpc_64l (); @@ -3307,6 +3491,7 @@ initialize_low_arch (void) init_registers_powerpc_isa205_vsx64l (); init_registers_powerpc_isa205_ppr_dscr_vsx64l (); init_registers_powerpc_isa207_vsx64l (); + init_registers_powerpc_isa207_htm_vsx64l (); #endif initialize_regsets_info (&ppc_regsets_info); diff --git a/gdb/gdbserver/linux-ppc-tdesc-init.h b/gdb/gdbserver/linux-ppc-tdesc-init.h index 29b8122886..d1dfdad571 100644 --- a/gdb/gdbserver/linux-ppc-tdesc-init.h +++ b/gdb/gdbserver/linux-ppc-tdesc-init.h @@ -31,6 +31,7 @@ enum ppc_linux_tdesc { PPC_TDESC_ISA205_VSX, PPC_TDESC_ISA205_PPR_DSCR_VSX, PPC_TDESC_ISA207_VSX, + PPC_TDESC_ISA207_HTM_VSX, PPC_TDESC_E500, }; @@ -63,6 +64,9 @@ void init_registers_powerpc_isa205_ppr_dscr_vsx32l (void); /* Defined in auto-generated file powerpc-isa207-vsx32l.c. */ void init_registers_powerpc_isa207_vsx32l (void); +/* Defined in auto-generated file powerpc-isa207-htm-vsx32l.c. */ +void init_registers_powerpc_isa207_htm_vsx32l (void); + /* Defined in auto-generated file powerpc-e500l.c. */ void init_registers_powerpc_e500l (void); @@ -97,4 +101,7 @@ void init_registers_powerpc_isa205_ppr_dscr_vsx64l (void); /* Defined in auto-generated file powerpc-isa207-vsx64l.c. */ void init_registers_powerpc_isa207_vsx64l (void); +/* Defined in auto-generated file powerpc-isa207-htm-vsx64l.c. */ +void init_registers_powerpc_isa207_htm_vsx64l (void); + #endif diff --git a/gdb/nat/ppc-linux.h b/gdb/nat/ppc-linux.h index c965030d91..65c60cb158 100644 --- a/gdb/nat/ppc-linux.h +++ b/gdb/nat/ppc-linux.h @@ -63,6 +63,9 @@ #ifndef PPC_FEATURE2_EBB #define PPC_FEATURE2_EBB 0x10000000 #endif +#ifndef PPC_FEATURE2_HTM +#define PPC_FEATURE2_HTM 0x40000000 +#endif /* Glibc's headers don't define PTRACE_GETVRREGS so we cannot use a configure time check. Some older glibc's (for instance 2.2.1) @@ -119,6 +122,46 @@ #define NT_PPC_PMU 0x107 #endif +/* TM checkpointed GPR Registers. */ +#ifndef NT_PPC_TM_CGPR +#define NT_PPC_TM_CGPR 0x108 +#endif + +/* TM checkpointed FPR Registers. */ +#ifndef NT_PPC_TM_CFPR +#define NT_PPC_TM_CFPR 0x109 +#endif + +/* TM checkpointed VMX Registers. */ +#ifndef NT_PPC_TM_CVMX +#define NT_PPC_TM_CVMX 0x10a +#endif + +/* TM checkpointed VSX Registers. */ +#ifndef NT_PPC_TM_CVSX +#define NT_PPC_TM_CVSX 0x10b +#endif + +/* TM Special Purpose Registers. */ +#ifndef NT_PPC_TM_SPR +#define NT_PPC_TM_SPR 0x10c +#endif + +/* TM checkpointed Target Address Register. */ +#ifndef NT_PPC_TM_CTAR +#define NT_PPC_TM_CTAR 0x10d +#endif + +/* TM checkpointed Program Priority Register. */ +#ifndef NT_PPC_TM_CPPR +#define NT_PPC_TM_CPPR 0x10e +#endif + +/* TM checkpointed Data Stream Control Register. */ +#ifndef NT_PPC_TM_CDSCR +#define NT_PPC_TM_CDSCR 0x10f +#endif + /* Return the wordsize of the target, either 4 or 8 bytes. */ int ppc_linux_target_wordsize (int tid); diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c index 3466f4dc7f..615d1b2836 100644 --- a/gdb/ppc-linux-nat.c +++ b/gdb/ppc-linux-nat.c @@ -684,6 +684,82 @@ fetch_register (struct regcache *regcache, int tid, int regno) &ppc32_linux_pmuregset); return; } + else if (PPC_IS_TMSPR_REGNUM (regno)) + { + gdb_assert (tdep->have_htm_spr); + + fetch_regset (regcache, tid, NT_PPC_TM_SPR, + PPC_LINUX_SIZEOF_TM_SPRREGSET, + &ppc32_linux_tm_sprregset); + return; + } + else if (PPC_IS_CKPTGP_REGNUM (regno)) + { + gdb_assert (tdep->have_htm_core); + + const struct regset *cgprregset = ppc_linux_cgprregset (gdbarch); + fetch_regset (regcache, tid, NT_PPC_TM_CGPR, + (tdep->wordsize == 4? + PPC32_LINUX_SIZEOF_CGPRREGSET + : PPC64_LINUX_SIZEOF_CGPRREGSET), + cgprregset); + return; + } + else if (PPC_IS_CKPTFP_REGNUM (regno)) + { + gdb_assert (tdep->have_htm_fpu); + + fetch_regset (regcache, tid, NT_PPC_TM_CFPR, + PPC_LINUX_SIZEOF_CFPRREGSET, + &ppc32_linux_cfprregset); + return; + } + else if (PPC_IS_CKPTVMX_REGNUM (regno)) + { + gdb_assert (tdep->have_htm_altivec); + + const struct regset *cvmxregset = ppc_linux_cvmxregset (gdbarch); + fetch_regset (regcache, tid, NT_PPC_TM_CVMX, + PPC_LINUX_SIZEOF_CVMXREGSET, + cvmxregset); + return; + } + else if (PPC_IS_CKPTVSX_REGNUM (regno)) + { + gdb_assert (tdep->have_htm_vsx); + + fetch_regset (regcache, tid, NT_PPC_TM_CVSX, + PPC_LINUX_SIZEOF_CVSXREGSET, + &ppc32_linux_cvsxregset); + return; + } + else if (regno == PPC_CPPR_REGNUM) + { + gdb_assert (tdep->ppc_cppr_regnum != -1); + + fetch_regset (regcache, tid, NT_PPC_TM_CPPR, + PPC_LINUX_SIZEOF_CPPRREGSET, + &ppc32_linux_cpprregset); + return; + } + else if (regno == PPC_CDSCR_REGNUM) + { + gdb_assert (tdep->ppc_cdscr_regnum != -1); + + fetch_regset (regcache, tid, NT_PPC_TM_CDSCR, + PPC_LINUX_SIZEOF_CDSCRREGSET, + &ppc32_linux_cdscrregset); + return; + } + else if (regno == PPC_CTAR_REGNUM) + { + gdb_assert (tdep->ppc_ctar_regnum != -1); + + fetch_regset (regcache, tid, NT_PPC_TM_CTAR, + PPC_LINUX_SIZEOF_CTARREGSET, + &ppc32_linux_ctarregset); + return; + } if (regaddr == -1) { @@ -897,6 +973,46 @@ fetch_ppc_registers (struct regcache *regcache, int tid) fetch_regset (regcache, tid, NT_PPC_PMU, PPC_LINUX_SIZEOF_PMUREGSET, &ppc32_linux_pmuregset); + if (tdep->have_htm_spr) + fetch_regset (regcache, tid, NT_PPC_TM_SPR, + PPC_LINUX_SIZEOF_TM_SPRREGSET, + &ppc32_linux_tm_sprregset); + if (tdep->have_htm_core) + { + const struct regset *cgprregset = ppc_linux_cgprregset (gdbarch); + fetch_regset (regcache, tid, NT_PPC_TM_CGPR, + (tdep->wordsize == 4? + PPC32_LINUX_SIZEOF_CGPRREGSET + : PPC64_LINUX_SIZEOF_CGPRREGSET), + cgprregset); + } + if (tdep->have_htm_fpu) + fetch_regset (regcache, tid, NT_PPC_TM_CFPR, + PPC_LINUX_SIZEOF_CFPRREGSET, + &ppc32_linux_cfprregset); + if (tdep->have_htm_altivec) + { + const struct regset *cvmxregset = ppc_linux_cvmxregset (gdbarch); + fetch_regset (regcache, tid, NT_PPC_TM_CVMX, + PPC_LINUX_SIZEOF_CVMXREGSET, + cvmxregset); + } + if (tdep->have_htm_vsx) + fetch_regset (regcache, tid, NT_PPC_TM_CVSX, + PPC_LINUX_SIZEOF_CVSXREGSET, + &ppc32_linux_cvsxregset); + if (tdep->ppc_cppr_regnum != -1) + fetch_regset (regcache, tid, NT_PPC_TM_CPPR, + PPC_LINUX_SIZEOF_CPPRREGSET, + &ppc32_linux_cpprregset); + if (tdep->ppc_cdscr_regnum != -1) + fetch_regset (regcache, tid, NT_PPC_TM_CDSCR, + PPC_LINUX_SIZEOF_CDSCRREGSET, + &ppc32_linux_cdscrregset); + if (tdep->ppc_ctar_regnum != -1) + fetch_regset (regcache, tid, NT_PPC_TM_CTAR, + PPC_LINUX_SIZEOF_CTARREGSET, + &ppc32_linux_ctarregset); } /* Fetch registers from the child process. Fetch all registers if @@ -1122,6 +1238,82 @@ store_register (const struct regcache *regcache, int tid, int regno) &ppc32_linux_pmuregset); return; } + else if (PPC_IS_TMSPR_REGNUM (regno)) + { + gdb_assert (tdep->have_htm_spr); + + store_regset (regcache, tid, regno, NT_PPC_TM_SPR, + PPC_LINUX_SIZEOF_TM_SPRREGSET, + &ppc32_linux_tm_sprregset); + return; + } + else if (PPC_IS_CKPTGP_REGNUM (regno)) + { + gdb_assert (tdep->have_htm_core); + + const struct regset *cgprregset = ppc_linux_cgprregset (gdbarch); + store_regset (regcache, tid, regno, NT_PPC_TM_CGPR, + (tdep->wordsize == 4? + PPC32_LINUX_SIZEOF_CGPRREGSET + : PPC64_LINUX_SIZEOF_CGPRREGSET), + cgprregset); + return; + } + else if (PPC_IS_CKPTFP_REGNUM (regno)) + { + gdb_assert (tdep->have_htm_fpu); + + store_regset (regcache, tid, regno, NT_PPC_TM_CFPR, + PPC_LINUX_SIZEOF_CFPRREGSET, + &ppc32_linux_cfprregset); + return; + } + else if (PPC_IS_CKPTVMX_REGNUM (regno)) + { + gdb_assert (tdep->have_htm_altivec); + + const struct regset *cvmxregset = ppc_linux_cvmxregset (gdbarch); + store_regset (regcache, tid, regno, NT_PPC_TM_CVMX, + PPC_LINUX_SIZEOF_CVMXREGSET, + cvmxregset); + return; + } + else if (PPC_IS_CKPTVSX_REGNUM (regno)) + { + gdb_assert (tdep->have_htm_vsx); + + store_regset (regcache, tid, regno, NT_PPC_TM_CVSX, + PPC_LINUX_SIZEOF_CVSXREGSET, + &ppc32_linux_cvsxregset); + return; + } + else if (regno == PPC_CPPR_REGNUM) + { + gdb_assert (tdep->ppc_cppr_regnum != -1); + + store_regset (regcache, tid, regno, NT_PPC_TM_CPPR, + PPC_LINUX_SIZEOF_CPPRREGSET, + &ppc32_linux_cpprregset); + return; + } + else if (regno == PPC_CDSCR_REGNUM) + { + gdb_assert (tdep->ppc_cdscr_regnum != -1); + + store_regset (regcache, tid, regno, NT_PPC_TM_CDSCR, + PPC_LINUX_SIZEOF_CDSCRREGSET, + &ppc32_linux_cdscrregset); + return; + } + else if (regno == PPC_CTAR_REGNUM) + { + gdb_assert (tdep->ppc_ctar_regnum != -1); + + store_regset (regcache, tid, regno, NT_PPC_TM_CTAR, + PPC_LINUX_SIZEOF_CTARREGSET, + &ppc32_linux_ctarregset); + return; + } if (regaddr == -1) return; @@ -1401,6 +1593,84 @@ store_ppc_registers (const struct regcache *regcache, int tid) store_regset (regcache, tid, -1, NT_PPC_PMU, PPC_LINUX_SIZEOF_PMUREGSET, &ppc32_linux_pmuregset); + + if (tdep->have_htm_spr) + store_regset (regcache, tid, -1, NT_PPC_TM_SPR, + PPC_LINUX_SIZEOF_TM_SPRREGSET, + &ppc32_linux_tm_sprregset); + + /* Checkpointed registers are unavailable if the inferior is not + in a transaction, which would cause calls to store_regset to + fail. Only try to store them if they are all valid in the + regcache. */ + + if (tdep->have_htm_core) + { + const struct regset *cgprregset = ppc_linux_cgprregset (gdbarch); + if (ppc_linux_regset_available_p (regcache, cgprregset)) + store_regset (regcache, tid, -1, NT_PPC_TM_CGPR, + (tdep->wordsize == 4? + PPC32_LINUX_SIZEOF_CGPRREGSET + : PPC64_LINUX_SIZEOF_CGPRREGSET), + cgprregset); + } + + if (tdep->have_htm_fpu) + { + if (ppc_linux_regset_available_p (regcache, + &ppc32_linux_cfprregset)) + store_regset (regcache, tid, -1, NT_PPC_TM_CFPR, + PPC_LINUX_SIZEOF_CFPRREGSET, + &ppc32_linux_cfprregset); + } + + if (tdep->have_htm_altivec) + { + const struct regset *cvmxregset = + ppc_linux_cvmxregset (gdbarch); + + if (ppc_linux_regset_available_p (regcache, cvmxregset)) + store_regset (regcache, tid, -1, NT_PPC_TM_CVMX, + PPC_LINUX_SIZEOF_CVMXREGSET, + cvmxregset); + } + + if (tdep->have_htm_vsx) + { + if (ppc_linux_regset_available_p (regcache, + &ppc32_linux_cvsxregset)) + store_regset (regcache, tid, -1, NT_PPC_TM_CVSX, + PPC_LINUX_SIZEOF_CVSXREGSET, + &ppc32_linux_cvsxregset); + } + + if (tdep->ppc_cppr_regnum != -1) + { + if (ppc_linux_regset_available_p (regcache, + &ppc32_linux_cpprregset)) + store_regset (regcache, tid, -1, NT_PPC_TM_CPPR, + PPC_LINUX_SIZEOF_CPPRREGSET, + &ppc32_linux_cpprregset); + } + + if (tdep->ppc_cdscr_regnum != -1) + { + if (ppc_linux_regset_available_p (regcache, + &ppc32_linux_cdscrregset)) + store_regset (regcache, tid, -1, NT_PPC_TM_CDSCR, + PPC_LINUX_SIZEOF_CDSCRREGSET, + &ppc32_linux_cdscrregset); + } + + if (tdep->ppc_ctar_regnum != -1) + { + if (ppc_linux_regset_available_p (regcache, + &ppc32_linux_ctarregset)) + store_regset (regcache, tid, -1, NT_PPC_TM_CTAR, + PPC_LINUX_SIZEOF_CTARREGSET, + &ppc32_linux_ctarregset); + + } } /* Fetch the AT_HWCAP entry from the aux vector. */ @@ -2533,7 +2803,13 @@ ppc_linux_nat_target::read_description () && check_regset (tid, NT_PPC_TAR, PPC_LINUX_SIZEOF_TARREGSET) && check_regset (tid, NT_PPC_EBB, PPC_LINUX_SIZEOF_EBBREGSET) && check_regset (tid, NT_PPC_PMU, PPC_LINUX_SIZEOF_PMUREGSET)) - features.isa207 = true; + { + features.isa207 = true; + if ((hwcap2 & PPC_FEATURE2_HTM) + && check_regset (tid, NT_PPC_TM_SPR, + PPC_LINUX_SIZEOF_TM_SPRREGSET)) + features.htm = true; + } } return ppc_linux_match_description (features); diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c index 503357299e..1a073dbd1a 100644 --- a/gdb/ppc-linux-tdep.c +++ b/gdb/ppc-linux-tdep.c @@ -73,6 +73,7 @@ #include "features/rs6000/powerpc-isa205-vsx32l.c" #include "features/rs6000/powerpc-isa205-ppr-dscr-vsx32l.c" #include "features/rs6000/powerpc-isa207-vsx32l.c" +#include "features/rs6000/powerpc-isa207-htm-vsx32l.c" #include "features/rs6000/powerpc-64l.c" #include "features/rs6000/powerpc-altivec64l.c" #include "features/rs6000/powerpc-cell64l.c" @@ -82,6 +83,7 @@ #include "features/rs6000/powerpc-isa205-vsx64l.c" #include "features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c" #include "features/rs6000/powerpc-isa207-vsx64l.c" +#include "features/rs6000/powerpc-isa207-htm-vsx64l.c" #include "features/rs6000/powerpc-e500l.c" /* Shared library operations for PowerPC-Linux. */ @@ -525,6 +527,116 @@ static const struct regcache_map_entry ppc32_regmap_pmu[] = { 0 } }; +static const struct regcache_map_entry ppc32_regmap_tm_spr[] = + { + { 1, PPC_TFHAR_REGNUM, 8 }, + { 1, PPC_TEXASR_REGNUM, 8 }, + { 1, PPC_TFIAR_REGNUM, 8 }, + { 0 } + }; + +/* The layout of checkpointed CGPR regset is the same as a regular + struct pt_regs, but we skip all registers that are not actually + checkpointed by the processor (e.g. msr, nip). The 64-bit regset + is 48 * 8 bytes long. In some 64-bit kernels, the regset for a + 32-bit inferior has the same length, but all the registers are + squeezed in the first half (48 * 4 bytes). The pt_regs struct + calls the regular cr ccr, but we use ccr for "checkpointed + condition register". Note that CR (condition register) field 0 is + not checkpointed. The skipped regisers should not be touched when + writing the regset to the inferior (with PTRACE_SETREGSET). */ + +static const struct regcache_map_entry ppc32_regmap_cgpr[] = + { + { 32, PPC_CR0_REGNUM, 4 }, + { 3, REGCACHE_MAP_SKIP, 4 }, /* nip, msr, orig_gpr3. */ + { 1, PPC_CCTR_REGNUM, 4 }, + { 1, PPC_CLR_REGNUM, 4 }, + { 1, PPC_CXER_REGNUM, 4 }, + { 1, PPC_CCR_REGNUM, 4 }, + { 9, REGCACHE_MAP_SKIP, 4 }, /* All the rest. */ + { 0 } + }; + +static const struct regcache_map_entry ppc64_le_regmap_cgpr[] = + { + { 32, PPC_CR0_REGNUM, 8 }, + { 3, REGCACHE_MAP_SKIP, 8 }, + { 1, PPC_CCTR_REGNUM, 8 }, + { 1, PPC_CLR_REGNUM, 8 }, + { 1, PPC_CXER_REGNUM, 4 }, + { 1, REGCACHE_MAP_SKIP, 4 }, /* CXER padding. */ + { 1, PPC_CCR_REGNUM, 4 }, + { 1, REGCACHE_MAP_SKIP, 4}, /* CCR padding. */ + { 9, REGCACHE_MAP_SKIP, 8}, + { 0 } + }; + +static const struct regcache_map_entry ppc64_be_regmap_cgpr[] = + { + { 32, PPC_CR0_REGNUM, 8 }, + { 3, REGCACHE_MAP_SKIP, 8 }, + { 1, PPC_CCTR_REGNUM, 8 }, + { 1, PPC_CLR_REGNUM, 8 }, + { 1, REGCACHE_MAP_SKIP, 4}, /* CXER padding. */ + { 1, PPC_CXER_REGNUM, 4 }, + { 1, REGCACHE_MAP_SKIP, 4}, /* CCR padding. */ + { 1, PPC_CCR_REGNUM, 4 }, + { 9, REGCACHE_MAP_SKIP, 8}, + { 0 } + }; + +static const struct regcache_map_entry ppc32_regmap_cfpr[] = + { + { 32, PPC_CF0_REGNUM, 8 }, + { 1, PPC_CFPSCR_REGNUM, 8 }, + { 0 } + }; + +static const struct regcache_map_entry ppc32_le_regmap_cvmx[] = + { + { 32, PPC_CVR0_REGNUM, 16 }, + { 1, PPC_CVSCR_REGNUM, 4 }, + { 1, REGCACHE_MAP_SKIP, 12 }, + { 1, PPC_CVRSAVE_REGNUM, 4 }, + { 1, REGCACHE_MAP_SKIP, 12 }, + { 0 } + }; + +static const struct regcache_map_entry ppc32_be_regmap_cvmx[] = + { + { 32, PPC_CVR0_REGNUM, 16 }, + { 1, REGCACHE_MAP_SKIP, 12 }, + { 1, PPC_CVSCR_REGNUM, 4 }, + { 1, PPC_CVRSAVE_REGNUM, 4 }, + { 1, REGCACHE_MAP_SKIP, 12}, + { 0 } + }; + +static const struct regcache_map_entry ppc32_regmap_cvsx[] = + { + { 32, PPC_CVSR0_UPPER_REGNUM, 8 }, + { 0 } + }; + +static const struct regcache_map_entry ppc32_regmap_cppr[] = + { + { 1, PPC_CPPR_REGNUM, 8 }, + { 0 } + }; + +static const struct regcache_map_entry ppc32_regmap_cdscr[] = + { + { 1, PPC_CDSCR_REGNUM, 8 }, + { 0 } + }; + +static const struct regcache_map_entry ppc32_regmap_ctar[] = + { + { 1, PPC_CTAR_REGNUM, 8 }, + { 0 } + }; + static const struct regset ppc32_linux_gregset = { &ppc32_linux_reg_offsets, ppc_linux_supply_gregset, @@ -617,6 +729,76 @@ const struct regset ppc32_linux_pmuregset = { regcache_collect_regset }; +const struct regset ppc32_linux_tm_sprregset = { + ppc32_regmap_tm_spr, + regcache_supply_regset, + regcache_collect_regset +}; + +/* Some 64-bit kernels generate a checkpointed gpr note section with + 48*8 bytes for a 32-bit thread, of which only 48*4 are actually + used, so we set the variable size flag to accept this case. */ +static const struct regset ppc32_linux_cgprregset = { + ppc32_regmap_cgpr, + regcache_supply_regset, + regcache_collect_regset, + REGSET_VARIABLE_SIZE +}; + +static const struct regset ppc64_be_linux_cgprregset = { + ppc64_be_regmap_cgpr, + regcache_supply_regset, + regcache_collect_regset +}; + +static const struct regset ppc64_le_linux_cgprregset = { + ppc64_le_regmap_cgpr, + regcache_supply_regset, + regcache_collect_regset +}; + +const struct regset ppc32_linux_cfprregset = { + ppc32_regmap_cfpr, + regcache_supply_regset, + regcache_collect_regset +}; + +static const struct regset ppc32_le_linux_cvmxregset = { + ppc32_le_regmap_cvmx, + regcache_supply_regset, + regcache_collect_regset +}; + +static const struct regset ppc32_be_linux_cvmxregset = { + ppc32_be_regmap_cvmx, + regcache_supply_regset, + regcache_collect_regset +}; + +const struct regset ppc32_linux_cvsxregset = { + ppc32_regmap_cvsx, + regcache_supply_regset, + regcache_collect_regset +}; + +const struct regset ppc32_linux_cpprregset = { + ppc32_regmap_cppr, + regcache_supply_regset, + regcache_collect_regset +}; + +const struct regset ppc32_linux_cdscrregset = { + ppc32_regmap_cdscr, + regcache_supply_regset, + regcache_collect_regset +}; + +const struct regset ppc32_linux_ctarregset = { + ppc32_regmap_ctar, + regcache_supply_regset, + regcache_collect_regset +}; + const struct regset * ppc_linux_gregset (int wordsize) { @@ -644,6 +826,33 @@ ppc_linux_vsxregset (void) return &ppc32_linux_vsxregset; } +const struct regset * +ppc_linux_cgprregset (struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + if (tdep->wordsize == 4) + { + return &ppc32_linux_cgprregset; + } + else + { + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + return &ppc64_be_linux_cgprregset; + else + return &ppc64_le_linux_cgprregset; + } +} + +const struct regset * +ppc_linux_cvmxregset (struct gdbarch *gdbarch) +{ + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + return &ppc32_be_linux_cvmxregset; + else + return &ppc32_le_linux_cvmxregset; +} + /* Iterate over supported core file register note sections. */ static void @@ -708,6 +917,101 @@ ppc_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, PPC_LINUX_SIZEOF_PMUREGSET, &ppc32_linux_pmuregset, "Performance Monitor Registers", cb_data); + + if (tdep->have_htm_spr) + cb (".reg-ppc-tm-spr", PPC_LINUX_SIZEOF_TM_SPRREGSET, + PPC_LINUX_SIZEOF_TM_SPRREGSET, + &ppc32_linux_tm_sprregset, + "Hardware Transactional Memory Special Purpose Registers", + cb_data); + + /* Checkpointed registers can be unavailable, don't call back if + we are generating a core file. */ + + if (tdep->have_htm_core) + { + if (regcache == NULL || + REG_VALID == regcache->get_register_status (PPC_CR0_REGNUM)) + { + const struct regset *cgprregset = + ppc_linux_cgprregset (gdbarch); + + int cgpr_size = (tdep->wordsize == 4? + PPC32_LINUX_SIZEOF_CGPRREGSET + : PPC64_LINUX_SIZEOF_CGPRREGSET); + + cb (".reg-ppc-tm-cgpr", + cgpr_size, cgpr_size, + cgprregset, + "Checkpointed General Purpose Registers", cb_data); + } + } + + if (tdep->have_htm_fpu) + { + if (regcache == NULL || + REG_VALID == regcache->get_register_status (PPC_CF0_REGNUM)) + cb (".reg-ppc-tm-cfpr", PPC_LINUX_SIZEOF_CFPRREGSET, + PPC_LINUX_SIZEOF_CFPRREGSET, + &ppc32_linux_cfprregset, + "Checkpointed Floating Point Registers", cb_data); + } + + if (tdep->have_htm_altivec) + { + if (regcache == NULL || + REG_VALID == regcache->get_register_status (PPC_CVR0_REGNUM)) + { + const struct regset *cvmxregset = + ppc_linux_cvmxregset (gdbarch); + + cb (".reg-ppc-tm-cvmx", PPC_LINUX_SIZEOF_CVMXREGSET, + PPC_LINUX_SIZEOF_CVMXREGSET, + cvmxregset, + "Checkpointed Altivec (VMX) Registers", cb_data); + } + } + + if (tdep->have_htm_vsx) + { + if (regcache == NULL || + (REG_VALID + == regcache->get_register_status (PPC_CVSR0_UPPER_REGNUM))) + cb (".reg-ppc-tm-cvsx", PPC_LINUX_SIZEOF_CVSXREGSET, + PPC_LINUX_SIZEOF_CVSXREGSET, + &ppc32_linux_cvsxregset, + "Checkpointed VSX Registers", cb_data); + } + + if (tdep->ppc_cppr_regnum != -1) + { + if (regcache == NULL || + REG_VALID == regcache->get_register_status (PPC_CPPR_REGNUM)) + cb (".reg-ppc-tm-cppr", PPC_LINUX_SIZEOF_CPPRREGSET, + PPC_LINUX_SIZEOF_CPPRREGSET, + &ppc32_linux_cpprregset, + "Checkpointed Priority Program Register", cb_data); + } + + if (tdep->ppc_cdscr_regnum != -1) + { + if (regcache == NULL || + REG_VALID == regcache->get_register_status (PPC_CDSCR_REGNUM)) + cb (".reg-ppc-tm-cdscr", PPC_LINUX_SIZEOF_CDSCRREGSET, + PPC_LINUX_SIZEOF_CDSCRREGSET, + &ppc32_linux_cdscrregset, + "Checkpointed Data Stream Control Register", cb_data); + } + + if (tdep->ppc_ctar_regnum) + { + if ( regcache == NULL || + REG_VALID == regcache->get_register_status (PPC_CTAR_REGNUM)) + cb (".reg-ppc-tm-ctar", PPC_LINUX_SIZEOF_CTARREGSET, + PPC_LINUX_SIZEOF_CTARREGSET, + &ppc32_linux_ctarregset, + "Checkpointed Target Address Register", cb_data); + } } static void @@ -1124,6 +1428,7 @@ ppc_linux_core_read_description (struct gdbarch *gdbarch, asection *dscr = bfd_get_section_by_name (abfd, ".reg-ppc-dscr"); asection *tar = bfd_get_section_by_name (abfd, ".reg-ppc-tar"); asection *pmu = bfd_get_section_by_name (abfd, ".reg-ppc-pmu"); + asection *htmspr = bfd_get_section_by_name (abfd, ".reg-ppc-tm-spr"); if (! section) return NULL; @@ -1165,7 +1470,11 @@ ppc_linux_core_read_description (struct gdbarch *gdbarch, been unavailable when the core file was created. They will be in the tdep but will show as unavailable. */ if (tar && pmu) - features.isa207 = true; + { + features.isa207 = true; + if (htmspr) + features.htm = true; + } } return ppc_linux_match_description (features); @@ -2043,6 +2352,7 @@ _initialize_ppc_linux_tdep (void) initialize_tdesc_powerpc_isa205_vsx32l (); initialize_tdesc_powerpc_isa205_ppr_dscr_vsx32l (); initialize_tdesc_powerpc_isa207_vsx32l (); + initialize_tdesc_powerpc_isa207_htm_vsx32l (); initialize_tdesc_powerpc_64l (); initialize_tdesc_powerpc_altivec64l (); initialize_tdesc_powerpc_cell64l (); @@ -2052,5 +2362,6 @@ _initialize_ppc_linux_tdep (void) initialize_tdesc_powerpc_isa205_vsx64l (); initialize_tdesc_powerpc_isa205_ppr_dscr_vsx64l (); initialize_tdesc_powerpc_isa207_vsx64l (); + initialize_tdesc_powerpc_isa207_htm_vsx64l (); initialize_tdesc_powerpc_e500l (); } diff --git a/gdb/ppc-linux-tdep.h b/gdb/ppc-linux-tdep.h index cce1ddd1ef..5fb42c9525 100644 --- a/gdb/ppc-linux-tdep.h +++ b/gdb/ppc-linux-tdep.h @@ -32,6 +32,14 @@ const struct regset *ppc_linux_fpregset (void); const struct regset *ppc_linux_vrregset (struct gdbarch *gdbarch); const struct regset *ppc_linux_vsxregset (void); +/* Get the checkpointed GPR regset that matches the target wordsize + and byteorder of GDBARCH. */ +const struct regset *ppc_linux_cgprregset (struct gdbarch *gdbarch); + +/* Get the checkpointed vector regset that matches the target byte + order. */ +const struct regset* ppc_linux_cvmxregset (struct gdbarch *gdbarch); + /* Extra register number constants. The Linux kernel stores a "trap" code and the original value of r3 into special "registers"; these need to be saved and restored when performing an inferior @@ -50,5 +58,11 @@ extern const struct regset ppc32_linux_dscrregset; extern const struct regset ppc32_linux_tarregset; extern const struct regset ppc32_linux_ebbregset; extern const struct regset ppc32_linux_pmuregset; +extern const struct regset ppc32_linux_tm_sprregset; +extern const struct regset ppc32_linux_cfprregset; +extern const struct regset ppc32_linux_cvsxregset; +extern const struct regset ppc32_linux_cpprregset; +extern const struct regset ppc32_linux_cdscrregset; +extern const struct regset ppc32_linux_ctarregset; #endif /* PPC_LINUX_TDEP_H */ diff --git a/gdb/ppc-tdep.h b/gdb/ppc-tdep.h index cfe32c9e87..dbafe2232d 100644 --- a/gdb/ppc-tdep.h +++ b/gdb/ppc-tdep.h @@ -274,6 +274,21 @@ struct gdbarch_tdep int ppc_sdar_regnum; int ppc_sier_regnum; + /* Hardware Transactional Memory registers. */ + int have_htm_spr; + int have_htm_core; + int have_htm_fpu; + int have_htm_altivec; + int have_htm_vsx; + int ppc_cppr_regnum; + int ppc_cdscr_regnum; + int ppc_ctar_regnum; + + /* HTM pseudo registers. */ + int ppc_cdl0_regnum; + int ppc_cvsr0_regnum; + int ppc_cefpr0_regnum; + /* Offset to ABI specific location where link register is saved. */ int lr_frame_offset; @@ -343,6 +358,29 @@ enum { PPC_SDAR_REGNUM = 181, PPC_SIER_REGNUM = 182, + /* Hardware transactional memory registers. */ + PPC_TFHAR_REGNUM = 183, + PPC_TEXASR_REGNUM = 184, + PPC_TFIAR_REGNUM = 185, + + PPC_CR0_REGNUM = 186, + PPC_CCR_REGNUM = 218, + PPC_CXER_REGNUM = 219, + PPC_CLR_REGNUM = 220, + PPC_CCTR_REGNUM = 221, + + PPC_CF0_REGNUM = 222, + PPC_CFPSCR_REGNUM = 254, + + PPC_CVR0_REGNUM = 255, + PPC_CVSCR_REGNUM = 287, + PPC_CVRSAVE_REGNUM = 288, + + PPC_CVSR0_UPPER_REGNUM = 289, + + PPC_CPPR_REGNUM = 321, + PPC_CDSCR_REGNUM = 322, + PPC_CTAR_REGNUM = 323, PPC_NUM_REGS }; @@ -355,6 +393,21 @@ enum { #define PPC_IS_PMU_REGNUM(i) \ ((i) >= PPC_MMCR0_REGNUM && (i) <= PPC_SIER_REGNUM) +#define PPC_IS_TMSPR_REGNUM(i) \ + ((i) >= PPC_TFHAR_REGNUM && (i) <= PPC_TFIAR_REGNUM) + +#define PPC_IS_CKPTGP_REGNUM(i) \ + ((i) >= PPC_CR0_REGNUM && (i) <= PPC_CCTR_REGNUM) + +#define PPC_IS_CKPTFP_REGNUM(i) \ + ((i) >= PPC_CF0_REGNUM && (i) <= PPC_CFPSCR_REGNUM) + +#define PPC_IS_CKPTVMX_REGNUM(i) \ + ((i) >= PPC_CVR0_REGNUM && (i) <= PPC_CVRSAVE_REGNUM) + +#define PPC_IS_CKPTVSX_REGNUM(i) \ + ((i) >= PPC_CVSR0_UPPER_REGNUM && (i) < (PPC_CVSR0_UPPER_REGNUM + 32)) + /* An instruction to match. */ struct ppc_insn_pattern diff --git a/gdb/regformats/rs6000/powerpc-isa207-htm-vsx32l.dat b/gdb/regformats/rs6000/powerpc-isa207-htm-vsx32l.dat new file mode 100644 index 0000000000..c19416db86 --- /dev/null +++ b/gdb/regformats/rs6000/powerpc-isa207-htm-vsx32l.dat @@ -0,0 +1,296 @@ +# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: +# Generated from: rs6000/powerpc-isa207-htm-vsx32l.xml +name:powerpc_isa207_htm_vsx32l +xmltarget:powerpc-isa207-htm-vsx32l.xml +expedite:r1,pc +32:r0 +32:r1 +32:r2 +32:r3 +32:r4 +32:r5 +32:r6 +32:r7 +32:r8 +32:r9 +32:r10 +32:r11 +32:r12 +32:r13 +32:r14 +32:r15 +32:r16 +32:r17 +32:r18 +32:r19 +32:r20 +32:r21 +32:r22 +32:r23 +32:r24 +32:r25 +32:r26 +32:r27 +32:r28 +32:r29 +32:r30 +32:r31 +64:f0 +64:f1 +64:f2 +64:f3 +64:f4 +64:f5 +64:f6 +64:f7 +64:f8 +64:f9 +64:f10 +64:f11 +64:f12 +64:f13 +64:f14 +64:f15 +64:f16 +64:f17 +64:f18 +64:f19 +64:f20 +64:f21 +64:f22 +64:f23 +64:f24 +64:f25 +64:f26 +64:f27 +64:f28 +64:f29 +64:f30 +64:f31 +32:pc +32:msr +32:cr +32:lr +32:ctr +32:xer +64:fpscr +32:orig_r3 +32:trap +128:vr0 +128:vr1 +128:vr2 +128:vr3 +128:vr4 +128:vr5 +128:vr6 +128:vr7 +128:vr8 +128:vr9 +128:vr10 +128:vr11 +128:vr12 +128:vr13 +128:vr14 +128:vr15 +128:vr16 +128:vr17 +128:vr18 +128:vr19 +128:vr20 +128:vr21 +128:vr22 +128:vr23 +128:vr24 +128:vr25 +128:vr26 +128:vr27 +128:vr28 +128:vr29 +128:vr30 +128:vr31 +32:vscr +32:vrsave +64:vs0h +64:vs1h +64:vs2h +64:vs3h +64:vs4h +64:vs5h +64:vs6h +64:vs7h +64:vs8h +64:vs9h +64:vs10h +64:vs11h +64:vs12h +64:vs13h +64:vs14h +64:vs15h +64:vs16h +64:vs17h +64:vs18h +64:vs19h +64:vs20h +64:vs21h +64:vs22h +64:vs23h +64:vs24h +64:vs25h +64:vs26h +64:vs27h +64:vs28h +64:vs29h +64:vs30h +64:vs31h +64:ppr +64:dscr +64:tar +64:bescr +64:ebbhr +64:ebbrr +64:mmcr0 +64:mmcr2 +64:siar +64:sdar +64:sier +64:tfhar +64:texasr +64:tfiar +32:cr0 +32:cr1 +32:cr2 +32:cr3 +32:cr4 +32:cr5 +32:cr6 +32:cr7 +32:cr8 +32:cr9 +32:cr10 +32:cr11 +32:cr12 +32:cr13 +32:cr14 +32:cr15 +32:cr16 +32:cr17 +32:cr18 +32:cr19 +32:cr20 +32:cr21 +32:cr22 +32:cr23 +32:cr24 +32:cr25 +32:cr26 +32:cr27 +32:cr28 +32:cr29 +32:cr30 +32:cr31 +32:ccr +32:cxer +32:clr +32:cctr +64:cf0 +64:cf1 +64:cf2 +64:cf3 +64:cf4 +64:cf5 +64:cf6 +64:cf7 +64:cf8 +64:cf9 +64:cf10 +64:cf11 +64:cf12 +64:cf13 +64:cf14 +64:cf15 +64:cf16 +64:cf17 +64:cf18 +64:cf19 +64:cf20 +64:cf21 +64:cf22 +64:cf23 +64:cf24 +64:cf25 +64:cf26 +64:cf27 +64:cf28 +64:cf29 +64:cf30 +64:cf31 +64:cfpscr +128:cvr0 +128:cvr1 +128:cvr2 +128:cvr3 +128:cvr4 +128:cvr5 +128:cvr6 +128:cvr7 +128:cvr8 +128:cvr9 +128:cvr10 +128:cvr11 +128:cvr12 +128:cvr13 +128:cvr14 +128:cvr15 +128:cvr16 +128:cvr17 +128:cvr18 +128:cvr19 +128:cvr20 +128:cvr21 +128:cvr22 +128:cvr23 +128:cvr24 +128:cvr25 +128:cvr26 +128:cvr27 +128:cvr28 +128:cvr29 +128:cvr30 +128:cvr31 +32:cvscr +32:cvrsave +64:cvs0h +64:cvs1h +64:cvs2h +64:cvs3h +64:cvs4h +64:cvs5h +64:cvs6h +64:cvs7h +64:cvs8h +64:cvs9h +64:cvs10h +64:cvs11h +64:cvs12h +64:cvs13h +64:cvs14h +64:cvs15h +64:cvs16h +64:cvs17h +64:cvs18h +64:cvs19h +64:cvs20h +64:cvs21h +64:cvs22h +64:cvs23h +64:cvs24h +64:cvs25h +64:cvs26h +64:cvs27h +64:cvs28h +64:cvs29h +64:cvs30h +64:cvs31h +64:cppr +64:cdscr +64:ctar diff --git a/gdb/regformats/rs6000/powerpc-isa207-htm-vsx64l.dat b/gdb/regformats/rs6000/powerpc-isa207-htm-vsx64l.dat new file mode 100644 index 0000000000..38359959fd --- /dev/null +++ b/gdb/regformats/rs6000/powerpc-isa207-htm-vsx64l.dat @@ -0,0 +1,296 @@ +# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: +# Generated from: rs6000/powerpc-isa207-htm-vsx64l.xml +name:powerpc_isa207_htm_vsx64l +xmltarget:powerpc-isa207-htm-vsx64l.xml +expedite:r1,pc +64:r0 +64:r1 +64:r2 +64:r3 +64:r4 +64:r5 +64:r6 +64:r7 +64:r8 +64:r9 +64:r10 +64:r11 +64:r12 +64:r13 +64:r14 +64:r15 +64:r16 +64:r17 +64:r18 +64:r19 +64:r20 +64:r21 +64:r22 +64:r23 +64:r24 +64:r25 +64:r26 +64:r27 +64:r28 +64:r29 +64:r30 +64:r31 +64:f0 +64:f1 +64:f2 +64:f3 +64:f4 +64:f5 +64:f6 +64:f7 +64:f8 +64:f9 +64:f10 +64:f11 +64:f12 +64:f13 +64:f14 +64:f15 +64:f16 +64:f17 +64:f18 +64:f19 +64:f20 +64:f21 +64:f22 +64:f23 +64:f24 +64:f25 +64:f26 +64:f27 +64:f28 +64:f29 +64:f30 +64:f31 +64:pc +64:msr +32:cr +64:lr +64:ctr +32:xer +64:fpscr +64:orig_r3 +64:trap +128:vr0 +128:vr1 +128:vr2 +128:vr3 +128:vr4 +128:vr5 +128:vr6 +128:vr7 +128:vr8 +128:vr9 +128:vr10 +128:vr11 +128:vr12 +128:vr13 +128:vr14 +128:vr15 +128:vr16 +128:vr17 +128:vr18 +128:vr19 +128:vr20 +128:vr21 +128:vr22 +128:vr23 +128:vr24 +128:vr25 +128:vr26 +128:vr27 +128:vr28 +128:vr29 +128:vr30 +128:vr31 +32:vscr +32:vrsave +64:vs0h +64:vs1h +64:vs2h +64:vs3h +64:vs4h +64:vs5h +64:vs6h +64:vs7h +64:vs8h +64:vs9h +64:vs10h +64:vs11h +64:vs12h +64:vs13h +64:vs14h +64:vs15h +64:vs16h +64:vs17h +64:vs18h +64:vs19h +64:vs20h +64:vs21h +64:vs22h +64:vs23h +64:vs24h +64:vs25h +64:vs26h +64:vs27h +64:vs28h +64:vs29h +64:vs30h +64:vs31h +64:ppr +64:dscr +64:tar +64:bescr +64:ebbhr +64:ebbrr +64:mmcr0 +64:mmcr2 +64:siar +64:sdar +64:sier +64:tfhar +64:texasr +64:tfiar +64:cr0 +64:cr1 +64:cr2 +64:cr3 +64:cr4 +64:cr5 +64:cr6 +64:cr7 +64:cr8 +64:cr9 +64:cr10 +64:cr11 +64:cr12 +64:cr13 +64:cr14 +64:cr15 +64:cr16 +64:cr17 +64:cr18 +64:cr19 +64:cr20 +64:cr21 +64:cr22 +64:cr23 +64:cr24 +64:cr25 +64:cr26 +64:cr27 +64:cr28 +64:cr29 +64:cr30 +64:cr31 +32:ccr +32:cxer +64:clr +64:cctr +64:cf0 +64:cf1 +64:cf2 +64:cf3 +64:cf4 +64:cf5 +64:cf6 +64:cf7 +64:cf8 +64:cf9 +64:cf10 +64:cf11 +64:cf12 +64:cf13 +64:cf14 +64:cf15 +64:cf16 +64:cf17 +64:cf18 +64:cf19 +64:cf20 +64:cf21 +64:cf22 +64:cf23 +64:cf24 +64:cf25 +64:cf26 +64:cf27 +64:cf28 +64:cf29 +64:cf30 +64:cf31 +64:cfpscr +128:cvr0 +128:cvr1 +128:cvr2 +128:cvr3 +128:cvr4 +128:cvr5 +128:cvr6 +128:cvr7 +128:cvr8 +128:cvr9 +128:cvr10 +128:cvr11 +128:cvr12 +128:cvr13 +128:cvr14 +128:cvr15 +128:cvr16 +128:cvr17 +128:cvr18 +128:cvr19 +128:cvr20 +128:cvr21 +128:cvr22 +128:cvr23 +128:cvr24 +128:cvr25 +128:cvr26 +128:cvr27 +128:cvr28 +128:cvr29 +128:cvr30 +128:cvr31 +32:cvscr +32:cvrsave +64:cvs0h +64:cvs1h +64:cvs2h +64:cvs3h +64:cvs4h +64:cvs5h +64:cvs6h +64:cvs7h +64:cvs8h +64:cvs9h +64:cvs10h +64:cvs11h +64:cvs12h +64:cvs13h +64:cvs14h +64:cvs15h +64:cvs16h +64:cvs17h +64:cvs18h +64:cvs19h +64:cvs20h +64:cvs21h +64:cvs22h +64:cvs23h +64:cvs24h +64:cvs25h +64:cvs26h +64:cvs27h +64:cvs28h +64:cvs29h +64:cvs30h +64:cvs31h +64:cppr +64:cdscr +64:ctar diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 8920a18089..ec532ee236 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -105,6 +105,22 @@ && (regnum) >= (tdep)->ppc_efpr0_regnum \ && (regnum) < (tdep)->ppc_efpr0_regnum + ppc_num_efprs) +/* Determine if regnum is a checkpointed decimal float + pseudo-register. */ +#define IS_CDFP_PSEUDOREG(tdep, regnum) ((tdep)->ppc_cdl0_regnum >= 0 \ + && (regnum) >= (tdep)->ppc_cdl0_regnum \ + && (regnum) < (tdep)->ppc_cdl0_regnum + 16) + +/* Determine if regnum is a Checkpointed POWER7 VSX register. */ +#define IS_CVSX_PSEUDOREG(tdep, regnum) ((tdep)->ppc_cvsr0_regnum >= 0 \ + && (regnum) >= (tdep)->ppc_cvsr0_regnum \ + && (regnum) < (tdep)->ppc_cvsr0_regnum + ppc_num_vsrs) + +/* Determine if regnum is a Checkpointed POWER7 Extended FP register. */ +#define IS_CEFP_PSEUDOREG(tdep, regnum) ((tdep)->ppc_cefpr0_regnum >= 0 \ + && (regnum) >= (tdep)->ppc_cefpr0_regnum \ + && (regnum) < (tdep)->ppc_cefpr0_regnum + ppc_num_efprs) + /* Holds the current set of options to be passed to the disassembler. */ static char *powerpc_disassembler_options; @@ -2324,6 +2340,11 @@ rs6000_register_name (struct gdbarch *gdbarch, int regno) && regno < tdep->ppc_vsr0_upper_regnum + ppc_num_gprs) return ""; + /* Hide the upper halves of the cvs0~cvs31 registers. */ + if (PPC_CVSR0_UPPER_REGNUM <= regno + && regno < PPC_CVSR0_UPPER_REGNUM + ppc_num_gprs) + return ""; + /* Check if the SPE pseudo registers are available. */ if (IS_SPE_PSEUDOREG (tdep, regno)) { @@ -2378,6 +2399,48 @@ rs6000_register_name (struct gdbarch *gdbarch, int regno) return efpr_regnames[regno - tdep->ppc_efpr0_regnum]; } + /* Check if this is a Checkpointed DFP pseudo-register. */ + if (IS_CDFP_PSEUDOREG (tdep, regno)) + { + static const char *const cdfp128_regnames[] = { + "cdl0", "cdl1", "cdl2", "cdl3", + "cdl4", "cdl5", "cdl6", "cdl7", + "cdl8", "cdl9", "cdl10", "cdl11", + "cdl12", "cdl13", "cdl14", "cdl15" + }; + return cdfp128_regnames[regno - tdep->ppc_cdl0_regnum]; + } + + /* Check if this is a Checkpointed VSX pseudo-register. */ + if (IS_CVSX_PSEUDOREG (tdep, regno)) + { + static const char *const cvsx_regnames[] = { + "cvs0", "cvs1", "cvs2", "cvs3", "cvs4", "cvs5", "cvs6", "cvs7", + "cvs8", "cvs9", "cvs10", "cvs11", "cvs12", "cvs13", "cvs14", + "cvs15", "cvs16", "cvs17", "cvs18", "cvs19", "cvs20", "cvs21", + "cvs22", "cvs23", "cvs24", "cvs25", "cvs26", "cvs27", "cvs28", + "cvs29", "cvs30", "cvs31", "cvs32", "cvs33", "cvs34", "cvs35", + "cvs36", "cvs37", "cvs38", "cvs39", "cvs40", "cvs41", "cvs42", + "cvs43", "cvs44", "cvs45", "cvs46", "cvs47", "cvs48", "cvs49", + "cvs50", "cvs51", "cvs52", "cvs53", "cvs54", "cvs55", "cvs56", + "cvs57", "cvs58", "cvs59", "cvs60", "cvs61", "cvs62", "cvs63" + }; + return cvsx_regnames[regno - tdep->ppc_cvsr0_regnum]; + } + + /* Check if the this is a Checkpointed Extended FP pseudo-register. */ + if (IS_CEFP_PSEUDOREG (tdep, regno)) + { + static const char *const cefpr_regnames[] = { + "cf32", "cf33", "cf34", "cf35", "cf36", "cf37", "cf38", + "cf39", "cf40", "cf41", "cf42", "cf43", "cf44", "cf45", + "cf46", "cf47", "cf48", "cf49", "cf50", "cf51", + "cf52", "cf53", "cf54", "cf55", "cf56", "cf57", + "cf58", "cf59", "cf60", "cf61", "cf62", "cf63" + }; + return cefpr_regnames[regno - tdep->ppc_cefpr0_regnum]; + } + return tdesc_register_name (gdbarch, regno); } @@ -2389,24 +2452,26 @@ rs6000_pseudo_register_type (struct gdbarch *gdbarch, int regnum) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - /* These are the only pseudo-registers we support. */ - gdb_assert (IS_SPE_PSEUDOREG (tdep, regnum) - || IS_DFP_PSEUDOREG (tdep, regnum) - || IS_VSX_PSEUDOREG (tdep, regnum) - || IS_EFP_PSEUDOREG (tdep, regnum)); - /* These are the e500 pseudo-registers. */ if (IS_SPE_PSEUDOREG (tdep, regnum)) return rs6000_builtin_type_vec64 (gdbarch); - else if (IS_DFP_PSEUDOREG (tdep, regnum)) + else if (IS_DFP_PSEUDOREG (tdep, regnum) + || IS_CDFP_PSEUDOREG (tdep, regnum)) /* PPC decimal128 pseudo-registers. */ return builtin_type (gdbarch)->builtin_declong; - else if (IS_VSX_PSEUDOREG (tdep, regnum)) + else if (IS_VSX_PSEUDOREG (tdep, regnum) + || IS_CVSX_PSEUDOREG (tdep, regnum)) /* POWER7 VSX pseudo-registers. */ return rs6000_builtin_type_vec128 (gdbarch); - else + else if (IS_EFP_PSEUDOREG (tdep, regnum) + || IS_CEFP_PSEUDOREG (tdep, regnum)) /* POWER7 Extended FP pseudo-registers. */ return builtin_type (gdbarch)->builtin_double; + else + internal_error (__FILE__, __LINE__, + _("rs6000_pseudo_register_type: " + "called on unexpected register '%s' (%d)"), + gdbarch_register_name (gdbarch, regnum), regnum); } /* The register format for RS/6000 floating point registers is always @@ -2582,25 +2647,35 @@ dfp_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache, int reg_nr, gdb_byte *buffer) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - int reg_index = reg_nr - tdep->ppc_dl0_regnum; + int reg_index, fp0; enum register_status status; + if (IS_DFP_PSEUDOREG (tdep, reg_nr)) + { + reg_index = reg_nr - tdep->ppc_dl0_regnum; + fp0 = PPC_F0_REGNUM; + } + else + { + gdb_assert (IS_CDFP_PSEUDOREG (tdep, reg_nr)); + + reg_index = reg_nr - tdep->ppc_cdl0_regnum; + fp0 = PPC_CF0_REGNUM; + } + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) { /* Read two FP registers to form a whole dl register. */ - status = regcache->raw_read (tdep->ppc_fp0_regnum + - 2 * reg_index, buffer); + status = regcache->raw_read (fp0 + 2 * reg_index, buffer); if (status == REG_VALID) - status = regcache->raw_read (tdep->ppc_fp0_regnum + - 2 * reg_index + 1, buffer + 8); + status = regcache->raw_read (fp0 + 2 * reg_index + 1, + buffer + 8); } else { - status = regcache->raw_read (tdep->ppc_fp0_regnum + - 2 * reg_index + 1, buffer); + status = regcache->raw_read (fp0 + 2 * reg_index + 1, buffer); if (status == REG_VALID) - status = regcache->raw_read (tdep->ppc_fp0_regnum + - 2 * reg_index, buffer + 8); + status = regcache->raw_read (fp0 + 2 * reg_index, buffer + 8); } return status; @@ -2612,23 +2687,32 @@ dfp_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, int reg_nr, const gdb_byte *buffer) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - int reg_index = reg_nr - tdep->ppc_dl0_regnum; + int reg_index, fp0; + + if (IS_DFP_PSEUDOREG (tdep, reg_nr)) + { + reg_index = reg_nr - tdep->ppc_dl0_regnum; + fp0 = PPC_F0_REGNUM; + } + else + { + gdb_assert (IS_CDFP_PSEUDOREG (tdep, reg_nr)); + + reg_index = reg_nr - tdep->ppc_cdl0_regnum; + fp0 = PPC_CF0_REGNUM; + } if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) { /* Write each half of the dl register into a separate - FP register. */ - regcache->raw_write (tdep->ppc_fp0_regnum + - 2 * reg_index, buffer); - regcache->raw_write (tdep->ppc_fp0_regnum + - 2 * reg_index + 1, buffer + 8); + FP register. */ + regcache->raw_write (fp0 + 2 * reg_index, buffer); + regcache->raw_write (fp0 + 2 * reg_index + 1, buffer + 8); } else { - regcache->raw_write (tdep->ppc_fp0_regnum + - 2 * reg_index + 1, buffer); - regcache->raw_write (tdep->ppc_fp0_regnum + - 2 * reg_index, buffer + 8); + regcache->raw_write (fp0 + 2 * reg_index + 1, buffer); + regcache->raw_write (fp0 + 2 * reg_index, buffer + 8); } } @@ -2638,30 +2722,43 @@ vsx_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache, int reg_nr, gdb_byte *buffer) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - int reg_index = reg_nr - tdep->ppc_vsr0_regnum; + int reg_index, vr0, fp0, vsr0_upper; enum register_status status; + if (IS_VSX_PSEUDOREG (tdep, reg_nr)) + { + reg_index = reg_nr - tdep->ppc_vsr0_regnum; + vr0 = PPC_VR0_REGNUM; + fp0 = PPC_F0_REGNUM; + vsr0_upper = PPC_VSR0_UPPER_REGNUM; + } + else + { + gdb_assert (IS_CVSX_PSEUDOREG (tdep, reg_nr)); + + reg_index = reg_nr - tdep->ppc_cvsr0_regnum; + vr0 = PPC_CVR0_REGNUM; + fp0 = PPC_CF0_REGNUM; + vsr0_upper = PPC_CVSR0_UPPER_REGNUM; + } + /* Read the portion that overlaps the VMX registers. */ if (reg_index > 31) - status = regcache->raw_read (tdep->ppc_vr0_regnum + - reg_index - 32, buffer); + status = regcache->raw_read (vr0 + reg_index - 32, buffer); else /* Read the portion that overlaps the FPR registers. */ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) { - status = regcache->raw_read (tdep->ppc_fp0_regnum + - reg_index, buffer); + status = regcache->raw_read (fp0 + reg_index, buffer); if (status == REG_VALID) - status = regcache->raw_read (tdep->ppc_vsr0_upper_regnum + - reg_index, buffer + 8); + status = regcache->raw_read (vsr0_upper + reg_index, + buffer + 8); } else { - status = regcache->raw_read (tdep->ppc_fp0_regnum + - reg_index, buffer + 8); + status = regcache->raw_read (fp0 + reg_index, buffer + 8); if (status == REG_VALID) - status = regcache->raw_read (tdep->ppc_vsr0_upper_regnum + - reg_index, buffer); + status = regcache->raw_read (vsr0_upper + reg_index, buffer); } return status; @@ -2673,56 +2770,103 @@ vsx_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, int reg_nr, const gdb_byte *buffer) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - int reg_index = reg_nr - tdep->ppc_vsr0_regnum; + int reg_index, vr0, fp0, vsr0_upper; + + if (IS_VSX_PSEUDOREG (tdep, reg_nr)) + { + reg_index = reg_nr - tdep->ppc_vsr0_regnum; + vr0 = PPC_VR0_REGNUM; + fp0 = PPC_F0_REGNUM; + vsr0_upper = PPC_VSR0_UPPER_REGNUM; + } + else + { + gdb_assert (IS_CVSX_PSEUDOREG (tdep, reg_nr)); + + reg_index = reg_nr - tdep->ppc_cvsr0_regnum; + vr0 = PPC_CVR0_REGNUM; + fp0 = PPC_CF0_REGNUM; + vsr0_upper = PPC_CVSR0_UPPER_REGNUM; + } /* Write the portion that overlaps the VMX registers. */ if (reg_index > 31) - regcache->raw_write (tdep->ppc_vr0_regnum + - reg_index - 32, buffer); + regcache->raw_write (vr0 + reg_index - 32, buffer); else /* Write the portion that overlaps the FPR registers. */ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) { - regcache->raw_write (tdep->ppc_fp0_regnum + - reg_index, buffer); - regcache->raw_write (tdep->ppc_vsr0_upper_regnum + - reg_index, buffer + 8); + regcache->raw_write (fp0 + reg_index, buffer); + regcache->raw_write (vsr0_upper + reg_index, buffer + 8); } else { - regcache->raw_write (tdep->ppc_fp0_regnum + - reg_index, buffer + 8); - regcache->raw_write (tdep->ppc_vsr0_upper_regnum + - reg_index, buffer); + regcache->raw_write (fp0 + reg_index, buffer + 8); + regcache->raw_write (vsr0_upper + reg_index, buffer); } } /* Read method for POWER7 Extended FP pseudo-registers. */ static enum register_status -efpr_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache, +efp_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache, int reg_nr, gdb_byte *buffer) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - int reg_index = reg_nr - tdep->ppc_efpr0_regnum; + int reg_index, vr0; + + if (IS_EFP_PSEUDOREG (tdep, reg_nr)) + { + reg_index = reg_nr - tdep->ppc_efpr0_regnum; + vr0 = PPC_VR0_REGNUM; + } + else + { + gdb_assert (IS_CEFP_PSEUDOREG (tdep, reg_nr)); + + reg_index = reg_nr - tdep->ppc_cefpr0_regnum; + vr0 = PPC_CVR0_REGNUM; + } + int offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8; /* Read the portion that overlaps the VMX register. */ - return regcache->raw_read_part (tdep->ppc_vr0_regnum + reg_index, - offset, register_size (gdbarch, reg_nr), + return regcache->raw_read_part (vr0 + reg_index, offset, + register_size (gdbarch, reg_nr), buffer); } /* Write method for POWER7 Extended FP pseudo-registers. */ static void -efpr_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, +efp_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, int reg_nr, const gdb_byte *buffer) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - int reg_index = reg_nr - tdep->ppc_efpr0_regnum; + int reg_index, vr0; int offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8; + if (IS_EFP_PSEUDOREG (tdep, reg_nr)) + { + reg_index = reg_nr - tdep->ppc_efpr0_regnum; + vr0 = PPC_VR0_REGNUM; + } + else + { + gdb_assert (IS_CEFP_PSEUDOREG (tdep, reg_nr)); + + reg_index = reg_nr - tdep->ppc_cefpr0_regnum; + vr0 = PPC_CVR0_REGNUM; + + /* The call to raw_write_part fails silently if the initial read + of the read-update-write sequence returns an invalid status, + so we check this manually and throw an error if needed. */ + regcache->raw_update (vr0 + reg_index); + if (regcache->get_register_status (vr0 + reg_index) != REG_VALID) + error (_("Cannot write to the checkpointed EFP register, " + "the corresponding vector register is unavailable.")); + } + /* Write the portion that overlaps the VMX register. */ - regcache->raw_write_part (tdep->ppc_vr0_regnum + reg_index, offset, + regcache->raw_write_part (vr0 + reg_index, offset, register_size (gdbarch, reg_nr), buffer); } @@ -2738,12 +2882,15 @@ rs6000_pseudo_register_read (struct gdbarch *gdbarch, if (IS_SPE_PSEUDOREG (tdep, reg_nr)) return e500_pseudo_register_read (gdbarch, regcache, reg_nr, buffer); - else if (IS_DFP_PSEUDOREG (tdep, reg_nr)) + else if (IS_DFP_PSEUDOREG (tdep, reg_nr) + || IS_CDFP_PSEUDOREG (tdep, reg_nr)) return dfp_pseudo_register_read (gdbarch, regcache, reg_nr, buffer); - else if (IS_VSX_PSEUDOREG (tdep, reg_nr)) + else if (IS_VSX_PSEUDOREG (tdep, reg_nr) + || IS_CVSX_PSEUDOREG (tdep, reg_nr)) return vsx_pseudo_register_read (gdbarch, regcache, reg_nr, buffer); - else if (IS_EFP_PSEUDOREG (tdep, reg_nr)) - return efpr_pseudo_register_read (gdbarch, regcache, reg_nr, buffer); + else if (IS_EFP_PSEUDOREG (tdep, reg_nr) + || IS_CEFP_PSEUDOREG (tdep, reg_nr)) + return efp_pseudo_register_read (gdbarch, regcache, reg_nr, buffer); else internal_error (__FILE__, __LINE__, _("rs6000_pseudo_register_read: " @@ -2763,12 +2910,15 @@ rs6000_pseudo_register_write (struct gdbarch *gdbarch, if (IS_SPE_PSEUDOREG (tdep, reg_nr)) e500_pseudo_register_write (gdbarch, regcache, reg_nr, buffer); - else if (IS_DFP_PSEUDOREG (tdep, reg_nr)) + else if (IS_DFP_PSEUDOREG (tdep, reg_nr) + || IS_CDFP_PSEUDOREG (tdep, reg_nr)) dfp_pseudo_register_write (gdbarch, regcache, reg_nr, buffer); - else if (IS_VSX_PSEUDOREG (tdep, reg_nr)) + else if (IS_VSX_PSEUDOREG (tdep, reg_nr) + || IS_CVSX_PSEUDOREG (tdep, reg_nr)) vsx_pseudo_register_write (gdbarch, regcache, reg_nr, buffer); - else if (IS_EFP_PSEUDOREG (tdep, reg_nr)) - efpr_pseudo_register_write (gdbarch, regcache, reg_nr, buffer); + else if (IS_EFP_PSEUDOREG (tdep, reg_nr) + || IS_CEFP_PSEUDOREG (tdep, reg_nr)) + efp_pseudo_register_write (gdbarch, regcache, reg_nr, buffer); else internal_error (__FILE__, __LINE__, _("rs6000_pseudo_register_write: " @@ -2776,6 +2926,88 @@ rs6000_pseudo_register_write (struct gdbarch *gdbarch, gdbarch_register_name (gdbarch, reg_nr), reg_nr); } +static void +dfp_ax_pseudo_register_collect (struct gdbarch *gdbarch, + struct agent_expr *ax, int reg_nr) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + int reg_index, fp0; + + if (IS_DFP_PSEUDOREG (tdep, reg_nr)) + { + reg_index = reg_nr - tdep->ppc_dl0_regnum; + fp0 = PPC_F0_REGNUM; + } + else + { + gdb_assert (IS_CDFP_PSEUDOREG (tdep, reg_nr)); + + reg_index = reg_nr - tdep->ppc_cdl0_regnum; + fp0 = PPC_CF0_REGNUM; + } + + ax_reg_mask (ax, fp0 + 2 * reg_index); + ax_reg_mask (ax, fp0 + 2 * reg_index + 1); +} + +static void +vsx_ax_pseudo_register_collect (struct gdbarch *gdbarch, + struct agent_expr *ax, int reg_nr) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + int reg_index, vr0, fp0, vsr0_upper; + + if (IS_VSX_PSEUDOREG (tdep, reg_nr)) + { + reg_index = reg_nr - tdep->ppc_vsr0_regnum; + vr0 = PPC_VR0_REGNUM; + fp0 = PPC_F0_REGNUM; + vsr0_upper = PPC_VSR0_UPPER_REGNUM; + } + else + { + gdb_assert (IS_CVSX_PSEUDOREG (tdep, reg_nr)); + + reg_index = reg_nr - tdep->ppc_cvsr0_regnum; + vr0 = PPC_CVR0_REGNUM; + fp0 = PPC_CF0_REGNUM; + vsr0_upper = PPC_CVSR0_UPPER_REGNUM; + } + + if (reg_index > 31) + { + ax_reg_mask (ax, vr0 + reg_index - 32); + } + else + { + ax_reg_mask (ax, fp0 + reg_index); + ax_reg_mask (ax, vsr0_upper + reg_index); + } +} + +static void +efp_ax_pseudo_register_collect (struct gdbarch *gdbarch, + struct agent_expr *ax, int reg_nr) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + int reg_index, vr0; + + if (IS_EFP_PSEUDOREG (tdep, reg_nr)) + { + reg_index = reg_nr - tdep->ppc_efpr0_regnum; + vr0 = PPC_VR0_REGNUM; + } + else + { + gdb_assert (IS_CEFP_PSEUDOREG (tdep, reg_nr)); + + reg_index = reg_nr - tdep->ppc_cefpr0_regnum; + vr0 = PPC_CVR0_REGNUM; + } + + ax_reg_mask (ax, vr0 + reg_index); +} + static int rs6000_ax_pseudo_register_collect (struct gdbarch *gdbarch, struct agent_expr *ax, int reg_nr) @@ -2787,29 +3019,20 @@ rs6000_ax_pseudo_register_collect (struct gdbarch *gdbarch, ax_reg_mask (ax, tdep->ppc_gp0_regnum + reg_index); ax_reg_mask (ax, tdep->ppc_ev0_upper_regnum + reg_index); } - else if (IS_DFP_PSEUDOREG (tdep, reg_nr)) + else if (IS_DFP_PSEUDOREG (tdep, reg_nr) + || IS_CDFP_PSEUDOREG (tdep, reg_nr)) { - int reg_index = reg_nr - tdep->ppc_dl0_regnum; - ax_reg_mask (ax, tdep->ppc_fp0_regnum + 2 * reg_index); - ax_reg_mask (ax, tdep->ppc_fp0_regnum + 2 * reg_index + 1); + dfp_ax_pseudo_register_collect (gdbarch, ax, reg_nr); } - else if (IS_VSX_PSEUDOREG (tdep, reg_nr)) + else if (IS_VSX_PSEUDOREG (tdep, reg_nr) + || IS_CVSX_PSEUDOREG (tdep, reg_nr)) { - int reg_index = reg_nr - tdep->ppc_vsr0_regnum; - if (reg_index > 31) - { - ax_reg_mask (ax, tdep->ppc_vr0_regnum + reg_index - 32); - } - else - { - ax_reg_mask (ax, tdep->ppc_fp0_regnum + reg_index); - ax_reg_mask (ax, tdep->ppc_vsr0_upper_regnum + reg_index); - } + vsx_ax_pseudo_register_collect (gdbarch, ax, reg_nr); } - else if (IS_EFP_PSEUDOREG (tdep, reg_nr)) + else if (IS_EFP_PSEUDOREG (tdep, reg_nr) + || IS_CEFP_PSEUDOREG (tdep, reg_nr)) { - int reg_index = reg_nr - tdep->ppc_efpr0_regnum; - ax_reg_mask (ax, tdep->ppc_vr0_regnum + reg_index); + efp_ax_pseudo_register_collect (gdbarch, ax, reg_nr); } else internal_error (__FILE__, __LINE__, @@ -5819,7 +6042,10 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) enum powerpc_elf_abi elf_abi = POWERPC_ELF_AUTO; int have_fpu = 0, have_spe = 0, have_mq = 0, have_altivec = 0; int have_dfp = 0, have_vsx = 0, have_ppr = 0, have_dscr = 0; - int have_tar = 0, have_ebb = 0, have_pmu = 0; + int have_tar = 0, have_ebb = 0, have_pmu = 0, have_htm_spr = 0; + int have_htm_core = 0, have_htm_fpu = 0, have_htm_altivec = 0; + int have_htm_vsx = 0, have_htm_ppr = 0, have_htm_dscr = 0; + int have_htm_tar = 0; int tdesc_wordsize = -1; const struct target_desc *tdesc = info.target_desc; struct tdesc_arch_data *tdesc_data = NULL; @@ -6218,6 +6444,201 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) } else have_pmu = 0; + + /* Hardware Transactional Memory Registers. */ + feature = tdesc_find_feature (tdesc, + "org.gnu.gdb.power.htm.spr"); + if (feature != NULL) + { + static const char *const tm_spr_regs[] = { + "tfhar", "texasr", "tfiar" + }; + + valid_p = 1; + for (i = 0; i < ARRAY_SIZE (tm_spr_regs); i++) + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_TFHAR_REGNUM + i, + tm_spr_regs[i]); + if (!valid_p) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + + have_htm_spr = 1; + } + else + have_htm_spr = 0; + + feature = tdesc_find_feature (tdesc, + "org.gnu.gdb.power.htm.core"); + if (feature != NULL) + { + static const char *const cgprs[] = { + "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", + "cr8", "cr9", "cr10", "cr11", "cr12", "cr13", "cr14", + "cr15", "cr16", "cr17", "cr18", "cr19", "cr20", "cr21", + "cr22", "cr23", "cr24", "cr25", "cr26", "cr27", "cr28", + "cr29", "cr30", "cr31", "ccr", "cxer", "clr", "cctr" + }; + + valid_p = 1; + + for (i = 0; i < ARRAY_SIZE (cgprs); i++) + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_CR0_REGNUM + i, + cgprs[i]); + if (!valid_p) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + + have_htm_core = 1; + } + else + have_htm_core = 0; + + feature = tdesc_find_feature (tdesc, + "org.gnu.gdb.power.htm.fpu"); + if (feature != NULL) + { + valid_p = 1; + + static const char *const cfprs[] = { + "cf0", "cf1", "cf2", "cf3", "cf4", "cf5", "cf6", "cf7", + "cf8", "cf9", "cf10", "cf11", "cf12", "cf13", "cf14", "cf15", + "cf16", "cf17", "cf18", "cf19", "cf20", "cf21", "cf22", + "cf23", "cf24", "cf25", "cf26", "cf27", "cf28", "cf29", + "cf30", "cf31", "cfpscr" + }; + + for (i = 0; i < ARRAY_SIZE (cfprs); i++) + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_CF0_REGNUM + i, + cfprs[i]); + + if (!valid_p) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + have_htm_fpu = 1; + } + else + have_htm_fpu = 0; + + feature = tdesc_find_feature (tdesc, + "org.gnu.gdb.power.htm.altivec"); + if (feature != NULL) + { + valid_p = 1; + + static const char *const cvmx[] = { + "cvr0", "cvr1", "cvr2", "cvr3", "cvr4", "cvr5", "cvr6", + "cvr7", "cvr8", "cvr9", "cvr10", "cvr11", "cvr12", "cvr13", + "cvr14", "cvr15","cvr16", "cvr17", "cvr18", "cvr19", "cvr20", + "cvr21", "cvr22", "cvr23", "cvr24", "cvr25", "cvr26", + "cvr27", "cvr28", "cvr29", "cvr30", "cvr31", "cvscr", + "cvrsave" + }; + + for (i = 0; i < ARRAY_SIZE (cvmx); i++) + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_CVR0_REGNUM + i, + cvmx[i]); + + if (!valid_p) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + have_htm_altivec = 1; + } + else + have_htm_altivec = 0; + + feature = tdesc_find_feature (tdesc, + "org.gnu.gdb.power.htm.vsx"); + if (feature != NULL) + { + valid_p = 1; + + static const char *const cvsx[] = { + "cvs0h", "cvs1h", "cvs2h", "cvs3h", "cvs4h", "cvs5h", + "cvs6h", "cvs7h", "cvs8h", "cvs9h", "cvs10h", "cvs11h", + "cvs12h", "cvs13h", "cvs14h", "cvs15h", "cvs16h", "cvs17h", + "cvs18h", "cvs19h", "cvs20h", "cvs21h", "cvs22h", "cvs23h", + "cvs24h", "cvs25h", "cvs26h", "cvs27h", "cvs28h", "cvs29h", + "cvs30h", "cvs31h" + }; + + for (i = 0; i < ARRAY_SIZE (cvsx); i++) + valid_p &= tdesc_numbered_register (feature, tdesc_data, + (PPC_CVSR0_UPPER_REGNUM + + i), + cvsx[i]); + + if (!valid_p || !have_htm_fpu || !have_htm_altivec) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + have_htm_vsx = 1; + } + else + have_htm_vsx = 0; + + feature = tdesc_find_feature (tdesc, + "org.gnu.gdb.power.htm.ppr"); + if (feature != NULL) + { + valid_p = tdesc_numbered_register (feature, tdesc_data, + PPC_CPPR_REGNUM, "cppr"); + + if (!valid_p) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + have_htm_ppr = 1; + } + else + have_htm_ppr = 0; + + feature = tdesc_find_feature (tdesc, + "org.gnu.gdb.power.htm.dscr"); + if (feature != NULL) + { + valid_p = tdesc_numbered_register (feature, tdesc_data, + PPC_CDSCR_REGNUM, "cdscr"); + + if (!valid_p) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + have_htm_dscr = 1; + } + else + have_htm_dscr = 0; + + feature = tdesc_find_feature (tdesc, + "org.gnu.gdb.power.htm.tar"); + if (feature != NULL) + { + valid_p = tdesc_numbered_register (feature, tdesc_data, + PPC_CTAR_REGNUM, "ctar"); + + if (!valid_p) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + have_htm_tar = 1; + } + else + have_htm_tar = 0; } /* If we have a 64-bit binary on a 32-bit target, complain. Also @@ -6430,6 +6851,15 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->ppc_sdar_regnum = have_pmu ? PPC_SDAR_REGNUM : -1; tdep->ppc_sier_regnum = have_pmu ? PPC_SIER_REGNUM : -1; + tdep->have_htm_spr = have_htm_spr; + tdep->have_htm_core = have_htm_core; + tdep->have_htm_fpu = have_htm_fpu; + tdep->have_htm_altivec = have_htm_altivec; + tdep->have_htm_vsx = have_htm_vsx; + tdep->ppc_cppr_regnum = have_htm_ppr ? PPC_CPPR_REGNUM : -1; + tdep->ppc_cdscr_regnum = have_htm_dscr ? PPC_CDSCR_REGNUM : -1; + tdep->ppc_ctar_regnum = have_htm_tar ? PPC_CTAR_REGNUM : -1; + set_gdbarch_pc_regnum (gdbarch, PPC_PC_REGNUM); set_gdbarch_sp_regnum (gdbarch, PPC_R0_REGNUM + 1); set_gdbarch_fp0_regnum (gdbarch, tdep->ppc_fp0_regnum); @@ -6451,7 +6881,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) else tdep->lr_frame_offset = 4; - if (have_spe || have_dfp || have_vsx) + if (have_spe || have_dfp || have_vsx || have_htm_fpu || have_htm_vsx) { set_gdbarch_pseudo_register_read (gdbarch, rs6000_pseudo_register_read); set_gdbarch_pseudo_register_write (gdbarch, @@ -6473,6 +6903,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) if (have_vsx) /* Include both VSX and Extended FP registers. */ num_pseudoregs += 96; + if (have_htm_fpu) + num_pseudoregs += 16; + /* Include both checkpointed VSX and EFP registers. */ + if (have_htm_vsx) + num_pseudoregs += 64 + 32; set_gdbarch_num_pseudo_regs (gdbarch, num_pseudoregs); @@ -6588,6 +7023,9 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->ppc_dl0_regnum = -1; tdep->ppc_vsr0_regnum = -1; tdep->ppc_efpr0_regnum = -1; + tdep->ppc_cdl0_regnum = -1; + tdep->ppc_cvsr0_regnum = -1; + tdep->ppc_cefpr0_regnum = -1; cur_reg = gdbarch_num_regs (gdbarch); @@ -6608,6 +7046,18 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->ppc_efpr0_regnum = cur_reg; cur_reg += 32; } + if (have_htm_fpu) + { + tdep->ppc_cdl0_regnum = cur_reg; + cur_reg += 16; + } + if (have_htm_vsx) + { + tdep->ppc_cvsr0_regnum = cur_reg; + cur_reg += 64; + tdep->ppc_cefpr0_regnum = cur_reg; + cur_reg += 32; + } gdb_assert (gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch) == cur_reg); diff --git a/gdb/testsuite/gdb.arch/powerpc-htm-regs.c b/gdb/testsuite/gdb.arch/powerpc-htm-regs.c new file mode 100644 index 0000000000..8c062ced31 --- /dev/null +++ b/gdb/testsuite/gdb.arch/powerpc-htm-regs.c @@ -0,0 +1,39 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright (C) 2018 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +int main (void) +{ + /* Touch DSCR. Some kernels won't schedule the thread with a DSCR + altered by ptrace unless the register was used at some point. */ + unsigned long dscr = 0x0; + + /* This is the non-privileged SPR number to access DSCR, + available since isa 207. */ + asm volatile ("mtspr 3,%0" : : "r" (dscr)); + + asm volatile ("tbegin."); // first marker + asm volatile goto ("bc 12,2,%l[end]" + : + : + : + : end); + asm volatile ("tabort. 0"); +end: + asm volatile ("nop"); // second marker + + return 0; +} diff --git a/gdb/testsuite/gdb.arch/powerpc-htm-regs.exp b/gdb/testsuite/gdb.arch/powerpc-htm-regs.exp new file mode 100644 index 0000000000..9291f234a3 --- /dev/null +++ b/gdb/testsuite/gdb.arch/powerpc-htm-regs.exp @@ -0,0 +1,320 @@ +# Copyright (C) 2018 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# This file is part of the gdb testsuite. + +# Test access to HTM (hardware transactional memory) registers. + +if {![istarget "powerpc*-*-linux*"]} then { + verbose "Skipping PowerPC test for HTM registers." + return +} + +standard_testfile .c .gen.c + +# First check if our processor and kernel support access to +# the registers we need and to the HTM facility. + +proc check_register_access { regname } { + global gdb_prompt + + set test "$regname register access" + gdb_test_multiple "info reg $regname" "$test" { + -re "Invalid register.*\r\n$gdb_prompt $" { + unsupported "$test" + return 0 + } + -re "\r\n$regname.*\r\n$gdb_prompt $" { + pass "$test" + return 1 + } + } + return 0 +} + +proc check_htm_support {} { + global gdb_prompt + set test "htm support" + + gdb_test_multiple "stepi" "$test" { + -re "Illegal instruction.*\r\n$gdb_prompt $" { + unsupported $test + return 0 + } + -re "nop.*\r\n$gdb_prompt $" + { + pass $test + return 1 + } + } + return 0; +} + +with_test_prefix "check htm support" { + set gen_src [standard_output_file $srcfile2] + + gdb_produce_source $gen_src { + int main () { + asm volatile ("tbegin."); // marker + asm volatile ("nop"); + return 0; + } + } + + if {[build_executable "compile" $binfile $gen_src {debug}] == -1} { + return + } + + clean_restart $binfile + + # Displaced-stepping a tbegin. causes problems, + # so we make the breakpoint temporary. + gdb_breakpoint [gdb_get_line_number "marker" "$gen_src"] temporary + + gdb_run_cmd + + # Wait for the prompt. + if {[gdb_test "" "Temporary breakpoint.*"] != 0 } { + return + } + + # Make sure that we stopped at the right place (just before tbegin. is + # executed). + if { [gdb_test "x/i \$pc" "=> $hex.*:.*tbegin\\..*" "disassemble tbegin"] != 0} { + return + } + + if {![check_register_access "vs0"]} { + return + } + + if {![check_register_access "texasr"]} { + return + } + + if {![check_register_access "dscr"]} { + return + } + + if {![check_register_access "ppr"]} { + return + } + + if {![check_register_access "tar"]} { + return + } + + if {![check_htm_support]} { + return + } +} + +# Now do the actual test. +if {[build_executable "compile" $binfile $srcfile {debug}] == -1} { + return +} + +clean_restart $binfile + +gdb_breakpoint [gdb_get_line_number "first marker"] temporary + +gdb_run_cmd + +# Wait for the prompt. +gdb_test "" "Temporary breakpoint.*" + +if {[gdb_test "x/i \$pc" "=> $hex.*:.*tbegin\\..*" "disassemble tbegin"] != 0} { + return +} + +# Now we write non-zero values to some registers, then read the values +# of various registers, then stepi to start the transaction. The +# checkpointed register state should correspond to the values we read. + +# Write to the GPRs +for {set i 0} {$i < 32} {incr i 1} { + gdb_test_no_output "set \$r$i = $i" +} + +gdb_test_no_output "set \$xer = 0xc0000000" + +# FPRs +gdb_test_no_output "set \$f0 = 0.5" +for {set i 1} {$i < 32} {incr i 1} { + gdb_test_no_output "set \$f$i = \$f[expr $i - 1] + 1.0" +} + +gdb_test_no_output "set \$fpscr = 0x84005000" + +# VRs +for {set i 0} {$i < 32} {incr i 1} { + for {set j 0} {$j < 4} {incr j 1} { + gdb_test_no_output "set \$vr$i.v4_int32\[$j\] = $i" + } +} + +gdb_test_no_output "set \$dscr = 0x2" +gdb_test_no_output "set \$tar = &main" "set tar" + +# Get the pre-transactional value of the registers. +for {set i 0} {$i < 32} {incr i 1} { + set "r$i" [get_hexadecimal_valueof "\$r$i" "default0"] +} + +set cr [get_hexadecimal_valueof "\$cr" "default0"] +set xer [get_hexadecimal_valueof "\$xer" "default0"] +set lr [get_hexadecimal_valueof "\$lr" "default0"] +set ctr [get_hexadecimal_valueof "\$ctr" "default0"] + +for {set i 0} {$i < 32} {incr i 1} { + set "f$i" [get_valueof "" "\$f$i" "default0"] +} + +set fpscr [get_hexadecimal_valueof "\$fpscr" "default0"] + +for {set i 0} {$i < 32} {incr i 1} { + set "vr$i" [get_hexadecimal_valueof "\$vr$i.uint128" "default0"] +} + +set vscr [get_hexadecimal_valueof "\$vscr" "default0"] +set vrsave [get_hexadecimal_valueof "\$vrsave" "default0"] + +for {set i 0} {$i < 64} {incr i 1} { + set "vs$i" [get_hexadecimal_valueof "\$vs$i.uint128" "default0"] +} + +set dscr [get_hexadecimal_valueof "\$dscr" "default0"] +set ppr [get_hexadecimal_valueof "\$ppr" "default0"] +set tar [get_hexadecimal_valueof "\$tar" "default0"] + +gdb_test "stepi" "asm.*bc.*" + +proc test_register_match {reg_name reg_var_name hex} { + set test "$reg_name matches $reg_var_name" + + # In some infrequent cases CXER doesn't match the + # pre-transactional XER, possibly due to a linux kernel bug. + set should_xfail 0 + if [istarget "powerpc*-*-linux*" && reg_name == "cxer"] { + set should_xfail 1 + } + + upvar $reg_var_name expected_val + + if {$hex} { + set actual_val [get_hexadecimal_valueof "\$$reg_name" "default1"] + } else { + set actual_val [get_valueof "" "\$$reg_name" "default1"] + } + + if { "$expected_val" == "$actual_val" } { + pass $test + } else { + if {$should_xfail} { + xfail $test + } else { + fail $test + } + } +} + +for {set i 0} {$i < 32} {incr i 1} { + test_register_match "cr$i" "r$i" 1 +} + +test_register_match "ccr" "cr" 1 +test_register_match "cxer" "xer" 1 +test_register_match "clr" "lr" 1 +test_register_match "cctr" "ctr" 1 + +for {set i 0} {$i < 32} {incr i 1} { + test_register_match "cf$i" "f$i" 0 +} + +test_register_match "cfpscr" "fpscr" 1 + +for {set i 0} {$i < 32} {incr i 1} { + test_register_match "cvr$i.uint128" "vr$i" 1 +} + +test_register_match "cvscr" "vscr" 1 +test_register_match "cvrsave" "vrsave" 1 + +for {set i 0} {$i < 64} {incr i 1} { + test_register_match "cvs$i.uint128" "vs$i" 1 +} + +test_register_match "cdscr" "dscr" 1 +test_register_match "cppr" "ppr" 1 +test_register_match "ctar" "tar" 1 + +# Support for writing to the checkpointed registers is not +# currently available in the gdbserver stub. +if [target_is_gdbserver] { + unsupported "write to checkpointed registers" + return +} + +# Now write different values to some of the checkpointed registers and +# check that the transaction abort reverts the register to these +# values. +for {set i 0} {$i < 32} {incr i 1} { + gdb_test_no_output "set \$cr$i = $i + 0xC00" +} + +gdb_test_no_output "set \$cf0 = 0.25" +for {set i 1} {$i < 32} {incr i 1} { + gdb_test_no_output "set \$cf$i = \$cf[expr $i - 1] + 1.0" +} + +for {set i 0} {$i < 32} {incr i 1} { + for {set j 0} {$j < 4} {incr j 1} { + gdb_test_no_output "set \$cvr$i.v4_int32\[$j\] = $i + 0xF00" + } +} + +# Read back the values. +with_test_prefix "after write" { + for {set i 0} {$i < 32} {incr i 1} { + set "cr$i" [get_hexadecimal_valueof "\$cr$i" "default0"] + } + + for {set i 0} {$i < 32} {incr i 1} { + set "cf$i" [get_valueof "" "\$cf$i" "default0"] + } + + for {set i 0} {$i < 64} {incr i 1} { + set "cvs$i" [get_hexadecimal_valueof "\$cvs$i.uint128" "default0"] + } +} + +gdb_breakpoint [gdb_get_line_number "second marker"] + +gdb_test "continue" + +with_test_prefix "after transaction failure" { + for {set i 0} {$i < 32} {incr i 1} { + test_register_match "r$i" "cr$i" 1 + } + + for {set i 0} {$i < 32} {incr i 1} { + test_register_match "f$i" "cf$i" 0 + } + + for {set i 0} {$i < 64} {incr i 1} { + test_register_match "vs$i.uint128" "cvs$i" 1 + } +} +