[PowerPC] Add support for HTM registers
authorEdjunior Barbosa Machado <emachado@linux.vnet.ibm.com>
Fri, 26 Oct 2018 12:37:55 +0000 (09:37 -0300)
committerPedro Franco de Carvalho <pedromfc@linux.ibm.com>
Fri, 26 Oct 2018 13:23:01 +0000 (10:23 -0300)
This patch adds support for Hardware Transactional Memory registers
for the powerpc linux native and core file targets, and for the
pwoerpc linux server stub.

These registers include both the HTM special-purpose registers (TFHAR,
TEXASR and TFIAR) as well as the set of registers that are
checkpointed (saved) when a transaction is initiated, which the
processor restores in the event of a transaction failure.

The set of checkpointed general-purpose registers is returned by the
linux kernel in the same format as the regular general-purpose
registers, defined in struct pt_regs.  However, the architecture
specifies that only some of the registers present in pt_regs are
checkpointed (GPRs 0-31, CR, XER, LR and CTR).  The kernel fills the
slots for MSR and NIP with other info.  The other fields usually don't
have meaningful values.  GDB doesn't define registers that are not
checkpointed in the architecture, but when generating a core file, GDB
fills the slot for the checkpointed MSR with the regular MSR.  These
are usually similar, although some bits might be different, and in
some cases the checkpointed MSR will have a value of 0 in a
kernel-generated core-file.  The checkpointed NIP is filled with TFHAR
by GDB in the core-file, which is what the kernel does.  The other
fields are set to 0 by GDB.

Core files generated by the kernel have a note section for
checkpointed GPRs with the same size for both 32-bit and 64-bit
threads, and the values for the registers of a 32-bit thread are
squeezed in the first half, with no useful data in the second half.
GDB generates a smaller note section for 32-bit threads, but can read
both sizes.

The checkpointed XER is required to be 32-bit in the target
description documentation, even though the more recent ISAs define it
as 64-bit wide, since the high-order 32-bits are reserved, and because
in Linux there is no way to get a 64-bit checkpointed XER for 32-bit
threads.  If this changes in the future, the target description
feature requirement can be relaxed to allow for a 64-bit checkpointed
XER.

Access to the checkpointed CR (condition register) can be confusing.
The architecture only specifies that CR fields 1 to 7 (the 24 least
significant bits) are checkpointed, but the kernel provides all 8
fields (32 bits).  The value of field 0 is not masked by ptrace, so it
will sometimes show the result of some kernel operation, probably
treclaim., which sets this field.

The checkpointed registers are marked not to be saved and restored.
Inferior function calls during an active transaction don't work well,
and it's unclear what should be done in this case.  TEXASR and TFIAR
can be altered asynchronously, during transaction failure recording,
so they are also not saved and restored.  For consistency neither is
TFHAR.

Record and replay also doesn't work well when transactions are
involved.  This patch doesn't address this, so the values of the HTM
SPRs will sometimes be innacurate when the record/relay target is
enabled.  For instance, executing a "tbegin." alters TFHAR and TEXASR,
but these changes are not currently recorded.

Because the checkpointed registers are only available when a
transaction is active (or suspended), ptrace can return ENODATA when
gdb tries to read these registers and the inferior is not in a
transactional state.  The registers are set to the unavailable state
when this happens.  When gbd tries to write to one of these registers,
and it is unavailable, an error is raised.

The "fill" functions for checkpointed register sets in the server stub
are not implemented for the same reason as for the EBB register set,
since ptrace can also return ENODATA for checkpointed regsets.  The
same issues with 'G' packets apply here.

Just like for the EBB registers, tracepoints will not mark the
checkpointed registers as unavailable if the inferior was not in a
transaction, so their content will also show 0 instead of
<unavailable> when inspecting trace data.

The new tests record the values of the regular registers before
stepping the inferior through a "tbegin." instruction to start a
transaction, then the checkpointed registers are checked against the
recorded pre-transactional values.  New values are written to the
checkpointed registers and recorded, the inferior continues until the
transaction aborts (which is usually immediately when it is resumed),
and the regular registers are checked against the recorded values,
because the abort should have reverted the registers to these values.

Like for the EBB registers, target_store_registers will ignore the
checkpointed registers when called with -1 as the regno
argument (store all registers in one go).

gdb/ChangeLog:
2018-10-26  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-spr.xml: New file.
* features/rs6000/power-htm-core.xml: New file.
* features/rs6000/power64-htm-core.xml: New file.
* features/rs6000/power-htm-fpu.xml: New file.
* features/rs6000/power-htm-altivec.xml: New file.
* features/rs6000/power-htm-vsx.xml: New file.
* features/rs6000/power-htm-ppr.xml: New file.
* features/rs6000/power-htm-dscr.xml: New file.
* features/rs6000/power-htm-tar.xml: New file.
* features/rs6000/powerpc-isa207-htm-vsx32l.xml: New file.
* features/rs6000/powerpc-isa207-htm-vsx64l.xml: New file.
* features/rs6000/powerpc-isa207-htm-vsx32l.c: Generate.
* features/rs6000/powerpc-isa207-htm-vsx64l.c: Generate.
* regformats/rs6000/powerpc-isa207-htm-vsx32l.dat: Generate.
* regformats/rs6000/powerpc-isa207-htm-vsx64l.dat: Generate.
* ppc-linux-nat.c (fetch_register, fetch_ppc_registers): Call
fetch_regset with HTM regsets.
(store_register, store_ppc_registers): Call store_regset with HTM
regsets.
(ppc_linux_nat_target::read_description): Set htm field in the
features struct if needed.
* ppc-linux-tdep.c: Include
features/rs6000/powerpc-isa207-htm-vsx32l.c and
features/rs6000/powerpc-isa207-htm-vsx64l.c.
(ppc32_regmap_tm_spr, ppc32_regmap_cgpr, ppc64_le_regmap_cgpr)
(ppc64_be_regmap_cgpr, ppc32_regmap_cfpr, ppc32_le_regmap_cvmx)
(ppc32_be_regmap_cvmx, ppc32_regmap_cvsx, ppc32_regmap_cppr)
(ppc32_regmap_cdscr, ppc32_regmap_ctar): New globals.
(ppc32_linux_tm_sprregset, ppc32_linux_cgprregset)
(ppc64_be_linux_cgprregset, ppc64_le_linux_cgprregset)
(ppc32_linux_cfprregset, ppc32_le_linux_cvmxregset)
(ppc32_be_linux_cvmxregset, ppc32_linux_cvsxregset)
(ppc32_linux_cpprregset, ppc32_linux_cdscrregset)
(ppc32_linux_ctarregset): New globals.
(ppc_linux_cgprregset, ppc_linux_cvmxregset): New functions.
(ppc_linux_collect_core_cpgrregset): New function.
(ppc_linux_iterate_over_regset_sections): Call back with the htm
regsets.
(ppc_linux_core_read_description): Check if the tm spr section is
present and set htm in the features struct.
(_initialize_ppc_linux_tdep): Call
initialize_tdesc_powerpc_isa207_htm_vsx32l and
initialize_tdesc_powerpc_isa207_htm_vsx64l.
* ppc-linux-tdep.h (ppc_linux_cgprregset, ppc_linux_cvmxregset):
Declare.
(ppc32_linux_tm_sprregset, ppc32_linux_cfprregset)
(ppc32_linux_cvsxregset, ppc32_linux_cpprregset)
(ppc32_linux_cdscrregset, ppc32_linux_ctarregset): Declare.
* ppc-tdep.h (struct gdbarch_tdep) <have_htm_spr, have_htm_core>:
New fields.
<have_htm_fpu, have_htm_altivec, have_htm_vsx>:
Likewise.
<ppc_cppr_regnum, ppc_cdscr_regnum, ppc_ctar_regnum>: Likewise.
<ppc_cdl0_regnum, ppc_cvsr0_regnum, ppc_cefpr0_regnum>: Likewise.
(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_CVSR0_UPPER_REGNUM>: Likewise.
<PPC_CPPR_REGNUM, PPC_CDSCR_REGNUM>: Likewise.
<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_CDFP_PSEUDOREG, IS_CVSX_PSEUDOREG)
(IS_CEFP_PSEUDOREG): Define.
(rs6000_register_name): Hide the upper halves of checkpointed VSX
registers.  Return names for the checkpointed DFP, VSX, and EFP
pseudo registers.
(rs6000_pseudo_register_type): Remove initial assert and raise an
internal error in the else clause instead.  Return types for the
checkpointed DFP, VSX, and EFP pseudo registers.
(dfp_pseudo_register_read, dfp_pseudo_register_write): Handle
checkpointed DFP pseudo registers.
(vsx_pseudo_register_read, vsx_pseudo_register_write): Handle
checkpointed VSX pseudo registers.
(efp_pseudo_register_read, efp_pseudo_register_write): Rename
from efpr_pseudo_register_read and
efpr_pseudo_register_write.  Handle checkpointed EFP pseudo
registers.
(rs6000_pseudo_register_read, rs6000_pseudo_register_write):
Handle checkpointed DFP, VSX, and EFP registers.
(dfp_ax_pseudo_register_collect, vsx_ax_pseudo_register_collect)
(efp_ax_pseudo_register_collect): New functions.
(rs6000_ax_pseudo_register_collect): Move DFP, VSX and EFP pseudo
register logic to new functions.  Handle checkpointed DFP, VSX,
and EFP pseudo registers.
(rs6000_gdbarch_init): Look for and validate the htm features.
Include checkpointed DFP, VSX and EFP pseudo-registers.
* NEWS: Mention access to PPR, DSCR, TAR, EBB/PMU registers and
HTM registers.

gdb/gdbserver/ChangeLog:
2018-10-26  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-spr.xml, rs6000/power-htm-core.xml,
rs6000/power64-htm-core.xml, rs6000/power-htm-fpu.xml,
rs6000/power-htm-altivec.xml, rs6000/power-htm-vsx.xml,
rs6000/power-htm-ppr.xml, rs6000/power-htm-dscr.xml,
rs6000/power-htm-tar.xml, rs6000/powerpc-isa207-htm-vsx32l.xml,
and rs6000/powerpc-isa207-htm-vsx64l.xml to srv_xmlfiles.
* linux-ppc-tdesc-init.h (enum ppc_linux_tdesc)
<PPC_TDESC_ISA207_HTM_VSX>: New enum value.
(init_registers_powerpc_isa207_htm_vsx32l)
(init_registers_powerpc_isa207_htm_vsx64l): Declare.
* linux-ppc-low.c (ppc_fill_tm_sprregset, ppc_store_tm_sprregset)
(ppc_store_tm_cgprregset, ppc_store_tm_cfprregset)
(ppc_store_tm_cvrregset, ppc_store_tm_cvsxregset)
(ppc_store_tm_cpprregset, ppc_store_tm_cdscrregset)
(ppc_store_tm_ctarregset): New functions.
(ppc_regsets): Add entries for HTM regsets.
(ppc_arch_setup): Set htm in features struct when needed.  Set
sizes for the HTM regsets.
(ppc_get_ipa_tdesc_idx): Return PPC_TDESC_ISA207_HTM_VSX.
(initialize_low_arch): Call
init_registers_powerpc_isa207_htm_vsx32l and
init_registers_powerpc_isa207_htm_vsx64l.
* linux-ppc-ipa.c (get_ipa_tdesc): Handle
PPC_TDESC_ISA207_HTM_VSX.
(initialize_low_tracepoint): Call
init_registers_powerpc_isa207_htm_vsx32l and
init_registers_powerpc_isa207_htm_vsx64l.

gdb/testsuite/ChangeLog:
2018-10-26  Pedro Franco de Carvalho  <pedromfc@linux.ibm.com>

* gdb.arch/powerpc-htm-regs.c: New file.
* gdb.arch/powerpc-htm-regs.exp: New file.

gdb/doc/ChangeLog:
2018-10-26  Pedro Franco de Carvalho  <pedromfc@linux.ibm.com>

* gdb.texinfo (PowerPC Features): Describe new features
"org.gnu.gdb.power.htm.spr", "org.gnu.gdb.power.htm.core",
"org.gnu.gdb.power.htm.fpu", "org.gnu.gdb.power.htm.altivec",
"org.gnu.gdb.power.htm.vsx", "org.gnu.gdb.power.htm.ppr",
"org.gnu.gdb.power.htm.dscr", "org.gnu.gdb.power.htm.tar".

37 files changed:
gdb/ChangeLog
gdb/NEWS
gdb/arch/ppc-linux-common.c
gdb/arch/ppc-linux-common.h
gdb/arch/ppc-linux-tdesc.h
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/features/Makefile
gdb/features/rs6000/power-htm-altivec.xml [new file with mode: 0644]
gdb/features/rs6000/power-htm-core.xml [new file with mode: 0644]
gdb/features/rs6000/power-htm-dscr.xml [new file with mode: 0644]
gdb/features/rs6000/power-htm-fpu.xml [new file with mode: 0644]
gdb/features/rs6000/power-htm-ppr.xml [new file with mode: 0644]
gdb/features/rs6000/power-htm-spr.xml [new file with mode: 0644]
gdb/features/rs6000/power-htm-tar.xml [new file with mode: 0644]
gdb/features/rs6000/power-htm-vsx.xml [new file with mode: 0644]
gdb/features/rs6000/power64-htm-core.xml [new file with mode: 0644]
gdb/features/rs6000/powerpc-isa207-htm-vsx32l.c [new file with mode: 0644]
gdb/features/rs6000/powerpc-isa207-htm-vsx32l.xml [new file with mode: 0644]
gdb/features/rs6000/powerpc-isa207-htm-vsx64l.c [new file with mode: 0644]
gdb/features/rs6000/powerpc-isa207-htm-vsx64l.xml [new file with mode: 0644]
gdb/gdbserver/ChangeLog
gdb/gdbserver/configure.srv
gdb/gdbserver/linux-ppc-ipa.c
gdb/gdbserver/linux-ppc-low.c
gdb/gdbserver/linux-ppc-tdesc-init.h
gdb/nat/ppc-linux.h
gdb/ppc-linux-nat.c
gdb/ppc-linux-tdep.c
gdb/ppc-linux-tdep.h
gdb/ppc-tdep.h
gdb/regformats/rs6000/powerpc-isa207-htm-vsx32l.dat [new file with mode: 0644]
gdb/regformats/rs6000/powerpc-isa207-htm-vsx64l.dat [new file with mode: 0644]
gdb/rs6000-tdep.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.arch/powerpc-htm-regs.c [new file with mode: 0644]
gdb/testsuite/gdb.arch/powerpc-htm-regs.exp [new file with mode: 0644]

index 74c7b39..4376263 100644 (file)
@@ -1,3 +1,118 @@
+2018-10-26  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-spr.xml: New file.
+       * features/rs6000/power-htm-core.xml: New file.
+       * features/rs6000/power64-htm-core.xml: New file.
+       * features/rs6000/power-htm-fpu.xml: New file.
+       * features/rs6000/power-htm-altivec.xml: New file.
+       * features/rs6000/power-htm-vsx.xml: New file.
+       * features/rs6000/power-htm-ppr.xml: New file.
+       * features/rs6000/power-htm-dscr.xml: New file.
+       * features/rs6000/power-htm-tar.xml: New file.
+       * features/rs6000/powerpc-isa207-htm-vsx32l.xml: New file.
+       * features/rs6000/powerpc-isa207-htm-vsx64l.xml: New file.
+       * features/rs6000/powerpc-isa207-htm-vsx32l.c: Generate.
+       * features/rs6000/powerpc-isa207-htm-vsx64l.c: Generate.
+       * regformats/rs6000/powerpc-isa207-htm-vsx32l.dat: Generate.
+       * regformats/rs6000/powerpc-isa207-htm-vsx64l.dat: Generate.
+       * ppc-linux-nat.c (fetch_register, fetch_ppc_registers): Call
+       fetch_regset with HTM regsets.
+       (store_register, store_ppc_registers): Call store_regset with HTM
+       regsets.
+       (ppc_linux_nat_target::read_description): Set htm field in the
+       features struct if needed.
+       * ppc-linux-tdep.c: Include
+       features/rs6000/powerpc-isa207-htm-vsx32l.c and
+       features/rs6000/powerpc-isa207-htm-vsx64l.c.
+       (ppc32_regmap_tm_spr, ppc32_regmap_cgpr, ppc64_le_regmap_cgpr)
+       (ppc64_be_regmap_cgpr, ppc32_regmap_cfpr, ppc32_le_regmap_cvmx)
+       (ppc32_be_regmap_cvmx, ppc32_regmap_cvsx, ppc32_regmap_cppr)
+       (ppc32_regmap_cdscr, ppc32_regmap_ctar): New globals.
+       (ppc32_linux_tm_sprregset, ppc32_linux_cgprregset)
+       (ppc64_be_linux_cgprregset, ppc64_le_linux_cgprregset)
+       (ppc32_linux_cfprregset, ppc32_le_linux_cvmxregset)
+       (ppc32_be_linux_cvmxregset, ppc32_linux_cvsxregset)
+       (ppc32_linux_cpprregset, ppc32_linux_cdscrregset)
+       (ppc32_linux_ctarregset): New globals.
+       (ppc_linux_cgprregset, ppc_linux_cvmxregset): New functions.
+       (ppc_linux_collect_core_cpgrregset): New function.
+       (ppc_linux_iterate_over_regset_sections): Call back with the htm
+       regsets.
+       (ppc_linux_core_read_description): Check if the tm spr section is
+       present and set htm in the features struct.
+       (_initialize_ppc_linux_tdep): Call
+       initialize_tdesc_powerpc_isa207_htm_vsx32l and
+       initialize_tdesc_powerpc_isa207_htm_vsx64l.
+       * ppc-linux-tdep.h (ppc_linux_cgprregset, ppc_linux_cvmxregset):
+       Declare.
+       (ppc32_linux_tm_sprregset, ppc32_linux_cfprregset)
+       (ppc32_linux_cvsxregset, ppc32_linux_cpprregset)
+       (ppc32_linux_cdscrregset, ppc32_linux_ctarregset): Declare.
+       * ppc-tdep.h (struct gdbarch_tdep) <have_htm_spr, have_htm_core>:
+       New fields.
+       <have_htm_fpu, have_htm_altivec, have_htm_vsx>:
+       Likewise.
+       <ppc_cppr_regnum, ppc_cdscr_regnum, ppc_ctar_regnum>: Likewise.
+       <ppc_cdl0_regnum, ppc_cvsr0_regnum, ppc_cefpr0_regnum>: Likewise.
+       (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_CVSR0_UPPER_REGNUM>: Likewise.
+       <PPC_CPPR_REGNUM, PPC_CDSCR_REGNUM>: Likewise.
+       <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_CDFP_PSEUDOREG, IS_CVSX_PSEUDOREG)
+       (IS_CEFP_PSEUDOREG): Define.
+       (rs6000_register_name): Hide the upper halves of checkpointed VSX
+       registers.  Return names for the checkpointed DFP, VSX, and EFP
+       pseudo registers.
+       (rs6000_pseudo_register_type): Remove initial assert and raise an
+       internal error in the else clause instead.  Return types for the
+       checkpointed DFP, VSX, and EFP pseudo registers.
+       (dfp_pseudo_register_read, dfp_pseudo_register_write): Handle
+       checkpointed DFP pseudo registers.
+       (vsx_pseudo_register_read, vsx_pseudo_register_write): Handle
+       checkpointed VSX pseudo registers.
+       (efp_pseudo_register_read, efp_pseudo_register_write): Rename
+       from efpr_pseudo_register_read and
+       efpr_pseudo_register_write.  Handle checkpointed EFP pseudo
+       registers.
+       (rs6000_pseudo_register_read, rs6000_pseudo_register_write):
+       Handle checkpointed DFP, VSX, and EFP registers.
+       (dfp_ax_pseudo_register_collect, vsx_ax_pseudo_register_collect)
+       (efp_ax_pseudo_register_collect): New functions.
+       (rs6000_ax_pseudo_register_collect): Move DFP, VSX and EFP pseudo
+       register logic to new functions.  Handle checkpointed DFP, VSX,
+       and EFP pseudo registers.
+       (rs6000_gdbarch_init): Look for and validate the htm features.
+       Include checkpointed DFP, VSX and EFP pseudo-registers.
+       * NEWS: Mention access to PPR, DSCR, TAR, EBB/PMU registers and
+       HTM registers.
+
 2018-10-26  Pedro Franco de Carvalho  <pedromfc@linux.ibm.com>
 
        * rs6000-tdep.c (rs6000_gdbarch_init): Reject tdescs with vsx but
index 6462e46..6b00cd8 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,10 @@
 
 *** Changes since GDB 8.2
 
+* GDB and GDBserver now support access to additional registers on
+  PowerPC GNU/Linux targets: PPR, DSCR, TAR, EBB/PMU registers, and
+  HTM registers.
+
 * GDB now has experimental support for the compilation and injection of
   C++ source code into the inferior.  This beta release does not include
   support for several language features, such as templates, constructors,
index b8a7cdb..cc4d164 100644 (file)
@@ -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);
index 50e9e06..9ecb02b 100644 (file)
@@ -35,6 +35,15 @@ struct target_desc;
 #define PPC_LINUX_SIZEOF_TARREGSET 8
 #define PPC_LINUX_SIZEOF_EBBREGSET (3*8)
 #define PPC_LINUX_SIZEOF_PMUREGSET (5*8)
+#define PPC_LINUX_SIZEOF_TM_SPRREGSET (3*8)
+#define PPC32_LINUX_SIZEOF_CGPRREGSET (48*4)
+#define PPC64_LINUX_SIZEOF_CGPRREGSET (48*8)
+#define PPC_LINUX_SIZEOF_CFPRREGSET (32*8+8)
+#define PPC_LINUX_SIZEOF_CVMXREGSET (34*16)
+#define PPC_LINUX_SIZEOF_CVSXREGSET (32*8)
+#define PPC_LINUX_SIZEOF_CPPRREGSET 8
+#define PPC_LINUX_SIZEOF_CDSCRREGSET 8
+#define PPC_LINUX_SIZEOF_CTARREGSET 8
 
 /* Check if the hwcap auxv entry indicates that isa205 is supported.  */
 bool ppc_linux_has_isa205 (CORE_ADDR hwcap);
@@ -48,6 +57,7 @@ struct ppc_linux_features
   bool isa205;
   bool ppr_dscr;
   bool isa207;
+  bool htm;
   bool cell;
 };
 
@@ -60,6 +70,7 @@ const struct ppc_linux_features ppc_linux_no_features = {
   false,
   false,
   false,
+  false,
 };
 
 /* Return a target description that matches FEATURES.  */
index 9962879..2716be7 100644 (file)
@@ -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 */
index ee5d23f..abcdbda 100644 (file)
@@ -1,6 +1,14 @@
 2018-10-26  Pedro Franco de Carvalho  <pedromfc@linux.ibm.com>
 
        * gdb.texinfo (PowerPC Features): Describe new features
+       "org.gnu.gdb.power.htm.spr", "org.gnu.gdb.power.htm.core",
+       "org.gnu.gdb.power.htm.fpu", "org.gnu.gdb.power.htm.altivec",
+       "org.gnu.gdb.power.htm.vsx", "org.gnu.gdb.power.htm.ppr",
+       "org.gnu.gdb.power.htm.dscr", "org.gnu.gdb.power.htm.tar".
+
+2018-10-26  Pedro Franco de Carvalho  <pedromfc@linux.ibm.com>
+
+       * gdb.texinfo (PowerPC Features): Describe new features
        "org.gnu.gdb.power.ebb" and "org.gnu.gdb.power.linux.pmu".
 
 2018-10-26  Pedro Franco de Carvalho  <pedromfc@linux.ibm.com>
index e8130ce..c49a774 100644 (file)
@@ -43210,6 +43210,48 @@ contain registers @samp{mmcr0}, @samp{mmcr2}, @samp{siar}, @samp{sdar}
 and @samp{sier}, all 64-bit wide.  This is the subset of the isa 2.07
 server PMU registers provided by @sc{gnu}/Linux.
 
+The @samp{org.gnu.gdb.power.htm.spr} feature is optional.  It should
+contain registers @samp{tfhar}, @samp{texasr} and @samp{tfiar}, all
+64-bit wide.
+
+The @samp{org.gnu.gdb.power.htm.core} feature is optional.  It should
+contain the checkpointed general-purpose registers @samp{cr0} through
+@samp{cr31}, as well as the checkpointed registers @samp{clr} and
+@samp{cctr}.  These registers may all be either 32-bit or 64-bit
+depending on the target.  It should also contain the checkpointed
+registers @samp{ccr} and @samp{cxer}, which should both be 32-bit
+wide.
+
+The @samp{org.gnu.gdb.power.htm.fpu} feature is optional.  It should
+contain the checkpointed 64-bit floating-point registers @samp{cf0}
+through @samp{cf31}, as well as the checkpointed 64-bit register
+@samp{cfpscr}.
+
+The @samp{org.gnu.gdb.power.htm.altivec} feature is optional.  It
+should contain the checkpointed altivec registers @samp{cvr0} through
+@samp{cvr31}, all 128-bit wide.  It should also contain the
+checkpointed registers @samp{cvscr} and @samp{cvrsave}, both 32-bit
+wide.
+
+The @samp{org.gnu.gdb.power.htm.vsx} feature is optional.  It should
+contain registers @samp{cvs0h} through @samp{cvs31h}.  @value{GDBN}
+will combine these registers with the checkpointed floating point
+registers (@samp{cf0} through @samp{cf31}) and the checkpointed
+altivec registers (@samp{cvr0} through @samp{cvr31}) to present the
+128-bit wide checkpointed vector-scalar registers @samp{cvs0} through
+@samp{cvs63}.  Therefore, this feature requires both
+@samp{org.gnu.gdb.power.htm.altivec} and
+@samp{org.gnu.gdb.power.htm.fpu}.
+
+The @samp{org.gnu.gdb.power.htm.ppr} feature is optional.  It should
+contain the 64-bit checkpointed register @samp{cppr}.
+
+The @samp{org.gnu.gdb.power.htm.dscr} feature is optional.  It should
+contain the 64-bit checkpointed register @samp{cdscr}.
+
+The @samp{org.gnu.gdb.power.htm.tar} feature is optional.  It should
+contain the 64-bit checkpointed register @samp{ctar}.
+
 @node S/390 and System z Features
 @subsection S/390 and System z Features
 @cindex target descriptions, S/390 features
index 6eaa7db..150fef2 100644 (file)
@@ -76,6 +76,8 @@ WHICH = aarch64 \
        rs6000/powerpc-isa205-ppr-dscr-vsx32l \
        rs6000/powerpc-isa205-ppr-dscr-vsx64l \
        rs6000/powerpc-isa207-vsx32l rs6000/powerpc-isa207-vsx64l \
+       rs6000/powerpc-isa207-htm-vsx32l \
+       rs6000/powerpc-isa207-htm-vsx64l \
        s390-linux32 s390-linux64 s390x-linux64 \
        s390-linux32v1 s390-linux64v1 s390x-linux64v1 \
        s390-linux32v2 s390-linux64v2 s390x-linux64v2 \
@@ -174,6 +176,8 @@ XMLTOC = \
        rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml \
        rs6000/powerpc-isa207-vsx32l.xml \
        rs6000/powerpc-isa207-vsx64l.xml \
+       rs6000/powerpc-isa207-htm-vsx32l.xml \
+       rs6000/powerpc-isa207-htm-vsx64l.xml \
        rs6000/powerpc-vsx32.xml \
        rs6000/powerpc-vsx32l.xml \
        rs6000/powerpc-vsx64.xml \
diff --git a/gdb/features/rs6000/power-htm-altivec.xml b/gdb/features/rs6000/power-htm-altivec.xml
new file mode 100644 (file)
index 0000000..efc33b7
--- /dev/null
@@ -0,0 +1,58 @@
+<?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 checkpointed VRs.  -->
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.power.htm.altivec">
+  <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" group="vector"/>
+  <reg name="cvrsave" bitsize="32" save-restore="no" group="vector"/>
+</feature>
diff --git a/gdb/features/rs6000/power-htm-core.xml b/gdb/features/rs6000/power-htm-core.xml
new file mode 100644 (file)
index 0000000..d067be8
--- /dev/null
@@ -0,0 +1,48 @@
+<?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 checkpointed GPRs.  -->
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.power.htm.core">
+  <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"/>
+</feature>
diff --git a/gdb/features/rs6000/power-htm-dscr.xml b/gdb/features/rs6000/power-htm-dscr.xml
new file mode 100644 (file)
index 0000000..9f218fa
--- /dev/null
@@ -0,0 +1,12 @@
+<?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 checkpointed DSCR.  -->
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.power.htm.dscr">
+  <reg name="cdscr" bitsize="64" type="uint64" save-restore="no"/>
+</feature>
diff --git a/gdb/features/rs6000/power-htm-fpu.xml b/gdb/features/rs6000/power-htm-fpu.xml
new file mode 100644 (file)
index 0000000..561a8c3
--- /dev/null
@@ -0,0 +1,45 @@
+<?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 checkpointed FPRs.  -->
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.power.htm.fpu">
+  <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"/>
+</feature>
diff --git a/gdb/features/rs6000/power-htm-ppr.xml b/gdb/features/rs6000/power-htm-ppr.xml
new file mode 100644 (file)
index 0000000..2725937
--- /dev/null
@@ -0,0 +1,12 @@
+<?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 checkpointed PPR.  -->
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.power.htm.ppr">
+  <reg name="cppr" bitsize="64" type="uint64" save-restore="no"/>
+</feature>
diff --git a/gdb/features/rs6000/power-htm-spr.xml b/gdb/features/rs6000/power-htm-spr.xml
new file mode 100644 (file)
index 0000000..e933439
--- /dev/null
@@ -0,0 +1,14 @@
+<?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 SPRs.  -->
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.power.htm.spr">
+  <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"/>
+</feature>
diff --git a/gdb/features/rs6000/power-htm-tar.xml b/gdb/features/rs6000/power-htm-tar.xml
new file mode 100644 (file)
index 0000000..bc6339d
--- /dev/null
@@ -0,0 +1,12 @@
+<?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 checkpointed TAR.  -->
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.power.htm.tar">
+  <reg name="ctar" bitsize="64" type="uint64" save-restore="no"/>
+</feature>
diff --git a/gdb/features/rs6000/power-htm-vsx.xml b/gdb/features/rs6000/power-htm-vsx.xml
new file mode 100644 (file)
index 0000000..2dd14fe
--- /dev/null
@@ -0,0 +1,43 @@
+<?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 checkpointed upper VSRs.  -->
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.power.htm.vsx">
+  <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"/>
+</feature>
diff --git a/gdb/features/rs6000/power64-htm-core.xml b/gdb/features/rs6000/power64-htm-core.xml
new file mode 100644 (file)
index 0000000..b8dd6ae
--- /dev/null
@@ -0,0 +1,48 @@
+<?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 checkpointed GPRs.  -->
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.power.htm.core">
+  <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"/>
+</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 (file)
index 0000000..e1b933c
--- /dev/null
@@ -0,0 +1,396 @@
+/* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
+  Original: powerpc-isa207-htm-vsx32l.xml */
+
+#include "defs.h"
+#include "osabi.h"
+#include "target-descriptions.h"
+
+struct target_desc *tdesc_powerpc_isa207_htm_vsx32l;
+static void
+initialize_tdesc_powerpc_isa207_htm_vsx32l (void)
+{
+  struct target_desc *result = allocate_target_description ();
+  set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common"));
+
+  struct tdesc_feature *feature;
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.core");
+  tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r2", 2, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r3", 3, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r4", 4, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r5", 5, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r6", 6, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r7", 7, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r8", 8, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r9", 9, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r10", 10, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r11", 11, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r12", 12, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r13", 13, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r14", 14, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r15", 15, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r16", 16, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r17", 17, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r18", 18, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r19", 19, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r20", 20, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r21", 21, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r22", 22, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r23", 23, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r24", 24, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r25", 25, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r26", 26, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r27", 27, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r28", 28, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r29", 29, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r30", 30, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "r31", 31, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "pc", 64, 1, NULL, 32, "code_ptr");
+  tdesc_create_reg (feature, "msr", 65, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr", 66, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "lr", 67, 1, NULL, 32, "code_ptr");
+  tdesc_create_reg (feature, "ctr", 68, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "xer", 69, 1, NULL, 32, "uint32");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.fpu");
+  tdesc_create_reg (feature, "f0", 32, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f1", 33, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f2", 34, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f3", 35, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f4", 36, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f5", 37, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f6", 38, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f7", 39, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f8", 40, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f9", 41, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f10", 42, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f11", 43, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f12", 44, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f13", 45, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f14", 46, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f15", 47, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f16", 48, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f17", 49, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f18", 50, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f19", 51, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f20", 52, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f21", 53, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f22", 54, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f23", 55, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f24", 56, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f25", 57, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f26", 58, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f27", 59, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f28", 60, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f29", 61, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f30", 62, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f31", 63, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "fpscr", 70, 1, "float", 64, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux");
+  tdesc_create_reg (feature, "orig_r3", 71, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "trap", 72, 1, NULL, 32, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec");
+  tdesc_type *element_type;
+  element_type = tdesc_named_type (feature, "ieee_single");
+  tdesc_create_vector (feature, "v4f", element_type, 4);
+
+  element_type = tdesc_named_type (feature, "int32");
+  tdesc_create_vector (feature, "v4i32", element_type, 4);
+
+  element_type = tdesc_named_type (feature, "int16");
+  tdesc_create_vector (feature, "v8i16", element_type, 8);
+
+  element_type = tdesc_named_type (feature, "int8");
+  tdesc_create_vector (feature, "v16i8", element_type, 16);
+
+  tdesc_type_with_fields *type_with_fields;
+  type_with_fields = tdesc_create_union (feature, "vec128");
+  tdesc_type *field_type;
+  field_type = tdesc_named_type (feature, "uint128");
+  tdesc_add_field (type_with_fields, "uint128", field_type);
+  field_type = tdesc_named_type (feature, "v4f");
+  tdesc_add_field (type_with_fields, "v4_float", field_type);
+  field_type = tdesc_named_type (feature, "v4i32");
+  tdesc_add_field (type_with_fields, "v4_int32", field_type);
+  field_type = tdesc_named_type (feature, "v8i16");
+  tdesc_add_field (type_with_fields, "v8_int16", field_type);
+  field_type = tdesc_named_type (feature, "v16i8");
+  tdesc_add_field (type_with_fields, "v16_int8", field_type);
+
+  tdesc_create_reg (feature, "vr0", 73, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr1", 74, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr2", 75, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr3", 76, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr4", 77, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr5", 78, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr6", 79, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr7", 80, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr8", 81, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr9", 82, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr10", 83, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr11", 84, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr12", 85, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr13", 86, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr14", 87, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr15", 88, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr16", 89, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr17", 90, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr18", 91, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr19", 92, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr20", 93, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr21", 94, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr22", 95, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr23", 96, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr24", 97, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr25", 98, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr26", 99, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr27", 100, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr28", 101, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr29", 102, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr30", 103, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr31", 104, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vscr", 105, 1, "vector", 32, "int");
+  tdesc_create_reg (feature, "vrsave", 106, 1, "vector", 32, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.vsx");
+  tdesc_create_reg (feature, "vs0h", 107, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs1h", 108, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs2h", 109, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs3h", 110, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs4h", 111, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs5h", 112, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs6h", 113, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs7h", 114, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs8h", 115, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs9h", 116, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs10h", 117, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs11h", 118, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs12h", 119, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs13h", 120, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs14h", 121, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs15h", 122, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs16h", 123, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs17h", 124, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs18h", 125, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs19h", 126, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs20h", 127, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs21h", 128, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs22h", 129, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs23h", 130, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs24h", 131, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs25h", 132, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs26h", 133, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs27h", 134, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs28h", 135, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs29h", 136, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs30h", 137, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs31h", 138, 1, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.ppr");
+  tdesc_create_reg (feature, "ppr", 139, 1, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.dscr");
+  tdesc_create_reg (feature, "dscr", 140, 1, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.tar");
+  tdesc_create_reg (feature, "tar", 141, 1, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.ebb");
+  tdesc_create_reg (feature, "bescr", 142, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "ebbhr", 143, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "ebbrr", 144, 0, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux.pmu");
+  tdesc_create_reg (feature, "mmcr0", 145, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "mmcr2", 146, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "siar", 147, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "sdar", 148, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "sier", 149, 0, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.spr");
+  tdesc_create_reg (feature, "tfhar", 150, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "texasr", 151, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "tfiar", 152, 0, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.core");
+  tdesc_create_reg (feature, "cr0", 153, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr1", 154, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr2", 155, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr3", 156, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr4", 157, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr5", 158, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr6", 159, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr7", 160, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr8", 161, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr9", 162, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr10", 163, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr11", 164, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr12", 165, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr13", 166, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr14", 167, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr15", 168, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr16", 169, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr17", 170, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr18", 171, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr19", 172, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr20", 173, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr21", 174, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr22", 175, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr23", 176, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr24", 177, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr25", 178, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr26", 179, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr27", 180, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr28", 181, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr29", 182, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr30", 183, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cr31", 184, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "ccr", 185, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cxer", 186, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "clr", 187, 0, NULL, 32, "code_ptr");
+  tdesc_create_reg (feature, "cctr", 188, 0, NULL, 32, "uint32");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.fpu");
+  tdesc_create_reg (feature, "cf0", 189, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf1", 190, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf2", 191, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf3", 192, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf4", 193, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf5", 194, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf6", 195, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf7", 196, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf8", 197, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf9", 198, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf10", 199, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf11", 200, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf12", 201, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf13", 202, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf14", 203, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf15", 204, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf16", 205, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf17", 206, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf18", 207, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf19", 208, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf20", 209, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf21", 210, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf22", 211, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf23", 212, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf24", 213, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf25", 214, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf26", 215, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf27", 216, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf28", 217, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf29", 218, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf30", 219, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf31", 220, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cfpscr", 221, 0, "float", 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.altivec");
+  element_type = tdesc_named_type (feature, "ieee_single");
+  tdesc_create_vector (feature, "v4f", element_type, 4);
+
+  element_type = tdesc_named_type (feature, "int32");
+  tdesc_create_vector (feature, "v4i32", element_type, 4);
+
+  element_type = tdesc_named_type (feature, "int16");
+  tdesc_create_vector (feature, "v8i16", element_type, 8);
+
+  element_type = tdesc_named_type (feature, "int8");
+  tdesc_create_vector (feature, "v16i8", element_type, 16);
+
+  type_with_fields = tdesc_create_union (feature, "vec128");
+  field_type = tdesc_named_type (feature, "uint128");
+  tdesc_add_field (type_with_fields, "uint128", field_type);
+  field_type = tdesc_named_type (feature, "v4f");
+  tdesc_add_field (type_with_fields, "v4_float", field_type);
+  field_type = tdesc_named_type (feature, "v4i32");
+  tdesc_add_field (type_with_fields, "v4_int32", field_type);
+  field_type = tdesc_named_type (feature, "v8i16");
+  tdesc_add_field (type_with_fields, "v8_int16", field_type);
+  field_type = tdesc_named_type (feature, "v16i8");
+  tdesc_add_field (type_with_fields, "v16_int8", field_type);
+
+  tdesc_create_reg (feature, "cvr0", 222, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr1", 223, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr2", 224, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr3", 225, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr4", 226, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr5", 227, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr6", 228, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr7", 229, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr8", 230, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr9", 231, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr10", 232, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr11", 233, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr12", 234, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr13", 235, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr14", 236, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr15", 237, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr16", 238, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr17", 239, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr18", 240, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr19", 241, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr20", 242, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr21", 243, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr22", 244, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr23", 245, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr24", 246, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr25", 247, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr26", 248, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr27", 249, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr28", 250, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr29", 251, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr30", 252, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr31", 253, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvscr", 254, 0, "vector", 32, "int");
+  tdesc_create_reg (feature, "cvrsave", 255, 0, "vector", 32, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.vsx");
+  tdesc_create_reg (feature, "cvs0h", 256, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs1h", 257, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs2h", 258, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs3h", 259, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs4h", 260, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs5h", 261, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs6h", 262, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs7h", 263, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs8h", 264, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs9h", 265, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs10h", 266, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs11h", 267, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs12h", 268, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs13h", 269, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs14h", 270, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs15h", 271, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs16h", 272, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs17h", 273, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs18h", 274, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs19h", 275, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs20h", 276, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs21h", 277, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs22h", 278, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs23h", 279, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs24h", 280, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs25h", 281, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs26h", 282, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs27h", 283, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs28h", 284, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs29h", 285, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs30h", 286, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs31h", 287, 0, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.ppr");
+  tdesc_create_reg (feature, "cppr", 288, 0, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.dscr");
+  tdesc_create_reg (feature, "cdscr", 289, 0, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.tar");
+  tdesc_create_reg (feature, "ctar", 290, 0, NULL, 64, "uint64");
+
+  tdesc_powerpc_isa207_htm_vsx32l = result;
+}
diff --git a/gdb/features/rs6000/powerpc-isa207-htm-vsx32l.xml b/gdb/features/rs6000/powerpc-isa207-htm-vsx32l.xml
new file mode 100644 (file)
index 0000000..6da85ad
--- /dev/null
@@ -0,0 +1,29 @@
+<?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-ebb.xml"/>
+  <xi:include href="power-linux-pmu.xml"/>
+  <xi:include href="power-htm-spr.xml"/>
+  <xi:include href="power-htm-core.xml"/>
+  <xi:include href="power-htm-fpu.xml"/>
+  <xi:include href="power-htm-altivec.xml"/>
+  <xi:include href="power-htm-vsx.xml"/>
+  <xi:include href="power-htm-ppr.xml"/>
+  <xi:include href="power-htm-dscr.xml"/>
+  <xi:include href="power-htm-tar.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 (file)
index 0000000..0d818d0
--- /dev/null
@@ -0,0 +1,396 @@
+/* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
+  Original: powerpc-isa207-htm-vsx64l.xml */
+
+#include "defs.h"
+#include "osabi.h"
+#include "target-descriptions.h"
+
+struct target_desc *tdesc_powerpc_isa207_htm_vsx64l;
+static void
+initialize_tdesc_powerpc_isa207_htm_vsx64l (void)
+{
+  struct target_desc *result = allocate_target_description ();
+  set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common64"));
+
+  struct tdesc_feature *feature;
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.core");
+  tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r2", 2, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r3", 3, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r4", 4, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r5", 5, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r6", 6, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r7", 7, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r8", 8, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r9", 9, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r10", 10, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r11", 11, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r12", 12, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r13", 13, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r14", 14, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r15", 15, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r16", 16, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r17", 17, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r18", 18, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r19", 19, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r20", 20, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r21", 21, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r22", 22, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r23", 23, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r24", 24, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r25", 25, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r26", 26, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r27", 27, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r28", 28, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r29", 29, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r30", 30, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "r31", 31, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "pc", 64, 1, NULL, 64, "code_ptr");
+  tdesc_create_reg (feature, "msr", 65, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr", 66, 1, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "lr", 67, 1, NULL, 64, "code_ptr");
+  tdesc_create_reg (feature, "ctr", 68, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "xer", 69, 1, NULL, 32, "uint32");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.fpu");
+  tdesc_create_reg (feature, "f0", 32, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f1", 33, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f2", 34, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f3", 35, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f4", 36, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f5", 37, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f6", 38, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f7", 39, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f8", 40, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f9", 41, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f10", 42, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f11", 43, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f12", 44, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f13", 45, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f14", 46, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f15", 47, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f16", 48, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f17", 49, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f18", 50, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f19", 51, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f20", 52, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f21", 53, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f22", 54, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f23", 55, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f24", 56, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f25", 57, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f26", 58, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f27", 59, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f28", 60, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f29", 61, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f30", 62, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f31", 63, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "fpscr", 70, 1, "float", 64, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux");
+  tdesc_create_reg (feature, "orig_r3", 71, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "trap", 72, 1, NULL, 64, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec");
+  tdesc_type *element_type;
+  element_type = tdesc_named_type (feature, "ieee_single");
+  tdesc_create_vector (feature, "v4f", element_type, 4);
+
+  element_type = tdesc_named_type (feature, "int32");
+  tdesc_create_vector (feature, "v4i32", element_type, 4);
+
+  element_type = tdesc_named_type (feature, "int16");
+  tdesc_create_vector (feature, "v8i16", element_type, 8);
+
+  element_type = tdesc_named_type (feature, "int8");
+  tdesc_create_vector (feature, "v16i8", element_type, 16);
+
+  tdesc_type_with_fields *type_with_fields;
+  type_with_fields = tdesc_create_union (feature, "vec128");
+  tdesc_type *field_type;
+  field_type = tdesc_named_type (feature, "uint128");
+  tdesc_add_field (type_with_fields, "uint128", field_type);
+  field_type = tdesc_named_type (feature, "v4f");
+  tdesc_add_field (type_with_fields, "v4_float", field_type);
+  field_type = tdesc_named_type (feature, "v4i32");
+  tdesc_add_field (type_with_fields, "v4_int32", field_type);
+  field_type = tdesc_named_type (feature, "v8i16");
+  tdesc_add_field (type_with_fields, "v8_int16", field_type);
+  field_type = tdesc_named_type (feature, "v16i8");
+  tdesc_add_field (type_with_fields, "v16_int8", field_type);
+
+  tdesc_create_reg (feature, "vr0", 73, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr1", 74, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr2", 75, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr3", 76, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr4", 77, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr5", 78, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr6", 79, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr7", 80, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr8", 81, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr9", 82, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr10", 83, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr11", 84, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr12", 85, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr13", 86, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr14", 87, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr15", 88, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr16", 89, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr17", 90, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr18", 91, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr19", 92, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr20", 93, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr21", 94, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr22", 95, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr23", 96, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr24", 97, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr25", 98, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr26", 99, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr27", 100, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr28", 101, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr29", 102, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr30", 103, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vr31", 104, 1, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "vscr", 105, 1, "vector", 32, "int");
+  tdesc_create_reg (feature, "vrsave", 106, 1, "vector", 32, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.vsx");
+  tdesc_create_reg (feature, "vs0h", 107, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs1h", 108, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs2h", 109, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs3h", 110, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs4h", 111, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs5h", 112, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs6h", 113, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs7h", 114, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs8h", 115, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs9h", 116, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs10h", 117, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs11h", 118, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs12h", 119, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs13h", 120, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs14h", 121, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs15h", 122, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs16h", 123, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs17h", 124, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs18h", 125, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs19h", 126, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs20h", 127, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs21h", 128, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs22h", 129, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs23h", 130, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs24h", 131, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs25h", 132, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs26h", 133, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs27h", 134, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs28h", 135, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs29h", 136, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs30h", 137, 1, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "vs31h", 138, 1, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.ppr");
+  tdesc_create_reg (feature, "ppr", 139, 1, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.dscr");
+  tdesc_create_reg (feature, "dscr", 140, 1, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.tar");
+  tdesc_create_reg (feature, "tar", 141, 1, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.ebb");
+  tdesc_create_reg (feature, "bescr", 142, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "ebbhr", 143, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "ebbrr", 144, 0, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux.pmu");
+  tdesc_create_reg (feature, "mmcr0", 145, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "mmcr2", 146, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "siar", 147, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "sdar", 148, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "sier", 149, 0, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.spr");
+  tdesc_create_reg (feature, "tfhar", 150, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "texasr", 151, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "tfiar", 152, 0, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.core");
+  tdesc_create_reg (feature, "cr0", 153, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr1", 154, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr2", 155, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr3", 156, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr4", 157, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr5", 158, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr6", 159, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr7", 160, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr8", 161, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr9", 162, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr10", 163, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr11", 164, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr12", 165, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr13", 166, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr14", 167, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr15", 168, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr16", 169, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr17", 170, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr18", 171, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr19", 172, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr20", 173, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr21", 174, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr22", 175, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr23", 176, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr24", 177, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr25", 178, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr26", 179, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr27", 180, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr28", 181, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr29", 182, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr30", 183, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cr31", 184, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "ccr", 185, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "cxer", 186, 0, NULL, 32, "uint32");
+  tdesc_create_reg (feature, "clr", 187, 0, NULL, 64, "code_ptr");
+  tdesc_create_reg (feature, "cctr", 188, 0, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.fpu");
+  tdesc_create_reg (feature, "cf0", 189, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf1", 190, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf2", 191, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf3", 192, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf4", 193, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf5", 194, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf6", 195, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf7", 196, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf8", 197, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf9", 198, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf10", 199, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf11", 200, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf12", 201, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf13", 202, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf14", 203, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf15", 204, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf16", 205, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf17", 206, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf18", 207, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf19", 208, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf20", 209, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf21", 210, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf22", 211, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf23", 212, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf24", 213, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf25", 214, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf26", 215, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf27", 216, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf28", 217, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf29", 218, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf30", 219, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cf31", 220, 0, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "cfpscr", 221, 0, "float", 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.altivec");
+  element_type = tdesc_named_type (feature, "ieee_single");
+  tdesc_create_vector (feature, "v4f", element_type, 4);
+
+  element_type = tdesc_named_type (feature, "int32");
+  tdesc_create_vector (feature, "v4i32", element_type, 4);
+
+  element_type = tdesc_named_type (feature, "int16");
+  tdesc_create_vector (feature, "v8i16", element_type, 8);
+
+  element_type = tdesc_named_type (feature, "int8");
+  tdesc_create_vector (feature, "v16i8", element_type, 16);
+
+  type_with_fields = tdesc_create_union (feature, "vec128");
+  field_type = tdesc_named_type (feature, "uint128");
+  tdesc_add_field (type_with_fields, "uint128", field_type);
+  field_type = tdesc_named_type (feature, "v4f");
+  tdesc_add_field (type_with_fields, "v4_float", field_type);
+  field_type = tdesc_named_type (feature, "v4i32");
+  tdesc_add_field (type_with_fields, "v4_int32", field_type);
+  field_type = tdesc_named_type (feature, "v8i16");
+  tdesc_add_field (type_with_fields, "v8_int16", field_type);
+  field_type = tdesc_named_type (feature, "v16i8");
+  tdesc_add_field (type_with_fields, "v16_int8", field_type);
+
+  tdesc_create_reg (feature, "cvr0", 222, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr1", 223, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr2", 224, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr3", 225, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr4", 226, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr5", 227, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr6", 228, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr7", 229, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr8", 230, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr9", 231, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr10", 232, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr11", 233, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr12", 234, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr13", 235, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr14", 236, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr15", 237, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr16", 238, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr17", 239, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr18", 240, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr19", 241, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr20", 242, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr21", 243, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr22", 244, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr23", 245, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr24", 246, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr25", 247, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr26", 248, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr27", 249, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr28", 250, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr29", 251, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr30", 252, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvr31", 253, 0, NULL, 128, "vec128");
+  tdesc_create_reg (feature, "cvscr", 254, 0, "vector", 32, "int");
+  tdesc_create_reg (feature, "cvrsave", 255, 0, "vector", 32, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.vsx");
+  tdesc_create_reg (feature, "cvs0h", 256, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs1h", 257, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs2h", 258, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs3h", 259, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs4h", 260, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs5h", 261, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs6h", 262, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs7h", 263, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs8h", 264, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs9h", 265, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs10h", 266, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs11h", 267, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs12h", 268, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs13h", 269, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs14h", 270, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs15h", 271, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs16h", 272, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs17h", 273, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs18h", 274, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs19h", 275, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs20h", 276, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs21h", 277, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs22h", 278, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs23h", 279, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs24h", 280, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs25h", 281, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs26h", 282, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs27h", 283, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs28h", 284, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs29h", 285, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs30h", 286, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "cvs31h", 287, 0, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.ppr");
+  tdesc_create_reg (feature, "cppr", 288, 0, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.dscr");
+  tdesc_create_reg (feature, "cdscr", 289, 0, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.htm.tar");
+  tdesc_create_reg (feature, "ctar", 290, 0, NULL, 64, "uint64");
+
+  tdesc_powerpc_isa207_htm_vsx64l = result;
+}
diff --git a/gdb/features/rs6000/powerpc-isa207-htm-vsx64l.xml b/gdb/features/rs6000/powerpc-isa207-htm-vsx64l.xml
new file mode 100644 (file)
index 0000000..28a8ea2
--- /dev/null
@@ -0,0 +1,29 @@
+<?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="power-ebb.xml"/>
+  <xi:include href="power-linux-pmu.xml"/>
+  <xi:include href="power-htm-spr.xml"/>
+  <xi:include href="power64-htm-core.xml"/>
+  <xi:include href="power-htm-fpu.xml"/>
+  <xi:include href="power-htm-altivec.xml"/>
+  <xi:include href="power-htm-vsx.xml"/>
+  <xi:include href="power-htm-ppr.xml"/>
+  <xi:include href="power-htm-dscr.xml"/>
+  <xi:include href="power-htm-tar.xml"/>
+</target>
index 56e724d..f7ae351 100644 (file)
@@ -1,5 +1,40 @@
 2018-10-26  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-spr.xml, rs6000/power-htm-core.xml,
+       rs6000/power64-htm-core.xml, rs6000/power-htm-fpu.xml,
+       rs6000/power-htm-altivec.xml, rs6000/power-htm-vsx.xml,
+       rs6000/power-htm-ppr.xml, rs6000/power-htm-dscr.xml,
+       rs6000/power-htm-tar.xml, rs6000/powerpc-isa207-htm-vsx32l.xml,
+       and rs6000/powerpc-isa207-htm-vsx64l.xml to srv_xmlfiles.
+       * linux-ppc-tdesc-init.h (enum ppc_linux_tdesc)
+       <PPC_TDESC_ISA207_HTM_VSX>: New enum value.
+       (init_registers_powerpc_isa207_htm_vsx32l)
+       (init_registers_powerpc_isa207_htm_vsx64l): Declare.
+       * linux-ppc-low.c (ppc_fill_tm_sprregset, ppc_store_tm_sprregset)
+       (ppc_store_tm_cgprregset, ppc_store_tm_cfprregset)
+       (ppc_store_tm_cvrregset, ppc_store_tm_cvsxregset)
+       (ppc_store_tm_cpprregset, ppc_store_tm_cdscrregset)
+       (ppc_store_tm_ctarregset): New functions.
+       (ppc_regsets): Add entries for HTM regsets.
+       (ppc_arch_setup): Set htm in features struct when needed.  Set
+       sizes for the HTM regsets.
+       (ppc_get_ipa_tdesc_idx): Return PPC_TDESC_ISA207_HTM_VSX.
+       (initialize_low_arch): Call
+       init_registers_powerpc_isa207_htm_vsx32l and
+       init_registers_powerpc_isa207_htm_vsx64l.
+       * linux-ppc-ipa.c (get_ipa_tdesc): Handle
+       PPC_TDESC_ISA207_HTM_VSX.
+       (initialize_low_tracepoint): Call
+       init_registers_powerpc_isa207_htm_vsx32l and
+       init_registers_powerpc_isa207_htm_vsx64l.
+
+2018-10-26  Pedro Franco de Carvalho  <pedromfc@linux.ibm.com>
+
        * configure.srv (powerpc*-*-linux*): Add rs6000/power-ebb.xml and
        rs6000/power-linux-pmu.xml to srv_xmlfiles.
        * linux-ppc-low.c (ppc_store_ebbregset, ppc_fill_pmuregset)
index eb5f208..d19d22b 100644 (file)
@@ -32,7 +32,7 @@ else
    srv_amd64_linux_regobj=""
 fi
 
-ipa_ppc_linux_regobj="powerpc-32l-ipa.o powerpc-altivec32l-ipa.o powerpc-cell32l-ipa.o powerpc-vsx32l-ipa.o powerpc-isa205-32l-ipa.o powerpc-isa205-altivec32l-ipa.o powerpc-isa205-vsx32l-ipa.o powerpc-isa205-ppr-dscr-vsx32l-ipa.o powerpc-isa207-vsx32l-ipa.o powerpc-e500l-ipa.o powerpc-64l-ipa.o powerpc-altivec64l-ipa.o powerpc-cell64l-ipa.o powerpc-vsx64l-ipa.o powerpc-isa205-64l-ipa.o powerpc-isa205-altivec64l-ipa.o powerpc-isa205-vsx64l-ipa.o powerpc-isa205-ppr-dscr-vsx64l-ipa.o powerpc-isa207-vsx64l-ipa.o"
+ipa_ppc_linux_regobj="powerpc-32l-ipa.o powerpc-altivec32l-ipa.o powerpc-cell32l-ipa.o powerpc-vsx32l-ipa.o powerpc-isa205-32l-ipa.o powerpc-isa205-altivec32l-ipa.o powerpc-isa205-vsx32l-ipa.o powerpc-isa205-ppr-dscr-vsx32l-ipa.o powerpc-isa207-vsx32l-ipa.o powerpc-isa207-htm-vsx32l-ipa.o powerpc-e500l-ipa.o powerpc-64l-ipa.o powerpc-altivec64l-ipa.o powerpc-cell64l-ipa.o powerpc-vsx64l-ipa.o powerpc-isa205-64l-ipa.o powerpc-isa205-altivec64l-ipa.o powerpc-isa205-vsx64l-ipa.o powerpc-isa205-ppr-dscr-vsx64l-ipa.o powerpc-isa207-vsx64l-ipa.o powerpc-isa207-htm-vsx64l-ipa.o"
 
 # Linux object files.  This is so we don't have to repeat
 # these files over and over again.
@@ -219,6 +219,7 @@ case "${target}" in
                        srv_regobj="${srv_regobj} powerpc-isa205-vsx32l.o"
                        srv_regobj="${srv_regobj} powerpc-isa205-ppr-dscr-vsx32l.o"
                        srv_regobj="${srv_regobj} powerpc-isa207-vsx32l.o"
+                       srv_regobj="${srv_regobj} powerpc-isa207-htm-vsx32l.o"
                        srv_regobj="${srv_regobj} powerpc-e500l.o"
                        srv_regobj="${srv_regobj} powerpc-64l.o"
                        srv_regobj="${srv_regobj} powerpc-altivec64l.o"
@@ -229,6 +230,7 @@ case "${target}" in
                        srv_regobj="${srv_regobj} powerpc-isa205-vsx64l.o"
                        srv_regobj="${srv_regobj} powerpc-isa205-ppr-dscr-vsx64l.o"
                        srv_regobj="${srv_regobj} powerpc-isa207-vsx64l.o"
+                       srv_regobj="${srv_regobj} powerpc-isa207-htm-vsx64l.o"
                        srv_tgtobj="$srv_linux_obj linux-ppc-low.o ppc-linux.o"
                        srv_tgtobj="${srv_tgtobj} arch/ppc-linux-common.o"
                        srv_xmlfiles="rs6000/powerpc-32l.xml"
@@ -240,6 +242,7 @@ case "${target}" in
                        srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-vsx32l.xml"
                        srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml"
                        srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa207-vsx32l.xml"
+                       srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa207-htm-vsx32l.xml"
                        srv_xmlfiles="${srv_xmlfiles} rs6000/power-altivec.xml"
                        srv_xmlfiles="${srv_xmlfiles} rs6000/power-vsx.xml"
                        srv_xmlfiles="${srv_xmlfiles} rs6000/power-core.xml"
@@ -251,6 +254,14 @@ case "${target}" in
                        srv_xmlfiles="${srv_xmlfiles} rs6000/power-tar.xml"
                        srv_xmlfiles="${srv_xmlfiles} rs6000/power-ebb.xml"
                        srv_xmlfiles="${srv_xmlfiles} rs6000/power-linux-pmu.xml"
+                       srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-spr.xml"
+                       srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-core.xml"
+                       srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-fpu.xml"
+                       srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-altivec.xml"
+                       srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-vsx.xml"
+                       srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-ppr.xml"
+                       srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-dscr.xml"
+                       srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-tar.xml"
                        srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-e500l.xml"
                        srv_xmlfiles="${srv_xmlfiles} rs6000/power-spe.xml"
                        srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-64l.xml"
@@ -262,8 +273,10 @@ case "${target}" in
                        srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-vsx64l.xml"
                        srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml"
                        srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa207-vsx64l.xml"
+                       srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa207-htm-vsx64l.xml"
                        srv_xmlfiles="${srv_xmlfiles} rs6000/power64-core.xml"
                        srv_xmlfiles="${srv_xmlfiles} rs6000/power64-linux.xml"
+                       srv_xmlfiles="${srv_xmlfiles} rs6000/power64-htm-core.xml"
                        srv_linux_usrregs=yes
                        srv_linux_regsets=yes
                        srv_linux_thread_db=yes
index b543dce..348d455 100644 (file)
@@ -195,6 +195,8 @@ get_ipa_tdesc (int idx)
       return tdesc_powerpc_isa205_ppr_dscr_vsx64l;
     case PPC_TDESC_ISA207_VSX:
       return tdesc_powerpc_isa207_vsx64l;
+    case PPC_TDESC_ISA207_HTM_VSX:
+      return tdesc_powerpc_isa207_htm_vsx64l;
 #else
     case PPC_TDESC_BASE:
       return tdesc_powerpc_32l;
@@ -214,6 +216,8 @@ get_ipa_tdesc (int idx)
       return tdesc_powerpc_isa205_ppr_dscr_vsx32l;
     case PPC_TDESC_ISA207_VSX:
       return tdesc_powerpc_isa207_vsx32l;
+    case PPC_TDESC_ISA207_HTM_VSX:
+      return tdesc_powerpc_isa207_htm_vsx32l;
     case PPC_TDESC_E500:
       return tdesc_powerpc_e500l;
 #endif
@@ -244,6 +248,7 @@ initialize_low_tracepoint (void)
   init_registers_powerpc_isa205_vsx64l ();
   init_registers_powerpc_isa205_ppr_dscr_vsx64l ();
   init_registers_powerpc_isa207_vsx64l ();
+  init_registers_powerpc_isa207_htm_vsx64l ();
 #else
   init_registers_powerpc_32l ();
   init_registers_powerpc_altivec32l ();
@@ -254,6 +259,7 @@ initialize_low_tracepoint (void)
   init_registers_powerpc_isa205_vsx32l ();
   init_registers_powerpc_isa205_ppr_dscr_vsx32l ();
   init_registers_powerpc_isa207_vsx32l ();
+  init_registers_powerpc_isa207_htm_vsx32l ();
   init_registers_powerpc_e500l ();
 #endif
 }
index e328151..12cb56a 100644 (file)
@@ -600,6 +600,158 @@ ppc_store_pmuregset (struct regcache *regcache, const void *buf)
   supply_register_by_name (regcache, "mmcr0", &regset[32]);
 }
 
+/* Hardware Transactional Memory special-purpose register regset fill
+   function.  */
+
+static void
+ppc_fill_tm_sprregset (struct regcache *regcache, void *buf)
+{
+  int i, base;
+  char *regset = (char *) buf;
+
+  base = find_regno (regcache->tdesc, "tfhar");
+  for (i = 0; i < 3; i++)
+    collect_register (regcache, base + i, &regset[i * 8]);
+}
+
+/* Hardware Transactional Memory special-purpose register regset store
+   function.  */
+
+static void
+ppc_store_tm_sprregset (struct regcache *regcache, const void *buf)
+{
+  int i, base;
+  const char *regset = (const char *) buf;
+
+  base = find_regno (regcache->tdesc, "tfhar");
+  for (i = 0; i < 3; i++)
+    supply_register (regcache, base + i, &regset[i * 8]);
+}
+
+/* For the same reasons as the EBB regset, none of the HTM
+   checkpointed regsets have a fill function.  These registers are
+   only available if the inferior is in a transaction.  */
+
+/* Hardware Transactional Memory checkpointed general-purpose regset
+   store function.  */
+
+static void
+ppc_store_tm_cgprregset (struct regcache *regcache, const void *buf)
+{
+  int i, base, size, endian_offset;
+  const char *regset = (const char *) buf;
+
+  base = find_regno (regcache->tdesc, "cr0");
+  size = register_size (regcache->tdesc, base);
+
+  gdb_assert (size == 4 || size == 8);
+
+  for (i = 0; i < 32; i++)
+    supply_register (regcache, base + i, &regset[i * size]);
+
+  endian_offset = 0;
+
+  if ((size == 8) && (__BYTE_ORDER == __BIG_ENDIAN))
+    endian_offset = 4;
+
+  supply_register_by_name (regcache, "ccr",
+                          &regset[PT_CCR * size + endian_offset]);
+
+  supply_register_by_name (regcache, "cxer",
+                          &regset[PT_XER * size + endian_offset]);
+
+  supply_register_by_name (regcache, "clr", &regset[PT_LNK * size]);
+  supply_register_by_name (regcache, "cctr", &regset[PT_CTR * size]);
+}
+
+/* Hardware Transactional Memory checkpointed floating-point regset
+   store function.  */
+
+static void
+ppc_store_tm_cfprregset (struct regcache *regcache, const void *buf)
+{
+  int i, base;
+  const char *regset = (const char *) buf;
+
+  base = find_regno (regcache->tdesc, "cf0");
+
+  for (i = 0; i < 32; i++)
+    supply_register (regcache, base + i, &regset[i * 8]);
+
+  supply_register_by_name (regcache, "cfpscr", &regset[32 * 8]);
+}
+
+/* Hardware Transactional Memory checkpointed vector regset store
+   function.  */
+
+static void
+ppc_store_tm_cvrregset (struct regcache *regcache, const void *buf)
+{
+  int i, base;
+  const char *regset = (const char *) buf;
+  int vscr_offset = 0;
+
+  base = find_regno (regcache->tdesc, "cvr0");
+
+  for (i = 0; i < 32; i++)
+    supply_register (regcache, base + i, &regset[i * 16]);
+
+  if (__BYTE_ORDER == __BIG_ENDIAN)
+    vscr_offset = 12;
+
+  supply_register_by_name (regcache, "cvscr",
+                          &regset[32 * 16 + vscr_offset]);
+
+  supply_register_by_name (regcache, "cvrsave", &regset[33 * 16]);
+}
+
+/* Hardware Transactional Memory checkpointed vector-scalar regset
+   store function.  */
+
+static void
+ppc_store_tm_cvsxregset (struct regcache *regcache, const void *buf)
+{
+  int i, base;
+  const char *regset = (const char *) buf;
+
+  base = find_regno (regcache->tdesc, "cvs0h");
+  for (i = 0; i < 32; i++)
+    supply_register (regcache, base + i, &regset[i * 8]);
+}
+
+/* Hardware Transactional Memory checkpointed Program Priority
+   Register regset store function.  */
+
+static void
+ppc_store_tm_cpprregset (struct regcache *regcache, const void *buf)
+{
+  const char *cppr = (const char *) buf;
+
+  supply_register_by_name (regcache, "cppr", cppr);
+}
+
+/* Hardware Transactional Memory checkpointed Data Stream Control
+   Register regset store function.  */
+
+static void
+ppc_store_tm_cdscrregset (struct regcache *regcache, const void *buf)
+{
+  const char *cdscr = (const char *) buf;
+
+  supply_register_by_name (regcache, "cdscr", cdscr);
+}
+
+/* Hardware Transactional Memory checkpointed Target Address Register
+   regset store function.  */
+
+static void
+ppc_store_tm_ctarregset (struct regcache *regcache, const void *buf)
+{
+  const char *ctar = (const char *) buf;
+
+  supply_register_by_name (regcache, "ctar", ctar);
+}
+
 static void
 ppc_fill_vsxregset (struct regcache *regcache, void *buf)
 {
@@ -709,6 +861,22 @@ static struct regset_info ppc_regsets[] = {
      fetch them every time, but still fall back to PTRACE_PEEKUSER for the
      general registers.  Some kernels support these, but not the newer
      PPC_PTRACE_GETREGS.  */
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CTAR, 0, EXTENDED_REGS,
+    NULL, ppc_store_tm_ctarregset },
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CDSCR, 0, EXTENDED_REGS,
+    NULL, ppc_store_tm_cdscrregset },
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CPPR, 0, EXTENDED_REGS,
+    NULL, ppc_store_tm_cpprregset },
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CVSX, 0, EXTENDED_REGS,
+    NULL, ppc_store_tm_cvsxregset },
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CVMX, 0, EXTENDED_REGS,
+    NULL, ppc_store_tm_cvrregset },
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CFPR, 0, EXTENDED_REGS,
+    NULL, ppc_store_tm_cfprregset },
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_CGPR, 0, EXTENDED_REGS,
+    NULL, ppc_store_tm_cgprregset },
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TM_SPR, 0, EXTENDED_REGS,
+    ppc_fill_tm_sprregset, ppc_store_tm_sprregset },
   { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_EBB, 0, EXTENDED_REGS,
     NULL, ppc_store_ebbregset },
   { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_PMU, 0, EXTENDED_REGS,
@@ -800,7 +968,13 @@ ppc_arch_setup (void)
                               PPC_LINUX_SIZEOF_EBBREGSET)
          && ppc_check_regset (tid, NT_PPC_PMU,
                               PPC_LINUX_SIZEOF_PMUREGSET))
-       features.isa207 = true;
+       {
+         features.isa207 = true;
+         if ((ppc_hwcap2 & PPC_FEATURE2_HTM)
+             && ppc_check_regset (tid, NT_PPC_TM_SPR,
+                                  PPC_LINUX_SIZEOF_TM_SPRREGSET))
+           features.htm = true;
+       }
     }
 
   if (ppc_hwcap & PPC_FEATURE_CELL)
@@ -870,6 +1044,42 @@ ppc_arch_setup (void)
            regset->size = (features.isa207 ?
                            PPC_LINUX_SIZEOF_PMUREGSET : 0);
            break;
+         case NT_PPC_TM_SPR:
+           regset->size = (features.htm ?
+                           PPC_LINUX_SIZEOF_TM_SPRREGSET : 0);
+           break;
+         case NT_PPC_TM_CGPR:
+           if (features.wordsize == 4)
+             regset->size = (features.htm ?
+                             PPC32_LINUX_SIZEOF_CGPRREGSET : 0);
+           else
+             regset->size = (features.htm ?
+                             PPC64_LINUX_SIZEOF_CGPRREGSET : 0);
+           break;
+         case NT_PPC_TM_CFPR:
+           regset->size = (features.htm ?
+                           PPC_LINUX_SIZEOF_CFPRREGSET : 0);
+           break;
+         case NT_PPC_TM_CVMX:
+           regset->size = (features.htm ?
+                           PPC_LINUX_SIZEOF_CVMXREGSET : 0);
+           break;
+         case NT_PPC_TM_CVSX:
+           regset->size = (features.htm ?
+                           PPC_LINUX_SIZEOF_CVSXREGSET : 0);
+           break;
+         case NT_PPC_TM_CPPR:
+           regset->size = (features.htm ?
+                           PPC_LINUX_SIZEOF_CPPRREGSET : 0);
+           break;
+         case NT_PPC_TM_CDSCR:
+           regset->size = (features.htm ?
+                           PPC_LINUX_SIZEOF_CDSCRREGSET : 0);
+           break;
+         case NT_PPC_TM_CTAR:
+           regset->size = (features.htm ?
+                           PPC_LINUX_SIZEOF_CTARREGSET : 0);
+           break;
          default:
            break;
          }
@@ -3253,6 +3463,8 @@ ppc_get_ipa_tdesc_idx (void)
     return PPC_TDESC_ISA205_PPR_DSCR_VSX;
   if (tdesc == tdesc_powerpc_isa207_vsx64l)
     return PPC_TDESC_ISA207_VSX;
+  if (tdesc == tdesc_powerpc_isa207_htm_vsx64l)
+    return PPC_TDESC_ISA207_HTM_VSX;
 #endif
 
   if (tdesc == tdesc_powerpc_32l)
@@ -3273,6 +3485,8 @@ ppc_get_ipa_tdesc_idx (void)
     return PPC_TDESC_ISA205_PPR_DSCR_VSX;
   if (tdesc == tdesc_powerpc_isa207_vsx32l)
     return PPC_TDESC_ISA207_VSX;
+  if (tdesc == tdesc_powerpc_isa207_htm_vsx32l)
+    return PPC_TDESC_ISA207_HTM_VSX;
   if (tdesc == tdesc_powerpc_e500l)
     return PPC_TDESC_E500;
 
@@ -3333,6 +3547,7 @@ initialize_low_arch (void)
   init_registers_powerpc_isa205_vsx32l ();
   init_registers_powerpc_isa205_ppr_dscr_vsx32l ();
   init_registers_powerpc_isa207_vsx32l ();
+  init_registers_powerpc_isa207_htm_vsx32l ();
   init_registers_powerpc_e500l ();
 #if __powerpc64__
   init_registers_powerpc_64l ();
@@ -3344,6 +3559,7 @@ initialize_low_arch (void)
   init_registers_powerpc_isa205_vsx64l ();
   init_registers_powerpc_isa205_ppr_dscr_vsx64l ();
   init_registers_powerpc_isa207_vsx64l ();
+  init_registers_powerpc_isa207_htm_vsx64l ();
 #endif
 
   initialize_regsets_info (&ppc_regsets_info);
index 29b8122..d1dfdad 100644 (file)
@@ -31,6 +31,7 @@ enum ppc_linux_tdesc {
   PPC_TDESC_ISA205_VSX,
   PPC_TDESC_ISA205_PPR_DSCR_VSX,
   PPC_TDESC_ISA207_VSX,
+  PPC_TDESC_ISA207_HTM_VSX,
   PPC_TDESC_E500,
 };
 
@@ -63,6 +64,9 @@ void init_registers_powerpc_isa205_ppr_dscr_vsx32l (void);
 /* Defined in auto-generated file powerpc-isa207-vsx32l.c.  */
 void init_registers_powerpc_isa207_vsx32l (void);
 
+/* Defined in auto-generated file powerpc-isa207-htm-vsx32l.c.  */
+void init_registers_powerpc_isa207_htm_vsx32l (void);
+
 /* Defined in auto-generated file powerpc-e500l.c.  */
 void init_registers_powerpc_e500l (void);
 
@@ -97,4 +101,7 @@ void init_registers_powerpc_isa205_ppr_dscr_vsx64l (void);
 /* Defined in auto-generated file powerpc-isa207-vsx64l.c.  */
 void init_registers_powerpc_isa207_vsx64l (void);
 
+/* Defined in auto-generated file powerpc-isa207-htm-vsx64l.c.  */
+void init_registers_powerpc_isa207_htm_vsx64l (void);
+
 #endif
index c965030..65c60cb 100644 (file)
@@ -63,6 +63,9 @@
 #ifndef PPC_FEATURE2_EBB
 #define PPC_FEATURE2_EBB 0x10000000
 #endif
+#ifndef PPC_FEATURE2_HTM
+#define PPC_FEATURE2_HTM 0x40000000
+#endif
 
 /* Glibc's headers don't define PTRACE_GETVRREGS so we cannot use a
    configure time check.  Some older glibc's (for instance 2.2.1)
 #define NT_PPC_PMU 0x107
 #endif
 
+/* TM checkpointed GPR Registers.  */
+#ifndef NT_PPC_TM_CGPR
+#define NT_PPC_TM_CGPR 0x108
+#endif
+
+/* TM checkpointed FPR Registers.  */
+#ifndef NT_PPC_TM_CFPR
+#define NT_PPC_TM_CFPR 0x109
+#endif
+
+/* TM checkpointed VMX Registers.  */
+#ifndef NT_PPC_TM_CVMX
+#define NT_PPC_TM_CVMX 0x10a
+#endif
+
+/* TM checkpointed VSX Registers.  */
+#ifndef NT_PPC_TM_CVSX
+#define NT_PPC_TM_CVSX 0x10b
+#endif
+
+/* TM Special Purpose Registers.  */
+#ifndef NT_PPC_TM_SPR
+#define NT_PPC_TM_SPR 0x10c
+#endif
+
+/* TM checkpointed Target Address Register.  */
+#ifndef NT_PPC_TM_CTAR
+#define NT_PPC_TM_CTAR 0x10d
+#endif
+
+/* TM checkpointed Program Priority Register.  */
+#ifndef NT_PPC_TM_CPPR
+#define NT_PPC_TM_CPPR 0x10e
+#endif
+
+/* TM checkpointed Data Stream Control Register.  */
+#ifndef NT_PPC_TM_CDSCR
+#define NT_PPC_TM_CDSCR 0x10f
+#endif
+
 /* Return the wordsize of the target, either 4 or 8 bytes.  */
 int ppc_linux_target_wordsize (int tid);
 
index 0bbdcdc..e83912d 100644 (file)
@@ -684,6 +684,82 @@ fetch_register (struct regcache *regcache, int tid, int regno)
                    &ppc32_linux_pmuregset);
       return;
     }
+  else if (PPC_IS_TMSPR_REGNUM (regno))
+    {
+      gdb_assert (tdep->have_htm_spr);
+
+      fetch_regset (regcache, tid, NT_PPC_TM_SPR,
+                   PPC_LINUX_SIZEOF_TM_SPRREGSET,
+                   &ppc32_linux_tm_sprregset);
+      return;
+    }
+  else if (PPC_IS_CKPTGP_REGNUM (regno))
+    {
+      gdb_assert (tdep->have_htm_core);
+
+      const struct regset *cgprregset = ppc_linux_cgprregset (gdbarch);
+      fetch_regset (regcache, tid, NT_PPC_TM_CGPR,
+                   (tdep->wordsize == 4?
+                    PPC32_LINUX_SIZEOF_CGPRREGSET
+                    : PPC64_LINUX_SIZEOF_CGPRREGSET),
+                   cgprregset);
+      return;
+    }
+  else if (PPC_IS_CKPTFP_REGNUM (regno))
+    {
+      gdb_assert (tdep->have_htm_fpu);
+
+      fetch_regset (regcache, tid, NT_PPC_TM_CFPR,
+                   PPC_LINUX_SIZEOF_CFPRREGSET,
+                   &ppc32_linux_cfprregset);
+      return;
+    }
+  else if (PPC_IS_CKPTVMX_REGNUM (regno))
+    {
+      gdb_assert (tdep->have_htm_altivec);
+
+      const struct regset *cvmxregset = ppc_linux_cvmxregset (gdbarch);
+      fetch_regset (regcache, tid, NT_PPC_TM_CVMX,
+                   PPC_LINUX_SIZEOF_CVMXREGSET,
+                   cvmxregset);
+      return;
+    }
+  else if (PPC_IS_CKPTVSX_REGNUM (regno))
+    {
+      gdb_assert (tdep->have_htm_vsx);
+
+      fetch_regset (regcache, tid, NT_PPC_TM_CVSX,
+                   PPC_LINUX_SIZEOF_CVSXREGSET,
+                   &ppc32_linux_cvsxregset);
+      return;
+    }
+  else if (regno == PPC_CPPR_REGNUM)
+    {
+      gdb_assert (tdep->ppc_cppr_regnum != -1);
+
+      fetch_regset (regcache, tid, NT_PPC_TM_CPPR,
+                   PPC_LINUX_SIZEOF_CPPRREGSET,
+                   &ppc32_linux_cpprregset);
+      return;
+    }
+  else if (regno == PPC_CDSCR_REGNUM)
+    {
+      gdb_assert (tdep->ppc_cdscr_regnum != -1);
+
+      fetch_regset (regcache, tid, NT_PPC_TM_CDSCR,
+                   PPC_LINUX_SIZEOF_CDSCRREGSET,
+                   &ppc32_linux_cdscrregset);
+      return;
+    }
+  else if (regno == PPC_CTAR_REGNUM)
+    {
+      gdb_assert (tdep->ppc_ctar_regnum != -1);
+
+      fetch_regset (regcache, tid, NT_PPC_TM_CTAR,
+                   PPC_LINUX_SIZEOF_CTARREGSET,
+                   &ppc32_linux_ctarregset);
+      return;
+    }
 
   if (regaddr == -1)
     {
@@ -897,6 +973,46 @@ fetch_ppc_registers (struct regcache *regcache, int tid)
     fetch_regset (regcache, tid, NT_PPC_PMU,
                  PPC_LINUX_SIZEOF_PMUREGSET,
                  &ppc32_linux_pmuregset);
+  if (tdep->have_htm_spr)
+    fetch_regset (regcache, tid, NT_PPC_TM_SPR,
+                 PPC_LINUX_SIZEOF_TM_SPRREGSET,
+                 &ppc32_linux_tm_sprregset);
+  if (tdep->have_htm_core)
+    {
+      const struct regset *cgprregset = ppc_linux_cgprregset (gdbarch);
+      fetch_regset (regcache, tid, NT_PPC_TM_CGPR,
+                   (tdep->wordsize == 4?
+                    PPC32_LINUX_SIZEOF_CGPRREGSET
+                    : PPC64_LINUX_SIZEOF_CGPRREGSET),
+                   cgprregset);
+    }
+  if (tdep->have_htm_fpu)
+    fetch_regset (regcache, tid, NT_PPC_TM_CFPR,
+                 PPC_LINUX_SIZEOF_CFPRREGSET,
+                 &ppc32_linux_cfprregset);
+  if (tdep->have_htm_altivec)
+    {
+      const struct regset *cvmxregset = ppc_linux_cvmxregset (gdbarch);
+      fetch_regset (regcache, tid, NT_PPC_TM_CVMX,
+                   PPC_LINUX_SIZEOF_CVMXREGSET,
+                   cvmxregset);
+    }
+  if (tdep->have_htm_vsx)
+    fetch_regset (regcache, tid, NT_PPC_TM_CVSX,
+                 PPC_LINUX_SIZEOF_CVSXREGSET,
+                 &ppc32_linux_cvsxregset);
+  if (tdep->ppc_cppr_regnum != -1)
+    fetch_regset (regcache, tid, NT_PPC_TM_CPPR,
+                 PPC_LINUX_SIZEOF_CPPRREGSET,
+                 &ppc32_linux_cpprregset);
+  if (tdep->ppc_cdscr_regnum != -1)
+    fetch_regset (regcache, tid, NT_PPC_TM_CDSCR,
+                 PPC_LINUX_SIZEOF_CDSCRREGSET,
+                 &ppc32_linux_cdscrregset);
+  if (tdep->ppc_ctar_regnum != -1)
+    fetch_regset (regcache, tid, NT_PPC_TM_CTAR,
+                 PPC_LINUX_SIZEOF_CTARREGSET,
+                 &ppc32_linux_ctarregset);
 }
 
 /* Fetch registers from the child process.  Fetch all registers if
@@ -1122,6 +1238,82 @@ store_register (const struct regcache *regcache, int tid, int regno)
                    &ppc32_linux_pmuregset);
       return;
     }
+  else if (PPC_IS_TMSPR_REGNUM (regno))
+    {
+      gdb_assert (tdep->have_htm_spr);
+
+      store_regset (regcache, tid, regno, NT_PPC_TM_SPR,
+                   PPC_LINUX_SIZEOF_TM_SPRREGSET,
+                   &ppc32_linux_tm_sprregset);
+      return;
+    }
+  else if (PPC_IS_CKPTGP_REGNUM (regno))
+    {
+      gdb_assert (tdep->have_htm_core);
+
+      const struct regset *cgprregset = ppc_linux_cgprregset (gdbarch);
+      store_regset (regcache, tid, regno, NT_PPC_TM_CGPR,
+                   (tdep->wordsize == 4?
+                    PPC32_LINUX_SIZEOF_CGPRREGSET
+                    : PPC64_LINUX_SIZEOF_CGPRREGSET),
+                   cgprregset);
+      return;
+    }
+  else if (PPC_IS_CKPTFP_REGNUM (regno))
+    {
+      gdb_assert (tdep->have_htm_fpu);
+
+      store_regset (regcache, tid, regno, NT_PPC_TM_CFPR,
+                   PPC_LINUX_SIZEOF_CFPRREGSET,
+                   &ppc32_linux_cfprregset);
+      return;
+    }
+  else if (PPC_IS_CKPTVMX_REGNUM (regno))
+    {
+      gdb_assert (tdep->have_htm_altivec);
+
+      const struct regset *cvmxregset = ppc_linux_cvmxregset (gdbarch);
+      store_regset (regcache, tid, regno, NT_PPC_TM_CVMX,
+                   PPC_LINUX_SIZEOF_CVMXREGSET,
+                   cvmxregset);
+      return;
+    }
+  else if (PPC_IS_CKPTVSX_REGNUM (regno))
+    {
+      gdb_assert (tdep->have_htm_vsx);
+
+      store_regset (regcache, tid, regno, NT_PPC_TM_CVSX,
+                   PPC_LINUX_SIZEOF_CVSXREGSET,
+                   &ppc32_linux_cvsxregset);
+      return;
+    }
+  else if (regno == PPC_CPPR_REGNUM)
+    {
+      gdb_assert (tdep->ppc_cppr_regnum != -1);
+
+      store_regset (regcache, tid, regno, NT_PPC_TM_CPPR,
+                   PPC_LINUX_SIZEOF_CPPRREGSET,
+                   &ppc32_linux_cpprregset);
+      return;
+    }
+  else if (regno == PPC_CDSCR_REGNUM)
+    {
+      gdb_assert (tdep->ppc_cdscr_regnum != -1);
+
+      store_regset (regcache, tid, regno, NT_PPC_TM_CDSCR,
+                   PPC_LINUX_SIZEOF_CDSCRREGSET,
+                   &ppc32_linux_cdscrregset);
+      return;
+    }
+  else if (regno == PPC_CTAR_REGNUM)
+    {
+      gdb_assert (tdep->ppc_ctar_regnum != -1);
+
+      store_regset (regcache, tid, regno, NT_PPC_TM_CTAR,
+                   PPC_LINUX_SIZEOF_CTARREGSET,
+                   &ppc32_linux_ctarregset);
+      return;
+    }
 
   if (regaddr == -1)
     return;
@@ -1351,9 +1543,14 @@ store_ppc_registers (const struct regcache *regcache, int tid)
                  PPC_LINUX_SIZEOF_PMUREGSET,
                  &ppc32_linux_pmuregset);
 
-  /* Because the EBB registers can be unavailable, attempts to store
-     them here would cause this function to fail most of the time, so
-     we ignore them.  */
+  if (tdep->have_htm_spr)
+    store_regset (regcache, tid, -1, NT_PPC_TM_SPR,
+                 PPC_LINUX_SIZEOF_TM_SPRREGSET,
+                 &ppc32_linux_tm_sprregset);
+
+  /* Because the EBB and checkpointed HTM registers can be
+     unavailable, attempts to store them here would cause this
+     function to fail most of the time, so we ignore them.  */
 }
 
 /* Fetch the AT_HWCAP entry from the aux vector.  */
@@ -2486,7 +2683,13 @@ ppc_linux_nat_target::read_description ()
          && check_regset (tid, NT_PPC_TAR, PPC_LINUX_SIZEOF_TARREGSET)
          && check_regset (tid, NT_PPC_EBB, PPC_LINUX_SIZEOF_EBBREGSET)
          && check_regset (tid, NT_PPC_PMU, PPC_LINUX_SIZEOF_PMUREGSET))
-       features.isa207 = true;
+       {
+         features.isa207 = true;
+         if ((hwcap2 & PPC_FEATURE2_HTM)
+             && check_regset (tid, NT_PPC_TM_SPR,
+                              PPC_LINUX_SIZEOF_TM_SPRREGSET))
+           features.htm = true;
+       }
     }
 
   return ppc_linux_match_description (features);
index 337ba67..ed44cbe 100644 (file)
@@ -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.  */
@@ -637,6 +639,239 @@ const struct regset ppc32_linux_pmuregset = {
   regcache_collect_regset
 };
 
+/* Hardware Transactional Memory special-purpose register regmap.  */
+
+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 }
+  };
+
+/* Hardware Transactional Memory special-purpose register regset.  */
+
+const struct regset ppc32_linux_tm_sprregset = {
+  ppc32_regmap_tm_spr,
+  regcache_supply_regset,
+  regcache_collect_regset
+};
+
+/* Regmaps for the Hardware Transactional Memory checkpointed
+   general-purpose regsets for 32-bit, 64-bit big-endian, and 64-bit
+   little endian targets.  The ptrace and core file buffers for 64-bit
+   targets use 8-byte fields for the 4-byte registers, and the
+   position of the register in the fields depends on the endianess.
+   The 32-bit regmap is the same for both endian types because the
+   fields are all 4-byte long.
+
+   The layout of checkpointed GPR 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), except when
+   generating a core file.  The 64-bit regset is 48 * 8 bytes long.
+   In some 64-bit kernels, the regset for a 32-bit inferior has the
+   same length, but all the registers are squeezed in the first half
+   (48 * 4 bytes).  The pt_regs struct calls the regular cr ccr, but
+   we use ccr for "checkpointed condition register".  Note that CR
+   (condition register) field 0 is not checkpointed, but the kernel
+   returns all 4 bytes.  The skipped registers 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 }
+  };
+
+/* Regsets for the Hardware Transactional Memory checkpointed
+   general-purpose registers for 32-bit, 64-bit big-endian, and 64-bit
+   little endian targets.
+
+   Some 64-bit kernels generate a checkpointed gpr note section with
+   48*8 bytes for a 32-bit thread, of which only 48*4 are actually
+   used, so we set the variable size flag in the corresponding regset
+   to accept this case.  */
+
+static const struct regset ppc32_linux_cgprregset = {
+  ppc32_regmap_cgpr,
+  regcache_supply_regset,
+  regcache_collect_regset,
+  REGSET_VARIABLE_SIZE
+};
+
+static const struct regset ppc64_be_linux_cgprregset = {
+  ppc64_be_regmap_cgpr,
+  regcache_supply_regset,
+  regcache_collect_regset
+};
+
+static const struct regset ppc64_le_linux_cgprregset = {
+  ppc64_le_regmap_cgpr,
+  regcache_supply_regset,
+  regcache_collect_regset
+};
+
+/* Hardware Transactional Memory checkpointed floating-point regmap.  */
+
+static const struct regcache_map_entry ppc32_regmap_cfpr[] =
+  {
+      { 32, PPC_CF0_REGNUM, 8 },
+      { 1, PPC_CFPSCR_REGNUM, 8 },
+      { 0 }
+  };
+
+/* Hardware Transactional Memory checkpointed floating-point regset.  */
+
+const struct regset ppc32_linux_cfprregset = {
+  ppc32_regmap_cfpr,
+  regcache_supply_regset,
+  regcache_collect_regset
+};
+
+/* Regmaps for the Hardware Transactional Memory checkpointed vector
+   regsets, for big and little endian targets.  The position of the
+   4-byte VSCR in its 16-byte field depends on the endianess.  */
+
+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 }
+  };
+
+/* Hardware Transactional Memory checkpointed vector regsets, for little
+   and big endian targets.  */
+
+static const struct regset ppc32_le_linux_cvmxregset = {
+  ppc32_le_regmap_cvmx,
+  regcache_supply_regset,
+  regcache_collect_regset
+};
+
+static const struct regset ppc32_be_linux_cvmxregset = {
+  ppc32_be_regmap_cvmx,
+  regcache_supply_regset,
+  regcache_collect_regset
+};
+
+/* Hardware Transactional Memory checkpointed vector-scalar regmap.  */
+
+static const struct regcache_map_entry ppc32_regmap_cvsx[] =
+  {
+      { 32, PPC_CVSR0_UPPER_REGNUM, 8 },
+      { 0 }
+  };
+
+/* Hardware Transactional Memory checkpointed vector-scalar regset.  */
+
+const struct regset ppc32_linux_cvsxregset = {
+  ppc32_regmap_cvsx,
+  regcache_supply_regset,
+  regcache_collect_regset
+};
+
+/* Hardware Transactional Memory checkpointed Program Priority Register
+   regmap.  */
+
+static const struct regcache_map_entry ppc32_regmap_cppr[] =
+  {
+      { 1, PPC_CPPR_REGNUM, 8 },
+      { 0 }
+  };
+
+/* Hardware Transactional Memory checkpointed Program Priority Register
+   regset.  */
+
+const struct regset ppc32_linux_cpprregset = {
+  ppc32_regmap_cppr,
+  regcache_supply_regset,
+  regcache_collect_regset
+};
+
+/* Hardware Transactional Memory checkpointed Data Stream Control
+   Register regmap.  */
+
+static const struct regcache_map_entry ppc32_regmap_cdscr[] =
+  {
+      { 1, PPC_CDSCR_REGNUM, 8 },
+      { 0 }
+  };
+
+/* Hardware Transactional Memory checkpointed Data Stream Control
+   Register regset.  */
+
+const struct regset ppc32_linux_cdscrregset = {
+  ppc32_regmap_cdscr,
+  regcache_supply_regset,
+  regcache_collect_regset
+};
+
+/* Hardware Transactional Memory checkpointed Target Address Register
+   regmap.  */
+
+static const struct regcache_map_entry ppc32_regmap_ctar[] =
+  {
+      { 1, PPC_CTAR_REGNUM, 8 },
+      { 0 }
+  };
+
+/* Hardware Transactional Memory checkpointed Target Address Register
+   regset.  */
+
+const struct regset ppc32_linux_ctarregset = {
+  ppc32_regmap_ctar,
+  regcache_supply_regset,
+  regcache_collect_regset
+};
+
 const struct regset *
 ppc_linux_gregset (int wordsize)
 {
@@ -664,6 +899,88 @@ ppc_linux_vsxregset (void)
   return &ppc32_linux_vsxregset;
 }
 
+const struct regset *
+ppc_linux_cgprregset (struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (tdep->wordsize == 4)
+    {
+      return &ppc32_linux_cgprregset;
+    }
+  else
+    {
+      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+       return &ppc64_be_linux_cgprregset;
+      else
+       return &ppc64_le_linux_cgprregset;
+    }
+}
+
+const struct regset *
+ppc_linux_cvmxregset (struct gdbarch *gdbarch)
+{
+  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+    return &ppc32_be_linux_cvmxregset;
+  else
+    return &ppc32_le_linux_cvmxregset;
+}
+
+/* Collect function used to generate the core note for the
+   checkpointed GPR regset.  Here, we don't want to skip the
+   "checkpointed" NIP and MSR, so that the note section we generate is
+   similar to the one generated by the kernel.  To avoid having to
+   define additional registers in GDB which are not actually
+   checkpointed in the architecture, we copy TFHAR to the checkpointed
+   NIP slot, which is what the kernel does, and copy the regular MSR
+   to the checkpointed MSR slot, which will have a similar value in
+   most cases.  */
+
+static void
+ppc_linux_collect_core_cpgrregset (const struct regset *regset,
+                                  const struct regcache *regcache,
+                                  int regnum, void *buf, size_t len)
+{
+  struct gdbarch *gdbarch = regcache->arch ();
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  const struct regset *cgprregset = ppc_linux_cgprregset (gdbarch);
+
+  /* We collect the checkpointed GPRs already defined in the regular
+     regmap, then overlay TFHAR/MSR on the checkpointed NIP/MSR
+     slots.  */
+  cgprregset->collect_regset (cgprregset, regcache, regnum, buf, len);
+
+  /* Check that we are collecting all the registers, which should be
+     the case when generating a core file.  */
+  if (regnum != -1)
+    return;
+
+  /* PT_NIP and PT_MSR are 32 and 33 for powerpc.  Don't redefine
+     these symbols since this file can run on clients in other
+     architectures where they can already be defined to other
+     values.  */
+  int pt_offset = 32;
+
+  /* Check that our buffer is long enough to hold two slots at
+     pt_offset * wordsize, one for NIP and one for MSR.  */
+  gdb_assert ((pt_offset + 2) * tdep->wordsize <= len);
+
+  /* TFHAR is 8 bytes wide, but the NIP slot for a 32-bit thread is
+     4-bytes long.  We use raw_collect_integer which handles
+     differences in the sizes for the source and destination buffers
+     for both endian modes.  */
+  (regcache->raw_collect_integer
+   (PPC_TFHAR_REGNUM, ((gdb_byte *) buf) + pt_offset * tdep->wordsize,
+    tdep->wordsize, false));
+
+  pt_offset = 33;
+
+  (regcache->raw_collect_integer
+   (PPC_MSR_REGNUM, ((gdb_byte *) buf) + pt_offset * tdep->wordsize,
+    tdep->wordsize, false));
+}
+
 /* Iterate over supported core file register note sections. */
 
 static void
@@ -728,6 +1045,121 @@ ppc_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
        PPC_LINUX_SIZEOF_PMUREGSET,
        &ppc32_linux_pmuregset, "Performance Monitor Registers",
        cb_data);
+
+  if (tdep->have_htm_spr)
+    cb (".reg-ppc-tm-spr", PPC_LINUX_SIZEOF_TM_SPRREGSET,
+       PPC_LINUX_SIZEOF_TM_SPRREGSET,
+       &ppc32_linux_tm_sprregset,
+       "Hardware Transactional Memory Special Purpose Registers",
+       cb_data);
+
+  /* Checkpointed registers can be unavailable, don't call back if
+     we are generating a core file.  */
+
+  if (tdep->have_htm_core)
+    {
+      /* Only generate the checkpointed GPR core note if we also have
+        access to the HTM SPRs, because we need TFHAR to fill the
+        "checkpointed" NIP slot.  We can read a core file without it
+        since GDB is not aware of this NIP as a visible register.  */
+      if (regcache == NULL ||
+         (REG_VALID == regcache->get_register_status (PPC_CR0_REGNUM)
+          && tdep->have_htm_spr))
+       {
+         int cgpr_size = (tdep->wordsize == 4?
+                          PPC32_LINUX_SIZEOF_CGPRREGSET
+                          : PPC64_LINUX_SIZEOF_CGPRREGSET);
+
+         const struct regset *cgprregset =
+           ppc_linux_cgprregset (gdbarch);
+
+         if (regcache != NULL)
+           {
+             struct regset core_cgprregset = *cgprregset;
+
+             core_cgprregset.collect_regset
+               = ppc_linux_collect_core_cpgrregset;
+
+             cb (".reg-ppc-tm-cgpr",
+                 cgpr_size, cgpr_size,
+                 &core_cgprregset,
+                 "Checkpointed General Purpose Registers", cb_data);
+           }
+         else
+           {
+             cb (".reg-ppc-tm-cgpr",
+                 cgpr_size, cgpr_size,
+                 cgprregset,
+                 "Checkpointed General Purpose Registers", cb_data);
+           }
+       }
+    }
+
+  if (tdep->have_htm_fpu)
+    {
+      if (regcache == NULL ||
+         REG_VALID == regcache->get_register_status (PPC_CF0_REGNUM))
+       cb (".reg-ppc-tm-cfpr", PPC_LINUX_SIZEOF_CFPRREGSET,
+           PPC_LINUX_SIZEOF_CFPRREGSET,
+           &ppc32_linux_cfprregset,
+           "Checkpointed Floating Point Registers", cb_data);
+    }
+
+  if (tdep->have_htm_altivec)
+    {
+      if (regcache == NULL ||
+         REG_VALID == regcache->get_register_status (PPC_CVR0_REGNUM))
+       {
+         const struct regset *cvmxregset =
+           ppc_linux_cvmxregset (gdbarch);
+
+         cb (".reg-ppc-tm-cvmx", PPC_LINUX_SIZEOF_CVMXREGSET,
+             PPC_LINUX_SIZEOF_CVMXREGSET,
+             cvmxregset,
+             "Checkpointed Altivec (VMX) Registers", cb_data);
+       }
+    }
+
+  if (tdep->have_htm_vsx)
+    {
+      if (regcache == NULL ||
+         (REG_VALID
+          == regcache->get_register_status (PPC_CVSR0_UPPER_REGNUM)))
+       cb (".reg-ppc-tm-cvsx", PPC_LINUX_SIZEOF_CVSXREGSET,
+           PPC_LINUX_SIZEOF_CVSXREGSET,
+           &ppc32_linux_cvsxregset,
+           "Checkpointed VSX Registers", cb_data);
+    }
+
+  if (tdep->ppc_cppr_regnum != -1)
+    {
+      if (regcache == NULL ||
+         REG_VALID == regcache->get_register_status (PPC_CPPR_REGNUM))
+       cb (".reg-ppc-tm-cppr", PPC_LINUX_SIZEOF_CPPRREGSET,
+           PPC_LINUX_SIZEOF_CPPRREGSET,
+           &ppc32_linux_cpprregset,
+           "Checkpointed Priority Program Register", cb_data);
+    }
+
+  if (tdep->ppc_cdscr_regnum != -1)
+    {
+      if (regcache == NULL ||
+         REG_VALID == regcache->get_register_status (PPC_CDSCR_REGNUM))
+       cb (".reg-ppc-tm-cdscr", PPC_LINUX_SIZEOF_CDSCRREGSET,
+           PPC_LINUX_SIZEOF_CDSCRREGSET,
+           &ppc32_linux_cdscrregset,
+           "Checkpointed Data Stream Control Register", cb_data);
+    }
+
+  if (tdep->ppc_ctar_regnum)
+    {
+      if ( regcache == NULL ||
+          REG_VALID == regcache->get_register_status (PPC_CTAR_REGNUM))
+       cb (".reg-ppc-tm-ctar", PPC_LINUX_SIZEOF_CTARREGSET,
+           PPC_LINUX_SIZEOF_CTARREGSET,
+           &ppc32_linux_ctarregset,
+           "Checkpointed Target Address Register", cb_data);
+    }
 }
 
 static void
@@ -1143,6 +1575,7 @@ ppc_linux_core_read_description (struct gdbarch *gdbarch,
   asection *dscr = bfd_get_section_by_name (abfd, ".reg-ppc-dscr");
   asection *tar = bfd_get_section_by_name (abfd, ".reg-ppc-tar");
   asection *pmu = bfd_get_section_by_name (abfd, ".reg-ppc-pmu");
+  asection *htmspr = bfd_get_section_by_name (abfd, ".reg-ppc-tm-spr");
 
   if (! section)
     return NULL;
@@ -1184,7 +1617,11 @@ ppc_linux_core_read_description (struct gdbarch *gdbarch,
         been unavailable when the core file was created.  They will
         be in the tdep but will show as unavailable.  */
       if (tar && pmu)
-       features.isa207 = true;
+       {
+         features.isa207 = true;
+         if (htmspr)
+           features.htm = true;
+       }
     }
 
   return ppc_linux_match_description (features);
@@ -2062,6 +2499,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 ();
@@ -2071,5 +2509,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 ();
 }
index cce1ddd..5fb42c9 100644 (file)
@@ -32,6 +32,14 @@ const struct regset *ppc_linux_fpregset (void);
 const struct regset *ppc_linux_vrregset (struct gdbarch *gdbarch);
 const struct regset *ppc_linux_vsxregset (void);
 
+/* Get the checkpointed GPR regset that matches the target wordsize
+   and byteorder of GDBARCH.  */
+const struct regset *ppc_linux_cgprregset (struct gdbarch *gdbarch);
+
+/* Get the checkpointed vector regset that matches the target byte
+   order.  */
+const struct regset* ppc_linux_cvmxregset (struct gdbarch *gdbarch);
+
 /* Extra register number constants.  The Linux kernel stores a
    "trap" code and the original value of r3 into special "registers";
    these need to be saved and restored when performing an inferior
@@ -50,5 +58,11 @@ extern const struct regset ppc32_linux_dscrregset;
 extern const struct regset ppc32_linux_tarregset;
 extern const struct regset ppc32_linux_ebbregset;
 extern const struct regset ppc32_linux_pmuregset;
+extern const struct regset ppc32_linux_tm_sprregset;
+extern const struct regset ppc32_linux_cfprregset;
+extern const struct regset ppc32_linux_cvsxregset;
+extern const struct regset ppc32_linux_cpprregset;
+extern const struct regset ppc32_linux_cdscrregset;
+extern const struct regset ppc32_linux_ctarregset;
 
 #endif /* PPC_LINUX_TDEP_H */
index cfe32c9..dbafe22 100644 (file)
@@ -274,6 +274,21 @@ struct gdbarch_tdep
     int ppc_sdar_regnum;
     int ppc_sier_regnum;
 
+    /* Hardware Transactional Memory registers.  */
+    int have_htm_spr;
+    int have_htm_core;
+    int have_htm_fpu;
+    int have_htm_altivec;
+    int have_htm_vsx;
+    int ppc_cppr_regnum;
+    int ppc_cdscr_regnum;
+    int ppc_ctar_regnum;
+
+    /* HTM pseudo registers.  */
+    int ppc_cdl0_regnum;
+    int ppc_cvsr0_regnum;
+    int ppc_cefpr0_regnum;
+
     /* Offset to ABI specific location where link register is saved.  */
     int lr_frame_offset;       
 
@@ -343,6 +358,29 @@ enum {
   PPC_SDAR_REGNUM = 181,
   PPC_SIER_REGNUM = 182,
 
+  /* Hardware transactional memory registers.  */
+  PPC_TFHAR_REGNUM = 183,
+  PPC_TEXASR_REGNUM = 184,
+  PPC_TFIAR_REGNUM = 185,
+
+  PPC_CR0_REGNUM = 186,
+  PPC_CCR_REGNUM = 218,
+  PPC_CXER_REGNUM = 219,
+  PPC_CLR_REGNUM = 220,
+  PPC_CCTR_REGNUM = 221,
+
+  PPC_CF0_REGNUM = 222,
+  PPC_CFPSCR_REGNUM = 254,
+
+  PPC_CVR0_REGNUM = 255,
+  PPC_CVSCR_REGNUM = 287,
+  PPC_CVRSAVE_REGNUM = 288,
+
+  PPC_CVSR0_UPPER_REGNUM = 289,
+
+  PPC_CPPR_REGNUM = 321,
+  PPC_CDSCR_REGNUM = 322,
+  PPC_CTAR_REGNUM = 323,
   PPC_NUM_REGS
 };
 
@@ -355,6 +393,21 @@ enum {
 #define PPC_IS_PMU_REGNUM(i) \
        ((i) >= PPC_MMCR0_REGNUM && (i) <= PPC_SIER_REGNUM)
 
+#define PPC_IS_TMSPR_REGNUM(i) \
+  ((i) >= PPC_TFHAR_REGNUM && (i) <= PPC_TFIAR_REGNUM)
+
+#define PPC_IS_CKPTGP_REGNUM(i) \
+  ((i) >= PPC_CR0_REGNUM && (i) <= PPC_CCTR_REGNUM)
+
+#define PPC_IS_CKPTFP_REGNUM(i) \
+  ((i) >= PPC_CF0_REGNUM && (i) <= PPC_CFPSCR_REGNUM)
+
+#define PPC_IS_CKPTVMX_REGNUM(i) \
+  ((i) >= PPC_CVR0_REGNUM && (i) <= PPC_CVRSAVE_REGNUM)
+
+#define PPC_IS_CKPTVSX_REGNUM(i) \
+  ((i) >= PPC_CVSR0_UPPER_REGNUM && (i) < (PPC_CVSR0_UPPER_REGNUM + 32))
+
 /* An instruction to match.  */
 
 struct ppc_insn_pattern
diff --git a/gdb/regformats/rs6000/powerpc-isa207-htm-vsx32l.dat b/gdb/regformats/rs6000/powerpc-isa207-htm-vsx32l.dat
new file mode 100644 (file)
index 0000000..c19416d
--- /dev/null
@@ -0,0 +1,296 @@
+# THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi :set ro:
+# Generated from: rs6000/powerpc-isa207-htm-vsx32l.xml
+name:powerpc_isa207_htm_vsx32l
+xmltarget:powerpc-isa207-htm-vsx32l.xml
+expedite:r1,pc
+32:r0
+32:r1
+32:r2
+32:r3
+32:r4
+32:r5
+32:r6
+32:r7
+32:r8
+32:r9
+32:r10
+32:r11
+32:r12
+32:r13
+32:r14
+32:r15
+32:r16
+32:r17
+32:r18
+32:r19
+32:r20
+32:r21
+32:r22
+32:r23
+32:r24
+32:r25
+32:r26
+32:r27
+32:r28
+32:r29
+32:r30
+32:r31
+64:f0
+64:f1
+64:f2
+64:f3
+64:f4
+64:f5
+64:f6
+64:f7
+64:f8
+64:f9
+64:f10
+64:f11
+64:f12
+64:f13
+64:f14
+64:f15
+64:f16
+64:f17
+64:f18
+64:f19
+64:f20
+64:f21
+64:f22
+64:f23
+64:f24
+64:f25
+64:f26
+64:f27
+64:f28
+64:f29
+64:f30
+64:f31
+32:pc
+32:msr
+32:cr
+32:lr
+32:ctr
+32:xer
+64:fpscr
+32:orig_r3
+32:trap
+128:vr0
+128:vr1
+128:vr2
+128:vr3
+128:vr4
+128:vr5
+128:vr6
+128:vr7
+128:vr8
+128:vr9
+128:vr10
+128:vr11
+128:vr12
+128:vr13
+128:vr14
+128:vr15
+128:vr16
+128:vr17
+128:vr18
+128:vr19
+128:vr20
+128:vr21
+128:vr22
+128:vr23
+128:vr24
+128:vr25
+128:vr26
+128:vr27
+128:vr28
+128:vr29
+128:vr30
+128:vr31
+32:vscr
+32:vrsave
+64:vs0h
+64:vs1h
+64:vs2h
+64:vs3h
+64:vs4h
+64:vs5h
+64:vs6h
+64:vs7h
+64:vs8h
+64:vs9h
+64:vs10h
+64:vs11h
+64:vs12h
+64:vs13h
+64:vs14h
+64:vs15h
+64:vs16h
+64:vs17h
+64:vs18h
+64:vs19h
+64:vs20h
+64:vs21h
+64:vs22h
+64:vs23h
+64:vs24h
+64:vs25h
+64:vs26h
+64:vs27h
+64:vs28h
+64:vs29h
+64:vs30h
+64:vs31h
+64:ppr
+64:dscr
+64:tar
+64:bescr
+64:ebbhr
+64:ebbrr
+64:mmcr0
+64:mmcr2
+64:siar
+64:sdar
+64:sier
+64:tfhar
+64:texasr
+64:tfiar
+32:cr0
+32:cr1
+32:cr2
+32:cr3
+32:cr4
+32:cr5
+32:cr6
+32:cr7
+32:cr8
+32:cr9
+32:cr10
+32:cr11
+32:cr12
+32:cr13
+32:cr14
+32:cr15
+32:cr16
+32:cr17
+32:cr18
+32:cr19
+32:cr20
+32:cr21
+32:cr22
+32:cr23
+32:cr24
+32:cr25
+32:cr26
+32:cr27
+32:cr28
+32:cr29
+32:cr30
+32:cr31
+32:ccr
+32:cxer
+32:clr
+32:cctr
+64:cf0
+64:cf1
+64:cf2
+64:cf3
+64:cf4
+64:cf5
+64:cf6
+64:cf7
+64:cf8
+64:cf9
+64:cf10
+64:cf11
+64:cf12
+64:cf13
+64:cf14
+64:cf15
+64:cf16
+64:cf17
+64:cf18
+64:cf19
+64:cf20
+64:cf21
+64:cf22
+64:cf23
+64:cf24
+64:cf25
+64:cf26
+64:cf27
+64:cf28
+64:cf29
+64:cf30
+64:cf31
+64:cfpscr
+128:cvr0
+128:cvr1
+128:cvr2
+128:cvr3
+128:cvr4
+128:cvr5
+128:cvr6
+128:cvr7
+128:cvr8
+128:cvr9
+128:cvr10
+128:cvr11
+128:cvr12
+128:cvr13
+128:cvr14
+128:cvr15
+128:cvr16
+128:cvr17
+128:cvr18
+128:cvr19
+128:cvr20
+128:cvr21
+128:cvr22
+128:cvr23
+128:cvr24
+128:cvr25
+128:cvr26
+128:cvr27
+128:cvr28
+128:cvr29
+128:cvr30
+128:cvr31
+32:cvscr
+32:cvrsave
+64:cvs0h
+64:cvs1h
+64:cvs2h
+64:cvs3h
+64:cvs4h
+64:cvs5h
+64:cvs6h
+64:cvs7h
+64:cvs8h
+64:cvs9h
+64:cvs10h
+64:cvs11h
+64:cvs12h
+64:cvs13h
+64:cvs14h
+64:cvs15h
+64:cvs16h
+64:cvs17h
+64:cvs18h
+64:cvs19h
+64:cvs20h
+64:cvs21h
+64:cvs22h
+64:cvs23h
+64:cvs24h
+64:cvs25h
+64:cvs26h
+64:cvs27h
+64:cvs28h
+64:cvs29h
+64:cvs30h
+64:cvs31h
+64:cppr
+64:cdscr
+64:ctar
diff --git a/gdb/regformats/rs6000/powerpc-isa207-htm-vsx64l.dat b/gdb/regformats/rs6000/powerpc-isa207-htm-vsx64l.dat
new file mode 100644 (file)
index 0000000..3835995
--- /dev/null
@@ -0,0 +1,296 @@
+# THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi :set ro:
+# Generated from: rs6000/powerpc-isa207-htm-vsx64l.xml
+name:powerpc_isa207_htm_vsx64l
+xmltarget:powerpc-isa207-htm-vsx64l.xml
+expedite:r1,pc
+64:r0
+64:r1
+64:r2
+64:r3
+64:r4
+64:r5
+64:r6
+64:r7
+64:r8
+64:r9
+64:r10
+64:r11
+64:r12
+64:r13
+64:r14
+64:r15
+64:r16
+64:r17
+64:r18
+64:r19
+64:r20
+64:r21
+64:r22
+64:r23
+64:r24
+64:r25
+64:r26
+64:r27
+64:r28
+64:r29
+64:r30
+64:r31
+64:f0
+64:f1
+64:f2
+64:f3
+64:f4
+64:f5
+64:f6
+64:f7
+64:f8
+64:f9
+64:f10
+64:f11
+64:f12
+64:f13
+64:f14
+64:f15
+64:f16
+64:f17
+64:f18
+64:f19
+64:f20
+64:f21
+64:f22
+64:f23
+64:f24
+64:f25
+64:f26
+64:f27
+64:f28
+64:f29
+64:f30
+64:f31
+64:pc
+64:msr
+32:cr
+64:lr
+64:ctr
+32:xer
+64:fpscr
+64:orig_r3
+64:trap
+128:vr0
+128:vr1
+128:vr2
+128:vr3
+128:vr4
+128:vr5
+128:vr6
+128:vr7
+128:vr8
+128:vr9
+128:vr10
+128:vr11
+128:vr12
+128:vr13
+128:vr14
+128:vr15
+128:vr16
+128:vr17
+128:vr18
+128:vr19
+128:vr20
+128:vr21
+128:vr22
+128:vr23
+128:vr24
+128:vr25
+128:vr26
+128:vr27
+128:vr28
+128:vr29
+128:vr30
+128:vr31
+32:vscr
+32:vrsave
+64:vs0h
+64:vs1h
+64:vs2h
+64:vs3h
+64:vs4h
+64:vs5h
+64:vs6h
+64:vs7h
+64:vs8h
+64:vs9h
+64:vs10h
+64:vs11h
+64:vs12h
+64:vs13h
+64:vs14h
+64:vs15h
+64:vs16h
+64:vs17h
+64:vs18h
+64:vs19h
+64:vs20h
+64:vs21h
+64:vs22h
+64:vs23h
+64:vs24h
+64:vs25h
+64:vs26h
+64:vs27h
+64:vs28h
+64:vs29h
+64:vs30h
+64:vs31h
+64:ppr
+64:dscr
+64:tar
+64:bescr
+64:ebbhr
+64:ebbrr
+64:mmcr0
+64:mmcr2
+64:siar
+64:sdar
+64:sier
+64:tfhar
+64:texasr
+64:tfiar
+64:cr0
+64:cr1
+64:cr2
+64:cr3
+64:cr4
+64:cr5
+64:cr6
+64:cr7
+64:cr8
+64:cr9
+64:cr10
+64:cr11
+64:cr12
+64:cr13
+64:cr14
+64:cr15
+64:cr16
+64:cr17
+64:cr18
+64:cr19
+64:cr20
+64:cr21
+64:cr22
+64:cr23
+64:cr24
+64:cr25
+64:cr26
+64:cr27
+64:cr28
+64:cr29
+64:cr30
+64:cr31
+32:ccr
+32:cxer
+64:clr
+64:cctr
+64:cf0
+64:cf1
+64:cf2
+64:cf3
+64:cf4
+64:cf5
+64:cf6
+64:cf7
+64:cf8
+64:cf9
+64:cf10
+64:cf11
+64:cf12
+64:cf13
+64:cf14
+64:cf15
+64:cf16
+64:cf17
+64:cf18
+64:cf19
+64:cf20
+64:cf21
+64:cf22
+64:cf23
+64:cf24
+64:cf25
+64:cf26
+64:cf27
+64:cf28
+64:cf29
+64:cf30
+64:cf31
+64:cfpscr
+128:cvr0
+128:cvr1
+128:cvr2
+128:cvr3
+128:cvr4
+128:cvr5
+128:cvr6
+128:cvr7
+128:cvr8
+128:cvr9
+128:cvr10
+128:cvr11
+128:cvr12
+128:cvr13
+128:cvr14
+128:cvr15
+128:cvr16
+128:cvr17
+128:cvr18
+128:cvr19
+128:cvr20
+128:cvr21
+128:cvr22
+128:cvr23
+128:cvr24
+128:cvr25
+128:cvr26
+128:cvr27
+128:cvr28
+128:cvr29
+128:cvr30
+128:cvr31
+32:cvscr
+32:cvrsave
+64:cvs0h
+64:cvs1h
+64:cvs2h
+64:cvs3h
+64:cvs4h
+64:cvs5h
+64:cvs6h
+64:cvs7h
+64:cvs8h
+64:cvs9h
+64:cvs10h
+64:cvs11h
+64:cvs12h
+64:cvs13h
+64:cvs14h
+64:cvs15h
+64:cvs16h
+64:cvs17h
+64:cvs18h
+64:cvs19h
+64:cvs20h
+64:cvs21h
+64:cvs22h
+64:cvs23h
+64:cvs24h
+64:cvs25h
+64:cvs26h
+64:cvs27h
+64:cvs28h
+64:cvs29h
+64:cvs30h
+64:cvs31h
+64:cppr
+64:cdscr
+64:ctar
index 7e41d8f..504de36 100644 (file)
     && (regnum) >= (tdep)->ppc_efpr0_regnum \
     && (regnum) < (tdep)->ppc_efpr0_regnum + ppc_num_efprs)
 
+/* Determine if regnum is a checkpointed decimal float
+   pseudo-register.  */
+#define IS_CDFP_PSEUDOREG(tdep, regnum) ((tdep)->ppc_cdl0_regnum >= 0 \
+    && (regnum) >= (tdep)->ppc_cdl0_regnum \
+    && (regnum) < (tdep)->ppc_cdl0_regnum + 16)
+
+/* Determine if regnum is a Checkpointed POWER7 VSX register.  */
+#define IS_CVSX_PSEUDOREG(tdep, regnum) ((tdep)->ppc_cvsr0_regnum >= 0 \
+    && (regnum) >= (tdep)->ppc_cvsr0_regnum \
+    && (regnum) < (tdep)->ppc_cvsr0_regnum + ppc_num_vsrs)
+
+/* Determine if regnum is a Checkpointed POWER7 Extended FP register.  */
+#define IS_CEFP_PSEUDOREG(tdep, regnum) ((tdep)->ppc_cefpr0_regnum >= 0 \
+    && (regnum) >= (tdep)->ppc_cefpr0_regnum \
+    && (regnum) < (tdep)->ppc_cefpr0_regnum + ppc_num_efprs)
+
 /* Holds the current set of options to be passed to the disassembler.  */
 static char *powerpc_disassembler_options;
 
@@ -2322,6 +2338,11 @@ rs6000_register_name (struct gdbarch *gdbarch, int regno)
       && regno < tdep->ppc_vsr0_upper_regnum + ppc_num_gprs)
     return "";
 
+  /* Hide the upper halves of the cvs0~cvs31 registers.  */
+  if (PPC_CVSR0_UPPER_REGNUM <= regno
+      && regno < PPC_CVSR0_UPPER_REGNUM + ppc_num_gprs)
+    return "";
+
   /* Check if the SPE pseudo registers are available.  */
   if (IS_SPE_PSEUDOREG (tdep, regno))
     {
@@ -2376,6 +2397,48 @@ rs6000_register_name (struct gdbarch *gdbarch, int regno)
       return efpr_regnames[regno - tdep->ppc_efpr0_regnum];
     }
 
+  /* Check if this is a Checkpointed DFP pseudo-register.  */
+  if (IS_CDFP_PSEUDOREG (tdep, regno))
+    {
+      static const char *const cdfp128_regnames[] = {
+       "cdl0", "cdl1", "cdl2", "cdl3",
+       "cdl4", "cdl5", "cdl6", "cdl7",
+       "cdl8", "cdl9", "cdl10", "cdl11",
+       "cdl12", "cdl13", "cdl14", "cdl15"
+      };
+      return cdfp128_regnames[regno - tdep->ppc_cdl0_regnum];
+    }
+
+  /* Check if this is a Checkpointed VSX pseudo-register.  */
+  if (IS_CVSX_PSEUDOREG (tdep, regno))
+    {
+      static const char *const cvsx_regnames[] = {
+       "cvs0", "cvs1", "cvs2", "cvs3", "cvs4", "cvs5", "cvs6", "cvs7",
+       "cvs8", "cvs9", "cvs10", "cvs11", "cvs12", "cvs13", "cvs14",
+       "cvs15", "cvs16", "cvs17", "cvs18", "cvs19", "cvs20", "cvs21",
+       "cvs22", "cvs23", "cvs24", "cvs25", "cvs26", "cvs27", "cvs28",
+       "cvs29", "cvs30", "cvs31", "cvs32", "cvs33", "cvs34", "cvs35",
+       "cvs36", "cvs37", "cvs38", "cvs39", "cvs40", "cvs41", "cvs42",
+       "cvs43", "cvs44", "cvs45", "cvs46", "cvs47", "cvs48", "cvs49",
+       "cvs50", "cvs51", "cvs52", "cvs53", "cvs54", "cvs55", "cvs56",
+       "cvs57", "cvs58", "cvs59", "cvs60", "cvs61", "cvs62", "cvs63"
+      };
+      return cvsx_regnames[regno - tdep->ppc_cvsr0_regnum];
+    }
+
+  /* Check if the this is a Checkpointed Extended FP pseudo-register.  */
+  if (IS_CEFP_PSEUDOREG (tdep, regno))
+    {
+      static const char *const cefpr_regnames[] = {
+       "cf32", "cf33", "cf34", "cf35", "cf36", "cf37", "cf38",
+       "cf39", "cf40", "cf41", "cf42", "cf43", "cf44", "cf45",
+       "cf46", "cf47", "cf48", "cf49", "cf50", "cf51",
+       "cf52", "cf53", "cf54", "cf55", "cf56", "cf57",
+       "cf58", "cf59", "cf60", "cf61", "cf62", "cf63"
+      };
+      return cefpr_regnames[regno - tdep->ppc_cefpr0_regnum];
+    }
+
   return tdesc_register_name (gdbarch, regno);
 }
 
@@ -2387,24 +2450,26 @@ rs6000_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  /* These are the only pseudo-registers we support.  */
-  gdb_assert (IS_SPE_PSEUDOREG (tdep, regnum)
-             || IS_DFP_PSEUDOREG (tdep, regnum)
-             || IS_VSX_PSEUDOREG (tdep, regnum)
-             || IS_EFP_PSEUDOREG (tdep, regnum));
-
   /* These are the e500 pseudo-registers.  */
   if (IS_SPE_PSEUDOREG (tdep, regnum))
     return rs6000_builtin_type_vec64 (gdbarch);
-  else if (IS_DFP_PSEUDOREG (tdep, regnum))
+  else if (IS_DFP_PSEUDOREG (tdep, regnum)
+          || IS_CDFP_PSEUDOREG (tdep, regnum))
     /* PPC decimal128 pseudo-registers.  */
     return builtin_type (gdbarch)->builtin_declong;
-  else if (IS_VSX_PSEUDOREG (tdep, regnum))
+  else if (IS_VSX_PSEUDOREG (tdep, regnum)
+          || IS_CVSX_PSEUDOREG (tdep, regnum))
     /* POWER7 VSX pseudo-registers.  */
     return rs6000_builtin_type_vec128 (gdbarch);
-  else
+  else if (IS_EFP_PSEUDOREG (tdep, regnum)
+          || IS_CEFP_PSEUDOREG (tdep, regnum))
     /* POWER7 Extended FP pseudo-registers.  */
     return builtin_type (gdbarch)->builtin_double;
+  else
+    internal_error (__FILE__, __LINE__,
+                   _("rs6000_pseudo_register_type: "
+                     "called on unexpected register '%s' (%d)"),
+                   gdbarch_register_name (gdbarch, regnum), regnum);
 }
 
 /* The register format for RS/6000 floating point registers is always
@@ -2580,25 +2645,35 @@ dfp_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
                           int reg_nr, gdb_byte *buffer)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  int reg_index = reg_nr - tdep->ppc_dl0_regnum;
+  int reg_index, fp0;
   enum register_status status;
 
+  if (IS_DFP_PSEUDOREG (tdep, reg_nr))
+    {
+      reg_index = reg_nr - tdep->ppc_dl0_regnum;
+      fp0 = PPC_F0_REGNUM;
+    }
+  else
+    {
+      gdb_assert (IS_CDFP_PSEUDOREG (tdep, reg_nr));
+
+      reg_index = reg_nr - tdep->ppc_cdl0_regnum;
+      fp0 = PPC_CF0_REGNUM;
+    }
+
   if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
     {
       /* Read two FP registers to form a whole dl register.  */
-      status = regcache->raw_read (tdep->ppc_fp0_regnum +
-                                  2 * reg_index, buffer);
+      status = regcache->raw_read (fp0 + 2 * reg_index, buffer);
       if (status == REG_VALID)
-       status = regcache->raw_read (tdep->ppc_fp0_regnum +
-                                    2 * reg_index + 1, buffer + 8);
+       status = regcache->raw_read (fp0 + 2 * reg_index + 1,
+                                    buffer + 8);
     }
   else
     {
-      status = regcache->raw_read (tdep->ppc_fp0_regnum +
-                                  2 * reg_index + 1, buffer);
+      status = regcache->raw_read (fp0 + 2 * reg_index + 1, buffer);
       if (status == REG_VALID)
-       status = regcache->raw_read (tdep->ppc_fp0_regnum +
-                                    2 * reg_index, buffer + 8);
+       status = regcache->raw_read (fp0 + 2 * reg_index, buffer + 8);
     }
 
   return status;
@@ -2610,23 +2685,32 @@ dfp_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
                            int reg_nr, const gdb_byte *buffer)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  int reg_index = reg_nr - tdep->ppc_dl0_regnum;
+  int reg_index, fp0;
+
+  if (IS_DFP_PSEUDOREG (tdep, reg_nr))
+    {
+      reg_index = reg_nr - tdep->ppc_dl0_regnum;
+      fp0 = PPC_F0_REGNUM;
+    }
+  else
+    {
+      gdb_assert (IS_CDFP_PSEUDOREG (tdep, reg_nr));
+
+      reg_index = reg_nr - tdep->ppc_cdl0_regnum;
+      fp0 = PPC_CF0_REGNUM;
+    }
 
   if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
     {
       /* Write each half of the dl register into a separate
-      FP register.  */
-      regcache->raw_write (tdep->ppc_fp0_regnum +
-                         2 * reg_index, buffer);
-      regcache->raw_write (tdep->ppc_fp0_regnum +
-                         2 * reg_index + 1, buffer + 8);
+        FP register.  */
+      regcache->raw_write (fp0 + 2 * reg_index, buffer);
+      regcache->raw_write (fp0 + 2 * reg_index + 1, buffer + 8);
     }
   else
     {
-      regcache->raw_write (tdep->ppc_fp0_regnum +
-                         2 * reg_index + 1, buffer);
-      regcache->raw_write (tdep->ppc_fp0_regnum +
-                         2 * reg_index, buffer + 8);
+      regcache->raw_write (fp0 + 2 * reg_index + 1, buffer);
+      regcache->raw_write (fp0 + 2 * reg_index, buffer + 8);
     }
 }
 
@@ -2636,30 +2720,43 @@ vsx_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
                           int reg_nr, gdb_byte *buffer)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  int reg_index = reg_nr - tdep->ppc_vsr0_regnum;
+  int reg_index, vr0, fp0, vsr0_upper;
   enum register_status status;
 
+  if (IS_VSX_PSEUDOREG (tdep, reg_nr))
+    {
+      reg_index = reg_nr - tdep->ppc_vsr0_regnum;
+      vr0 = PPC_VR0_REGNUM;
+      fp0 = PPC_F0_REGNUM;
+      vsr0_upper = PPC_VSR0_UPPER_REGNUM;
+    }
+  else
+    {
+      gdb_assert (IS_CVSX_PSEUDOREG (tdep, reg_nr));
+
+      reg_index = reg_nr - tdep->ppc_cvsr0_regnum;
+      vr0 = PPC_CVR0_REGNUM;
+      fp0 = PPC_CF0_REGNUM;
+      vsr0_upper = PPC_CVSR0_UPPER_REGNUM;
+    }
+
   /* Read the portion that overlaps the VMX registers.  */
   if (reg_index > 31)
-    status = regcache->raw_read (tdep->ppc_vr0_regnum +
-                                reg_index - 32, buffer);
+    status = regcache->raw_read (vr0 + reg_index - 32, buffer);
   else
     /* Read the portion that overlaps the FPR registers.  */
     if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
       {
-       status = regcache->raw_read (tdep->ppc_fp0_regnum +
-                                    reg_index, buffer);
+       status = regcache->raw_read (fp0 + reg_index, buffer);
        if (status == REG_VALID)
-         status = regcache->raw_read (tdep->ppc_vsr0_upper_regnum +
-                                      reg_index, buffer + 8);
+         status = regcache->raw_read (vsr0_upper + reg_index,
+                                      buffer + 8);
       }
     else
       {
-       status = regcache->raw_read (tdep->ppc_fp0_regnum +
-                                    reg_index, buffer + 8);
+       status = regcache->raw_read (fp0 + reg_index, buffer + 8);
        if (status == REG_VALID)
-         status = regcache->raw_read (tdep->ppc_vsr0_upper_regnum +
-                                      reg_index, buffer);
+         status = regcache->raw_read (vsr0_upper + reg_index, buffer);
       }
 
   return status;
@@ -2671,56 +2768,103 @@ vsx_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
                            int reg_nr, const gdb_byte *buffer)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  int reg_index = reg_nr - tdep->ppc_vsr0_regnum;
+  int reg_index, vr0, fp0, vsr0_upper;
+
+  if (IS_VSX_PSEUDOREG (tdep, reg_nr))
+    {
+      reg_index = reg_nr - tdep->ppc_vsr0_regnum;
+      vr0 = PPC_VR0_REGNUM;
+      fp0 = PPC_F0_REGNUM;
+      vsr0_upper = PPC_VSR0_UPPER_REGNUM;
+    }
+  else
+    {
+      gdb_assert (IS_CVSX_PSEUDOREG (tdep, reg_nr));
+
+      reg_index = reg_nr - tdep->ppc_cvsr0_regnum;
+      vr0 = PPC_CVR0_REGNUM;
+      fp0 = PPC_CF0_REGNUM;
+      vsr0_upper = PPC_CVSR0_UPPER_REGNUM;
+    }
 
   /* Write the portion that overlaps the VMX registers.  */
   if (reg_index > 31)
-    regcache->raw_write (tdep->ppc_vr0_regnum +
-                       reg_index - 32, buffer);
+    regcache->raw_write (vr0 + reg_index - 32, buffer);
   else
     /* Write the portion that overlaps the FPR registers.  */
     if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
       {
-       regcache->raw_write (tdep->ppc_fp0_regnum +
-                       reg_index, buffer);
-       regcache->raw_write (tdep->ppc_vsr0_upper_regnum +
-                       reg_index, buffer + 8);
+       regcache->raw_write (fp0 + reg_index, buffer);
+       regcache->raw_write (vsr0_upper + reg_index, buffer + 8);
       }
     else
       {
-       regcache->raw_write (tdep->ppc_fp0_regnum +
-                       reg_index, buffer + 8);
-       regcache->raw_write (tdep->ppc_vsr0_upper_regnum +
-                       reg_index, buffer);
+       regcache->raw_write (fp0 + reg_index, buffer + 8);
+       regcache->raw_write (vsr0_upper + reg_index, buffer);
       }
 }
 
 /* Read method for POWER7 Extended FP pseudo-registers.  */
 static enum register_status
-efpr_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
+efp_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
                           int reg_nr, gdb_byte *buffer)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  int reg_index = reg_nr - tdep->ppc_efpr0_regnum;
+  int reg_index, vr0;
+
+  if (IS_EFP_PSEUDOREG (tdep, reg_nr))
+    {
+      reg_index = reg_nr - tdep->ppc_efpr0_regnum;
+      vr0 = PPC_VR0_REGNUM;
+    }
+  else
+    {
+      gdb_assert (IS_CEFP_PSEUDOREG (tdep, reg_nr));
+
+      reg_index = reg_nr - tdep->ppc_cefpr0_regnum;
+      vr0 = PPC_CVR0_REGNUM;
+    }
+
   int offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8;
 
   /* Read the portion that overlaps the VMX register.  */
-  return regcache->raw_read_part (tdep->ppc_vr0_regnum + reg_index,
-                                 offset, register_size (gdbarch, reg_nr),
+  return regcache->raw_read_part (vr0 + reg_index, offset,
+                                 register_size (gdbarch, reg_nr),
                                  buffer);
 }
 
 /* Write method for POWER7 Extended FP pseudo-registers.  */
 static void
-efpr_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
+efp_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
                            int reg_nr, const gdb_byte *buffer)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  int reg_index = reg_nr - tdep->ppc_efpr0_regnum;
+  int reg_index, vr0;
   int offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8;
 
+  if (IS_EFP_PSEUDOREG (tdep, reg_nr))
+    {
+      reg_index = reg_nr - tdep->ppc_efpr0_regnum;
+      vr0 = PPC_VR0_REGNUM;
+    }
+  else
+    {
+      gdb_assert (IS_CEFP_PSEUDOREG (tdep, reg_nr));
+
+      reg_index = reg_nr - tdep->ppc_cefpr0_regnum;
+      vr0 = PPC_CVR0_REGNUM;
+
+      /* The call to raw_write_part fails silently if the initial read
+        of the read-update-write sequence returns an invalid status,
+        so we check this manually and throw an error if needed.  */
+      regcache->raw_update (vr0 + reg_index);
+      if (regcache->get_register_status (vr0 + reg_index) != REG_VALID)
+       error (_("Cannot write to the checkpointed EFP register, "
+                "the corresponding vector register is unavailable."));
+    }
+
   /* Write the portion that overlaps the VMX register.  */
-  regcache->raw_write_part (tdep->ppc_vr0_regnum + reg_index, offset,
+  regcache->raw_write_part (vr0 + reg_index, offset,
                            register_size (gdbarch, reg_nr), buffer);
 }
 
@@ -2736,12 +2880,15 @@ rs6000_pseudo_register_read (struct gdbarch *gdbarch,
 
   if (IS_SPE_PSEUDOREG (tdep, reg_nr))
     return e500_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
-  else if (IS_DFP_PSEUDOREG (tdep, reg_nr))
+  else if (IS_DFP_PSEUDOREG (tdep, reg_nr)
+          || IS_CDFP_PSEUDOREG (tdep, reg_nr))
     return dfp_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
-  else if (IS_VSX_PSEUDOREG (tdep, reg_nr))
+  else if (IS_VSX_PSEUDOREG (tdep, reg_nr)
+          || IS_CVSX_PSEUDOREG (tdep, reg_nr))
     return vsx_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
-  else if (IS_EFP_PSEUDOREG (tdep, reg_nr))
-    return efpr_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
+  else if (IS_EFP_PSEUDOREG (tdep, reg_nr)
+          || IS_CEFP_PSEUDOREG (tdep, reg_nr))
+    return efp_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
   else
     internal_error (__FILE__, __LINE__,
                    _("rs6000_pseudo_register_read: "
@@ -2761,12 +2908,15 @@ rs6000_pseudo_register_write (struct gdbarch *gdbarch,
 
   if (IS_SPE_PSEUDOREG (tdep, reg_nr))
     e500_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
-  else if (IS_DFP_PSEUDOREG (tdep, reg_nr))
+  else if (IS_DFP_PSEUDOREG (tdep, reg_nr)
+          || IS_CDFP_PSEUDOREG (tdep, reg_nr))
     dfp_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
-  else if (IS_VSX_PSEUDOREG (tdep, reg_nr))
+  else if (IS_VSX_PSEUDOREG (tdep, reg_nr)
+          || IS_CVSX_PSEUDOREG (tdep, reg_nr))
     vsx_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
-  else if (IS_EFP_PSEUDOREG (tdep, reg_nr))
-    efpr_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
+  else if (IS_EFP_PSEUDOREG (tdep, reg_nr)
+          || IS_CEFP_PSEUDOREG (tdep, reg_nr))
+    efp_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
   else
     internal_error (__FILE__, __LINE__,
                    _("rs6000_pseudo_register_write: "
@@ -2774,6 +2924,97 @@ rs6000_pseudo_register_write (struct gdbarch *gdbarch,
                    gdbarch_register_name (gdbarch, reg_nr), reg_nr);
 }
 
+/* Set the register mask in AX with the registers that form the DFP or
+   checkpointed DFP pseudo-register REG_NR.  */
+
+static void
+dfp_ax_pseudo_register_collect (struct gdbarch *gdbarch,
+                               struct agent_expr *ax, int reg_nr)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int reg_index, fp0;
+
+  if (IS_DFP_PSEUDOREG (tdep, reg_nr))
+    {
+      reg_index = reg_nr - tdep->ppc_dl0_regnum;
+      fp0 = PPC_F0_REGNUM;
+    }
+  else
+    {
+      gdb_assert (IS_CDFP_PSEUDOREG (tdep, reg_nr));
+
+      reg_index = reg_nr - tdep->ppc_cdl0_regnum;
+      fp0 = PPC_CF0_REGNUM;
+    }
+
+  ax_reg_mask (ax, fp0 + 2 * reg_index);
+  ax_reg_mask (ax, fp0 + 2 * reg_index + 1);
+}
+
+/* Set the register mask in AX with the registers that form the VSX or
+   checkpointed VSX pseudo-register REG_NR.  */
+
+static void
+vsx_ax_pseudo_register_collect (struct gdbarch *gdbarch,
+                               struct agent_expr *ax, int reg_nr)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int reg_index, vr0, fp0, vsr0_upper;
+
+  if (IS_VSX_PSEUDOREG (tdep, reg_nr))
+    {
+      reg_index = reg_nr - tdep->ppc_vsr0_regnum;
+      vr0 = PPC_VR0_REGNUM;
+      fp0 = PPC_F0_REGNUM;
+      vsr0_upper = PPC_VSR0_UPPER_REGNUM;
+    }
+  else
+    {
+      gdb_assert (IS_CVSX_PSEUDOREG (tdep, reg_nr));
+
+      reg_index = reg_nr - tdep->ppc_cvsr0_regnum;
+      vr0 = PPC_CVR0_REGNUM;
+      fp0 = PPC_CF0_REGNUM;
+      vsr0_upper = PPC_CVSR0_UPPER_REGNUM;
+    }
+
+  if (reg_index > 31)
+    {
+      ax_reg_mask (ax, vr0 + reg_index - 32);
+    }
+  else
+    {
+      ax_reg_mask (ax, fp0 + reg_index);
+      ax_reg_mask (ax, vsr0_upper + reg_index);
+    }
+}
+
+/* Set the register mask in AX with the register that corresponds to
+   the EFP or checkpointed EFP pseudo-register REG_NR.  */
+
+static void
+efp_ax_pseudo_register_collect (struct gdbarch *gdbarch,
+                               struct agent_expr *ax, int reg_nr)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int reg_index, vr0;
+
+  if (IS_EFP_PSEUDOREG (tdep, reg_nr))
+    {
+      reg_index = reg_nr - tdep->ppc_efpr0_regnum;
+      vr0 = PPC_VR0_REGNUM;
+    }
+  else
+    {
+      gdb_assert (IS_CEFP_PSEUDOREG (tdep, reg_nr));
+
+      reg_index = reg_nr - tdep->ppc_cefpr0_regnum;
+      vr0 = PPC_CVR0_REGNUM;
+    }
+
+  ax_reg_mask (ax, vr0 + reg_index);
+}
+
 static int
 rs6000_ax_pseudo_register_collect (struct gdbarch *gdbarch,
                                   struct agent_expr *ax, int reg_nr)
@@ -2785,29 +3026,20 @@ rs6000_ax_pseudo_register_collect (struct gdbarch *gdbarch,
       ax_reg_mask (ax, tdep->ppc_gp0_regnum + reg_index);
       ax_reg_mask (ax, tdep->ppc_ev0_upper_regnum + reg_index);
     }
-  else if (IS_DFP_PSEUDOREG (tdep, reg_nr))
+  else if (IS_DFP_PSEUDOREG (tdep, reg_nr)
+          || IS_CDFP_PSEUDOREG (tdep, reg_nr))
     {
-      int reg_index = reg_nr - tdep->ppc_dl0_regnum;
-      ax_reg_mask (ax, tdep->ppc_fp0_regnum + 2 * reg_index);
-      ax_reg_mask (ax, tdep->ppc_fp0_regnum + 2 * reg_index + 1);
+      dfp_ax_pseudo_register_collect (gdbarch, ax, reg_nr);
     }
-  else if (IS_VSX_PSEUDOREG (tdep, reg_nr))
+  else if (IS_VSX_PSEUDOREG (tdep, reg_nr)
+          || IS_CVSX_PSEUDOREG (tdep, reg_nr))
     {
-      int reg_index = reg_nr - tdep->ppc_vsr0_regnum;
-      if (reg_index > 31)
-        {
-          ax_reg_mask (ax, tdep->ppc_vr0_regnum + reg_index - 32);
-       }
-      else
-        {
-          ax_reg_mask (ax, tdep->ppc_fp0_regnum + reg_index);
-          ax_reg_mask (ax, tdep->ppc_vsr0_upper_regnum + reg_index);
-        }
+      vsx_ax_pseudo_register_collect (gdbarch, ax, reg_nr);
     }
-  else if (IS_EFP_PSEUDOREG (tdep, reg_nr))
+  else if (IS_EFP_PSEUDOREG (tdep, reg_nr)
+          || IS_CEFP_PSEUDOREG (tdep, reg_nr))
     {
-      int reg_index = reg_nr - tdep->ppc_efpr0_regnum;
-      ax_reg_mask (ax, tdep->ppc_vr0_regnum + reg_index);
+      efp_ax_pseudo_register_collect (gdbarch, ax, reg_nr);
     }
   else
     internal_error (__FILE__, __LINE__,
@@ -5817,7 +6049,10 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   enum powerpc_elf_abi elf_abi = POWERPC_ELF_AUTO;
   int have_fpu = 0, have_spe = 0, have_mq = 0, have_altivec = 0;
   int have_dfp = 0, have_vsx = 0, have_ppr = 0, have_dscr = 0;
-  int have_tar = 0, have_ebb = 0, have_pmu = 0;
+  int have_tar = 0, have_ebb = 0, have_pmu = 0, have_htm_spr = 0;
+  int have_htm_core = 0, have_htm_fpu = 0, have_htm_altivec = 0;
+  int have_htm_vsx = 0, have_htm_ppr = 0, have_htm_dscr = 0;
+  int have_htm_tar = 0;
   int tdesc_wordsize = -1;
   const struct target_desc *tdesc = info.target_desc;
   struct tdesc_arch_data *tdesc_data = NULL;
@@ -6216,6 +6451,201 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        }
       else
        have_pmu = 0;
+
+      /* Hardware Transactional Memory Registers.  */
+      feature = tdesc_find_feature (tdesc,
+                                   "org.gnu.gdb.power.htm.spr");
+      if (feature != NULL)
+       {
+         static const char *const tm_spr_regs[] = {
+           "tfhar", "texasr", "tfiar"
+         };
+
+         valid_p = 1;
+         for (i = 0; i < ARRAY_SIZE (tm_spr_regs); i++)
+           valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                               PPC_TFHAR_REGNUM + i,
+                                               tm_spr_regs[i]);
+         if (!valid_p)
+           {
+             tdesc_data_cleanup (tdesc_data);
+             return NULL;
+           }
+
+         have_htm_spr = 1;
+       }
+      else
+       have_htm_spr = 0;
+
+      feature = tdesc_find_feature (tdesc,
+                                   "org.gnu.gdb.power.htm.core");
+      if (feature != NULL)
+       {
+         static const char *const cgprs[] = {
+           "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
+           "cr8", "cr9", "cr10", "cr11", "cr12", "cr13", "cr14",
+           "cr15", "cr16", "cr17", "cr18", "cr19", "cr20", "cr21",
+           "cr22", "cr23", "cr24", "cr25", "cr26", "cr27", "cr28",
+           "cr29", "cr30", "cr31", "ccr", "cxer", "clr", "cctr"
+         };
+
+         valid_p = 1;
+
+         for (i = 0; i < ARRAY_SIZE (cgprs); i++)
+           valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                               PPC_CR0_REGNUM + i,
+                                               cgprs[i]);
+         if (!valid_p)
+           {
+             tdesc_data_cleanup (tdesc_data);
+             return NULL;
+           }
+
+         have_htm_core = 1;
+       }
+      else
+       have_htm_core = 0;
+
+      feature = tdesc_find_feature (tdesc,
+                                   "org.gnu.gdb.power.htm.fpu");
+      if (feature != NULL)
+       {
+         valid_p = 1;
+
+         static const char *const cfprs[] = {
+           "cf0", "cf1", "cf2", "cf3", "cf4", "cf5", "cf6", "cf7",
+           "cf8", "cf9", "cf10", "cf11", "cf12", "cf13", "cf14", "cf15",
+           "cf16", "cf17", "cf18", "cf19", "cf20", "cf21", "cf22",
+           "cf23", "cf24", "cf25", "cf26", "cf27", "cf28", "cf29",
+           "cf30", "cf31", "cfpscr"
+         };
+
+         for (i = 0; i < ARRAY_SIZE (cfprs); i++)
+           valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                               PPC_CF0_REGNUM + i,
+                                               cfprs[i]);
+
+         if (!valid_p)
+           {
+             tdesc_data_cleanup (tdesc_data);
+             return NULL;
+           }
+         have_htm_fpu = 1;
+       }
+      else
+       have_htm_fpu = 0;
+
+      feature = tdesc_find_feature (tdesc,
+                                   "org.gnu.gdb.power.htm.altivec");
+      if (feature != NULL)
+       {
+         valid_p = 1;
+
+         static const char *const cvmx[] = {
+           "cvr0", "cvr1", "cvr2", "cvr3", "cvr4", "cvr5", "cvr6",
+           "cvr7", "cvr8", "cvr9", "cvr10", "cvr11", "cvr12", "cvr13",
+           "cvr14", "cvr15","cvr16", "cvr17", "cvr18", "cvr19", "cvr20",
+           "cvr21", "cvr22", "cvr23", "cvr24", "cvr25", "cvr26",
+           "cvr27", "cvr28", "cvr29", "cvr30", "cvr31", "cvscr",
+           "cvrsave"
+         };
+
+         for (i = 0; i < ARRAY_SIZE (cvmx); i++)
+           valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                               PPC_CVR0_REGNUM + i,
+                                               cvmx[i]);
+
+         if (!valid_p)
+           {
+             tdesc_data_cleanup (tdesc_data);
+             return NULL;
+           }
+         have_htm_altivec = 1;
+       }
+      else
+       have_htm_altivec = 0;
+
+      feature = tdesc_find_feature (tdesc,
+                                   "org.gnu.gdb.power.htm.vsx");
+      if (feature != NULL)
+       {
+         valid_p = 1;
+
+         static const char *const cvsx[] = {
+           "cvs0h", "cvs1h", "cvs2h", "cvs3h", "cvs4h", "cvs5h",
+           "cvs6h", "cvs7h", "cvs8h", "cvs9h", "cvs10h", "cvs11h",
+           "cvs12h", "cvs13h", "cvs14h", "cvs15h", "cvs16h", "cvs17h",
+           "cvs18h", "cvs19h", "cvs20h", "cvs21h", "cvs22h", "cvs23h",
+           "cvs24h", "cvs25h", "cvs26h", "cvs27h", "cvs28h", "cvs29h",
+           "cvs30h", "cvs31h"
+         };
+
+         for (i = 0; i < ARRAY_SIZE (cvsx); i++)
+           valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                               (PPC_CVSR0_UPPER_REGNUM
+                                                + i),
+                                               cvsx[i]);
+
+         if (!valid_p || !have_htm_fpu || !have_htm_altivec)
+           {
+             tdesc_data_cleanup (tdesc_data);
+             return NULL;
+           }
+         have_htm_vsx = 1;
+       }
+      else
+       have_htm_vsx = 0;
+
+      feature = tdesc_find_feature (tdesc,
+                                   "org.gnu.gdb.power.htm.ppr");
+      if (feature != NULL)
+       {
+         valid_p = tdesc_numbered_register (feature, tdesc_data,
+                                            PPC_CPPR_REGNUM, "cppr");
+
+         if (!valid_p)
+           {
+             tdesc_data_cleanup (tdesc_data);
+             return NULL;
+           }
+         have_htm_ppr = 1;
+       }
+      else
+       have_htm_ppr = 0;
+
+      feature = tdesc_find_feature (tdesc,
+                                   "org.gnu.gdb.power.htm.dscr");
+      if (feature != NULL)
+       {
+         valid_p = tdesc_numbered_register (feature, tdesc_data,
+                                            PPC_CDSCR_REGNUM, "cdscr");
+
+         if (!valid_p)
+           {
+             tdesc_data_cleanup (tdesc_data);
+             return NULL;
+           }
+         have_htm_dscr = 1;
+       }
+      else
+       have_htm_dscr = 0;
+
+      feature = tdesc_find_feature (tdesc,
+                                   "org.gnu.gdb.power.htm.tar");
+      if (feature != NULL)
+       {
+         valid_p = tdesc_numbered_register (feature, tdesc_data,
+                                            PPC_CTAR_REGNUM, "ctar");
+
+         if (!valid_p)
+           {
+             tdesc_data_cleanup (tdesc_data);
+             return NULL;
+           }
+         have_htm_tar = 1;
+       }
+      else
+       have_htm_tar = 0;
     }
 
   /* If we have a 64-bit binary on a 32-bit target, complain.  Also
@@ -6428,6 +6858,15 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->ppc_sdar_regnum = have_pmu ? PPC_SDAR_REGNUM : -1;
   tdep->ppc_sier_regnum = have_pmu ? PPC_SIER_REGNUM : -1;
 
+  tdep->have_htm_spr = have_htm_spr;
+  tdep->have_htm_core = have_htm_core;
+  tdep->have_htm_fpu = have_htm_fpu;
+  tdep->have_htm_altivec = have_htm_altivec;
+  tdep->have_htm_vsx = have_htm_vsx;
+  tdep->ppc_cppr_regnum = have_htm_ppr ? PPC_CPPR_REGNUM : -1;
+  tdep->ppc_cdscr_regnum = have_htm_dscr ? PPC_CDSCR_REGNUM : -1;
+  tdep->ppc_ctar_regnum = have_htm_tar ? PPC_CTAR_REGNUM : -1;
+
   set_gdbarch_pc_regnum (gdbarch, PPC_PC_REGNUM);
   set_gdbarch_sp_regnum (gdbarch, PPC_R0_REGNUM + 1);
   set_gdbarch_fp0_regnum (gdbarch, tdep->ppc_fp0_regnum);
@@ -6449,7 +6888,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   else
     tdep->lr_frame_offset = 4;
 
-  if (have_spe || have_dfp || have_vsx)
+  if (have_spe || have_dfp || have_vsx || have_htm_fpu || have_htm_vsx)
     {
       set_gdbarch_pseudo_register_read (gdbarch, rs6000_pseudo_register_read);
       set_gdbarch_pseudo_register_write (gdbarch,
@@ -6471,6 +6910,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   if (have_vsx)
     /* Include both VSX and Extended FP registers.  */
     num_pseudoregs += 96;
+  if (have_htm_fpu)
+    num_pseudoregs += 16;
+  /* Include both checkpointed VSX and EFP registers.  */
+  if (have_htm_vsx)
+    num_pseudoregs += 64 + 32;
 
   set_gdbarch_num_pseudo_regs (gdbarch, num_pseudoregs);
 
@@ -6586,6 +7030,9 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->ppc_dl0_regnum = -1;
   tdep->ppc_vsr0_regnum = -1;
   tdep->ppc_efpr0_regnum = -1;
+  tdep->ppc_cdl0_regnum = -1;
+  tdep->ppc_cvsr0_regnum = -1;
+  tdep->ppc_cefpr0_regnum = -1;
 
   cur_reg = gdbarch_num_regs (gdbarch);
 
@@ -6606,6 +7053,18 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       tdep->ppc_efpr0_regnum = cur_reg;
       cur_reg += 32;
     }
+  if (have_htm_fpu)
+    {
+      tdep->ppc_cdl0_regnum = cur_reg;
+      cur_reg += 16;
+    }
+  if (have_htm_vsx)
+    {
+      tdep->ppc_cvsr0_regnum = cur_reg;
+      cur_reg += 64;
+      tdep->ppc_cefpr0_regnum = cur_reg;
+      cur_reg += 32;
+    }
 
   gdb_assert (gdbarch_num_cooked_regs (gdbarch) == cur_reg);
 
index bb02933..a8c83d7 100644 (file)
@@ -1,5 +1,10 @@
 2018-10-26  Pedro Franco de Carvalho  <pedromfc@linux.ibm.com>
 
+       * gdb.arch/powerpc-htm-regs.c: New file.
+       * gdb.arch/powerpc-htm-regs.exp: New file.
+
+2018-10-26  Pedro Franco de Carvalho  <pedromfc@linux.ibm.com>
+
        * gdb.arch/powerpc-tar.c: New file.
        * gdb.arch/powerpc-tar.exp: New file.
 
diff --git a/gdb/testsuite/gdb.arch/powerpc-htm-regs.c b/gdb/testsuite/gdb.arch/powerpc-htm-regs.c
new file mode 100644 (file)
index 0000000..8c062ce
--- /dev/null
@@ -0,0 +1,39 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright (C) 2018 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+int main (void)
+{
+  /* Touch DSCR.  Some kernels won't schedule the thread with a DSCR
+     altered by ptrace unless the register was used at some point.  */
+  unsigned long dscr = 0x0;
+
+  /* This is the non-privileged SPR number to access DSCR,
+     available since isa 207.  */
+  asm volatile ("mtspr 3,%0" : : "r" (dscr));
+
+  asm volatile ("tbegin."); // first marker
+  asm volatile goto ("bc 12,2,%l[end]"
+                    :
+                    :
+                    :
+                    : end);
+  asm volatile ("tabort. 0");
+end:
+  asm volatile ("nop"); // second marker
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.arch/powerpc-htm-regs.exp b/gdb/testsuite/gdb.arch/powerpc-htm-regs.exp
new file mode 100644 (file)
index 0000000..a1c876a
--- /dev/null
@@ -0,0 +1,328 @@
+# Copyright (C) 2018 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the gdb testsuite.
+
+# Test access to HTM (Hardware Transactional Memory) registers.  The
+# tests read the values of various registers before stepping the
+# inferior through a "tbegin." instruction to start a transaction,
+# then the checkpointed versions of the registers are checked against
+# the pre-transactional values.  Then, new values are written to some
+# of the checkpointed registers, these values are read back and saved,
+# the inferior continues until the transaction aborts, and the regular
+# registers are then checked against the saved values, because the
+# abort should have reverted the registers to these values.
+
+if {![istarget "powerpc*-*-linux*"]} then {
+    verbose "Skipping PowerPC test for HTM registers."
+    return
+}
+
+standard_testfile .c .gen.c
+
+# First check if our processor and kernel support access to
+# the registers we need and to the HTM facility.
+
+proc check_register_access { regname } {
+    global gdb_prompt
+
+    set test "$regname register access"
+    gdb_test_multiple "info reg $regname" "$test" {
+       -re "Invalid register.*\r\n$gdb_prompt $" {
+           unsupported "$test"
+           return 0
+       }
+       -re "\r\n$regname.*\r\n$gdb_prompt $" {
+           pass "$test"
+           return 1
+       }
+    }
+    return 0
+}
+
+proc check_htm_support {} {
+    global gdb_prompt
+    set test "htm support"
+
+    gdb_test_multiple "stepi" "$test" {
+       -re "Illegal instruction.*\r\n$gdb_prompt $" {
+           unsupported $test
+           return 0
+       }
+       -re "nop.*\r\n$gdb_prompt $"
+       {
+           pass $test
+           return 1
+       }
+    }
+    return 0;
+}
+
+with_test_prefix "check htm support" {
+    set gen_src [standard_output_file $srcfile2]
+
+    gdb_produce_source $gen_src {
+       int main () {
+           asm volatile ("tbegin."); // marker
+           asm volatile ("nop");
+           return 0;
+       }
+    }
+
+    if {[build_executable "compile" $binfile $gen_src {debug}] == -1} {
+       return
+    }
+
+    clean_restart $binfile
+
+    # Displaced-stepping a tbegin. causes problems,
+    # so we make the breakpoint temporary.
+    gdb_breakpoint [gdb_get_line_number "marker" "$gen_src"] temporary
+
+    gdb_run_cmd
+
+    # Wait for the prompt.
+    if {[gdb_test "" "Temporary breakpoint.*"] != 0 } {
+       return
+    }
+
+    # Make sure that we stopped at the right place (just before tbegin. is
+    # executed).
+    if { [gdb_test "x/i \$pc" "=> $hex.*:.*tbegin\\..*" "disassemble tbegin"] != 0} {
+       return
+    }
+
+    if {![check_register_access "vs0"]} {
+       return
+    }
+
+    if {![check_register_access "texasr"]} {
+       return
+    }
+
+    if {![check_register_access "dscr"]} {
+       return
+    }
+
+    if {![check_register_access "ppr"]} {
+       return
+    }
+
+    if {![check_register_access "tar"]} {
+       return
+    }
+
+    if {![check_htm_support]} {
+       return
+    }
+}
+
+# Now do the actual test.
+if {[build_executable "compile" $binfile $srcfile {debug}] == -1} {
+    return
+}
+
+clean_restart $binfile
+
+gdb_breakpoint [gdb_get_line_number "first marker"] temporary
+
+gdb_run_cmd
+
+# Wait for the prompt.
+gdb_test "" "Temporary breakpoint.*"
+
+if {[gdb_test "x/i \$pc" "=> $hex.*:.*tbegin\\..*" "disassemble tbegin"] != 0} {
+    return
+}
+
+# Now we write non-zero values to some registers, then read the values
+# of various registers, then stepi to start the transaction.  The
+# checkpointed register state should correspond to the values we read.
+
+# Write to the GPRs
+for {set i 0} {$i < 32} {incr i 1} {
+    gdb_test_no_output "set \$r$i = $i"
+}
+
+gdb_test_no_output "set \$xer = 0xc0000000"
+
+# FPRs
+gdb_test_no_output "set \$f0 = 0.5"
+for {set i 1} {$i < 32} {incr i 1} {
+    gdb_test_no_output "set \$f$i = \$f[expr $i - 1] + 1.0"
+}
+
+gdb_test_no_output "set \$fpscr = 0x84005000"
+
+# VRs
+for {set i 0} {$i < 32} {incr i 1} {
+    for {set j 0} {$j < 4} {incr j 1} {
+       gdb_test_no_output "set \$vr$i.v4_int32\[$j\] = $i"
+    }
+}
+
+gdb_test_no_output "set \$dscr = 0x2"
+gdb_test_no_output "set \$tar = &main" "set tar"
+
+# Get the pre-transactional value of the registers.
+for {set i 0} {$i < 32} {incr i 1} {
+    set "r$i" [get_hexadecimal_valueof "\$r$i" "default0"]
+}
+
+set cr [get_hexadecimal_valueof "\$cr" "default0"]
+set xer [get_hexadecimal_valueof "\$xer" "default0"]
+set lr [get_hexadecimal_valueof "\$lr" "default0"]
+set ctr [get_hexadecimal_valueof "\$ctr" "default0"]
+
+for {set i 0} {$i < 32} {incr i 1} {
+    set "f$i" [get_valueof "" "\$f$i" "default0"]
+}
+
+set fpscr [get_hexadecimal_valueof "\$fpscr" "default0"]
+
+for {set i 0} {$i < 32} {incr i 1} {
+    set "vr$i" [get_hexadecimal_valueof "\$vr$i.uint128" "default0"]
+}
+
+set vscr [get_hexadecimal_valueof "\$vscr" "default0"]
+set vrsave [get_hexadecimal_valueof "\$vrsave" "default0"]
+
+for {set i 0} {$i < 64} {incr i 1} {
+    set "vs$i" [get_hexadecimal_valueof "\$vs$i.uint128" "default0"]
+}
+
+set dscr [get_hexadecimal_valueof "\$dscr" "default0"]
+set ppr [get_hexadecimal_valueof "\$ppr" "default0"]
+set tar [get_hexadecimal_valueof "\$tar" "default0"]
+
+gdb_test "stepi" "asm.*bc.*"
+
+proc test_register_match {reg_name reg_var_name hex} {
+    set test "$reg_name matches $reg_var_name"
+
+    # In some infrequent cases CXER doesn't match the
+    # pre-transactional XER, possibly due to a linux kernel bug.
+    set should_xfail 0
+    if [istarget "powerpc*-*-linux*" && reg_name == "cxer"] {
+       set should_xfail 1
+    }
+
+    upvar $reg_var_name expected_val
+
+    if {$hex} {
+       set actual_val [get_hexadecimal_valueof "\$$reg_name" "default1"]
+    } else {
+       set actual_val [get_valueof "" "\$$reg_name" "default1"]
+    }
+
+    if { "$expected_val" == "$actual_val" } {
+       pass $test
+    } else {
+       if {$should_xfail} {
+           xfail $test
+       } else {
+           fail $test
+       }
+    }
+}
+
+for {set i 0} {$i < 32} {incr i 1} {
+    test_register_match "cr$i" "r$i" 1
+}
+
+test_register_match "ccr" "cr" 1
+test_register_match "cxer" "xer" 1
+test_register_match "clr" "lr" 1
+test_register_match "cctr" "ctr" 1
+
+for {set i 0} {$i < 32} {incr i 1} {
+    test_register_match "cf$i" "f$i" 0
+}
+
+test_register_match "cfpscr" "fpscr" 1
+
+for {set i 0} {$i < 32} {incr i 1} {
+    test_register_match "cvr$i.uint128" "vr$i" 1
+}
+
+test_register_match "cvscr" "vscr" 1
+test_register_match "cvrsave" "vrsave" 1
+
+for {set i 0} {$i < 64} {incr i 1} {
+    test_register_match "cvs$i.uint128" "vs$i" 1
+}
+
+test_register_match "cdscr" "dscr" 1
+test_register_match "cppr" "ppr" 1
+test_register_match "ctar" "tar" 1
+
+# Support for writing to the checkpointed registers is not
+# currently available in the gdbserver stub.
+if [target_is_gdbserver] {
+    unsupported "write to checkpointed registers"
+    return
+}
+
+# Now write different values to some of the checkpointed registers and
+# check that the transaction abort reverts the register to these
+# values.
+for {set i 0} {$i < 32} {incr i 1} {
+    gdb_test_no_output "set \$cr$i = $i + 0xC00"
+}
+
+gdb_test_no_output "set \$cf0 = 0.25"
+for {set i 1} {$i < 32} {incr i 1} {
+    gdb_test_no_output "set \$cf$i = \$cf[expr $i - 1] + 1.0"
+}
+
+for {set i 0} {$i < 32} {incr i 1} {
+    for {set j 0} {$j < 4} {incr j 1} {
+       gdb_test_no_output "set \$cvr$i.v4_int32\[$j\] = $i + 0xF00"
+    }
+}
+
+# Read back the values.
+with_test_prefix "after write" {
+    for {set i 0} {$i < 32} {incr i 1} {
+       set "cr$i" [get_hexadecimal_valueof "\$cr$i" "default0"]
+    }
+
+    for {set i 0} {$i < 32} {incr i 1} {
+       set "cf$i" [get_valueof "" "\$cf$i" "default0"]
+    }
+
+    for {set i 0} {$i < 64} {incr i 1} {
+       set "cvs$i" [get_hexadecimal_valueof "\$cvs$i.uint128" "default0"]
+    }
+}
+
+gdb_breakpoint [gdb_get_line_number "second marker"]
+
+gdb_test "continue"
+
+with_test_prefix "after transaction failure" {
+    for {set i 0} {$i < 32} {incr i 1} {
+       test_register_match "r$i" "cr$i" 1
+    }
+
+    for {set i 0} {$i < 32} {incr i 1} {
+       test_register_match "f$i" "cf$i" 0
+    }
+
+    for {set i 0} {$i < 64} {incr i 1} {
+       test_register_match "vs$i.uint128" "cvs$i" 1
+    }
+}
+