gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / rs6000-tdep.c
index 3bcd20515b602b2296e60f20e715a377b2109b1c..ead3500c26300c78c9d509833eb1dad7973bbe47 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2016 Free Software Foundation, Inc.
+   Copyright (C) 1986-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -29,7 +29,7 @@
 #include "arch-utils.h"
 #include "regcache.h"
 #include "regset.h"
-#include "doublest.h"
+#include "target-float.h"
 #include "value.h"
 #include "parser-defs.h"
 #include "osabi.h"
 #include "sim-regno.h"
 #include "gdb/sim-ppc.h"
 #include "reggroups.h"
-#include "dwarf2-frame.h"
+#include "dwarf2/frame.h"
 #include "target-descriptions.h"
 #include "user-regs.h"
 #include "record-full.h"
 #include "auxv.h"
 
-#include "libbfd.h"            /* for bfd_default_set_arch_mach */
 #include "coff/internal.h"     /* for libcoff.h */
 #include "libcoff.h"           /* for xcoff_data */
 #include "coff/xcoff.h"
 #include "frame-unwind.h"
 #include "frame-base.h"
 
+#include "ax.h"
+#include "ax-gdb.h"
+#include <algorithm>
+
 #include "features/rs6000/powerpc-32.c"
 #include "features/rs6000/powerpc-altivec32.c"
 #include "features/rs6000/powerpc-vsx32.c"
     && (regnum) >= (tdep)->ppc_dl0_regnum \
     && (regnum) < (tdep)->ppc_dl0_regnum + 16)
 
+/* Determine if regnum is a "vX" alias for the raw "vrX" vector
+   registers.  */
+#define IS_V_ALIAS_PSEUDOREG(tdep, regnum) (\
+    (tdep)->ppc_v0_alias_regnum >= 0 \
+    && (regnum) >= (tdep)->ppc_v0_alias_regnum \
+    && (regnum) < (tdep)->ppc_v0_alias_regnum + ppc_num_vrs)
+
 /* Determine if regnum is a POWER7 VSX register.  */
 #define IS_VSX_PSEUDOREG(tdep, regnum) ((tdep)->ppc_vsr0_regnum >= 0 \
     && (regnum) >= (tdep)->ppc_vsr0_regnum \
     && (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;
+
 /* The list of available "set powerpc ..." and "show powerpc ..."
    commands.  */
 static struct cmd_list_element *setpowerpccmdlist = NULL;
@@ -217,16 +246,6 @@ ppc_floating_point_unit_p (struct gdbarch *gdbarch)
           && tdep->ppc_fpscr_regnum >= 0);
 }
 
-/* Return non-zero if the architecture described by GDBARCH has
-   VSX registers (vsr0 --- vsr63).  */
-static int
-ppc_vsx_support_p (struct gdbarch *gdbarch)
-{
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
-  return tdep->ppc_vsr0_regnum >= 0;
-}
-
 /* Return non-zero if the architecture described by GDBARCH has
    Altivec registers (vr0 --- vr31, vrsave and vscr).  */
 int
@@ -361,9 +380,7 @@ rs6000_register_sim_regno (struct gdbarch *gdbarch, int reg)
   if (tdep->sim_regno == NULL)
     init_sim_regno_table (gdbarch);
 
-  gdb_assert (0 <= reg 
-             && reg <= gdbarch_num_regs (gdbarch)
-                       + gdbarch_num_pseudo_regs (gdbarch));
+  gdb_assert (0 <= reg && reg <= gdbarch_num_cooked_regs (gdbarch));
   sim_regno = tdep->sim_regno[reg];
 
   if (sim_regno >= 0)
@@ -387,13 +404,13 @@ ppc_supply_reg (struct regcache *regcache, int regnum,
     {
       if (regsize > 4)
        {
-         struct gdbarch *gdbarch = get_regcache_arch (regcache);
+         struct gdbarch *gdbarch = regcache->arch ();
          int gdb_regsize = register_size (gdbarch, regnum);
          if (gdb_regsize < regsize
              && gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
            offset += regsize - gdb_regsize;
        }
-      regcache_raw_supply (regcache, regnum, regs + offset);
+      regcache->raw_supply (regnum, regs + offset);
     }
 }
 
@@ -408,7 +425,7 @@ ppc_collect_reg (const struct regcache *regcache, int regnum,
     {
       if (regsize > 4)
        {
-         struct gdbarch *gdbarch = get_regcache_arch (regcache);
+         struct gdbarch *gdbarch = regcache->arch ();
          int gdb_regsize = register_size (gdbarch, regnum);
          if (gdb_regsize < regsize)
            {
@@ -422,7 +439,7 @@ ppc_collect_reg (const struct regcache *regcache, int regnum,
                        regsize - gdb_regsize);
            }
        }
-      regcache_raw_collect (regcache, regnum, regs + offset);
+      regcache->raw_collect (regnum, regs + offset);
     }
 }
     
@@ -479,24 +496,6 @@ ppc_fpreg_offset (struct gdbarch_tdep *tdep,
   return -1;
 }
 
-static int
-ppc_vrreg_offset (struct gdbarch_tdep *tdep,
-                 const struct ppc_reg_offsets *offsets,
-                 int regnum)
-{
-  if (regnum >= tdep->ppc_vr0_regnum
-      && regnum < tdep->ppc_vr0_regnum + ppc_num_vrs)
-    return offsets->vr0_offset + (regnum - tdep->ppc_vr0_regnum) * 16;
-
-  if (regnum == tdep->ppc_vrsave_regnum - 1)
-    return offsets->vscr_offset;
-
-  if (regnum == tdep->ppc_vrsave_regnum)
-    return offsets->vrsave_offset;
-
-  return -1;
-}
-
 /* Supply register REGNUM in the general-purpose register set REGSET
    from the buffer specified by GREGS and LEN to register cache
    REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */
@@ -505,7 +504,7 @@ void
 ppc_supply_gregset (const struct regset *regset, struct regcache *regcache,
                    int regnum, const void *gregs, size_t len)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   const struct ppc_reg_offsets *offsets
     = (const struct ppc_reg_offsets *) regset->regmap;
@@ -555,7 +554,7 @@ void
 ppc_supply_fpregset (const struct regset *regset, struct regcache *regcache,
                     int regnum, const void *fpregs, size_t len)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep;
   const struct ppc_reg_offsets *offsets;
   size_t offset;
@@ -585,81 +584,6 @@ ppc_supply_fpregset (const struct regset *regset, struct regcache *regcache,
                  regnum == tdep->ppc_fpscr_regnum ? offsets->fpscr_size : 8);
 }
 
-/* Supply register REGNUM in the VSX register set REGSET
-   from the buffer specified by VSXREGS and LEN to register cache
-   REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */
-
-void
-ppc_supply_vsxregset (const struct regset *regset, struct regcache *regcache,
-                    int regnum, const void *vsxregs, size_t len)
-{
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  struct gdbarch_tdep *tdep;
-
-  if (!ppc_vsx_support_p (gdbarch))
-    return;
-
-  tdep = gdbarch_tdep (gdbarch);
-
-  if (regnum == -1)
-    {
-      int i;
-
-      for (i = tdep->ppc_vsr0_upper_regnum;
-          i < tdep->ppc_vsr0_upper_regnum + 32;
-          i++)
-       ppc_supply_reg (regcache, i, (const gdb_byte *) vsxregs, 0, 8);
-
-      return;
-    }
-  else
-    ppc_supply_reg (regcache, regnum, (const gdb_byte *) vsxregs, 0, 8);
-}
-
-/* Supply register REGNUM in the Altivec register set REGSET
-   from the buffer specified by VRREGS and LEN to register cache
-   REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */
-
-void
-ppc_supply_vrregset (const struct regset *regset, struct regcache *regcache,
-                    int regnum, const void *vrregs, size_t len)
-{
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  struct gdbarch_tdep *tdep;
-  const struct ppc_reg_offsets *offsets;
-  size_t offset;
-
-  if (!ppc_altivec_support_p (gdbarch))
-    return;
-
-  tdep = gdbarch_tdep (gdbarch);
-  offsets = (const struct ppc_reg_offsets *) regset->regmap;
-  if (regnum == -1)
-    {
-      int i;
-
-      for (i = tdep->ppc_vr0_regnum, offset = offsets->vr0_offset;
-          i < tdep->ppc_vr0_regnum + ppc_num_vrs;
-          i++, offset += 16)
-        ppc_supply_reg (regcache, i, (const gdb_byte *) vrregs, offset, 16);
-
-      ppc_supply_reg (regcache, (tdep->ppc_vrsave_regnum - 1),
-                     (const gdb_byte *) vrregs, offsets->vscr_offset, 4);
-
-      ppc_supply_reg (regcache, tdep->ppc_vrsave_regnum,
-                     (const gdb_byte *) vrregs, offsets->vrsave_offset, 4);
-      return;
-    }
-
-  offset = ppc_vrreg_offset (tdep, offsets, regnum);
-  if (regnum != tdep->ppc_vrsave_regnum
-      && regnum != tdep->ppc_vrsave_regnum - 1)
-    ppc_supply_reg (regcache, regnum, (const gdb_byte *) vrregs, offset, 16);
-  else
-    ppc_supply_reg (regcache, regnum,
-                   (const gdb_byte *) vrregs, offset, 4);
-}
-
 /* Collect register REGNUM in the general-purpose register set
    REGSET from register cache REGCACHE into the buffer specified by
    GREGS and LEN.  If REGNUM is -1, do this for all registers in
@@ -670,7 +594,7 @@ ppc_collect_gregset (const struct regset *regset,
                     const struct regcache *regcache,
                     int regnum, void *gregs, size_t len)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   const struct ppc_reg_offsets *offsets
     = (const struct ppc_reg_offsets *) regset->regmap;
@@ -721,7 +645,7 @@ ppc_collect_fpregset (const struct regset *regset,
                      const struct regcache *regcache,
                      int regnum, void *fpregs, size_t len)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep;
   const struct ppc_reg_offsets *offsets;
   size_t offset;
@@ -751,87 +675,6 @@ ppc_collect_fpregset (const struct regset *regset,
                   regnum == tdep->ppc_fpscr_regnum ? offsets->fpscr_size : 8);
 }
 
-/* Collect register REGNUM in the VSX register set
-   REGSET from register cache REGCACHE into the buffer specified by
-   VSXREGS and LEN.  If REGNUM is -1, do this for all registers in
-   REGSET.  */
-
-void
-ppc_collect_vsxregset (const struct regset *regset,
-                     const struct regcache *regcache,
-                     int regnum, void *vsxregs, size_t len)
-{
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  struct gdbarch_tdep *tdep;
-
-  if (!ppc_vsx_support_p (gdbarch))
-    return;
-
-  tdep = gdbarch_tdep (gdbarch);
-
-  if (regnum == -1)
-    {
-      int i;
-
-      for (i = tdep->ppc_vsr0_upper_regnum;
-          i < tdep->ppc_vsr0_upper_regnum + 32;
-          i++)
-       ppc_collect_reg (regcache, i, (gdb_byte *) vsxregs, 0, 8);
-
-      return;
-    }
-  else
-    ppc_collect_reg (regcache, regnum, (gdb_byte *) vsxregs, 0, 8);
-}
-
-
-/* Collect register REGNUM in the Altivec register set
-   REGSET from register cache REGCACHE into the buffer specified by
-   VRREGS and LEN.  If REGNUM is -1, do this for all registers in
-   REGSET.  */
-
-void
-ppc_collect_vrregset (const struct regset *regset,
-                     const struct regcache *regcache,
-                     int regnum, void *vrregs, size_t len)
-{
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  struct gdbarch_tdep *tdep;
-  const struct ppc_reg_offsets *offsets;
-  size_t offset;
-
-  if (!ppc_altivec_support_p (gdbarch))
-    return;
-
-  tdep = gdbarch_tdep (gdbarch);
-  offsets = (const struct ppc_reg_offsets *) regset->regmap;
-  if (regnum == -1)
-    {
-      int i;
-
-      for (i = tdep->ppc_vr0_regnum, offset = offsets->vr0_offset;
-          i < tdep->ppc_vr0_regnum + ppc_num_vrs;
-          i++, offset += 16)
-       ppc_collect_reg (regcache, i, (gdb_byte *) vrregs, offset, 16);
-
-      ppc_collect_reg (regcache, (tdep->ppc_vrsave_regnum - 1),
-                      (gdb_byte *) vrregs, offsets->vscr_offset, 4);
-
-      ppc_collect_reg (regcache, tdep->ppc_vrsave_regnum,
-                      (gdb_byte *) vrregs, offsets->vrsave_offset, 4);
-      return;
-    }
-
-  offset = ppc_vrreg_offset (tdep, offsets, regnum);
-  if (regnum != tdep->ppc_vrsave_regnum
-      && regnum != tdep->ppc_vrsave_regnum - 1)
-    ppc_collect_reg (regcache, regnum, (gdb_byte *) vrregs, offset, 16);
-  else
-    ppc_collect_reg (regcache, regnum,
-                   (gdb_byte *) vrregs, offset, 4);
-}
-\f
-
 static int
 insn_changes_sp_or_jumps (unsigned long insn)
 {
@@ -964,18 +807,11 @@ rs6000_fetch_pointer_argument (struct frame_info *frame, int argi,
 
 /* Sequence of bytes for breakpoint instruction.  */
 
-static const unsigned char *
-rs6000_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
-                          int *bp_size)
-{
-  static unsigned char big_breakpoint[] = { 0x7d, 0x82, 0x10, 0x08 };
-  static unsigned char little_breakpoint[] = { 0x08, 0x10, 0x82, 0x7d };
-  *bp_size = 4;
-  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
-    return big_breakpoint;
-  else
-    return little_breakpoint;
-}
+constexpr gdb_byte big_breakpoint[] = { 0x7d, 0x82, 0x10, 0x08 };
+constexpr gdb_byte little_breakpoint[] = { 0x08, 0x10, 0x82, 0x7d };
+
+typedef BP_MANIPULATION_ENDIAN (little_breakpoint, big_breakpoint)
+  rs6000_breakpoint;
 
 /* Instruction masks for displaced stepping.  */
 #define BRANCH_MASK 0xfc000000
@@ -987,24 +823,47 @@ rs6000_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
 
 /* Instruction masks used during single-stepping of atomic
    sequences.  */
-#define LWARX_MASK 0xfc0007fe
+#define LOAD_AND_RESERVE_MASK 0xfc0007fe
 #define LWARX_INSTRUCTION 0x7c000028
 #define LDARX_INSTRUCTION 0x7c0000A8
-#define STWCX_MASK 0xfc0007ff
+#define LBARX_INSTRUCTION 0x7c000068
+#define LHARX_INSTRUCTION 0x7c0000e8
+#define LQARX_INSTRUCTION 0x7c000228
+#define STORE_CONDITIONAL_MASK 0xfc0007ff
 #define STWCX_INSTRUCTION 0x7c00012d
 #define STDCX_INSTRUCTION 0x7c0001ad
+#define STBCX_INSTRUCTION 0x7c00056d
+#define STHCX_INSTRUCTION 0x7c0005ad
+#define STQCX_INSTRUCTION 0x7c00016d
+
+/* Check if insn is one of the Load And Reserve instructions used for atomic
+   sequences.  */
+#define IS_LOAD_AND_RESERVE_INSN(insn) ((insn & LOAD_AND_RESERVE_MASK) == LWARX_INSTRUCTION \
+                                        || (insn & LOAD_AND_RESERVE_MASK) == LDARX_INSTRUCTION \
+                                        || (insn & LOAD_AND_RESERVE_MASK) == LBARX_INSTRUCTION \
+                                        || (insn & LOAD_AND_RESERVE_MASK) == LHARX_INSTRUCTION \
+                                        || (insn & LOAD_AND_RESERVE_MASK) == LQARX_INSTRUCTION)
+/* Check if insn is one of the Store Conditional instructions used for atomic
+   sequences.  */
+#define IS_STORE_CONDITIONAL_INSN(insn)        ((insn & STORE_CONDITIONAL_MASK) == STWCX_INSTRUCTION \
+                                        || (insn & STORE_CONDITIONAL_MASK) == STDCX_INSTRUCTION \
+                                        || (insn & STORE_CONDITIONAL_MASK) == STBCX_INSTRUCTION \
+                                        || (insn & STORE_CONDITIONAL_MASK) == STHCX_INSTRUCTION \
+                                        || (insn & STORE_CONDITIONAL_MASK) == STQCX_INSTRUCTION)
+
+typedef buf_displaced_step_copy_insn_closure ppc_displaced_step_copy_insn_closure;
 
-/* We can't displaced step atomic sequences.  Otherwise this is just
-   like simple_displaced_step_copy_insn.  */
+/* We can't displaced step atomic sequences.  */
 
-static struct displaced_step_closure *
+static displaced_step_copy_insn_closure_up
 ppc_displaced_step_copy_insn (struct gdbarch *gdbarch,
                              CORE_ADDR from, CORE_ADDR to,
                              struct regcache *regs)
 {
   size_t len = gdbarch_max_insn_length (gdbarch);
-  gdb_byte *buf = (gdb_byte *) xmalloc (len);
-  struct cleanup *old_chain = make_cleanup (xfree, buf);
+  std::unique_ptr<ppc_displaced_step_copy_insn_closure> closure
+    (new ppc_displaced_step_copy_insn_closure (len));
+  gdb_byte *buf = closure->buf.data ();
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int insn;
 
@@ -1012,9 +871,8 @@ ppc_displaced_step_copy_insn (struct gdbarch *gdbarch,
 
   insn = extract_signed_integer (buf, PPC_INSN_SIZE, byte_order);
 
-  /* Assume all atomic sequences start with a lwarx/ldarx instruction.  */
-  if ((insn & LWARX_MASK) == LWARX_INSTRUCTION
-      || (insn & LWARX_MASK) == LDARX_INSTRUCTION)
+  /* Assume all atomic sequences start with a Load and Reserve instruction.  */
+  if (IS_LOAD_AND_RESERVE_INSN (insn))
     {
       if (debug_displaced)
        {
@@ -1023,7 +881,7 @@ ppc_displaced_step_copy_insn (struct gdbarch *gdbarch,
                              "atomic sequence at %s\n",
                              paddress (gdbarch, from));
        }
-      do_cleanups (old_chain);
+
       return NULL;
     }
 
@@ -1036,22 +894,23 @@ ppc_displaced_step_copy_insn (struct gdbarch *gdbarch,
       displaced_step_dump_bytes (gdb_stdlog, buf, len);
     }
 
-  discard_cleanups (old_chain);
-  return (struct displaced_step_closure *) buf;
+  /* This is a work around for a problem with g++ 4.8.  */
+  return displaced_step_copy_insn_closure_up (closure.release ());
 }
 
 /* Fix up the state of registers and memory after having single-stepped
    a displaced instruction.  */
 static void
 ppc_displaced_step_fixup (struct gdbarch *gdbarch,
-                         struct displaced_step_closure *closure,
+                         struct displaced_step_copy_insn_closure *closure_,
                          CORE_ADDR from, CORE_ADDR to,
                          struct regcache *regs)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   /* Our closure is a copy of the instruction.  */
-  ULONGEST insn  = extract_unsigned_integer ((gdb_byte *) closure,
-                                             PPC_INSN_SIZE, byte_order);
+  ppc_displaced_step_copy_insn_closure *closure = (ppc_displaced_step_copy_insn_closure *) closure_;
+  ULONGEST insn  = extract_unsigned_integer (closure->buf.data (),
+                                            PPC_INSN_SIZE, byte_order);
   ULONGEST opcode = 0;
   /* Offset for non PC-relative instructions.  */
   LONGEST offset = PPC_INSN_SIZE;
@@ -1137,24 +996,22 @@ ppc_displaced_step_fixup (struct gdbarch *gdbarch,
    displaced instruction.  */
 static int
 ppc_displaced_step_hw_singlestep (struct gdbarch *gdbarch,
-                                 struct displaced_step_closure *closure)
+                                 struct displaced_step_copy_insn_closure *closure)
 {
   return 1;
 }
 
-/* Checks for an atomic sequence of instructions beginning with a LWARX/LDARX
-   instruction and ending with a STWCX/STDCX instruction.  If such a sequence
-   is found, attempt to step through it.  A breakpoint is placed at the end of 
-   the sequence.  */
-
-int 
-ppc_deal_with_atomic_sequence (struct frame_info *frame)
+/* Checks for an atomic sequence of instructions beginning with a
+   Load And Reserve instruction and ending with a Store Conditional
+   instruction.  If such a sequence is found, attempt to step through it.
+   A breakpoint is placed at the end of the sequence.  */
+std::vector<CORE_ADDR>
+ppc_deal_with_atomic_sequence (struct regcache *regcache)
 {
-  struct gdbarch *gdbarch = get_frame_arch (frame);
-  struct address_space *aspace = get_frame_address_space (frame);
+  struct gdbarch *gdbarch = regcache->arch ();
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  CORE_ADDR pc = get_frame_pc (frame);
-  CORE_ADDR breaks[2] = {-1, -1};
+  CORE_ADDR pc = regcache_read_pc (regcache);
+  CORE_ADDR breaks[2] = {CORE_ADDR_MAX, CORE_ADDR_MAX};
   CORE_ADDR loc = pc;
   CORE_ADDR closing_insn; /* Instruction that closes the atomic sequence.  */
   int insn = read_memory_integer (loc, PPC_INSN_SIZE, byte_order);
@@ -1162,13 +1019,11 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame)
   int index;
   int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed).  */  
   const int atomic_sequence_length = 16; /* Instruction sequence length.  */
-  int opcode; /* Branch instruction's OPcode.  */
   int bc_insn_count = 0; /* Conditional branch instruction count.  */
 
-  /* Assume all atomic sequences start with a lwarx/ldarx instruction.  */
-  if ((insn & LWARX_MASK) != LWARX_INSTRUCTION
-      && (insn & LWARX_MASK) != LDARX_INSTRUCTION)
-    return 0;
+  /* Assume all atomic sequences start with a Load And Reserve instruction.  */
+  if (!IS_LOAD_AND_RESERVE_INSN (insn))
+    return {};
 
   /* Assume that no atomic sequence is longer than "atomic_sequence_length" 
      instructions.  */
@@ -1186,8 +1041,8 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame)
           int absolute = insn & 2;
 
           if (bc_insn_count >= 1)
-            return 0; /* More than one conditional branch found, fallback 
-                         to the standard single-step code.  */
+            return {}; /* More than one conditional branch found, fallback
+                          to the standard single-step code.  */
  
          if (absolute)
            breaks[1] = immediate;
@@ -1198,19 +1053,17 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame)
          last_breakpoint++;
         }
 
-      if ((insn & STWCX_MASK) == STWCX_INSTRUCTION
-          || (insn & STWCX_MASK) == STDCX_INSTRUCTION)
+      if (IS_STORE_CONDITIONAL_INSN (insn))
         break;
     }
 
-  /* Assume that the atomic sequence ends with a stwcx/stdcx instruction.  */
-  if ((insn & STWCX_MASK) != STWCX_INSTRUCTION
-      && (insn & STWCX_MASK) != STDCX_INSTRUCTION)
-    return 0;
+  /* Assume that the atomic sequence ends with a Store Conditional
+     instruction.  */
+  if (!IS_STORE_CONDITIONAL_INSN (insn))
+    return {};
 
   closing_insn = loc;
   loc += PPC_INSN_SIZE;
-  insn = read_memory_integer (loc, PPC_INSN_SIZE, byte_order);
 
   /* Insert a breakpoint right after the end of the atomic sequence.  */
   breaks[0] = loc;
@@ -1222,11 +1075,12 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame)
          || (breaks[1] >= pc && breaks[1] <= closing_insn)))
     last_breakpoint = 0;
 
-  /* Effectively inserts the breakpoints.  */
+  std::vector<CORE_ADDR> next_pcs;
+
   for (index = 0; index <= last_breakpoint; index++)
-    insert_single_step_breakpoint (gdbarch, aspace, breaks[index]);
+    next_pcs.push_back (breaks[index]);
 
-  return 1;
+  return next_pcs;
 }
 
 
@@ -1341,6 +1195,39 @@ bl_to_blrl_insn_p (CORE_ADDR pc, int insn, enum bfd_endian byte_order)
   return 0;
 }
 
+/* Return true if OP is a stw or std instruction with
+   register operands RS and RA and any immediate offset.
+
+   If WITH_UPDATE is true, also return true if OP is
+   a stwu or stdu instruction with the same operands.
+
+   Return false otherwise.
+   */
+static bool
+store_insn_p (unsigned long op, unsigned long rs,
+             unsigned long ra, bool with_update)
+{
+  rs = rs << 21;
+  ra = ra << 16;
+
+  if (/* std RS, SIMM(RA) */
+      ((op & 0xffff0003) == (rs | ra | 0xf8000000)) ||
+      /* stw RS, SIMM(RA) */
+      ((op & 0xffff0000) == (rs | ra | 0x90000000)))
+    return true;
+
+  if (with_update)
+    {
+      if (/* stdu RS, SIMM(RA) */
+         ((op & 0xffff0003) == (rs | ra | 0xf8000001)) ||
+         /* stwu RS, SIMM(RA) */
+         ((op & 0xffff0000) == (rs | ra | 0x94000000)))
+       return true;
+    }
+
+  return false;
+}
+
 /* Masks for decoding a branch-and-link (bl) instruction.
 
    BL_MASK and BL_INSTRUCTION are used in combination with each other.
@@ -1348,7 +1235,7 @@ bl_to_blrl_insn_p (CORE_ADDR pc, int insn, enum bfd_endian byte_order)
    this masking operation is equal to BL_INSTRUCTION, then the opcode in
    question is a ``bl'' instruction.
    
-   BL_DISPLACMENT_MASK is anded with the opcode in order to extract
+   BL_DISPLACEMENT_MASK is anded with the opcode in order to extract
    the branch displacement.  */
 
 #define BL_MASK 0xfc000001
@@ -1474,7 +1361,7 @@ rs6000_skip_stack_check (struct gdbarch *gdbarch, const CORE_ADDR start_pc)
       return pc;
     }
 
-  /* Third sequence: No probe; instead, a comparizon between the stack size
+  /* Third sequence: No probe; instead, a comparison between the stack size
      limit (saved in a run-time global variable) and the current stack
      pointer:
 
@@ -1567,6 +1454,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
   gdb_byte buf[4];
   unsigned long op;
   long offset = 0;
+  long alloca_reg_offset = 0;
   long vr_saved_offset = 0;
   int lr_reg = -1;
   int cr_reg = -1;
@@ -1645,7 +1533,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
        }
       else if ((op & 0xfc1fffff) == 0x7c000026)
        {                       /* mfcr Rx */
-         cr_reg = (op & 0x03e00000);
+         cr_reg = (op & 0x03e00000) >> 21;
           if (cr_reg == 0)
             r0_contains_arg = 0;
          continue;
@@ -1722,14 +1610,17 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
 
        }
       else if (lr_reg >= 0 &&
-              /* std Rx, NUM(r1) || stdu Rx, NUM(r1) */
-              (((op & 0xffff0000) == (lr_reg | 0xf8010000)) ||
-               /* stw Rx, NUM(r1) */
-               ((op & 0xffff0000) == (lr_reg | 0x90010000)) ||
-               /* stwu Rx, NUM(r1) */
-               ((op & 0xffff0000) == (lr_reg | 0x94010000))))
-       {       /* where Rx == lr */
-         fdata->lr_offset = offset;
+              ((store_insn_p (op, lr_reg, 1, true)) ||
+               (framep &&
+                (store_insn_p (op, lr_reg,
+                               fdata->alloca_reg - tdep->ppc_gp0_regnum,
+                               false)))))
+       {
+         if (store_insn_p (op, lr_reg, 1, true))
+           fdata->lr_offset = offset;
+         else /* LR save through frame pointer. */
+           fdata->lr_offset = alloca_reg_offset;
+
          fdata->nosavedpc = 0;
          /* Invalidate lr_reg, but don't set it to -1.
             That would mean that it had never been set.  */
@@ -1744,13 +1635,8 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
 
        }
       else if (cr_reg >= 0 &&
-              /* std Rx, NUM(r1) || stdu Rx, NUM(r1) */
-              (((op & 0xffff0000) == (cr_reg | 0xf8010000)) ||
-               /* stw Rx, NUM(r1) */
-               ((op & 0xffff0000) == (cr_reg | 0x90010000)) ||
-               /* stwu Rx, NUM(r1) */
-               ((op & 0xffff0000) == (cr_reg | 0x94010000))))
-       {       /* where Rx == cr */
+              (store_insn_p (op, cr_reg, 1, true)))
+       {
          fdata->cr_offset = offset;
          /* Invalidate cr_reg, but don't set it to -1.
             That would mean that it had never been set.  */
@@ -1841,8 +1727,8 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
          offset = fdata->offset;
          continue;
        }
-      else if ((op & 0xfc1f016a) == 0x7c01016e)
-       {                       /* stwux rX,r1,rY */
+      else if ((op & 0xfc1f07fa) == 0x7c01016a)
+       {               /* stwux rX,r1,rY  || stdux rX,r1,rY */
          /* No way to figure out what r1 is going to be.  */
          fdata->frameless = 0;
          offset = fdata->offset;
@@ -1855,13 +1741,6 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
          offset = fdata->offset;
          continue;
        }
-      else if ((op & 0xfc1f016a) == 0x7c01016a)
-       {                       /* stdux rX,r1,rY */
-         /* No way to figure out what r1 is going to be.  */
-         fdata->frameless = 0;
-         offset = fdata->offset;
-         continue;
-       }
       else if ((op & 0xffff0000) == 0x38210000)
        {                       /* addi r1,r1,SIMM */
          fdata->frameless = 0;
@@ -1904,6 +1783,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
          fdata->frameless = 0;
          framep = 1;
          fdata->alloca_reg = (tdep->ppc_gp0_regnum + 29);
+         alloca_reg_offset = offset;
          continue;
 
          /* Another way to set up the frame pointer.  */
@@ -1914,6 +1794,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
          fdata->frameless = 0;
          framep = 1;
          fdata->alloca_reg = (tdep->ppc_gp0_regnum + 31);
+         alloca_reg_offset = offset;
          continue;
 
          /* Another way to set up the frame pointer.  */
@@ -1924,6 +1805,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
          framep = 1;
          fdata->alloca_reg = (tdep->ppc_gp0_regnum
                               + ((op & ~0x38010000) >> 21));
+         alloca_reg_offset = offset;
          continue;
        }
       /* AltiVec related instructions.  */
@@ -2102,16 +1984,19 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
 
       else
        {
-         unsigned int all_mask = ~((1U << fdata->saved_gpr) - 1);
-
          /* Not a recognized prologue instruction.
             Handle optimizer code motions into the prologue by continuing
             the search if we have no valid frame yet or if the return
             address is not yet saved in the frame.  Also skip instructions
             if some of the GPRs expected to be saved are not yet saved.  */
          if (fdata->frameless == 0 && fdata->nosavedpc == 0
-             && (fdata->gpr_mask & all_mask) == all_mask)
-           break;
+             && fdata->saved_gpr != -1)
+           {
+             unsigned int all_mask = ~((1U << fdata->saved_gpr) - 1);
+
+             if ((fdata->gpr_mask & all_mask) == all_mask)
+               break;
+           }
 
          if (op == 0x4e800020          /* blr */
              || op == 0x4e800420)      /* bctr */
@@ -2184,7 +2069,7 @@ rs6000_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
       CORE_ADDR post_prologue_pc
        = skip_prologue_using_sal (gdbarch, func_addr);
       if (post_prologue_pc != 0)
-       return max (pc, post_prologue_pc);
+       return std::max (pc, post_prologue_pc);
     }
 
   /* Can't determine prologue from the symbol table, need to examine
@@ -2235,9 +2120,9 @@ rs6000_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
          to __eabi in case the GCC option "-fleading-underscore" was
         used to compile the program.  */
       if (s.minsym != NULL
-          && MSYMBOL_LINKAGE_NAME (s.minsym) != NULL
-         && (strcmp (MSYMBOL_LINKAGE_NAME (s.minsym), "__eabi") == 0
-             || strcmp (MSYMBOL_LINKAGE_NAME (s.minsym), "___eabi") == 0))
+          && s.minsym->linkage_name () != NULL
+         && (strcmp (s.minsym->linkage_name (), "__eabi") == 0
+             || strcmp (s.minsym->linkage_name (), "___eabi") == 0))
        pc += 4;
     }
   return pc;
@@ -2321,7 +2206,7 @@ rs6000_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
   msymbol = lookup_minimal_symbol_by_pc (pc);
   if (msymbol.minsym
       && rs6000_in_solib_return_trampoline (gdbarch, pc,
-                                           MSYMBOL_LINKAGE_NAME (msymbol.minsym)))
+                                           msymbol.minsym->linkage_name ()))
     {
       /* Double-check that the third instruction from PC is relative "b".  */
       op = read_memory_integer (pc + 8, 4, byte_order);
@@ -2389,7 +2274,7 @@ rs6000_builtin_type_vec64 (struct gdbarch *gdbarch)
                                   init_vector_type (bt->builtin_int8, 8));
 
       TYPE_VECTOR (t) = 1;
-      TYPE_NAME (t) = "ppc_builtin_type_vec64";
+      t->set_name ("ppc_builtin_type_vec64");
       tdep->ppc_builtin_type_vec64 = t;
     }
 
@@ -2436,7 +2321,7 @@ rs6000_builtin_type_vec128 (struct gdbarch *gdbarch)
                                   init_vector_type (bt->builtin_int8, 16));
 
       TYPE_VECTOR (t) = 1;
-      TYPE_NAME (t) = "ppc_builtin_type_vec128";
+      t->set_name ("ppc_builtin_type_vec128");
       tdep->ppc_builtin_type_vec128 = t;
     }
 
@@ -2465,6 +2350,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))
     {
@@ -2489,6 +2379,18 @@ rs6000_register_name (struct gdbarch *gdbarch, int regno)
       return dfp128_regnames[regno - tdep->ppc_dl0_regnum];
     }
 
+  /* Check if this is a vX alias for a raw vrX vector register.  */
+  if (IS_V_ALIAS_PSEUDOREG (tdep, regno))
+    {
+      static const char *const vector_alias_regnames[] = {
+       "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
+       "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
+       "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
+       "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
+      };
+      return vector_alias_regnames[regno - tdep->ppc_v0_alias_regnum];
+    }
+
   /* Check if this is a VSX pseudo-register.  */
   if (IS_VSX_PSEUDOREG (tdep, regno))
     {
@@ -2519,6 +2421,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);
 }
 
@@ -2530,45 +2474,49 @@ 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_V_ALIAS_PSEUDOREG (tdep, regnum))
+    return gdbarch_register_type (gdbarch,
+                                 tdep->ppc_vr0_regnum
+                                 + (regnum
+                                    - tdep->ppc_v0_alias_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);
 }
 
-/* Is REGNUM a member of REGGROUP?  */
+/* Check if REGNUM is a member of REGGROUP.  We only need to handle
+   the vX aliases for the vector registers by always returning false
+   to avoid duplicated information in "info register vector/all",
+   since the raw vrX registers will already show in these cases.  For
+   other pseudo-registers we use the default membership function.  */
+
 static int
 rs6000_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
                                   struct reggroup *group)
 {
   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 or the POWER7 VSX registers.  */
-  if (IS_SPE_PSEUDOREG (tdep, regnum) || IS_VSX_PSEUDOREG (tdep, regnum))
-    return group == all_reggroup || group == vector_reggroup;
+  if (IS_V_ALIAS_PSEUDOREG (tdep, regnum))
+    return 0;
   else
-    /* PPC decimal128 or Extended FP pseudo-registers.  */
-    return group == all_reggroup || group == float_reggroup;
+    return default_register_reggroup_p (gdbarch, regnum, group);
 }
 
 /* The register format for RS/6000 floating point registers is always
@@ -2583,7 +2531,7 @@ rs6000_convert_register_p (struct gdbarch *gdbarch, int regnum,
   return (tdep->ppc_fp0_regnum >= 0
          && regnum >= tdep->ppc_fp0_regnum
          && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs
-         && TYPE_CODE (type) == TYPE_CODE_FLT
+         && type->code () == TYPE_CODE_FLT
          && TYPE_LENGTH (type)
             != TYPE_LENGTH (builtin_type (gdbarch)->builtin_double));
 }
@@ -2596,17 +2544,17 @@ rs6000_register_to_value (struct frame_info *frame,
                          int *optimizedp, int *unavailablep)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  gdb_byte from[MAX_REGISTER_SIZE];
+  gdb_byte from[PPC_MAX_REGISTER_SIZE];
   
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
+  gdb_assert (type->code () == TYPE_CODE_FLT);
 
   if (!get_frame_register_bytes (frame, regnum, 0,
                                 register_size (gdbarch, regnum),
                                 from, optimizedp, unavailablep))
     return 0;
 
-  convert_typed_floating (from, builtin_type (gdbarch)->builtin_double,
-                         to, type);
+  target_float_convert (from, builtin_type (gdbarch)->builtin_double,
+                       to, type);
   *optimizedp = *unavailablep = 0;
   return 1;
 }
@@ -2618,12 +2566,12 @@ rs6000_value_to_register (struct frame_info *frame,
                           const gdb_byte *from)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  gdb_byte to[MAX_REGISTER_SIZE];
+  gdb_byte to[PPC_MAX_REGISTER_SIZE];
 
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
+  gdb_assert (type->code () == TYPE_CODE_FLT);
 
-  convert_typed_floating (from, type,
-                         to, builtin_type (gdbarch)->builtin_double);
+  target_float_convert (from, type,
+                       to, builtin_type (gdbarch)->builtin_double);
   put_frame_register (frame, regnum, to);
 }
 
@@ -2660,7 +2608,7 @@ static enum register_status
 e500_move_ev_register (move_ev_register_func move,
                       struct regcache *regcache, int ev_reg, void *buffer)
 {
-  struct gdbarch *arch = get_regcache_arch (regcache);
+  struct gdbarch *arch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (arch); 
   int reg_index;
   gdb_byte *byte_buffer = (gdb_byte *) buffer;
@@ -2689,25 +2637,45 @@ e500_move_ev_register (move_ev_register_func move,
   return status;
 }
 
-static enum register_status
-do_regcache_raw_read (struct regcache *regcache, int regnum, void *buffer)
-{
-  return regcache_raw_read (regcache, regnum, (gdb_byte *) buffer);
-}
-
 static enum register_status
 do_regcache_raw_write (struct regcache *regcache, int regnum, void *buffer)
 {
-  regcache_raw_write (regcache, regnum, (const gdb_byte *) buffer);
+  regcache->raw_write (regnum, (const gdb_byte *) buffer);
 
   return REG_VALID;
 }
 
 static enum register_status
-e500_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
-                          int reg_nr, gdb_byte *buffer)
+e500_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
+                          int ev_reg, gdb_byte *buffer)
 {
-  return e500_move_ev_register (do_regcache_raw_read, regcache, reg_nr, buffer);
+  struct gdbarch *arch = regcache->arch ();
+  struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
+  int reg_index;
+  enum register_status status;
+
+  gdb_assert (IS_SPE_PSEUDOREG (tdep, ev_reg));
+
+  reg_index = ev_reg - tdep->ppc_ev0_regnum;
+
+  if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG)
+    {
+      status = regcache->raw_read (tdep->ppc_ev0_upper_regnum + reg_index,
+                                  buffer);
+      if (status == REG_VALID)
+       status = regcache->raw_read (tdep->ppc_gp0_regnum + reg_index,
+                                    buffer + 4);
+    }
+  else
+    {
+      status = regcache->raw_read (tdep->ppc_gp0_regnum + reg_index, buffer);
+      if (status == REG_VALID)
+       status = regcache->raw_read (tdep->ppc_ev0_upper_regnum + reg_index,
+                                    buffer + 4);
+    }
+
+  return status;
+
 }
 
 static void
@@ -2720,29 +2688,39 @@ e500_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 
 /* Read method for DFP pseudo-registers.  */
 static enum register_status
-dfp_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+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 (regcache, 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 (regcache, 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 (regcache, 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 (regcache, tdep->ppc_fp0_regnum +
-                                   2 * reg_index, buffer + 8);
+       status = regcache->raw_read (fp0 + 2 * reg_index, buffer + 8);
     }
 
   return status;
@@ -2754,56 +2732,107 @@ 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 (regcache, tdep->ppc_fp0_regnum +
-                         2 * reg_index, buffer);
-      regcache_raw_write (regcache, 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 (regcache, tdep->ppc_fp0_regnum +
-                         2 * reg_index + 1, buffer);
-      regcache_raw_write (regcache, 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);
     }
 }
 
+/* Read method for the vX aliases for the raw vrX registers.  */
+
+static enum register_status
+v_alias_pseudo_register_read (struct gdbarch *gdbarch,
+                             readable_regcache *regcache, int reg_nr,
+                             gdb_byte *buffer)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  gdb_assert (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr));
+
+  return regcache->raw_read (tdep->ppc_vr0_regnum
+                            + (reg_nr - tdep->ppc_v0_alias_regnum),
+                            buffer);
+}
+
+/* Write method for the vX aliases for the raw vrX registers.  */
+
+static void
+v_alias_pseudo_register_write (struct gdbarch *gdbarch,
+                              struct regcache *regcache,
+                              int reg_nr, const gdb_byte *buffer)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  gdb_assert (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr));
+
+  regcache->raw_write (tdep->ppc_vr0_regnum
+                      + (reg_nr - tdep->ppc_v0_alias_regnum), buffer);
+}
+
 /* Read method for POWER7 VSX pseudo-registers.  */
 static enum register_status
-vsx_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+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 (regcache, 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 (regcache, tdep->ppc_fp0_regnum +
-                                   reg_index, buffer);
+       status = regcache->raw_read (fp0 + reg_index, buffer);
        if (status == REG_VALID)
-         status = regcache_raw_read (regcache, tdep->ppc_vsr0_upper_regnum +
-                                     reg_index, buffer + 8);
+         status = regcache->raw_read (vsr0_upper + reg_index,
+                                      buffer + 8);
       }
     else
       {
-       status = regcache_raw_read (regcache, 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 (regcache, tdep->ppc_vsr0_upper_regnum +
-                                     reg_index, buffer);
+         status = regcache->raw_read (vsr0_upper + reg_index, buffer);
       }
 
   return status;
@@ -2815,78 +2844,130 @@ 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 (regcache, 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 (regcache, tdep->ppc_fp0_regnum +
-                       reg_index, buffer);
-       regcache_raw_write (regcache, 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 (regcache, tdep->ppc_fp0_regnum +
-                       reg_index, buffer + 8);
-       regcache_raw_write (regcache, 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, struct 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 (regcache, tdep->ppc_vr0_regnum + reg_index,
-                                offset, register_size (gdbarch, reg_nr),
-                                buffer);
+  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 (regcache, tdep->ppc_vr0_regnum + reg_index,
-                          offset, register_size (gdbarch, reg_nr),
-                          buffer);
+  regcache->raw_write_part (vr0 + reg_index, offset,
+                           register_size (gdbarch, reg_nr), buffer);
 }
 
 static enum register_status
 rs6000_pseudo_register_read (struct gdbarch *gdbarch,
-                            struct regcache *regcache,
+                            readable_regcache *regcache,
                             int reg_nr, gdb_byte *buffer)
 {
-  struct gdbarch *regcache_arch = get_regcache_arch (regcache);
+  struct gdbarch *regcache_arch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 
 
   gdb_assert (regcache_arch == 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_V_ALIAS_PSEUDOREG (tdep, reg_nr))
+    return v_alias_pseudo_register_read (gdbarch, regcache, reg_nr,
+                                        buffer);
+  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: "
@@ -2899,19 +2980,24 @@ rs6000_pseudo_register_write (struct gdbarch *gdbarch,
                              struct regcache *regcache,
                              int reg_nr, const gdb_byte *buffer)
 {
-  struct gdbarch *regcache_arch = get_regcache_arch (regcache);
+  struct gdbarch *regcache_arch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 
 
   gdb_assert (regcache_arch == 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_V_ALIAS_PSEUDOREG (tdep, reg_nr))
+    v_alias_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
+  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: "
@@ -2919,6 +3005,111 @@ 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 raw vector register that
+   corresponds to its REG_NR alias.  */
+
+static void
+v_alias_pseudo_register_collect (struct gdbarch *gdbarch,
+                                struct agent_expr *ax, int reg_nr)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  gdb_assert (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr));
+
+  ax_reg_mask (ax, tdep->ppc_vr0_regnum
+              + (reg_nr - tdep->ppc_v0_alias_regnum));
+}
+
+/* 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)
@@ -2930,29 +3121,24 @@ 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_V_ALIAS_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);
-        }
+      v_alias_pseudo_register_collect (gdbarch, ax, reg_nr);
+    }
+  else if (IS_VSX_PSEUDOREG (tdep, reg_nr)
+          || IS_CVSX_PSEUDOREG (tdep, reg_nr))
+    {
+      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__,
@@ -2963,6 +3149,18 @@ rs6000_ax_pseudo_register_collect (struct gdbarch *gdbarch,
 }
 
 
+static void
+rs6000_gen_return_address (struct gdbarch *gdbarch,
+                          struct agent_expr *ax, struct axs_value *value,
+                          CORE_ADDR scope)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  value->type = register_type (gdbarch, tdep->ppc_lr_regnum);
+  value->kind = axs_lvalue_register;
+  value->u.reg = tdep->ppc_lr_regnum;
+}
+
+
 /* Convert a DBX STABS register number to a GDB register number.  */
 static int
 rs6000_stab_reg_to_regnum (struct gdbarch *gdbarch, int num)
@@ -3117,13 +3315,13 @@ rs6000_adjust_frame_regnum (struct gdbarch *gdbarch, int num, int eh_frame_p)
 
 /* Information about a particular processor variant.  */
 
-struct variant
+struct ppc_variant
   {
     /* Name of this variant.  */
-    char *name;
+    const char *name;
 
     /* English description of the variant.  */
-    char *description;
+    const char *description;
 
     /* bfd_arch_info.arch corresponding to variant.  */
     enum bfd_architecture arch;
@@ -3135,7 +3333,7 @@ struct variant
     struct target_desc **tdesc;
   };
 
-static struct variant variants[] =
+static struct ppc_variant variants[] =
 {
   {"powerpc", "PowerPC user-level", bfd_arch_powerpc,
    bfd_mach_ppc, &tdesc_powerpc_altivec32},
@@ -3194,10 +3392,10 @@ static struct variant variants[] =
 /* Return the variant corresponding to architecture ARCH and machine number
    MACH.  If no such variant exists, return null.  */
 
-static const struct variant *
+static const struct ppc_variant *
 find_variant_by_arch (enum bfd_architecture arch, unsigned long mach)
 {
-  const struct variant *v;
+  const struct ppc_variant *v;
 
   for (v = variants; v->name; v++)
     if (arch == v->arch && mach == v->mach)
@@ -3206,29 +3404,7 @@ find_variant_by_arch (enum bfd_architecture arch, unsigned long mach)
   return NULL;
 }
 
-static int
-gdb_print_insn_powerpc (bfd_vma memaddr, disassemble_info *info)
-{
-  if (info->endian == BFD_ENDIAN_BIG)
-    return print_insn_big_powerpc (memaddr, info);
-  else
-    return print_insn_little_powerpc (memaddr, info);
-}
 \f
-static CORE_ADDR
-rs6000_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  return frame_unwind_register_unsigned (next_frame,
-                                        gdbarch_pc_regnum (gdbarch));
-}
-
-static struct frame_id
-rs6000_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
-{
-  return frame_id_build (get_frame_register_unsigned
-                         (this_frame, gdbarch_sp_regnum (gdbarch)),
-                        get_frame_pc (this_frame));
-}
 
 struct rs6000_frame_cache
 {
@@ -3262,7 +3438,7 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
   cache->pc = 0;
   cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
 
-  TRY
+  try
     {
       func = get_frame_func (this_frame);
       cache->pc = func;
@@ -3279,13 +3455,12 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
       cache->base = get_frame_register_unsigned
        (this_frame, gdbarch_sp_regnum (gdbarch));
     }
-  CATCH (ex, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &ex)
     {
       if (ex.error != NOT_AVAILABLE_ERROR)
-       throw_exception (ex);
+       throw;
       return (struct rs6000_frame_cache *) (*this_cache);
     }
-  END_CATCH
 
   /* If the function appears to be frameless, check a couple of likely
      indicators that we have simply failed to find the frame setup.
@@ -3321,10 +3496,10 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
   if (!fdata.frameless)
     {
       /* Frameless really means stackless.  */
-      LONGEST backchain;
+      ULONGEST backchain;
 
-      if (safe_read_memory_integer (cache->base, wordsize,
-                                   byte_order, &backchain))
+      if (safe_read_memory_unsigned_integer (cache->base, wordsize,
+                                            byte_order, &backchain))
         cache->base = (CORE_ADDR) backchain;
     }
 
@@ -3494,7 +3669,7 @@ rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
   (*this_cache) = cache;
   cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
 
-  TRY
+  try
     {
       /* At this point the stack looks as if we just entered the
         function, and the return address is stored in LR.  */
@@ -3509,12 +3684,11 @@ rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
       trad_frame_set_value (cache->saved_regs,
                            gdbarch_pc_regnum (gdbarch), lr);
     }
-  CATCH (ex, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &ex)
     {
       if (ex.error != NOT_AVAILABLE_ERROR)
-       throw_exception (ex);
+       throw;
     }
-  END_CATCH
 
   return cache;
 }
@@ -3675,7 +3849,6 @@ bfd_uses_spe_extensions (bfd *abfd)
   bfd_size_type size;
   gdb_byte *ptr;
   int success = 0;
-  int vector_abi;
 
   if (!abfd)
     return 0;
@@ -3684,8 +3857,8 @@ bfd_uses_spe_extensions (bfd *abfd)
   /* Using Tag_GNU_Power_ABI_Vector here is a bit of a hack, as the user
      could be using the SPE vector abi without actually using any spe
      bits whatsoever.  But it's close enough for now.  */
-  vector_abi = bfd_elf_get_obj_attr_int (abfd, OBJ_ATTR_GNU,
-                                        Tag_GNU_Power_ABI_Vector);
+  int vector_abi = bfd_elf_get_obj_attr_int (abfd, OBJ_ATTR_GNU,
+                                            Tag_GNU_Power_ABI_Vector);
   if (vector_abi == 3)
     return 1;
 #endif
@@ -3694,7 +3867,7 @@ bfd_uses_spe_extensions (bfd *abfd)
   if (!sect)
     return 0;
 
-  size = bfd_get_section_size (sect);
+  size = bfd_section_size (sect);
   contents = (gdb_byte *) xmalloc (size);
   if (!bfd_get_section_contents (abfd, sect, contents, 0, size))
     {
@@ -3803,6 +3976,7 @@ bfd_uses_spe_extensions (bfd *abfd)
 #define PPC_T(insn)    PPC_FIELD (insn, 6, 5)
 #define PPC_D(insn)    PPC_SEXT (PPC_FIELD (insn, 16, 16), 16)
 #define PPC_DS(insn)   PPC_SEXT (PPC_FIELD (insn, 16, 14), 14)
+#define PPC_DQ(insn)   PPC_SEXT (PPC_FIELD (insn, 16, 12), 12)
 #define PPC_BIT(insn,n)        ((insn & (1 << (31 - (n)))) ? 1 : 0)
 #define PPC_OE(insn)   PPC_BIT (insn, 21)
 #define PPC_RC(insn)   PPC_BIT (insn, 31)
@@ -3850,6 +4024,7 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int ext = PPC_FIELD (insn, 21, 11);
+  int vra = PPC_FIELD (insn, 11, 5);
 
   switch (ext & 0x3f)
     {
@@ -3861,6 +4036,7 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
       /* FALL-THROUGH */
     case 42:           /* Vector Select */
     case 43:           /* Vector Permute */
+    case 59:           /* Vector Permute Right-indexed */
     case 44:           /* Vector Shift Left Double by Octet Immediate */
     case 45:           /* Vector Permute and Exclusive-OR */
     case 60:           /* Vector Add Extended Unsigned Quadword Modulo */
@@ -3868,6 +4044,7 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 62:           /* Vector Subtract Extended Unsigned Quadword Modulo */
     case 63:           /* Vector Subtract Extended & write Carry Unsigned Quadword */
     case 34:           /* Vector Multiply-Low-Add Unsigned Halfword Modulo */
+    case 35:           /* Vector Multiply-Sum Unsigned Doubleword Modulo */
     case 36:           /* Vector Multiply-Sum Unsigned Byte Modulo */
     case 37:           /* Vector Multiply-Sum Mixed Byte Modulo */
     case 38:           /* Vector Multiply-Sum Unsigned Halfword Modulo */
@@ -3877,14 +4054,38 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_reg (regcache,
                                     tdep->ppc_vr0_regnum + PPC_VRT (insn));
       return 0;
+
+    case 48:           /* Multiply-Add High Doubleword */
+    case 49:           /* Multiply-Add High Doubleword Unsigned */
+    case 51:           /* Multiply-Add Low Doubleword */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
     }
 
   switch ((ext & 0x1ff))
     {
+    case 385:
+      if (vra != 0     /* Decimal Convert To Signed Quadword */
+         && vra != 2   /* Decimal Convert From Signed Quadword */
+         && vra != 4   /* Decimal Convert To Zoned */
+         && vra != 5   /* Decimal Convert To National */
+         && vra != 6   /* Decimal Convert From Zoned */
+         && vra != 7   /* Decimal Convert From National */
+         && vra != 31) /* Decimal Set Sign */
+       break;
+      /* Fall through.  */
                        /* 5.16 Decimal Integer Arithmetic Instructions */
     case 1:            /* Decimal Add Modulo */
     case 65:           /* Decimal Subtract Modulo */
 
+    case 193:          /* Decimal Shift */
+    case 129:          /* Decimal Unsigned Shift */
+    case 449:          /* Decimal Shift and Round */
+
+    case 257:          /* Decimal Truncate */
+    case 321:          /* Decimal Unsigned Truncate */
+
       /* Bit-21 should be set.  */
       if (!PPC_BIT (insn, 21))
        break;
@@ -3914,6 +4115,12 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 198:          /* Vector Compare Equal To Single-Precision */
     case 454:          /* Vector Compare Greater Than or Equal To Single-Precision */
     case 710:          /* Vector Compare Greater Than Single-Precision */
+    case 7:            /* Vector Compare Not Equal Byte */
+    case 71:           /* Vector Compare Not Equal Halfword */
+    case 135:          /* Vector Compare Not Equal Word */
+    case 263:          /* Vector Compare Not Equal or Zero Byte */
+    case 327:          /* Vector Compare Not Equal or Zero Halfword */
+    case 391:          /* Vector Compare Not Equal or Zero Word */
       if (PPC_Rc (insn))
        record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       record_full_arch_list_add_reg (regcache,
@@ -3921,6 +4128,38 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
       return 0;
     }
 
+  if (ext  == 1538)
+    {
+      switch (vra)
+       {
+       case 0:         /* Vector Count Leading Zero Least-Significant Bits
+                          Byte */
+       case 1:         /* Vector Count Trailing Zero Least-Significant Bits
+                          Byte */
+         record_full_arch_list_add_reg (regcache,
+                                        tdep->ppc_gp0_regnum + PPC_RT (insn));
+         return 0;
+
+       case 6:         /* Vector Negate Word */
+       case 7:         /* Vector Negate Doubleword */
+       case 8:         /* Vector Parity Byte Word */
+       case 9:         /* Vector Parity Byte Doubleword */
+       case 10:        /* Vector Parity Byte Quadword */
+       case 16:        /* Vector Extend Sign Byte To Word */
+       case 17:        /* Vector Extend Sign Halfword To Word */
+       case 24:        /* Vector Extend Sign Byte To Doubleword */
+       case 25:        /* Vector Extend Sign Halfword To Doubleword */
+       case 26:        /* Vector Extend Sign Word To Doubleword */
+       case 28:        /* Vector Count Trailing Zeros Byte */
+       case 29:        /* Vector Count Trailing Zeros Halfword */
+       case 30:        /* Vector Count Trailing Zeros Word */
+       case 31:        /* Vector Count Trailing Zeros Doubleword */
+         record_full_arch_list_add_reg (regcache,
+                                        tdep->ppc_vr0_regnum + PPC_VRT (insn));
+         return 0;
+       }
+    }
+
   switch (ext)
     {
     case 142:          /* Vector Pack Unsigned Halfword Unsigned Saturate */
@@ -4092,10 +4331,44 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 1923:         /* Vector Population Count Word */
     case 1987:         /* Vector Population Count Doubleword */
     case 1356:         /* Vector Bit Permute Quadword */
+    case 1484:         /* Vector Bit Permute Doubleword */
+    case 513:          /* Vector Multiply-by-10 Unsigned Quadword */
+    case 1:            /* Vector Multiply-by-10 & write Carry Unsigned
+                          Quadword */
+    case 577:          /* Vector Multiply-by-10 Extended Unsigned Quadword */
+    case 65:           /* Vector Multiply-by-10 Extended & write Carry
+                          Unsigned Quadword */
+    case 1027:         /* Vector Absolute Difference Unsigned Byte */
+    case 1091:         /* Vector Absolute Difference Unsigned Halfword */
+    case 1155:         /* Vector Absolute Difference Unsigned Word */
+    case 1796:         /* Vector Shift Right Variable */
+    case 1860:         /* Vector Shift Left Variable */
+    case 133:          /* Vector Rotate Left Word then Mask Insert */
+    case 197:          /* Vector Rotate Left Doubleword then Mask Insert */
+    case 389:          /* Vector Rotate Left Word then AND with Mask */
+    case 453:          /* Vector Rotate Left Doubleword then AND with Mask */
+    case 525:          /* Vector Extract Unsigned Byte */
+    case 589:          /* Vector Extract Unsigned Halfword */
+    case 653:          /* Vector Extract Unsigned Word */
+    case 717:          /* Vector Extract Doubleword */
+    case 781:          /* Vector Insert Byte */
+    case 845:          /* Vector Insert Halfword */
+    case 909:          /* Vector Insert Word */
+    case 973:          /* Vector Insert Doubleword */
       record_full_arch_list_add_reg (regcache,
                                     tdep->ppc_vr0_regnum + PPC_VRT (insn));
       return 0;
 
+    case 1549:         /* Vector Extract Unsigned Byte Left-Indexed */
+    case 1613:         /* Vector Extract Unsigned Halfword Left-Indexed */
+    case 1677:         /* Vector Extract Unsigned Word Left-Indexed */
+    case 1805:         /* Vector Extract Unsigned Byte Right-Indexed */
+    case 1869:         /* Vector Extract Unsigned Halfword Right-Indexed */
+    case 1933:         /* Vector Extract Unsigned Word Right-Indexed */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
+
     case 1604:         /* Move To Vector Status and Control Register */
       record_full_arch_list_add_reg (regcache, PPC_VSCR_REGNUM);
       return 0;
@@ -4103,6 +4376,11 @@ ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_reg (regcache,
                                     tdep->ppc_vr0_regnum + PPC_VRT (insn));
       return 0;
+    case 833:          /* Decimal Copy Sign */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_vr0_regnum + PPC_VRT (insn));
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
     }
 
   fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
@@ -4120,6 +4398,14 @@ ppc_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache,
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int ext = PPC_EXTOP (insn);
 
+  switch (ext & 0x01f)
+    {
+    case 2:            /* Add PC Immediate Shifted */
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
+    }
+
   switch (ext)
     {
     case 0:            /* Move Condition Register Field */
@@ -4225,6 +4511,15 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       return 0;
     }
 
+  if ((ext & 0xff) == 170)
+    {
+      /* Add Extended using alternate carry bits */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
+      record_full_arch_list_add_reg (regcache,
+                                    tdep->ppc_gp0_regnum + PPC_RT (insn));
+      return 0;
+    }
+
   switch (ext)
     {
     case 78:           /* Determine Leftmost Zero Byte */
@@ -4243,6 +4538,9 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 302:          /* Move From Branch History Rolling Buffer */
     case 339:          /* Move From Special Purpose Register */
     case 371:          /* Move From Time Base [Phased-Out]  */
+    case 309:          /* Load Doubleword Monitored Indexed  */
+    case 128:          /* Set Boolean */
+    case 755:          /* Deliver A Random Number */
       record_full_arch_list_add_reg (regcache,
                                     tdep->ppc_gp0_regnum + PPC_RT (insn));
       return 0;
@@ -4259,6 +4557,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 282:          /* Convert Declets To Binary Coded Decimal */
     case 314:          /* Convert Binary Coded Decimal To Declets */
     case 508:          /* Compare bytes */
+    case 307:          /* Move From VSR Lower Doubleword */
       record_full_arch_list_add_reg (regcache,
                                     tdep->ppc_gp0_regnum + PPC_RA (insn));
       return 0;
@@ -4277,6 +4576,12 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 32:           /* Compare logical */
     case 144:          /* Move To Condition Register Fields */
                        /* Move To One Condition Register Field */
+    case 192:          /* Compare Ranged Byte */
+    case 224:          /* Compare Equal Byte */
+    case 576:          /* Move XER to CR Extended */
+    case 902:          /* Paste (should always fail due to single-stepping and
+                          the memory location might not be accessible, so
+                          record only CR) */
       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       return 0;
 
@@ -4303,6 +4608,12 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 790:          /* Load Halfword Byte-Reverse Indexed */
     case 534:          /* Load Word Byte-Reverse Indexed */
     case 532:          /* Load Doubleword Byte-Reverse Indexed */
+    case 582:          /* Load Word Atomic */
+    case 614:          /* Load Doubleword Atomic */
+    case 265:          /* Modulo Unsigned Doubleword */
+    case 777:          /* Modulo Signed Doubleword */
+    case 267:          /* Modulo Unsigned Word */
+    case 779:          /* Modulo Signed Word */
       record_full_arch_list_add_reg (regcache,
                                     tdep->ppc_gp0_regnum + PPC_RT (insn));
       return 0;
@@ -4381,6 +4692,16 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 844:          /* Load VSX Vector Doubleword*2 Indexed */
     case 332:          /* Load VSX Vector Doubleword & Splat Indexed */
     case 780:          /* Load VSX Vector Word*4 Indexed */
+    case 268:          /* Load VSX Vector Indexed */
+    case 364:          /* Load VSX Vector Word & Splat Indexed */
+    case 812:          /* Load VSX Vector Halfword*8 Indexed */
+    case 876:          /* Load VSX Vector Byte*16 Indexed */
+    case 269:          /* Load VSX Vector with Length */
+    case 301:          /* Load VSX Vector Left-justified with Length */
+    case 781:          /* Load VSX Scalar as Integer Byte & Zero Indexed */
+    case 813:          /* Load VSX Scalar as Integer Halfword & Zero Indexed */
+    case 403:          /* Move To VSR Word & Splat */
+    case 435:          /* Move To VSR Double Doubleword */
       ppc_record_vsr (regcache, tdep, PPC_XT (insn));
       return 0;
 
@@ -4402,6 +4723,21 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 922:          /* Extend Sign Halfword */
     case 954:          /* Extend Sign Byte */
     case 986:          /* Extend Sign Word */
+    case 538:          /* Count Trailing Zeros Word */
+    case 570:          /* Count Trailing Zeros Doubleword */
+    case 890:          /* Extend-Sign Word and Shift Left Immediate (445) */
+    case 890 | 1:      /* Extend-Sign Word and Shift Left Immediate (445) */
+
+      if (ext == 444 && tdep->ppc_ppr_regnum >= 0
+         && (PPC_RS (insn) == PPC_RA (insn))
+         && (PPC_RA (insn) == PPC_RB (insn))
+         && !PPC_RC (insn))
+       {
+         /* or Rx,Rx,Rx alters PRI in PPR.  */
+         record_full_arch_list_add_reg (regcache, tdep->ppc_ppr_regnum);
+         return 0;
+       }
+
       if (PPC_RC (insn))
        record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       record_full_arch_list_add_reg (regcache,
@@ -4444,6 +4780,11 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 727:          /* Store Floating-Point Double Indexed */
     case 919:          /* Store Floating-Point Double Pair Indexed */
     case 983:          /* Store Floating-Point as Integer Word Indexed */
+    case 396:          /* Store VSX Vector Indexed */
+    case 940:          /* Store VSX Vector Halfword*8 Indexed */
+    case 1004:         /* Store VSX Vector Byte*16 Indexed */
+    case 909:          /* Store VSX Scalar as Integer Byte Indexed */
+    case 941:          /* Store VSX Scalar as Integer Halfword Indexed */
       if (ext == 694 || ext == 726 || ext == 150 || ext == 214 || ext == 182)
        record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
 
@@ -4473,6 +4814,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
        case 135:       /* Store Vector Element Byte Indexed */
        case 215:       /* Store Byte Indexed */
        case 694:       /* Store Byte Conditional Indexed */
+       case 909:       /* Store VSX Scalar as Integer Byte Indexed */
          size = 1;
          break;
        case 439:       /* Store Halfword with Update Indexed */
@@ -4480,6 +4822,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
        case 407:       /* Store Halfword Indexed */
        case 726:       /* Store Halfword Conditional Indexed */
        case 918:       /* Store Halfword Byte-Reverse Indexed */
+       case 941:       /* Store VSX Scalar as Integer Halfword Indexed */
          size = 2;
          break;
        case 181:       /* Store Doubleword with Update Indexed */
@@ -4497,6 +4840,9 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
        case 231:       /* Store Vector Indexed */
        case 487:       /* Store Vector Indexed LRU */
        case 919:       /* Store Floating-Point Double Pair Indexed */
+       case 396:       /* Store VSX Vector Indexed */
+       case 940:       /* Store VSX Vector Halfword*8 Indexed */
+       case 1004:      /* Store VSX Vector Byte*16 Indexed */
          size = 16;
          break;
        default:
@@ -4523,10 +4869,47 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_mem (addr, size);
       return 0;
 
+    case 397:          /* Store VSX Vector with Length */
+    case 429:          /* Store VSX Vector Left-justified with Length */
+      ra = 0;
+      if (PPC_RA (insn) != 0)
+       regcache_raw_read_unsigned (regcache,
+                                   tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
+      ea = ra;
+      regcache_raw_read_unsigned (regcache,
+                                 tdep->ppc_gp0_regnum + PPC_RB (insn), &rb);
+      /* Store up to 16 bytes.  */
+      nb = (rb & 0xff) > 16 ? 16 : (rb & 0xff);
+      if (nb > 0)
+       record_full_arch_list_add_mem (ea, nb);
+      return 0;
+
+    case 710:          /* Store Word Atomic */
+    case 742:          /* Store Doubleword Atomic */
+      ra = 0;
+      if (PPC_RA (insn) != 0)
+       regcache_raw_read_unsigned (regcache,
+                                   tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
+      ea = ra;
+      switch (ext)
+       {
+       case 710:       /* Store Word Atomic */
+         size = 8;
+         break;
+       case 742:       /* Store Doubleword Atomic */
+         size = 16;
+         break;
+       default:
+         gdb_assert (0);
+       }
+      record_full_arch_list_add_mem (ea, size);
+      return 0;
+
     case 725:          /* Store String Word Immediate */
       ra = 0;
       if (PPC_RA (insn) != 0)
-       regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &ra);
+       regcache_raw_read_unsigned (regcache,
+                                   tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
       ea += ra;
 
       nb = PPC_NB (insn);
@@ -4540,7 +4923,8 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 661:          /* Store String Word Indexed */
       ra = 0;
       if (PPC_RA (insn) != 0)
-       regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &ra);
+       regcache_raw_read_unsigned (regcache,
+                                   tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
       ea += ra;
 
       regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &xer);
@@ -4548,7 +4932,9 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
 
       if (nb != 0)
        {
-         regcache_raw_read_unsigned (regcache, tdep->ppc_xer_regnum, &rb);
+         regcache_raw_read_unsigned (regcache,
+                                     tdep->ppc_gp0_regnum + PPC_RB (insn),
+                                     &rb);
          ea += rb;
          record_full_arch_list_add_mem (ea, nb);
        }
@@ -4561,6 +4947,10 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
        case 1:                 /* XER */
          record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
          return 0;
+       case 3:                 /* DSCR */
+         if (tdep->ppc_dscr_regnum >= 0)
+           record_full_arch_list_add_reg (regcache, tdep->ppc_dscr_regnum);
+         return 0;
        case 8:                 /* LR */
          record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum);
          return 0;
@@ -4570,6 +4960,15 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
        case 256:               /* VRSAVE */
          record_full_arch_list_add_reg (regcache, tdep->ppc_vrsave_regnum);
          return 0;
+       case 815:               /* TAR */
+         if (tdep->ppc_tar_regnum >= 0)
+           record_full_arch_list_add_reg (regcache, tdep->ppc_tar_regnum);
+         return 0;
+       case 896:
+       case 898:               /* PPR */
+         if (tdep->ppc_ppr_regnum >= 0)
+           record_full_arch_list_add_reg (regcache, tdep->ppc_ppr_regnum);
+         return 0;
        }
 
       goto UNKNOWN_OP;
@@ -4588,6 +4987,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 430:          /* Clear BHRB */
     case 598:          /* Synchronize */
     case 62:           /* Wait for Interrupt */
+    case 30:           /* Wait */
     case 22:           /* Instruction Cache Block Touch */
     case 854:          /* Enforce In-order Execution of I/O */
     case 246:          /* Data Cache Block Touch for Store */
@@ -4596,27 +4996,30 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 278:          /* Data Cache Block Touch */
     case 758:          /* Data Cache Block Allocate */
     case 982:          /* Instruction Cache Block Invalidate */
+    case 774:          /* Copy */
+    case 838:          /* CP_Abort */
       return 0;
 
     case 654:          /* Transaction Begin */
     case 686:          /* Transaction End */
-    case 718:          /* Transaction Check */
     case 750:          /* Transaction Suspend or Resume */
     case 782:          /* Transaction Abort Word Conditional */
     case 814:          /* Transaction Abort Doubleword Conditional */
     case 846:          /* Transaction Abort Word Conditional Immediate */
     case 878:          /* Transaction Abort Doubleword Conditional Immediate */
     case 910:          /* Transaction Abort */
-      fprintf_unfiltered (gdb_stdlog, "Cannot record Transaction instructions. "
-                         "%08x at %s, 31-%d.\n",
-                         insn, paddress (gdbarch, addr), ext);
-      return -1;
+      record_full_arch_list_add_reg (regcache, tdep->ppc_ps_regnum);
+      /* FALL-THROUGH */
+    case 718:          /* Transaction Check */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
 
     case 1014:         /* Data Cache Block set to Zero */
-      if (target_auxv_search (&current_target, AT_DCACHEBSIZE, &at_dcsz) <= 0
+      if (target_auxv_search (current_top_target (), AT_DCACHEBSIZE, &at_dcsz) <= 0
          || at_dcsz == 0)
        at_dcsz = 128; /* Assume 128-byte cache line size (POWER8)  */
 
+      ra = 0;
       if (PPC_RA (insn) != 0)
        regcache_raw_read_unsigned (regcache,
                                    tdep->ppc_gp0_regnum + PPC_RA (insn), &ra);
@@ -4694,6 +5097,7 @@ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 226:          /* DFP Test Data Group */
     case 642:          /* DFP Compare Unordered */
     case 674:          /* DFP Test Significance */
+    case 675:          /* DFP Test Significance Immediate */
       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
       return 0;
@@ -4793,7 +5197,16 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 217:          /* ditto */
     case 104:          /* VSX Vector Subtract Double-Precision */
     case 72:           /* VSX Vector Subtract Single-Precision */
+    case 128:          /* VSX Scalar Maximum Type-C Double-Precision */
+    case 136:          /* VSX Scalar Minimum Type-C Double-Precision */
+    case 144:          /* VSX Scalar Maximum Type-J Double-Precision */
+    case 152:          /* VSX Scalar Minimum Type-J Double-Precision */
+    case 3:            /* VSX Scalar Compare Equal Double-Precision */
+    case 11:           /* VSX Scalar Compare Greater Than Double-Precision */
+    case 19:           /* VSX Scalar Compare Greater Than or Equal
+                          Double-Precision */
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      /* FALL-THROUGH */
     case 240:          /* VSX Vector Copy Sign Double-Precision */
     case 208:          /* VSX Vector Copy Sign Single-Precision */
     case 130:          /* VSX Logical AND */
@@ -4814,6 +5227,14 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 2 | 0x20:     /* VSX Shift Left Double by Word Immediate (SHW=1) */
     case 2 | 0x40:     /* VSX Shift Left Double by Word Immediate (SHW=2) */
     case 2 | 0x60:     /* VSX Shift Left Double by Word Immediate (SHW=3) */
+    case 216:          /* VSX Vector Insert Exponent Single-Precision */
+    case 248:          /* VSX Vector Insert Exponent Double-Precision */
+    case 26:           /* VSX Vector Permute */
+    case 58:           /* VSX Vector Permute Right-indexed */
+    case 213:          /* VSX Vector Test Data Class Single-Precision (DC=0) */
+    case 213 | 0x8:    /* VSX Vector Test Data Class Single-Precision (DC=1) */
+    case 245:          /* VSX Vector Test Data Class Double-Precision (DC=0) */
+    case 245 | 0x8:    /* VSX Vector Test Data Class Double-Precision (DC=1) */
       ppc_record_vsr (regcache, tdep, PPC_XT (insn));
       return 0;
 
@@ -4825,6 +5246,7 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
 
     case 35:           /* VSX Scalar Compare Unordered Double-Precision */
     case 43:           /* VSX Scalar Compare Ordered Double-Precision */
+    case 59:           /* VSX Scalar Compare Exponents Double-Precision */
       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
       return 0;
@@ -4971,6 +5393,7 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 203:          /* VSX Vector Square Root Double-Precision */
     case 139:          /* VSX Vector Square Root Single-Precision */
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      /* FALL-THROUGH */
     case 345:          /* VSX Scalar Absolute Value Double-Precision */
     case 267:          /* VSX Scalar Convert Scalar Single-Precision to
                           Vector Single-Precision format Non-signalling */
@@ -4985,9 +5408,15 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 505:          /* VSX Vector Negate Double-Precision */
     case 441:          /* VSX Vector Negate Single-Precision */
     case 164:          /* VSX Splat Word */
+    case 165:          /* VSX Vector Extract Unsigned Word */
+    case 181:          /* VSX Vector Insert Word */
       ppc_record_vsr (regcache, tdep, PPC_XT (insn));
       return 0;
 
+    case 298:          /* VSX Scalar Test Data Class Single-Precision */
+    case 362:          /* VSX Scalar Test Data Class Double-Precision */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      /* FALL-THROUGH */
     case 106:          /* VSX Scalar Test for software Square Root
                           Double-Precision */
     case 234:          /* VSX Vector Test for software Square Root
@@ -4996,6 +5425,60 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
                           Single-Precision */
       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       return 0;
+
+    case 347:
+      switch (PPC_FIELD (insn, 11, 5))
+       {
+       case 0:         /* VSX Scalar Extract Exponent Double-Precision */
+       case 1:         /* VSX Scalar Extract Significand Double-Precision */
+          record_full_arch_list_add_reg (regcache,
+                                        tdep->ppc_gp0_regnum + PPC_RT (insn));
+         return 0;
+       case 16:        /* VSX Scalar Convert Half-Precision format to
+                          Double-Precision format */
+       case 17:        /* VSX Scalar round & Convert Double-Precision format
+                          to Half-Precision format */
+         record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+         ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+         return 0;
+       }
+      break;
+
+    case 475:
+      switch (PPC_FIELD (insn, 11, 5))
+       {
+       case 24:        /* VSX Vector Convert Half-Precision format to
+                          Single-Precision format */
+       case 25:        /* VSX Vector round and Convert Single-Precision format
+                          to Half-Precision format */
+         record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+         /* FALL-THROUGH */
+       case 0:         /* VSX Vector Extract Exponent Double-Precision */
+       case 1:         /* VSX Vector Extract Significand Double-Precision */
+       case 7:         /* VSX Vector Byte-Reverse Halfword */
+       case 8:         /* VSX Vector Extract Exponent Single-Precision */
+       case 9:         /* VSX Vector Extract Significand Single-Precision */
+       case 15:        /* VSX Vector Byte-Reverse Word */
+       case 23:        /* VSX Vector Byte-Reverse Doubleword */
+       case 31:        /* VSX Vector Byte-Reverse Quadword */
+         ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+         return 0;
+       }
+      break;
+    }
+
+  switch (ext)
+    {
+    case 360:          /* VSX Vector Splat Immediate Byte */
+      if (PPC_FIELD (insn, 11, 2) == 0)
+       {
+         ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+         return 0;
+       }
+      break;
+    case 918:          /* VSX Scalar Insert Exponent Double-Precision */
+      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+      return 0;
     }
 
   if (((ext >> 3) & 0x3) == 3) /* VSX Select */
@@ -5009,6 +5492,65 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
   return -1;
 }
 
+/* Parse and record instructions of primary opcode-61 at ADDR.
+   Return 0 if successful.  */
+
+static int
+ppc_process_record_op61 (struct gdbarch *gdbarch, struct regcache *regcache,
+                          CORE_ADDR addr, uint32_t insn)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ULONGEST ea = 0;
+  int size;
+
+  switch (insn & 0x3)
+    {
+    case 0:            /* Store Floating-Point Double Pair */
+    case 2:            /* Store VSX Scalar Doubleword */
+    case 3:            /* Store VSX Scalar Single */
+      if (PPC_RA (insn) != 0)
+       regcache_raw_read_unsigned (regcache,
+                                   tdep->ppc_gp0_regnum + PPC_RA (insn),
+                                   &ea);
+      ea += PPC_DS (insn) << 2;
+      switch (insn & 0x3)
+       {
+       case 0:         /* Store Floating-Point Double Pair */
+         size = 16;
+         break;
+       case 2:         /* Store VSX Scalar Doubleword */
+         size = 8;
+         break;
+       case 3:         /* Store VSX Scalar Single */
+         size = 4;
+         break;
+       default:
+         gdb_assert (0);
+       }
+      record_full_arch_list_add_mem (ea, size);
+      return 0;
+    }
+
+  switch (insn & 0x7)
+    {
+    case 1:            /* Load VSX Vector */
+      ppc_record_vsr (regcache, tdep, PPC_XT (insn));
+      return 0;
+    case 5:            /* Store VSX Vector */
+      if (PPC_RA (insn) != 0)
+       regcache_raw_read_unsigned (regcache,
+                                   tdep->ppc_gp0_regnum + PPC_RA (insn),
+                                   &ea);
+      ea += PPC_DQ (insn) << 4;
+      record_full_arch_list_add_mem (ea, 16);
+      return 0;
+    }
+
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
+                     "at %s.\n", insn, paddress (gdbarch, addr));
+  return -1;
+}
+
 /* Parse and record instructions of primary opcode-63 at ADDR.
    Return 0 if successful.  */
 
@@ -5045,6 +5587,17 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
                                     tdep->ppc_fp0_regnum + PPC_FRT (insn));
       if (PPC_RC (insn))
        record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+      return 0;
+    }
+
+  switch (ext & 0xff)
+    {
+    case 5:            /* VSX Scalar Round to Quad-Precision Integer */
+    case 37:           /* VSX Scalar Round Quad-Precision to Double-Extended
+                          Precision */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+      return 0;
     }
 
   switch (ext)
@@ -5076,6 +5629,7 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
     case 226:          /* DFP Test Data Group Quad */
     case 642:          /* DFP Compare Unordered Quad */
     case 674:          /* DFP Test Significance Quad */
+    case 675:          /* DFP Test Significance Immediate Quad */
       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
       return 0;
@@ -5097,7 +5651,7 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
       if (PPC_RC (insn))
        record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
-      break;
+      return 0;
 
     case 354:          /* DFP Extract Biased Exponent Quad */
       record_full_arch_list_add_reg (regcache,
@@ -5132,7 +5686,27 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
       return 0;
 
-    case 583:          /* Move From FPSCR */
+    case 583:
+      switch (PPC_FIELD (insn, 11, 5))
+        {
+         case 1:       /* Move From FPSCR & Clear Enables */
+         case 20:      /* Move From FPSCR Control & set DRN */
+         case 21:      /* Move From FPSCR Control & set DRN Immediate */
+         case 22:      /* Move From FPSCR Control & set RN */
+         case 23:      /* Move From FPSCR Control & set RN Immediate */
+           record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+           /* Fall through.  */
+         case 0:       /* Move From FPSCR */
+         case 24:      /* Move From FPSCR Lightweight */
+           if (PPC_FIELD (insn, 11, 5) == 0 && PPC_RC (insn))
+             record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
+           record_full_arch_list_add_reg (regcache,
+                                          tdep->ppc_fp0_regnum
+                                          + PPC_FRT (insn));
+           return 0;
+        }
+      break;
+
     case 8:            /* Floating Copy Sign */
     case 40:           /* Floating Negate */
     case 72:           /* Floating Move Register */
@@ -5157,11 +5731,15 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
       if (PPC_RC (insn))
        record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
-      break;
+      return 0;
 
     case 0:            /* Floating Compare Unordered */
     case 32:           /* Floating Compare Ordered */
     case 64:           /* Move to Condition Register from FPSCR */
+    case 132:          /* VSX Scalar Compare Ordered Quad-Precision */
+    case 164:          /* VSX Scalar Compare Exponents Quad-Precision */
+    case 644:          /* VSX Scalar Compare Unordered Quad-Precision */
+    case 708:          /* VSX Scalar Test Data Class Quad-Precision */
       record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
       /* FALL-THROUGH */
     case 128:          /* Floating Test for software Divide */
@@ -5169,10 +5747,65 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
       record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       return 0;
 
+    case 4:            /* VSX Scalar Add Quad-Precision */
+    case 36:           /* VSX Scalar Multiply Quad-Precision */
+    case 388:          /* VSX Scalar Multiply-Add Quad-Precision */
+    case 420:          /* VSX Scalar Multiply-Subtract Quad-Precision */
+    case 452:          /* VSX Scalar Negative Multiply-Add Quad-Precision */
+    case 484:          /* VSX Scalar Negative Multiply-Subtract
+                          Quad-Precision */
+    case 516:          /* VSX Scalar Subtract Quad-Precision */
+    case 548:          /* VSX Scalar Divide Quad-Precision */
+      record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+      /* FALL-THROUGH */
+    case 100:          /* VSX Scalar Copy Sign Quad-Precision */
+    case 868:          /* VSX Scalar Insert Exponent Quad-Precision */
+      ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+      return 0;
+
+    case 804:
+      switch (PPC_FIELD (insn, 11, 5))
+       {
+       case 27:        /* VSX Scalar Square Root Quad-Precision */
+         record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+         /* FALL-THROUGH */
+       case 0:         /* VSX Scalar Absolute Quad-Precision */
+       case 2:         /* VSX Scalar Extract Exponent Quad-Precision */
+       case 8:         /* VSX Scalar Negative Absolute Quad-Precision */
+       case 16:        /* VSX Scalar Negate Quad-Precision */
+       case 18:        /* VSX Scalar Extract Significand Quad-Precision */
+         ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+         return 0;
+       }
+      break;
+
+    case 836:
+      switch (PPC_FIELD (insn, 11, 5))
+       {
+       case 1:         /* VSX Scalar truncate & Convert Quad-Precision format
+                          to Unsigned Word format */
+       case 2:         /* VSX Scalar Convert Unsigned Doubleword format to
+                          Quad-Precision format */
+       case 9:         /* VSX Scalar truncate & Convert Quad-Precision format
+                          to Signed Word format */
+       case 10:        /* VSX Scalar Convert Signed Doubleword format to
+                          Quad-Precision format */
+       case 17:        /* VSX Scalar truncate & Convert Quad-Precision format
+                          to Unsigned Doubleword format */
+       case 20:        /* VSX Scalar round & Convert Quad-Precision format to
+                          Double-Precision format */
+       case 22:        /* VSX Scalar Convert Double-Precision format to
+                          Quad-Precision format */
+       case 25:        /* VSX Scalar truncate & Convert Quad-Precision format
+                          to Signed Doubleword format */
+         record_full_arch_list_add_reg (regcache, tdep->ppc_fpscr_regnum);
+         ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+         return 0;
+       }
     }
 
   fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
-                     "at %s, 59-%d.\n", insn, paddress (gdbarch, addr), ext);
+                     "at %s, 63-%d.\n", insn, paddress (gdbarch, addr), ext);
   return -1;
 }
 
@@ -5333,15 +5966,15 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 
     case 47:           /* Store Multiple Word */
        {
-         ULONGEST addr = 0;
+         ULONGEST iaddr = 0;
 
          if (PPC_RA (insn) != 0)
            regcache_raw_read_unsigned (regcache,
                                        tdep->ppc_gp0_regnum + PPC_RA (insn),
-                                       &addr);
+                                       &iaddr);
 
-         addr += PPC_D (insn);
-         record_full_arch_list_add_mem (addr, 4 * (32 - PPC_RS (insn)));
+         iaddr += PPC_D (insn);
+         record_full_arch_list_add_mem (iaddr, 4 * (32 - PPC_RS (insn)));
        }
       break;
 
@@ -5359,14 +5992,14 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
     case 52:           /* Store Floating-Point Single */
     case 54:           /* Store Floating-Point Double */
        {
-         ULONGEST addr = 0;
+         ULONGEST iaddr = 0;
          int size = -1;
 
          if (PPC_RA (insn) != 0)
            regcache_raw_read_unsigned (regcache,
                                        tdep->ppc_gp0_regnum + PPC_RA (insn),
-                                       &addr);
-         addr += PPC_D (insn);
+                                       &iaddr);
+         iaddr += PPC_D (insn);
 
          if (op6 == 36 || op6 == 37 || op6 == 52 || op6 == 53)
            size = 4;
@@ -5379,16 +6012,25 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
          else
            gdb_assert (0);
 
-         record_full_arch_list_add_mem (addr, size);
+         record_full_arch_list_add_mem (iaddr, size);
        }
       break;
 
-    case 57:           /* Load Floating-Point Double Pair */
-      if (PPC_FIELD (insn, 30, 2) != 0)
-       goto UNKNOWN_OP;
-      tmp = tdep->ppc_fp0_regnum + (PPC_RT (insn) & ~1);
-      record_full_arch_list_add_reg (regcache, tmp);
-      record_full_arch_list_add_reg (regcache, tmp + 1);
+    case 57:
+      switch (insn & 0x3)
+        {
+       case 0:         /* Load Floating-Point Double Pair */
+         tmp = tdep->ppc_fp0_regnum + (PPC_RT (insn) & ~1);
+         record_full_arch_list_add_reg (regcache, tmp);
+         record_full_arch_list_add_reg (regcache, tmp + 1);
+         break;
+       case 2:         /* Load VSX Scalar Doubleword */
+       case 3:         /* Load VSX Scalar Single */
+         ppc_record_vsr (regcache, tdep, PPC_VRT (insn) + 32);
+         break;
+       default:
+         goto UNKNOWN_OP;
+       }
       break;
 
     case 58:           /* Load Doubleword */
@@ -5414,27 +6056,31 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
        return -1;
       break;
 
-    case 61:           /* Store Floating-Point Double Pair */
+    case 61:
+      if (ppc_process_record_op61 (gdbarch, regcache, addr, insn) != 0)
+       return -1;
+      break;
+
     case 62:           /* Store Doubleword */
                        /* Store Doubleword with Update */
                        /* Store Quadword with Update */
        {
-         ULONGEST addr = 0;
+         ULONGEST iaddr = 0;
          int size;
          int sub2 = PPC_FIELD (insn, 30, 2);
 
-         if ((op6 == 61 && sub2 != 0) || (op6 == 62 && sub2 > 2))
+         if (sub2 > 2)
            goto UNKNOWN_OP;
 
          if (PPC_RA (insn) != 0)
            regcache_raw_read_unsigned (regcache,
                                        tdep->ppc_gp0_regnum + PPC_RA (insn),
-                                       &addr);
+                                       &iaddr);
 
-         size = ((op6 == 61) || sub2 == 2) ? 16 : 8;
+         size = (sub2 == 2) ? 16 : 8;
 
-         addr += PPC_DS (insn) << 2;
-         record_full_arch_list_add_mem (addr, size);
+         iaddr += PPC_DS (insn) << 2;
+         record_full_arch_list_add_mem (iaddr, size);
 
          if (op6 == 62 && sub2 == 1)
            record_full_arch_list_add_reg (regcache,
@@ -5481,26 +6127,21 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   bfd abfd;
   enum auto_boolean soft_float_flag = powerpc_soft_float_global;
   int soft_float;
+  enum powerpc_long_double_abi long_double_abi = POWERPC_LONG_DOUBLE_AUTO;
   enum powerpc_vector_abi vector_abi = powerpc_vector_abi_global;
   enum powerpc_elf_abi elf_abi = POWERPC_ELF_AUTO;
-  int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0, have_dfp = 0,
-      have_vsx = 0;
+  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, 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;
   int num_pseudoregs = 0;
   int cur_reg;
 
-  /* INFO may refer to a binary that is not of the PowerPC architecture,
-     e.g. when debugging a stand-alone SPE executable on a Cell/B.E. system.
-     In this case, we must not attempt to infer properties of the (PowerPC
-     side) of the target system from properties of that executable.  Trust
-     the target description instead.  */
-  if (info.abfd
-      && bfd_get_arch (info.abfd) != bfd_arch_powerpc
-      && bfd_get_arch (info.abfd) != bfd_arch_rs6000)
-    info.abfd = NULL;
-
   from_xcoff_exec = info.abfd && info.abfd->format == bfd_object &&
     bfd_get_flavour (info.abfd) == bfd_target_xcoff_flavour;
 
@@ -5558,7 +6199,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      layout, if we do not already have one.  */
   if (! tdesc_has_registers (tdesc))
     {
-      const struct variant *v;
+      const struct ppc_variant *v;
 
       /* Choose variant.  */
       v = find_variant_by_arch (arch, mach);
@@ -5620,7 +6261,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       have_mq = tdesc_numbered_register (feature, tdesc_data, PPC_MQ_REGNUM,
                                         "mq");
 
-      tdesc_wordsize = tdesc_register_size (feature, "pc") / 8;
+      tdesc_wordsize = tdesc_register_bitsize (feature, "pc") / 8;
       if (wordsize == -1)
        wordsize = tdesc_wordsize;
 
@@ -5647,14 +6288,16 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
              return NULL;
            }
          have_fpu = 1;
+
+         /* The fpscr register was expanded in isa 2.05 to 64 bits
+            along with the addition of the decimal floating point
+            facility.  */
+         if (tdesc_register_bitsize (feature, "fpscr") > 32)
+           have_dfp = 1;
        }
       else
        have_fpu = 0;
 
-      /* The DFP pseudo-registers will be available when there are floating
-         point registers.  */
-      have_dfp = have_fpu;
-
       feature = tdesc_find_feature (tdesc,
                                    "org.gnu.gdb.power.altivec");
       if (feature != NULL)
@@ -5707,7 +6350,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
            valid_p &= tdesc_numbered_register (feature, tdesc_data,
                                                PPC_VSR0_UPPER_REGNUM + i,
                                                vsx_regs[i]);
-         if (!valid_p)
+
+         if (!valid_p || !have_fpu || !have_altivec)
            {
              tdesc_data_cleanup (tdesc_data);
              return NULL;
@@ -5765,6 +6409,316 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        }
       else
        have_spe = 0;
+
+      /* Program Priority Register.  */
+      feature = tdesc_find_feature (tdesc,
+                                   "org.gnu.gdb.power.ppr");
+      if (feature != NULL)
+       {
+         valid_p = 1;
+         valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                             PPC_PPR_REGNUM, "ppr");
+
+         if (!valid_p)
+           {
+             tdesc_data_cleanup (tdesc_data);
+             return NULL;
+           }
+         have_ppr = 1;
+       }
+      else
+       have_ppr = 0;
+
+      /* Data Stream Control Register.  */
+      feature = tdesc_find_feature (tdesc,
+                                   "org.gnu.gdb.power.dscr");
+      if (feature != NULL)
+       {
+         valid_p = 1;
+         valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                             PPC_DSCR_REGNUM, "dscr");
+
+         if (!valid_p)
+           {
+             tdesc_data_cleanup (tdesc_data);
+             return NULL;
+           }
+         have_dscr = 1;
+       }
+      else
+       have_dscr = 0;
+
+      /* Target Address Register.  */
+      feature = tdesc_find_feature (tdesc,
+                                   "org.gnu.gdb.power.tar");
+      if (feature != NULL)
+       {
+         valid_p = 1;
+         valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                             PPC_TAR_REGNUM, "tar");
+
+         if (!valid_p)
+           {
+             tdesc_data_cleanup (tdesc_data);
+             return NULL;
+           }
+         have_tar = 1;
+       }
+      else
+       have_tar = 0;
+
+      /* Event-based Branching Registers.  */
+      feature = tdesc_find_feature (tdesc,
+                                   "org.gnu.gdb.power.ebb");
+      if (feature != NULL)
+       {
+         static const char *const ebb_regs[] = {
+           "bescr", "ebbhr", "ebbrr"
+         };
+
+         valid_p = 1;
+         for (i = 0; i < ARRAY_SIZE (ebb_regs); i++)
+           valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                               PPC_BESCR_REGNUM + i,
+                                               ebb_regs[i]);
+         if (!valid_p)
+           {
+             tdesc_data_cleanup (tdesc_data);
+             return NULL;
+           }
+         have_ebb = 1;
+       }
+      else
+       have_ebb = 0;
+
+      /* Subset of the ISA 2.07 Performance Monitor Registers provided
+        by Linux.  */
+      feature = tdesc_find_feature (tdesc,
+                                   "org.gnu.gdb.power.linux.pmu");
+      if (feature != NULL)
+       {
+         valid_p = 1;
+
+         valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                             PPC_MMCR0_REGNUM,
+                                             "mmcr0");
+         valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                             PPC_MMCR2_REGNUM,
+                                             "mmcr2");
+         valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                             PPC_SIAR_REGNUM,
+                                             "siar");
+         valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                             PPC_SDAR_REGNUM,
+                                             "sdar");
+         valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                             PPC_SIER_REGNUM,
+                                             "sier");
+
+         if (!valid_p)
+           {
+             tdesc_data_cleanup (tdesc_data);
+             return NULL;
+           }
+         have_pmu = 1;
+       }
+      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
@@ -5803,7 +6757,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   if (soft_float_flag == AUTO_BOOLEAN_AUTO && from_elf_exec)
     {
       switch (bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU,
-                                       Tag_GNU_Power_ABI_FP))
+                                       Tag_GNU_Power_ABI_FP) & 3)
        {
        case 1:
          soft_float_flag = AUTO_BOOLEAN_FALSE;
@@ -5816,6 +6770,22 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        }
     }
 
+  if (long_double_abi == POWERPC_LONG_DOUBLE_AUTO && from_elf_exec)
+    {
+      switch (bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU,
+                                       Tag_GNU_Power_ABI_FP) >> 2)
+       {
+       case 1:
+         long_double_abi = POWERPC_LONG_DOUBLE_IBM128;
+         break;
+       case 3:
+         long_double_abi = POWERPC_LONG_DOUBLE_IEEE128;
+         break;
+       default:
+         break;
+       }
+    }
+
   if (vector_abi == POWERPC_VEC_AUTO && from_elf_exec)
     {
       switch (bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU,
@@ -5897,6 +6867,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        continue;
       if (tdep && tdep->soft_float != soft_float)
        continue;
+      if (tdep && tdep->long_double_abi != long_double_abi)
+       continue;
       if (tdep && tdep->vector_abi != vector_abi)
        continue;
       if (tdep && tdep->wordsize == wordsize)
@@ -5919,6 +6891,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->wordsize = wordsize;
   tdep->elf_abi = elf_abi;
   tdep->soft_float = soft_float;
+  tdep->long_double_abi = long_double_abi;
   tdep->vector_abi = vector_abi;
 
   gdbarch = gdbarch_alloc (&info, tdep);
@@ -5940,10 +6913,35 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->ppc_ev0_upper_regnum = have_spe ? PPC_SPE_UPPER_GP0_REGNUM : -1;
   tdep->ppc_acc_regnum = have_spe ? PPC_SPE_ACC_REGNUM : -1;
   tdep->ppc_spefscr_regnum = have_spe ? PPC_SPE_FSCR_REGNUM : -1;
+  tdep->ppc_ppr_regnum = have_ppr ? PPC_PPR_REGNUM : -1;
+  tdep->ppc_dscr_regnum = have_dscr ? PPC_DSCR_REGNUM : -1;
+  tdep->ppc_tar_regnum = have_tar ? PPC_TAR_REGNUM : -1;
+  tdep->have_ebb = have_ebb;
+
+  /* If additional pmu registers are added, care must be taken when
+     setting new fields in the tdep below, to maintain compatibility
+     with features that only provide some of the registers.  Currently
+     gdb access to the pmu registers is only supported in linux, and
+     linux only provides a subset of the pmu registers defined in the
+     architecture.  */
+
+  tdep->ppc_mmcr0_regnum = have_pmu ? PPC_MMCR0_REGNUM : -1;
+  tdep->ppc_mmcr2_regnum = have_pmu ? PPC_MMCR2_REGNUM : -1;
+  tdep->ppc_siar_regnum = have_pmu ? PPC_SIAR_REGNUM : -1;
+  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_deprecated_fp_regnum (gdbarch, PPC_R0_REGNUM + 1);
   set_gdbarch_fp0_regnum (gdbarch, tdep->ppc_fp0_regnum);
   set_gdbarch_register_sim_regno (gdbarch, rs6000_register_sim_regno);
 
@@ -5963,7 +6961,8 @@ 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_altivec
+      || have_vsx || have_htm_fpu || have_htm_vsx)
     {
       set_gdbarch_pseudo_register_read (gdbarch, rs6000_pseudo_register_read);
       set_gdbarch_pseudo_register_write (gdbarch,
@@ -5972,13 +6971,9 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
              rs6000_ax_pseudo_register_collect);
     }
 
-  set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
+  set_gdbarch_gen_return_address (gdbarch, rs6000_gen_return_address);
 
-  /* Select instruction printer.  */
-  if (arch == bfd_arch_rs6000)
-    set_gdbarch_print_insn (gdbarch, print_insn_rs6000);
-  else
-    set_gdbarch_print_insn (gdbarch, gdb_print_insn_powerpc);
+  set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
 
   set_gdbarch_num_regs (gdbarch, PPC_NUM_REGS);
 
@@ -5986,9 +6981,16 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     num_pseudoregs += 32;
   if (have_dfp)
     num_pseudoregs += 16;
+  if (have_altivec)
+    num_pseudoregs += 32;
   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);
 
@@ -6024,7 +7026,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_skip_main_prologue (gdbarch, rs6000_skip_main_prologue);
 
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
-  set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc);
+
+  set_gdbarch_breakpoint_kind_from_pc (gdbarch,
+                                      rs6000_breakpoint::kind_from_pc);
+  set_gdbarch_sw_breakpoint_from_kind (gdbarch,
+                                      rs6000_breakpoint::bp_from_kind);
 
   /* The value of symbols of type N_SO and N_FUN maybe null when
      it shouldn't be.  */
@@ -6057,8 +7063,6 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_displaced_step_hw_singlestep (gdbarch,
                                            ppc_displaced_step_hw_singlestep);
   set_gdbarch_displaced_step_fixup (gdbarch, ppc_displaced_step_fixup);
-  set_gdbarch_displaced_step_free_closure (gdbarch,
-                                          simple_displaced_step_free_closure);
   set_gdbarch_displaced_step_location (gdbarch,
                                       displaced_step_at_entry_point);
 
@@ -6066,28 +7070,23 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
   info.target_desc = tdesc;
-  info.tdep_info = tdesc_data;
+  info.tdesc_data = tdesc_data;
   gdbarch_init_osabi (info, gdbarch);
 
   switch (info.osabi)
     {
     case GDB_OSABI_LINUX:
-    case GDB_OSABI_NETBSD_AOUT:
-    case GDB_OSABI_NETBSD_ELF:
+    case GDB_OSABI_NETBSD:
     case GDB_OSABI_UNKNOWN:
-      set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc);
       frame_unwind_append_unwinder (gdbarch, &rs6000_epilogue_frame_unwind);
       frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind);
-      set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id);
       frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer);
       break;
     default:
       set_gdbarch_believe_pcc_promotion (gdbarch, 1);
 
-      set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc);
       frame_unwind_append_unwinder (gdbarch, &rs6000_epilogue_frame_unwind);
       frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind);
-      set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id);
       frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer);
     }
 
@@ -6103,8 +7102,12 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Choose register numbers for all supported pseudo-registers.  */
   tdep->ppc_ev0_regnum = -1;
   tdep->ppc_dl0_regnum = -1;
+  tdep->ppc_v0_alias_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);
 
@@ -6118,6 +7121,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       tdep->ppc_dl0_regnum = cur_reg;
       cur_reg += 16;
     }
+  if (have_altivec)
+    {
+      tdep->ppc_v0_alias_regnum = cur_reg;
+      cur_reg += 32;
+    }
   if (have_vsx)
     {
       tdep->ppc_vsr0_regnum = cur_reg;
@@ -6125,9 +7133,20 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       tdep->ppc_efpr0_regnum = cur_reg;
       cur_reg += 32;
     }
+  if (have_htm_fpu)
+    {
+      tdep->ppc_cdl0_regnum = cur_reg;
+      cur_reg += 16;
+    }
+  if (have_htm_vsx)
+    {
+      tdep->ppc_cvsr0_regnum = cur_reg;
+      cur_reg += 64;
+      tdep->ppc_cefpr0_regnum = cur_reg;
+      cur_reg += 32;
+    }
 
-  gdb_assert (gdbarch_num_regs (gdbarch)
-             + gdbarch_num_pseudo_regs (gdbarch) == cur_reg);
+  gdb_assert (gdbarch_num_cooked_regs (gdbarch) == cur_reg);
 
   /* Register the ravenscar_arch_ops.  */
   if (mach == bfd_mach_ppc_e500)
@@ -6135,6 +7154,10 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   else
     register_ppc_ravenscar_ops (gdbarch);
 
+  set_gdbarch_disassembler_options (gdbarch, &powerpc_disassembler_options);
+  set_gdbarch_valid_disassembler_options (gdbarch,
+                                         disassembler_options_powerpc ());
+
   return gdbarch;
 }
 
@@ -6149,24 +7172,8 @@ rs6000_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
   /* FIXME: Dump gdbarch_tdep.  */
 }
 
-/* PowerPC-specific commands.  */
-
 static void
-set_powerpc_command (char *args, int from_tty)
-{
-  printf_unfiltered (_("\
-\"set powerpc\" must be followed by an appropriate subcommand.\n"));
-  help_list (setpowerpccmdlist, "set powerpc ", all_commands, gdb_stdout);
-}
-
-static void
-show_powerpc_command (char *args, int from_tty)
-{
-  cmd_show_list (showpowerpccmdlist, from_tty, "");
-}
-
-static void
-powerpc_set_soft_float (char *args, int from_tty,
+powerpc_set_soft_float (const char *args, int from_tty,
                        struct cmd_list_element *c)
 {
   struct gdbarch_info info;
@@ -6178,7 +7185,7 @@ powerpc_set_soft_float (char *args, int from_tty,
 }
 
 static void
-powerpc_set_vector_abi (char *args, int from_tty,
+powerpc_set_vector_abi (const char *args, int from_tty,
                        struct cmd_list_element *c)
 {
   struct gdbarch_info info;
@@ -6230,17 +7237,17 @@ read_insn (struct frame_info *frame, CORE_ADDR pc)
    'struct ppc_insn_pattern' objects, terminated by an entry whose
    mask is zero.
 
-   When the match is successful, fill INSN[i] with what PATTERN[i]
+   When the match is successful, fill INSNS[i] with what PATTERN[i]
    matched.  If PATTERN[i] is optional, and the instruction wasn't
-   present, set INSN[i] to 0 (which is not a valid PPC instruction).
-   INSN should have as many elements as PATTERN.  Note that, if
-   PATTERN contains optional instructions which aren't present in
-   memory, then INSN will have holes, so INSN[i] isn't necessarily the
-   i'th instruction in memory.  */
+   present, set INSNS[i] to 0 (which is not a valid PPC instruction).
+   INSNS should have as many elements as PATTERN, minus the terminator.
+   Note that, if PATTERN contains optional instructions which aren't
+   present in memory, then INSNS will have holes, so INSNS[i] isn't
+   necessarily the i'th instruction in memory.  */
 
 int
 ppc_insns_match_pattern (struct frame_info *frame, CORE_ADDR pc,
-                        struct ppc_insn_pattern *pattern,
+                        const struct ppc_insn_pattern *pattern,
                         unsigned int *insns)
 {
   int i;
@@ -6285,11 +7292,9 @@ ppc_insn_ds_field (unsigned int insn)
 
 /* Initialization code.  */
 
-/* -Wmissing-prototypes */
-extern initialize_file_ftype _initialize_rs6000_tdep;
-
+void _initialize_rs6000_tdep ();
 void
-_initialize_rs6000_tdep (void)
+_initialize_rs6000_tdep ()
 {
   gdbarch_register (bfd_arch_rs6000, rs6000_gdbarch_init, rs6000_dump_tdep);
   gdbarch_register (bfd_arch_powerpc, rs6000_gdbarch_init, rs6000_dump_tdep);
@@ -6317,13 +7322,13 @@ _initialize_rs6000_tdep (void)
 
   /* Add root prefix command for all "set powerpc"/"show powerpc"
      commands.  */
-  add_prefix_cmd ("powerpc", no_class, set_powerpc_command,
-                 _("Various PowerPC-specific commands."),
-                 &setpowerpccmdlist, "set powerpc ", 0, &setlist);
+  add_basic_prefix_cmd ("powerpc", no_class,
+                       _("Various PowerPC-specific commands."),
+                       &setpowerpccmdlist, "set powerpc ", 0, &setlist);
 
-  add_prefix_cmd ("powerpc", no_class, show_powerpc_command,
-                 _("Various PowerPC-specific commands."),
-                 &showpowerpccmdlist, "show powerpc ", 0, &showlist);
+  add_show_prefix_cmd ("powerpc", no_class,
+                      _("Various PowerPC-specific commands."),
+                      &showpowerpccmdlist, "show powerpc ", 0, &showlist);
 
   /* Add a command to allow the user to force the ABI.  */
   add_setshow_auto_boolean_cmd ("soft-float", class_support,
This page took 0.064902 seconds and 4 git commands to generate.