[13/17,PowerPC] Add support for HTM registers

Message ID 20180713135226.2321-14-pedromfc@linux.ibm.com
State New, archived
Headers

Commit Message

Pedro Franco de Carvalho July 13, 2018, 1:52 p.m. UTC
  From: Edjunior Barbosa Machado <emachado@linux.vnet.ibm.com>

This patch adds support for Hardware Transactional Memory registers
for the powerpc linux native and core file targets.

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.

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.

Like for the previous patches, configure.srv is updated here to avoid
breaking the build at this patch.

gdb/ChangeLog:
YYYY-MM-DD  Edjunior Barbosa Machado  <emachado@linux.vnet.ibm.com>
	    Pedro Franco de Carvalho  <pedromfc@linux.ibm.com>

	* 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) <htm>: 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.xml: New file.
	* features/rs6000/power64-htm.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.
	(ppc_linux_regset_available_p): New function.
	(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.
	(ppc_linux_collect_vrregset): Zero pad if regno is the
	checkpointed VSCR or the checkpointed VRSAVE.
	(ppc_linux_collect_and_clear_cgprregset): New function.
	(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_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)
	(ppc32_linux_tm_sprregset, ppc32_linux_cfprregset)
	(ppc32_linux_cvsxregset, ppc32_linux_cpprregset)
	(ppc32_linux_cdscrregset, ppc32_linux_ctarregset)
	(ppc_linux_cvmxregset): Declare.
	* ppc-tdep.h (struct gdbarch_tdep) <have_htm, ppc_cvsr0_regnum>:
	New fields.
	(enum) <PPC_TFHAR_REGNUM, PPC_TEXASR_REGNUM, PPC_TFIAR_REGNUM>:
	New enum fields.
	<PPC_CR0_REGNUM, PPC_CCR_REGNUM, PPC_CXER_REGNUM>: Likewise.
	<PPC_CLR_REGNUM, PPC_CCTR_REGNUM, PPC_CF0_REGNUM>: Likewise.
	<PPC_CFPSCR_REGNUM, PPC_CVR0_REGNUM, PPC_CVSCR_REGNUM>: Likewise.
	<PPC_CVRSAVE_REGNUM, PPC_CVS0H_REGNUM, PPC_CPPR_REGNUM>: Likewise.
	<PPC_CDSCR_REGNUM, PPC_CTAR_REGNUM>: 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_CVSX_PSEUDOREG): Define.
	(rs6000_register_name): Hide the upper halves of checkpointed VSX
	registers. Return names for the full checkpointed VSX registers.
	(rs6000_pseudo_register_type): Include checkpointed VSX registers
	in the assert expression and return rs6000_builtin_type_vec128 for
	them.
	(rs6000_pseudo_register_reggroup_p): Include checkpointed VSX
	registers in the assert expression.
	(cvsx_pseudo_register_read, cvsx_pseudo_register_write): New
	functions.
	(rs6000_pseudo_register_read, rs6000_pseudo_register_write)
	(rs6000_ax_pseudo_register_collect): Handle checkpointed VSX
	registers.
	(rs6000_gdbarch_init): Look for and validate the htm
	feature. Include checkpointed VSX pseudo-registers.

gdb/gdbserver/ChangeLog:
YYYY-MM-DD  Pedro Franco de Carvalho  <pedromfc@linux.ibm.com>

	* 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.xml, rs6000/power64-htm.xml,
	rs6000/powerpc-isa207-htm-vsx32l.xml, and
	rs6000/powerpc-isa207-htm-vsx64l.xml to srv_xmlfiles.
---
 gdb/arch/ppc-linux-common.c                        |   6 +-
 gdb/arch/ppc-linux-common.h                        |  11 +
 gdb/arch/ppc-linux-tdesc.h                         |   2 +
 gdb/features/Makefile                              |   4 +
 gdb/features/rs6000/power-htm.xml                  | 174 ++++++++++
 gdb/features/rs6000/power64-htm.xml                | 174 ++++++++++
 gdb/features/rs6000/powerpc-isa207-htm-vsx32l.c    | 370 +++++++++++++++++++++
 gdb/features/rs6000/powerpc-isa207-htm-vsx32l.xml  |  20 ++
 gdb/features/rs6000/powerpc-isa207-htm-vsx64l.c    | 370 +++++++++++++++++++++
 gdb/features/rs6000/powerpc-isa207-htm-vsx64l.xml  |  20 ++
 gdb/gdbserver/configure.srv                        |   8 +-
 gdb/nat/ppc-linux.h                                |  43 +++
 gdb/ppc-linux-nat.c                                | 304 ++++++++++++++++-
 gdb/ppc-linux-tdep.c                               | 292 +++++++++++++++-
 gdb/ppc-linux-tdep.h                               |  22 ++
 gdb/ppc-tdep.h                                     |  44 +++
 .../rs6000/powerpc-isa207-htm-vsx32l.dat           | 288 ++++++++++++++++
 .../rs6000/powerpc-isa207-htm-vsx64l.dat           | 288 ++++++++++++++++
 gdb/rs6000-tdep.c                                  | 239 ++++++++++++-
 19 files changed, 2661 insertions(+), 18 deletions(-)
 create mode 100644 gdb/features/rs6000/power-htm.xml
 create mode 100644 gdb/features/rs6000/power64-htm.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
  

Patch

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 f0e4a4221f..71e2d5d173 100644
--- a/gdb/arch/ppc-linux-common.h
+++ b/gdb/arch/ppc-linux-common.h
@@ -33,6 +33,15 @@  struct target_desc;
 #define PPC_LINUX_SIZEOF_PPRREGSET 8
 #define PPC_LINUX_SIZEOF_DSCRREGSET 8
 #define PPC_LINUX_SIZEOF_TARREGSET 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);
@@ -46,6 +55,7 @@  struct ppc_linux_features
   bool isa205;
   bool ppr_dscr;
   bool isa207;
+  bool htm;
   bool cell;
 };
 
@@ -58,6 +68,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/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.xml b/gdb/features/rs6000/power-htm.xml
new file mode 100644
index 0000000000..5dab31b82f
--- /dev/null
+++ b/gdb/features/rs6000/power-htm.xml
@@ -0,0 +1,174 @@ 
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!-- POWER8 Hardware Transactional Memory Registers.  -->
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.power.htm">
+  <reg name="tfhar" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="texasr" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="tfiar" bitsize="64" type="uint64" save-restore="no"/>
+
+  <reg name="cr0" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr1" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr2" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr3" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr4" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr5" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr6" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr7" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr8" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr9" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr10" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr11" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr12" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr13" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr14" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr15" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr16" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr17" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr18" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr19" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr20" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr21" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr22" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr23" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr24" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr25" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr26" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr27" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr28" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr29" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr30" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cr31" bitsize="32" type="uint32" save-restore="no"/>
+
+  <reg name="ccr" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cxer" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="clr" bitsize="32" type="code_ptr" save-restore="no"/>
+  <reg name="cctr" bitsize="32" type="uint32" save-restore="no"/>
+
+  <reg name="cf0" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf1" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf2" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf3" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf4" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf5" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf6" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf7" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf8" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf9" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf10" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf11" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf12" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf13" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf14" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf15" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf16" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf17" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf18" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf19" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf20" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf21" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf22" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf23" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf24" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf25" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf26" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf27" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf28" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf29" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf30" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf31" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cfpscr" bitsize="64" type="uint64" group="float"
+       save-restore="no"/>
+
+  <!-- HTM Checkpointed Altivec (VMX) registers -->
+  <vector id="v4f" type="ieee_single" count="4"/>
+  <vector id="v4i32" type="int32" count="4"/>
+  <vector id="v8i16" type="int16" count="8"/>
+  <vector id="v16i8" type="int8" count="16"/>
+  <union id="vec128">
+    <field name="uint128" type="uint128"/>
+    <field name="v4_float" type="v4f"/>
+    <field name="v4_int32" type="v4i32"/>
+    <field name="v8_int16" type="v8i16"/>
+    <field name="v16_int8" type="v16i8"/>
+  </union>
+
+  <reg name="cvr0" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr1" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr2" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr3" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr4" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr5" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr6" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr7" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr8" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr9" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr10" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr11" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr12" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr13" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr14" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr15" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr16" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr17" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr18" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr19" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr20" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr21" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr22" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr23" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr24" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr25" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr26" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr27" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr28" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr29" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr30" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr31" bitsize="128" type="vec128" save-restore="no"/>
+
+  <reg name="cvscr" bitsize="32" save-restore="no"/>
+  <reg name="cvrsave" bitsize="32" save-restore="no"/>
+
+  <!-- HTM Checkpointed VSX registers -->
+  <reg name="cvs0h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs1h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs2h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs3h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs4h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs5h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs6h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs7h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs8h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs9h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs10h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs11h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs12h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs13h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs14h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs15h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs16h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs17h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs18h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs19h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs20h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs21h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs22h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs23h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs24h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs25h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs26h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs27h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs28h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs29h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs30h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs31h" bitsize="64" type="uint64" save-restore="no"/>
+
+  <reg name="cppr" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cdscr" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="ctar" bitsize="64" type="uint64" save-restore="no"/>
+</feature>
diff --git a/gdb/features/rs6000/power64-htm.xml b/gdb/features/rs6000/power64-htm.xml
new file mode 100644
index 0000000000..6900418bd7
--- /dev/null
+++ b/gdb/features/rs6000/power64-htm.xml
@@ -0,0 +1,174 @@ 
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!-- POWER8 Hardware Transactional Memory Registers.  -->
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.power.htm">
+  <reg name="tfhar" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="texasr" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="tfiar" bitsize="64" type="uint64" save-restore="no"/>
+
+  <reg name="cr0" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr1" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr2" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr3" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr4" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr5" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr6" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr7" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr8" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr9" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr10" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr11" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr12" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr13" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr14" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr15" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr16" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr17" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr18" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr19" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr20" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr21" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr22" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr23" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr24" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr25" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr26" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr27" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr28" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr29" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr30" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cr31" bitsize="64" type="uint64" save-restore="no"/>
+
+  <reg name="ccr" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="cxer" bitsize="32" type="uint32" save-restore="no"/>
+  <reg name="clr" bitsize="64" type="code_ptr" save-restore="no"/>
+  <reg name="cctr" bitsize="64" type="uint64" save-restore="no"/>
+
+  <reg name="cf0" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf1" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf2" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf3" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf4" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf5" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf6" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf7" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf8" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf9" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf10" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf11" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf12" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf13" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf14" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf15" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf16" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf17" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf18" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf19" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf20" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf21" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf22" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf23" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf24" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf25" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf26" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf27" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf28" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf29" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf30" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cf31" bitsize="64" type="ieee_double" save-restore="no"/>
+  <reg name="cfpscr" bitsize="64" type="uint64" group="float"
+       save-restore="no"/>
+
+  <!-- HTM Checkpointed Altivec (VMX) registers -->
+  <vector id="v4f" type="ieee_single" count="4"/>
+  <vector id="v4i32" type="int32" count="4"/>
+  <vector id="v8i16" type="int16" count="8"/>
+  <vector id="v16i8" type="int8" count="16"/>
+  <union id="vec128">
+    <field name="uint128" type="uint128"/>
+    <field name="v4_float" type="v4f"/>
+    <field name="v4_int32" type="v4i32"/>
+    <field name="v8_int16" type="v8i16"/>
+    <field name="v16_int8" type="v16i8"/>
+  </union>
+
+  <reg name="cvr0" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr1" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr2" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr3" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr4" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr5" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr6" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr7" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr8" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr9" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr10" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr11" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr12" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr13" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr14" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr15" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr16" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr17" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr18" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr19" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr20" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr21" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr22" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr23" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr24" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr25" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr26" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr27" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr28" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr29" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr30" bitsize="128" type="vec128" save-restore="no"/>
+  <reg name="cvr31" bitsize="128" type="vec128" save-restore="no"/>
+
+  <reg name="cvscr" bitsize="32" save-restore="no"/>
+  <reg name="cvrsave" bitsize="32" save-restore="no"/>
+
+  <!-- HTM Checkpointed VSX registers -->
+  <reg name="cvs0h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs1h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs2h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs3h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs4h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs5h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs6h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs7h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs8h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs9h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs10h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs11h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs12h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs13h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs14h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs15h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs16h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs17h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs18h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs19h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs20h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs21h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs22h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs23h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs24h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs25h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs26h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs27h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs28h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs29h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs30h" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cvs31h" bitsize="64" type="uint64" save-restore="no"/>
+
+  <reg name="cppr" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="cdscr" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="ctar" bitsize="64" type="uint64" save-restore="no"/>
+</feature>
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..99c6a7feb7
--- /dev/null
+++ b/gdb/features/rs6000/powerpc-isa207-htm-vsx32l.c
@@ -0,0 +1,370 @@ 
+/* 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.htm");
+  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, "tfhar", 142, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "texasr", 143, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "tfiar", 144, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr0", 145, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr1", 146, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr2", 147, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr3", 148, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr4", 149, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr5", 150, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr6", 151, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr7", 152, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr8", 153, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr9", 154, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr10", 155, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr11", 156, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr12", 157, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr13", 158, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr14", 159, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr15", 160, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr16", 161, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr17", 162, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr18", 163, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr19", 164, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr20", 165, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr21", 166, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr22", 167, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr23", 168, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr24", 169, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr25", 170, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr26", 171, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr27", 172, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr28", 173, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr29", 174, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr30", 175, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr31", 176, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "ccr", 177, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cxer", 178, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "clr", 179, 0, NULL, 32, "code_ptr");
+  tdesc_create_reg (feature, "cctr", 180, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cf0", 181, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf1", 182, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf2", 183, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf3", 184, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf4", 185, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf5", 186, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf6", 187, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf7", 188, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf8", 189, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf9", 190, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf10", 191, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf11", 192, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf12", 193, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf13", 194, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf14", 195, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf15", 196, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf16", 197, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf17", 198, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf18", 199, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf19", 200, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf20", 201, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf21", 202, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf22", 203, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf23", 204, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf24", 205, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf25", 206, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf26", 207, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf27", 208, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf28", 209, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf29", 210, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf30", 211, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf31", 212, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cfpscr", 213, 0, "float", 64, "uint64");
+  tdesc_create_reg (feature, "cvr0", 214, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr1", 215, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr2", 216, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr3", 217, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr4", 218, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr5", 219, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr6", 220, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr7", 221, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr8", 222, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr9", 223, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr10", 224, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr11", 225, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr12", 226, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr13", 227, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr14", 228, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr15", 229, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr16", 230, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr17", 231, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr18", 232, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr19", 233, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr20", 234, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr21", 235, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr22", 236, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr23", 237, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr24", 238, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr25", 239, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr26", 240, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr27", 241, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr28", 242, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr29", 243, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr30", 244, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr31", 245, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvscr", 246, 0, NULL, 32, "int");
+  tdesc_create_reg (feature, "cvrsave", 247, 0, NULL, 32, "int");
+  tdesc_create_reg (feature, "cvs0h", 248, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs1h", 249, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs2h", 250, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs3h", 251, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs4h", 252, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs5h", 253, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs6h", 254, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs7h", 255, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs8h", 256, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs9h", 257, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs10h", 258, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs11h", 259, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs12h", 260, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs13h", 261, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs14h", 262, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs15h", 263, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs16h", 264, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs17h", 265, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs18h", 266, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs19h", 267, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs20h", 268, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs21h", 269, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs22h", 270, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs23h", 271, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs24h", 272, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs25h", 273, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs26h", 274, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs27h", 275, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs28h", 276, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs29h", 277, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs30h", 278, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs31h", 279, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cppr", 280, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cdscr", 281, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "ctar", 282, 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..84192b0c38
--- /dev/null
+++ b/gdb/features/rs6000/powerpc-isa207-htm-vsx32l.xml
@@ -0,0 +1,20 @@ 
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+  <architecture>powerpc:common</architecture>
+  <xi:include href="power-core.xml"/>
+  <xi:include href="power-fpu-isa205.xml"/>
+  <xi:include href="power-linux.xml"/>
+  <xi:include href="power-altivec.xml"/>
+  <xi:include href="power-vsx.xml"/>
+  <xi:include href="power-ppr.xml"/>
+  <xi:include href="power-dscr.xml"/>
+  <xi:include href="power-tar.xml"/>
+  <xi:include href="power-htm.xml"/>
+</target>
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..2647a077dd
--- /dev/null
+++ b/gdb/features/rs6000/powerpc-isa207-htm-vsx64l.c
@@ -0,0 +1,370 @@ 
+/* 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.htm");
+  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, "tfhar", 142, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "texasr", 143, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "tfiar", 144, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr0", 145, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr1", 146, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr2", 147, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr3", 148, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr4", 149, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr5", 150, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr6", 151, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr7", 152, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr8", 153, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr9", 154, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr10", 155, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr11", 156, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr12", 157, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr13", 158, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr14", 159, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr15", 160, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr16", 161, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr17", 162, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr18", 163, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr19", 164, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr20", 165, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr21", 166, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr22", 167, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr23", 168, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr24", 169, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr25", 170, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr26", 171, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr27", 172, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr28", 173, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr29", 174, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr30", 175, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr31", 176, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "ccr", 177, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cxer", 178, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "clr", 179, 0, NULL, 64, "code_ptr");
+  tdesc_create_reg (feature, "cctr", 180, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cf0", 181, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf1", 182, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf2", 183, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf3", 184, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf4", 185, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf5", 186, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf6", 187, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf7", 188, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf8", 189, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf9", 190, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf10", 191, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf11", 192, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf12", 193, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf13", 194, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf14", 195, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf15", 196, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf16", 197, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf17", 198, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf18", 199, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf19", 200, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf20", 201, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf21", 202, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf22", 203, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf23", 204, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf24", 205, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf25", 206, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf26", 207, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf27", 208, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf28", 209, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf29", 210, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf30", 211, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf31", 212, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cfpscr", 213, 0, "float", 64, "uint64");
+  tdesc_create_reg (feature, "cvr0", 214, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr1", 215, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr2", 216, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr3", 217, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr4", 218, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr5", 219, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr6", 220, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr7", 221, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr8", 222, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr9", 223, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr10", 224, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr11", 225, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr12", 226, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr13", 227, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr14", 228, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr15", 229, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr16", 230, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr17", 231, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr18", 232, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr19", 233, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr20", 234, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr21", 235, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr22", 236, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr23", 237, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr24", 238, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr25", 239, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr26", 240, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr27", 241, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr28", 242, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr29", 243, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr30", 244, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr31", 245, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvscr", 246, 0, NULL, 32, "int");
+  tdesc_create_reg (feature, "cvrsave", 247, 0, NULL, 32, "int");
+  tdesc_create_reg (feature, "cvs0h", 248, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs1h", 249, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs2h", 250, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs3h", 251, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs4h", 252, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs5h", 253, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs6h", 254, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs7h", 255, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs8h", 256, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs9h", 257, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs10h", 258, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs11h", 259, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs12h", 260, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs13h", 261, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs14h", 262, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs15h", 263, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs16h", 264, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs17h", 265, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs18h", 266, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs19h", 267, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs20h", 268, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs21h", 269, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs22h", 270, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs23h", 271, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs24h", 272, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs25h", 273, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs26h", 274, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs27h", 275, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs28h", 276, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs29h", 277, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs30h", 278, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs31h", 279, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cppr", 280, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cdscr", 281, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "ctar", 282, 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..e1649d0d9e
--- /dev/null
+++ b/gdb/features/rs6000/powerpc-isa207-htm-vsx64l.xml
@@ -0,0 +1,20 @@ 
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+  <architecture>powerpc:common64</architecture>
+  <xi:include href="power64-core.xml"/>
+  <xi:include href="power-fpu-isa205.xml"/>
+  <xi:include href="power64-linux.xml"/>
+  <xi:include href="power-altivec.xml"/>
+  <xi:include href="power-vsx.xml"/>
+  <xi:include href="power-ppr.xml"/>
+  <xi:include href="power-dscr.xml"/>
+  <xi:include href="power-tar.xml"/>
+  <xi:include href="power64-htm.xml"/>
+</target>
diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
index 0cb50627aa..6559ab1643 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"
@@ -249,6 +252,7 @@  case "${target}" in
 			srv_xmlfiles="${srv_xmlfiles} rs6000/power-dscr.xml"
 			srv_xmlfiles="${srv_xmlfiles} rs6000/power-ppr.xml"
 			srv_xmlfiles="${srv_xmlfiles} rs6000/power-tar.xml"
+			srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm.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"
@@ -260,8 +264,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.xml"
 			srv_linux_usrregs=yes
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
diff --git a/gdb/nat/ppc-linux.h b/gdb/nat/ppc-linux.h
index 913a9e0bd8..44b76e2891 100644
--- a/gdb/nat/ppc-linux.h
+++ b/gdb/nat/ppc-linux.h
@@ -60,6 +60,9 @@ 
 #ifndef PPC_FEATURE2_TAR
 #define PPC_FEATURE2_TAR 0x04000000
 #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)
@@ -106,6 +109,46 @@ 
 #define NT_PPC_DSCR 0x105
 #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 390df17c10..b084934b22 100644
--- a/gdb/ppc-linux-nat.c
+++ b/gdb/ppc-linux-nat.c
@@ -667,6 +667,83 @@  fetch_register (struct regcache *regcache, int tid, int regno)
 		    &ppc32_linux_tarregset);
       return;
     }
+  else if (PPC_IS_TMSPR_REGNUM (regno))
+    {
+      gdb_assert (tdep->have_htm);
+
+      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);
+
+      const struct regset cgprregset =
+	ppc_linux_cgprregset (gdbarch, false);
+
+      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);
+
+      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);
+
+      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);
+
+      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->have_htm);
+
+      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->have_htm);
+
+      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->have_htm);
+
+      fetch_regset (regcache, tid, NT_PPC_TM_CTAR,
+		    PPC_LINUX_SIZEOF_CTARREGSET,
+		    &ppc32_linux_ctarregset);
+      return;
+    }
 
   if (regaddr == -1)
     {
@@ -875,6 +952,43 @@  fetch_ppc_registers (struct regcache *regcache, int tid)
     fetch_regset (regcache, tid, NT_PPC_TAR,
 		  PPC_LINUX_SIZEOF_TARREGSET,
 		  &ppc32_linux_tarregset);
+
+  if (tdep->have_htm)
+    {
+      fetch_regset (regcache, tid, NT_PPC_TM_SPR,
+		    PPC_LINUX_SIZEOF_TM_SPRREGSET,
+		    &ppc32_linux_tm_sprregset);
+
+      const struct regset cgprregset =
+	ppc_linux_cgprregset (gdbarch, false);
+
+      fetch_regset (regcache, tid, NT_PPC_TM_CGPR,
+		    tdep->wordsize == 4? PPC32_LINUX_SIZEOF_CGPRREGSET
+		    : PPC64_LINUX_SIZEOF_CGPRREGSET,
+		    &cgprregset);
+
+      fetch_regset (regcache, tid, NT_PPC_TM_CFPR,
+		    PPC_LINUX_SIZEOF_CFPRREGSET,
+		    &ppc32_linux_cfprregset);
+
+      const struct regset *cvmxregset = ppc_linux_cvmxregset (gdbarch);
+      fetch_regset (regcache, tid, NT_PPC_TM_CVMX,
+		    PPC_LINUX_SIZEOF_CVMXREGSET,
+		    cvmxregset);
+
+      fetch_regset (regcache, tid, NT_PPC_TM_CVSX,
+		    PPC_LINUX_SIZEOF_CVSXREGSET,
+		    &ppc32_linux_cvsxregset);
+      fetch_regset (regcache, tid, NT_PPC_TM_CPPR,
+		    PPC_LINUX_SIZEOF_CPPRREGSET,
+		    &ppc32_linux_cpprregset);
+      fetch_regset (regcache, tid, NT_PPC_TM_CDSCR,
+		    PPC_LINUX_SIZEOF_CDSCRREGSET,
+		    &ppc32_linux_cdscrregset);
+      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
@@ -1082,6 +1196,83 @@  store_register (const struct regcache *regcache, int tid, int regno)
 		    &ppc32_linux_tarregset);
       return;
     }
+  else if (PPC_IS_TMSPR_REGNUM (regno))
+    {
+      gdb_assert (tdep->have_htm);
+
+      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);
+
+      const struct regset cgprregset =
+	ppc_linux_cgprregset (gdbarch, false);
+
+      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);
+
+      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);
+
+      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);
+
+      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->have_htm);
+
+      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->have_htm);
+
+      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->have_htm);
+
+      store_regset (regcache, tid, regno, NT_PPC_TM_CTAR,
+		    PPC_LINUX_SIZEOF_CTARREGSET,
+		    &ppc32_linux_ctarregset);
+      return;
+    }
 
   if (regaddr == -1)
     return;
@@ -1258,6 +1449,50 @@  store_fp_regs (const struct regcache *regcache, int tid, int regno)
     store_register (regcache, tid, tdep->ppc_fp0_regnum + i);
 }
 
+/* Returns true if all the registers in REGSET are valid in REGCACHE,
+   false if no registers are valid, and throws an internal error if
+   only some are valid.  The regmap field in REGSET must be of type
+   regcache_map_entry.  */
+
+static bool
+ppc_linux_regset_available_p (const struct regcache *regcache,
+			      const struct regset *regset)
+{
+  struct gdbarch *gdbarch = regcache->arch ();
+  const struct regcache_map_entry *map;
+  int count;
+  int valid = 0;
+  int total = 0;
+
+  for (map = (const struct regcache_map_entry *) regset->regmap;
+       (count = map->count) != 0;
+       map++)
+    {
+      int regno = map->regno;
+
+      /* Ignore REGCACHE_MAP_SKIP.  */
+      if (regno >= 0 && regno < gdbarch_num_regs (gdbarch))
+	{
+	  for (int i = regno; i < regno + count; i++)
+	    {
+	      if (regcache->get_register_status (i) == REG_VALID)
+		valid++;
+	      total++;
+	    }
+	}
+    }
+
+  if (valid > 0 && valid < total)
+    internal_error (__FILE__, __LINE__,
+		    _("Only some registers in a regset"
+		      "are valid."));
+
+  if (valid == total)
+    return true;
+  else
+    return false;
+}
+
 static void
 store_ppc_registers (const struct regcache *regcache, int tid)
 {
@@ -1308,6 +1543,67 @@  store_ppc_registers (const struct regcache *regcache, int tid)
     store_regset (regcache, tid, -1, NT_PPC_TAR,
 		  PPC_LINUX_SIZEOF_TARREGSET,
 		  &ppc32_linux_tarregset);
+
+  if (tdep->have_htm)
+    {
+      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.  */
+
+      const struct regset cgprregset =
+	ppc_linux_cgprregset (gdbarch, false);
+
+      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 (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);
+
+      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 (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 (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 (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 (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.  */
@@ -2439,7 +2735,13 @@  ppc_linux_nat_target::read_description ()
       if ((hwcap2 & PPC_FEATURE2_ARCH_2_07)
 	  && (hwcap2 & PPC_FEATURE2_TAR)
 	  && check_regset (tid, NT_PPC_TAR, PPC_LINUX_SIZEOF_TARREGSET))
-	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 9d952c3388..74e4eec413 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.  */
@@ -457,15 +459,29 @@  ppc_linux_collect_vrregset (const struct regset *regset,
 
   /* Zero-pad the unused bytes in the fields for vscr and vrsave
      in case they get displayed somewhere (e.g. in core files).  */
-  if (regnum == PPC_VSCR_REGNUM || regnum == -1)
+  if (regnum == PPC_VSCR_REGNUM || regnum == PPC_CVSCR_REGNUM
+      || regnum == -1)
     memset (&vrregs[32 * 16], 0, 16);
 
-  if (regnum == PPC_VRSAVE_REGNUM || regnum == -1)
+  if (regnum == PPC_VRSAVE_REGNUM || regnum == PPC_CVRSAVE_REGNUM
+      || regnum == -1)
     memset (&vrregs[33 * 16], 0, 16);
 
   regcache_collect_regset (regset, regcache, regnum, buf, len);
 }
 
+static void
+ppc_linux_collect_and_clear_cgprregset (const struct regset *regset,
+					const struct regcache *regcache,
+					int regnum, void *buf,
+					size_t len)
+{
+  if (regnum == -1)
+    memset (buf, 0, len);
+
+  regcache_collect_regset (regset, regcache, regnum, buf, len);
+}
+
 /* Regset descriptions.  */
 static const struct ppc_reg_offsets ppc32_linux_reg_offsets =
   {
@@ -525,6 +541,116 @@  static const struct regcache_map_entry ppc32_regmap_tar[] =
       { 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.  If the kernel is 64-bit, 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 CR0 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_CVS0H_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,
@@ -605,6 +731,54 @@  const struct regset ppc32_linux_tarregset = {
   regcache_collect_regset
 };
 
+const struct regset ppc32_linux_tm_sprregset = {
+  ppc32_regmap_tm_spr,
+  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,
+  ppc_linux_collect_vrregset
+};
+
+static const struct regset ppc32_be_linux_cvmxregset = {
+  ppc32_be_regmap_cvmx,
+  regcache_supply_regset,
+  ppc_linux_collect_vrregset
+};
+
+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)
 {
@@ -632,6 +806,46 @@  ppc_linux_vsxregset (void)
   return &ppc32_linux_vsxregset;
 }
 
+const struct regset
+ppc_linux_cgprregset (struct gdbarch *gdbarch, bool clear_on_collect)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  struct regset ret;
+
+  ret.flags = 0;
+
+  if (tdep->wordsize == 4)
+    {
+      ret.regmap = ppc32_regmap_cgpr;
+      ret.flags = REGSET_VARIABLE_SIZE;
+    }
+  else
+    {
+      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+	ret.regmap = ppc64_be_regmap_cgpr;
+      else
+	ret.regmap = ppc64_le_regmap_cgpr;
+    }
+
+  ret.supply_regset = regcache_supply_regset;
+
+  if (clear_on_collect)
+    ret.collect_regset = ppc_linux_collect_and_clear_cgprregset;
+  else
+    ret.collect_regset = regcache_collect_regset;
+
+  return ret;
+}
+
+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
@@ -677,6 +891,71 @@  ppc_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
   if (have_tar)
     cb (".reg-ppc-tar", PPC_LINUX_SIZEOF_TARREGSET,
 	&ppc32_linux_tarregset, "Target Address Register", cb_data);
+
+  if (tdep->have_htm)
+    {
+      cb (".reg-ppc-tm-spr", 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 (regcache == NULL ||
+	  REG_VALID == regcache->get_register_status (PPC_CR0_REGNUM))
+	{
+	  const struct regset cgprregset =
+	    ppc_linux_cgprregset (gdbarch, regcache != NULL);
+
+	  cb (".reg-ppc-tm-cgpr",
+	      tdep->wordsize == 4? PPC32_LINUX_SIZEOF_CGPRREGSET
+	      : PPC64_LINUX_SIZEOF_CGPRREGSET,
+	      &cgprregset,
+	      "Checkpointed General Purpose Registers", cb_data);
+	}
+
+      if (regcache == NULL ||
+	  REG_VALID == regcache->get_register_status (PPC_CF0_REGNUM))
+	cb (".reg-ppc-tm-cfpr", PPC_LINUX_SIZEOF_CFPRREGSET,
+	    &ppc32_linux_cfprregset,
+	    "Checkpointed Floating Point Registers", cb_data);
+
+      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,
+	      cvmxregset,
+	      "Checkpointed Altivec (VMX) Registers", cb_data);
+	}
+
+      if (regcache == NULL ||
+	  REG_VALID == regcache->get_register_status (PPC_CVS0H_REGNUM))
+	cb (".reg-ppc-tm-cvsx", PPC_LINUX_SIZEOF_CVSXREGSET,
+	    &ppc32_linux_cvsxregset,
+	    "Checkpointed VSX Registers", cb_data);
+
+      if (regcache == NULL ||
+	  REG_VALID == regcache->get_register_status (PPC_CPPR_REGNUM))
+	cb (".reg-ppc-tm-cppr", PPC_LINUX_SIZEOF_CPPRREGSET,
+	    &ppc32_linux_cpprregset,
+	    "Checkpointed Priority Program Register", cb_data);
+
+      if (regcache == NULL ||
+	  REG_VALID == regcache->get_register_status (PPC_CDSCR_REGNUM))
+	cb (".reg-ppc-tm-cdscr", PPC_LINUX_SIZEOF_CDSCRREGSET,
+	    &ppc32_linux_cdscrregset,
+	    "Checkpointed Data Stream Control Register", cb_data);
+
+      if ( regcache == NULL ||
+	   REG_VALID == regcache->get_register_status (PPC_CTAR_REGNUM))
+	cb (".reg-ppc-tm-ctar", PPC_LINUX_SIZEOF_CTARREGSET,
+	    &ppc32_linux_ctarregset,
+	    "Checkpointed Target Address Register", cb_data);
+    }
 }
 
 static void
@@ -1092,6 +1371,7 @@  ppc_linux_core_read_description (struct gdbarch *gdbarch,
   asection *ppr = bfd_get_section_by_name (abfd, ".reg-ppc-ppr");
   asection *dscr = bfd_get_section_by_name (abfd, ".reg-ppc-dscr");
   asection *tar = bfd_get_section_by_name (abfd, ".reg-ppc-tar");
+  asection *htmspr = bfd_get_section_by_name (abfd, ".reg-ppc-tm-spr");
 
   if (! section)
     return NULL;
@@ -1128,7 +1408,11 @@  ppc_linux_core_read_description (struct gdbarch *gdbarch,
     {
       features.ppr_dscr = true;
       if (tar)
-	features.isa207 = true;
+	{
+	  features.isa207 = true;
+	  if (htmspr)
+	    features.htm = true;
+	}
     }
 
   return ppc_linux_match_description (features);
@@ -2006,6 +2290,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 ();
@@ -2015,5 +2300,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 d6ddf69354..a68eca6d42 100644
--- a/gdb/ppc-linux-tdep.h
+++ b/gdb/ppc-linux-tdep.h
@@ -32,6 +32,17 @@  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.  The collect function of the returned
+   regset will clear the buffer passed to it before collecting the
+   registers to 0 if CLEAR_ON_COLLECT is true and the collect function
+   is called with regno == -1 (collect all regs in the regset). This
+   is useful for generating core files without garbage in the register
+   slots that are not seen by gdb.  When collecting for storing the
+   registers in the inferior, these slots should not be cleared.  */
+const struct regset ppc_linux_cgprregset (struct gdbarch *gdbarch,
+					  bool clear_on_collect);
+
 /* 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
@@ -48,5 +59,16 @@  int ppc_linux_trap_reg_p (struct gdbarch *gdbarch);
 extern const struct regset ppc32_linux_pprregset;
 extern const struct regset ppc32_linux_dscrregset;
 extern const struct regset ppc32_linux_tarregset;
+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;
+
+/* Get the checkpointed vector regset that matches the target byte
+   order.  */
+const struct regset*
+ppc_linux_cvmxregset (struct gdbarch *gdbarch);
 
 #endif /* PPC_LINUX_TDEP_H */
diff --git a/gdb/ppc-tdep.h b/gdb/ppc-tdep.h
index e2b968177e..ddb1c5e84b 100644
--- a/gdb/ppc-tdep.h
+++ b/gdb/ppc-tdep.h
@@ -262,6 +262,11 @@  struct gdbarch_tdep
     /* Target Address Register.  */
     int ppc_tar_regnum;
 
+    int have_htm;
+
+    /* HTM pseudo registers.  */
+    int ppc_cvsr0_regnum;
+
     /* Decimal 128 registers.  */
     int ppc_dl0_regnum;		/* First Decimal128 argument register pair.  */
 
@@ -321,12 +326,51 @@  enum {
   PPC_PPR_REGNUM = 172,
   PPC_DSCR_REGNUM = 173,
   PPC_TAR_REGNUM = 174,
+
+  /* Hardware transactional memory registers.  */
+  PPC_TFHAR_REGNUM = 175,
+  PPC_TEXASR_REGNUM = 176,
+  PPC_TFIAR_REGNUM = 177,
+
+  PPC_CR0_REGNUM = 178,
+  PPC_CCR_REGNUM = 210,
+  PPC_CXER_REGNUM = 211,
+  PPC_CLR_REGNUM = 212,
+  PPC_CCTR_REGNUM = 213,
+
+  PPC_CF0_REGNUM = 214,
+  PPC_CFPSCR_REGNUM = 246,
+
+  PPC_CVR0_REGNUM = 247,
+  PPC_CVSCR_REGNUM = 279,
+  PPC_CVRSAVE_REGNUM = 280,
+
+  PPC_CVS0H_REGNUM = 281,
+
+  PPC_CPPR_REGNUM = 313,
+  PPC_CDSCR_REGNUM = 314,
+  PPC_CTAR_REGNUM = 315,
   PPC_NUM_REGS
 };
 
 /* Big enough to hold the size of the largest register in bytes.  */
 #define PPC_MAX_REGISTER_SIZE	64
 
+#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_CVS0H_REGNUM && (i) < (PPC_CVS0H_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..6f5bbad28f
--- /dev/null
+++ b/gdb/regformats/rs6000/powerpc-isa207-htm-vsx32l.dat
@@ -0,0 +1,288 @@ 
+# 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: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..2f3d21c4c6
--- /dev/null
+++ b/gdb/regformats/rs6000/powerpc-isa207-htm-vsx64l.dat
@@ -0,0 +1,288 @@ 
+# 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: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 134e9d0cbc..6687e20d2b 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -109,6 +109,11 @@ 
 /* Holds the current set of options to be passed to the disassembler.  */
 static char *powerpc_disassembler_options;
 
+/* 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)
+
 /* The list of available "set powerpc ..." and "show powerpc ..."
    commands.  */
 static struct cmd_list_element *setpowerpccmdlist = NULL;
@@ -2325,6 +2330,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_CVS0H_REGNUM <= regno
+      && regno < PPC_CVS0H_REGNUM + ppc_num_gprs)
+    return "";
+
   /* Check if the SPE pseudo registers are available.  */
   if (IS_SPE_PSEUDOREG (tdep, regno))
     {
@@ -2379,6 +2389,23 @@  rs6000_register_name (struct gdbarch *gdbarch, int regno)
       return efpr_regnames[regno - tdep->ppc_efpr0_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];
+    }
+
   return tdesc_register_name (gdbarch, regno);
 }
 
@@ -2394,7 +2421,8 @@  rs6000_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
   gdb_assert (IS_SPE_PSEUDOREG (tdep, regnum)
 	      || IS_DFP_PSEUDOREG (tdep, regnum)
 	      || IS_VSX_PSEUDOREG (tdep, regnum)
-	      || IS_EFP_PSEUDOREG (tdep, regnum));
+	      || IS_EFP_PSEUDOREG (tdep, regnum)
+	      || IS_CVSX_PSEUDOREG (tdep, regnum));
 
   /* These are the e500 pseudo-registers.  */
   if (IS_SPE_PSEUDOREG (tdep, regnum))
@@ -2402,7 +2430,8 @@  rs6000_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
   else if (IS_DFP_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
@@ -2421,7 +2450,8 @@  rs6000_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
   gdb_assert (IS_SPE_PSEUDOREG (tdep, regnum)
 	      || IS_DFP_PSEUDOREG (tdep, regnum)
 	      || IS_VSX_PSEUDOREG (tdep, regnum)
-	      || IS_EFP_PSEUDOREG (tdep, regnum));
+	      || IS_EFP_PSEUDOREG (tdep, regnum)
+	      || IS_CVSX_PSEUDOREG (tdep, regnum));
 
   /* builtin_declong doesn't have TYPE_CODE_FLT, so it won't be
      detected as a float register by default_register_reggroup_p.  */
@@ -2689,6 +2719,42 @@  vsx_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
   return status;
 }
 
+/* Read method for checkpointed POWER7 VSX pseudo-registers.  */
+static enum register_status
+cvsx_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_cvsr0_regnum;
+  enum register_status status;
+
+  /* Read the portion that overlaps the VMX registers.  */
+  if (reg_index > 31)
+    status = regcache->raw_read (PPC_CVR0_REGNUM + 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 (PPC_CF0_REGNUM + reg_index,
+				     buffer);
+	if (status == REG_VALID)
+	  status = regcache->raw_read (PPC_CVS0H_REGNUM + reg_index,
+				       buffer + 8);
+      }
+    else
+      {
+	status = regcache->raw_read (PPC_CF0_REGNUM + reg_index,
+				     buffer + 8);
+	if (status == REG_VALID)
+	  status = regcache->raw_read (PPC_CVS0H_REGNUM + reg_index,
+				       buffer);
+      }
+
+  return status;
+}
+
 /* Write method for POWER7 VSX pseudo-registers.  */
 static void
 vsx_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
@@ -2719,6 +2785,32 @@  vsx_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
       }
 }
 
+/* Write method for checkpointed VSX pseudo-registers.  */
+static void
+cvsx_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_cvsr0_regnum;
+
+  /* Write the portion that overlaps the CVMX registers.  */
+  if (reg_index > 31)
+    regcache->raw_write (PPC_CVR0_REGNUM + reg_index - 32, buffer);
+  else
+    /* Write the portion that overlaps the CFPR registers.  */
+    if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+      {
+	regcache->raw_write (PPC_CF0_REGNUM + reg_index, buffer);
+	regcache->raw_write (PPC_CVS0H_REGNUM + reg_index, buffer + 8);
+      }
+    else
+      {
+	regcache->raw_write (PPC_CF0_REGNUM + reg_index, buffer + 8);
+	regcache->raw_write (PPC_CVS0H_REGNUM + 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,
@@ -2766,6 +2858,8 @@  rs6000_pseudo_register_read (struct gdbarch *gdbarch,
     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_CVSX_PSEUDOREG (tdep, reg_nr))
+    return cvsx_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
   else
     internal_error (__FILE__, __LINE__,
 		    _("rs6000_pseudo_register_read: "
@@ -2791,6 +2885,8 @@  rs6000_pseudo_register_write (struct gdbarch *gdbarch,
     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_CVSX_PSEUDOREG (tdep, reg_nr))
+    cvsx_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
   else
     internal_error (__FILE__, __LINE__,
 		    _("rs6000_pseudo_register_write: "
@@ -2815,17 +2911,34 @@  rs6000_ax_pseudo_register_collect (struct gdbarch *gdbarch,
       ax_reg_mask (ax, tdep->ppc_fp0_regnum + 2 * reg_index);
       ax_reg_mask (ax, tdep->ppc_fp0_regnum + 2 * reg_index + 1);
     }
-  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;
+      int reg_index, vr0, fp0, vsr0_upper;
+
+      if (IS_VSX_PSEUDOREG (tdep, reg_nr))
+	{
+	  reg_index = reg_nr - tdep->ppc_vsr0_regnum;
+	  vr0 = tdep->ppc_vr0_regnum;
+	  fp0 = tdep->ppc_fp0_regnum;
+	  vsr0_upper = tdep->ppc_vsr0_upper_regnum;
+	}
+      else
+	{
+	  reg_index = reg_nr - tdep->ppc_cvsr0_regnum;
+	  vr0 = PPC_CVR0_REGNUM;
+	  fp0 = PPC_CF0_REGNUM;
+	  vsr0_upper = PPC_CVS0H_REGNUM;
+	}
+
       if (reg_index > 31)
         {
-          ax_reg_mask (ax, tdep->ppc_vr0_regnum + reg_index - 32);
+          ax_reg_mask (ax, vr0 + 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);
+          ax_reg_mask (ax, fp0 + reg_index);
+          ax_reg_mask (ax, vsr0_upper + reg_index);
         }
     }
   else if (IS_EFP_PSEUDOREG (tdep, reg_nr))
@@ -5841,7 +5954,7 @@  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;
+  int have_tar = 0, have_htm = 0;
   int tdesc_wordsize = -1;
   const struct target_desc *tdesc = info.target_desc;
   struct tdesc_arch_data *tdesc_data = NULL;
@@ -6181,6 +6294,97 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	}
       else
 	have_tar = 0;
+
+      /* Hardware Transactional Memory Registers.  */
+      feature = tdesc_find_feature (tdesc,
+				    "org.gnu.gdb.power.htm");
+      if (feature != NULL)
+	{
+
+	  /* Make sure that all the checkpointed registers we are
+	     about to validate have already been seen in their normal
+	     non-checkpointed form.  We expect a 64-bit checkpointed
+	     FPSCR, which implies have_dfp, which implies
+	     have_fpu.  */
+
+	  if (!(have_dfp && have_altivec && have_vsx &&
+		have_ppr && have_dscr && have_tar))
+	    {
+	      tdesc_data_cleanup (tdesc_data);
+	      return NULL;
+	    }
+
+	  static const char *const tm_spr_regs[] = {
+	    "tfhar", "texasr", "tfiar"
+	  };
+
+	  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"
+	  };
+
+	  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"
+	  };
+	  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"
+	  };
+	  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"
+	  };
+
+	  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]);
+	  for (i = 0; i < ARRAY_SIZE (cgprs); i++)
+	    valid_p &= tdesc_numbered_register (feature, tdesc_data,
+						PPC_CR0_REGNUM + i, cgprs[i]);
+	  for (i = 0; i < ARRAY_SIZE (cfprs); i++)
+	    valid_p &= tdesc_numbered_register (feature, tdesc_data,
+						PPC_CF0_REGNUM + i, cfprs[i]);
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+					      PPC_CFPSCR_REGNUM, "cfpscr");
+	  for (i = 0; i < ARRAY_SIZE (cvmx); i++)
+	    valid_p &= tdesc_numbered_register (feature, tdesc_data,
+						PPC_CVR0_REGNUM + i, cvmx[i]);
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+					      PPC_CVSCR_REGNUM, "cvscr");
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+					      PPC_CVRSAVE_REGNUM, "cvrsave");
+	  for (i = 0; i < ARRAY_SIZE (cvsx); i++)
+	    valid_p &= tdesc_numbered_register (feature, tdesc_data,
+						PPC_CVS0H_REGNUM + i, cvsx[i]);
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+					      PPC_CPPR_REGNUM, "cppr");
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+					      PPC_CDSCR_REGNUM, "cdscr");
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+					      PPC_CTAR_REGNUM, "ctar");
+	  if (!valid_p)
+	    {
+	      tdesc_data_cleanup (tdesc_data);
+	      return NULL;
+	    }
+	  have_htm = 1;
+	}
+      else
+	have_htm = 0;
     }
 
   /* If we have a 64-bit binary on a 32-bit target, complain.  Also
@@ -6378,6 +6582,7 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->ppc_ppr_regnum = have_ppr ? PPC_PPR_REGNUM : -1;
   tdep->ppc_dscr_regnum = have_dscr ? PPC_DSCR_REGNUM : -1;
   tdep->ppc_tar_regnum = have_tar ? PPC_TAR_REGNUM : -1;
+  tdep->have_htm = have_htm;
 
   set_gdbarch_pc_regnum (gdbarch, PPC_PC_REGNUM);
   set_gdbarch_sp_regnum (gdbarch, PPC_R0_REGNUM + 1);
@@ -6420,8 +6625,14 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   if (have_dfp)
     num_pseudoregs += 16;
   if (have_vsx)
-    /* Include both VSX and Extended FP registers.  */
-    num_pseudoregs += 96;
+    {
+      /* Include both VSX and Extended FP registers  */
+      num_pseudoregs += 96;
+
+      /* Includes CVSX.  */
+      if (have_htm)
+	num_pseudoregs += 64;
+    }
 
   set_gdbarch_num_pseudo_regs (gdbarch, num_pseudoregs);
 
@@ -6539,6 +6750,7 @@  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_cvsr0_regnum = -1;
 
   cur_reg = gdbarch_num_regs (gdbarch);
 
@@ -6558,6 +6770,11 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       cur_reg += 64;
       tdep->ppc_efpr0_regnum = cur_reg;
       cur_reg += 32;
+      if (have_htm)
+        {
+	  tdep->ppc_cvsr0_regnum = cur_reg;
+	  cur_reg += ppc_num_vsrs;
+        }
     }
 
   gdb_assert (gdbarch_num_regs (gdbarch)