AArch64: Add MOVPRFX tests and update testsuite
[deliverable/binutils-gdb.git] / gdb / rs6000-tdep.c
index 75811d105c03ddbf175058f1645093649185a92b..5a3e65f211b71b5f380d3445055d3e2a32b55714 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2015 Free Software Foundation, Inc.
+   Copyright (C) 1986-2018 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"
@@ -43,7 +43,6 @@
 #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_efpr0_regnum \
     && (regnum) < (tdep)->ppc_efpr0_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 +223,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
@@ -328,7 +324,7 @@ init_sim_regno_table (struct gdbarch *arch)
     set_sim_regno (sim_regno, tdep->ppc_acc_regnum, sim_ppc_acc_regnum);
   /* spefscr is a special-purpose register, so the code below handles it.  */
 
-#ifdef WITH_SIM
+#ifdef WITH_PPC_SIM
   /* Now handle all special-purpose registers.  Verify that they
      haven't mistakenly been assigned numbers by any of the above
      code.  */
@@ -387,13 +383,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 +404,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 +418,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 +475,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,9 +483,10 @@ 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 = regset->regmap;
+  const struct ppc_reg_offsets *offsets
+    = (const struct ppc_reg_offsets *) regset->regmap;
   size_t offset;
   int regsize;
 
@@ -519,27 +498,31 @@ ppc_supply_gregset (const struct regset *regset, struct regcache *regcache,
       for (i = tdep->ppc_gp0_regnum, offset = offsets->r0_offset;
           i < tdep->ppc_gp0_regnum + ppc_num_gprs;
           i++, offset += gpr_size)
-       ppc_supply_reg (regcache, i, gregs, offset, gpr_size);
+       ppc_supply_reg (regcache, i, (const gdb_byte *) gregs, offset,
+                       gpr_size);
 
       ppc_supply_reg (regcache, gdbarch_pc_regnum (gdbarch),
-                     gregs, offsets->pc_offset, gpr_size);
+                     (const gdb_byte *) gregs, offsets->pc_offset, gpr_size);
       ppc_supply_reg (regcache, tdep->ppc_ps_regnum,
-                     gregs, offsets->ps_offset, gpr_size);
+                     (const gdb_byte *) gregs, offsets->ps_offset, gpr_size);
       ppc_supply_reg (regcache, tdep->ppc_lr_regnum,
-                     gregs, offsets->lr_offset, gpr_size);
+                     (const gdb_byte *) gregs, offsets->lr_offset, gpr_size);
       ppc_supply_reg (regcache, tdep->ppc_ctr_regnum,
-                     gregs, offsets->ctr_offset, gpr_size);
+                     (const gdb_byte *) gregs, offsets->ctr_offset, gpr_size);
       ppc_supply_reg (regcache, tdep->ppc_cr_regnum,
-                     gregs, offsets->cr_offset, offsets->xr_size);
+                     (const gdb_byte *) gregs, offsets->cr_offset,
+                     offsets->xr_size);
       ppc_supply_reg (regcache, tdep->ppc_xer_regnum,
-                     gregs, offsets->xer_offset, offsets->xr_size);
+                     (const gdb_byte *) gregs, offsets->xer_offset,
+                     offsets->xr_size);
       ppc_supply_reg (regcache, tdep->ppc_mq_regnum,
-                     gregs, offsets->mq_offset, offsets->xr_size);
+                     (const gdb_byte *) gregs, offsets->mq_offset,
+                     offsets->xr_size);
       return;
     }
 
   offset = ppc_greg_offset (gdbarch, tdep, offsets, regnum, &regsize);
-  ppc_supply_reg (regcache, regnum, gregs, offset, regsize);
+  ppc_supply_reg (regcache, regnum, (const gdb_byte *) gregs, offset, regsize);
 }
 
 /* Supply register REGNUM in the floating-point register set REGSET
@@ -550,7 +533,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;
@@ -559,7 +542,7 @@ ppc_supply_fpregset (const struct regset *regset, struct regcache *regcache,
     return;
 
   tdep = gdbarch_tdep (gdbarch);
-  offsets = regset->regmap;
+  offsets = (const struct ppc_reg_offsets *) regset->regmap;
   if (regnum == -1)
     {
       int i;
@@ -567,93 +550,19 @@ ppc_supply_fpregset (const struct regset *regset, struct regcache *regcache,
       for (i = tdep->ppc_fp0_regnum, offset = offsets->f0_offset;
           i < tdep->ppc_fp0_regnum + ppc_num_fprs;
           i++, offset += 8)
-       ppc_supply_reg (regcache, i, fpregs, offset, 8);
+       ppc_supply_reg (regcache, i, (const gdb_byte *) fpregs, offset, 8);
 
       ppc_supply_reg (regcache, tdep->ppc_fpscr_regnum,
-                     fpregs, offsets->fpscr_offset, offsets->fpscr_size);
+                     (const gdb_byte *) fpregs, offsets->fpscr_offset,
+                     offsets->fpscr_size);
       return;
     }
 
   offset = ppc_fpreg_offset (tdep, offsets, regnum);
-  ppc_supply_reg (regcache, regnum, fpregs, offset,
+  ppc_supply_reg (regcache, regnum, (const gdb_byte *) fpregs, offset,
                  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, vsxregs, 0, 8);
-
-      return;
-    }
-  else
-    ppc_supply_reg (regcache, regnum, 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 = 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, vrregs, offset, 16);
-
-      ppc_supply_reg (regcache, (tdep->ppc_vrsave_regnum - 1),
-                     vrregs, offsets->vscr_offset, 4);
-
-      ppc_supply_reg (regcache, tdep->ppc_vrsave_regnum,
-                     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, vrregs, offset, 16);
-  else
-    ppc_supply_reg (regcache, regnum,
-                   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
@@ -664,9 +573,10 @@ 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 = regset->regmap;
+  const struct ppc_reg_offsets *offsets
+    = (const struct ppc_reg_offsets *) regset->regmap;
   size_t offset;
   int regsize;
 
@@ -678,27 +588,30 @@ ppc_collect_gregset (const struct regset *regset,
       for (i = tdep->ppc_gp0_regnum, offset = offsets->r0_offset;
           i < tdep->ppc_gp0_regnum + ppc_num_gprs;
           i++, offset += gpr_size)
-       ppc_collect_reg (regcache, i, gregs, offset, gpr_size);
+       ppc_collect_reg (regcache, i, (gdb_byte *) gregs, offset, gpr_size);
 
       ppc_collect_reg (regcache, gdbarch_pc_regnum (gdbarch),
-                      gregs, offsets->pc_offset, gpr_size);
+                      (gdb_byte *) gregs, offsets->pc_offset, gpr_size);
       ppc_collect_reg (regcache, tdep->ppc_ps_regnum,
-                      gregs, offsets->ps_offset, gpr_size);
+                      (gdb_byte *) gregs, offsets->ps_offset, gpr_size);
       ppc_collect_reg (regcache, tdep->ppc_lr_regnum,
-                      gregs, offsets->lr_offset, gpr_size);
+                      (gdb_byte *) gregs, offsets->lr_offset, gpr_size);
       ppc_collect_reg (regcache, tdep->ppc_ctr_regnum,
-                      gregs, offsets->ctr_offset, gpr_size);
+                      (gdb_byte *) gregs, offsets->ctr_offset, gpr_size);
       ppc_collect_reg (regcache, tdep->ppc_cr_regnum,
-                      gregs, offsets->cr_offset, offsets->xr_size);
+                      (gdb_byte *) gregs, offsets->cr_offset,
+                      offsets->xr_size);
       ppc_collect_reg (regcache, tdep->ppc_xer_regnum,
-                      gregs, offsets->xer_offset, offsets->xr_size);
+                      (gdb_byte *) gregs, offsets->xer_offset,
+                      offsets->xr_size);
       ppc_collect_reg (regcache, tdep->ppc_mq_regnum,
-                      gregs, offsets->mq_offset, offsets->xr_size);
+                      (gdb_byte *) gregs, offsets->mq_offset,
+                      offsets->xr_size);
       return;
     }
 
   offset = ppc_greg_offset (gdbarch, tdep, offsets, regnum, &regsize);
-  ppc_collect_reg (regcache, regnum, gregs, offset, regsize);
+  ppc_collect_reg (regcache, regnum, (gdb_byte *) gregs, offset, regsize);
 }
 
 /* Collect register REGNUM in the floating-point register set
@@ -711,7 +624,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;
@@ -720,7 +633,7 @@ ppc_collect_fpregset (const struct regset *regset,
     return;
 
   tdep = gdbarch_tdep (gdbarch);
-  offsets = regset->regmap;
+  offsets = (const struct ppc_reg_offsets *) regset->regmap;
   if (regnum == -1)
     {
       int i;
@@ -728,99 +641,19 @@ ppc_collect_fpregset (const struct regset *regset,
       for (i = tdep->ppc_fp0_regnum, offset = offsets->f0_offset;
           i < tdep->ppc_fp0_regnum + ppc_num_fprs;
           i++, offset += 8)
-       ppc_collect_reg (regcache, i, fpregs, offset, 8);
+       ppc_collect_reg (regcache, i, (gdb_byte *) fpregs, offset, 8);
 
       ppc_collect_reg (regcache, tdep->ppc_fpscr_regnum,
-                      fpregs, offsets->fpscr_offset, offsets->fpscr_size);
+                      (gdb_byte *) fpregs, offsets->fpscr_offset,
+                      offsets->fpscr_size);
       return;
     }
 
   offset = ppc_fpreg_offset (tdep, offsets, regnum);
-  ppc_collect_reg (regcache, regnum, fpregs, offset,
+  ppc_collect_reg (regcache, regnum, (gdb_byte *) fpregs, offset,
                   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, vsxregs, 0, 8);
-
-      return;
-    }
-  else
-    ppc_collect_reg (regcache, regnum, 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 = 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, vrregs, offset, 16);
-
-      ppc_collect_reg (regcache, (tdep->ppc_vrsave_regnum - 1),
-                      vrregs, offsets->vscr_offset, 4);
-
-      ppc_collect_reg (regcache, tdep->ppc_vrsave_regnum,
-                      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, vrregs, offset, 16);
-  else
-    ppc_collect_reg (regcache, regnum,
-                   vrregs, offset, 4);
-}
-\f
-
 static int
 insn_changes_sp_or_jumps (unsigned long insn)
 {
@@ -934,10 +767,10 @@ rs6000_in_function_epilogue_frame_p (struct frame_info *curfrm,
   return 0;
 }
 
-/* Implementation of gdbarch_in_function_epilogue_p.  */
+/* Implement the stack_frame_destroyed_p gdbarch method.  */
 
 static int
-rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+rs6000_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   return rs6000_in_function_epilogue_frame_p (get_current_frame (),
                                              gdbarch, pc);
@@ -953,18 +786,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
@@ -974,19 +800,95 @@ rs6000_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
 #define BXL_INSN 0x4c000000
 #define BP_INSN 0x7C000008
 
+/* Instruction masks used during single-stepping of atomic
+   sequences.  */
+#define LOAD_AND_RESERVE_MASK 0xfc0007fe
+#define LWARX_INSTRUCTION 0x7c000028
+#define LDARX_INSTRUCTION 0x7c0000A8
+#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_closure ppc_displaced_step_closure;
+
+/* We can't displaced step atomic sequences.  */
+
+static struct displaced_step_closure *
+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);
+  std::unique_ptr<ppc_displaced_step_closure> closure
+    (new ppc_displaced_step_closure (len));
+  gdb_byte *buf = closure->buf.data ();
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  int insn;
+
+  read_memory (from, buf, len);
+
+  insn = extract_signed_integer (buf, PPC_INSN_SIZE, byte_order);
+
+  /* Assume all atomic sequences start with a Load and Reserve instruction.  */
+  if (IS_LOAD_AND_RESERVE_INSN (insn))
+    {
+      if (debug_displaced)
+       {
+         fprintf_unfiltered (gdb_stdlog,
+                             "displaced: can't displaced step "
+                             "atomic sequence at %s\n",
+                             paddress (gdbarch, from));
+       }
+
+      return NULL;
+    }
+
+  write_memory (to, buf, len);
+
+  if (debug_displaced)
+    {
+      fprintf_unfiltered (gdb_stdlog, "displaced: copy %s->%s: ",
+                          paddress (gdbarch, from), paddress (gdbarch, to));
+      displaced_step_dump_bytes (gdb_stdlog, buf, len);
+    }
+
+  return 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_closure *closure_,
                          CORE_ADDR from, CORE_ADDR to,
                          struct regcache *regs)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  /* Since we use simple_displaced_step_copy_insn, our closure is a
-     copy of the instruction.  */
-  ULONGEST insn  = extract_unsigned_integer ((gdb_byte *) closure,
-                                             PPC_INSN_SIZE, byte_order);
+  /* Our closure is a copy of the instruction.  */
+  ppc_displaced_step_closure *closure = (ppc_displaced_step_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;
@@ -1077,27 +979,17 @@ ppc_displaced_step_hw_singlestep (struct gdbarch *gdbarch,
   return 1;
 }
 
-/* Instruction masks used during single-stepping of atomic sequences.  */
-#define LWARX_MASK 0xfc0007fe
-#define LWARX_INSTRUCTION 0x7c000028
-#define LDARX_INSTRUCTION 0x7c0000A8
-#define STWCX_MASK 0xfc0007ff
-#define STWCX_INSTRUCTION 0x7c00012d
-#define STDCX_INSTRUCTION 0x7c0001ad
-
-/* 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);
@@ -1105,13 +997,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.  */
@@ -1129,8 +1019,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;
@@ -1141,19 +1031,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;
@@ -1165,11 +1053,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;
 }
 
 
@@ -1284,6 +1173,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.
@@ -1510,6 +1432,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;
@@ -1588,7 +1511,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;
@@ -1665,14 +1588,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.  */
@@ -1687,13 +1613,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.  */
@@ -1784,8 +1705,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;
@@ -1798,13 +1719,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;
@@ -1847,6 +1761,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.  */
@@ -1857,6 +1772,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.  */
@@ -1867,6 +1783,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.  */
@@ -2127,7 +2044,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
@@ -2220,7 +2137,7 @@ static int
 rs6000_in_solib_return_trampoline (struct gdbarch *gdbarch,
                                   CORE_ADDR pc, const char *name)
 {
-  return name && !strncmp (name, "@FIX", 4);
+  return name && startswith (name, "@FIX");
 }
 
 /* Skip code that the user doesn't want to see when stepping:
@@ -2539,7 +2456,7 @@ 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);
 
@@ -2548,8 +2465,8 @@ rs6000_register_to_value (struct frame_info *frame,
                                 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;
 }
@@ -2561,12 +2478,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);
 
-  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);
 }
 
@@ -2603,10 +2520,10 @@ 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 = buffer;
+  gdb_byte *byte_buffer = (gdb_byte *) buffer;
   enum register_status status;
 
   gdb_assert (IS_SPE_PSEUDOREG (tdep, ev_reg));
@@ -2632,25 +2549,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, buffer);
-}
-
 static enum register_status
 do_regcache_raw_write (struct regcache *regcache, int regnum, void *buffer)
 {
-  regcache_raw_write (regcache, regnum, 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
@@ -2663,7 +2600,7 @@ 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);
@@ -2673,19 +2610,19 @@ dfp_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
   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 (tdep->ppc_fp0_regnum +
+                                  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 (tdep->ppc_fp0_regnum +
+                                    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 (tdep->ppc_fp0_regnum +
+                                  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 (tdep->ppc_fp0_regnum +
+                                    2 * reg_index, buffer + 8);
     }
 
   return status;
@@ -2703,23 +2640,23 @@ dfp_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
     {
       /* Write each half of the dl register into a separate
       FP register.  */
-      regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+      regcache->raw_write (tdep->ppc_fp0_regnum +
                          2 * reg_index, buffer);
-      regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+      regcache->raw_write (tdep->ppc_fp0_regnum +
                          2 * reg_index + 1, buffer + 8);
     }
   else
     {
-      regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+      regcache->raw_write (tdep->ppc_fp0_regnum +
                          2 * reg_index + 1, buffer);
-      regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+      regcache->raw_write (tdep->ppc_fp0_regnum +
                          2 * reg_index, buffer + 8);
     }
 }
 
 /* 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);
@@ -2728,25 +2665,25 @@ vsx_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
 
   /* 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 (tdep->ppc_vr0_regnum +
+                                reg_index - 32, buffer);
   else
     /* Read the portion that overlaps the FPR registers.  */
     if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
       {
-       status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
-                                   reg_index, buffer);
+       status = regcache->raw_read (tdep->ppc_fp0_regnum +
+                                    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 (tdep->ppc_vsr0_upper_regnum +
+                                      reg_index, buffer + 8);
       }
     else
       {
-       status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
-                                   reg_index, buffer + 8);
+       status = regcache->raw_read (tdep->ppc_fp0_regnum +
+                                    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 (tdep->ppc_vsr0_upper_regnum +
+                                      reg_index, buffer);
       }
 
   return status;
@@ -2762,29 +2699,29 @@ vsx_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 
   /* Write the portion that overlaps the VMX registers.  */
   if (reg_index > 31)
-    regcache_raw_write (regcache, tdep->ppc_vr0_regnum +
+    regcache->raw_write (tdep->ppc_vr0_regnum +
                        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 +
+       regcache->raw_write (tdep->ppc_fp0_regnum +
                        reg_index, buffer);
-       regcache_raw_write (regcache, tdep->ppc_vsr0_upper_regnum +
+       regcache->raw_write (tdep->ppc_vsr0_upper_regnum +
                        reg_index, buffer + 8);
       }
     else
       {
-       regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+       regcache->raw_write (tdep->ppc_fp0_regnum +
                        reg_index, buffer + 8);
-       regcache_raw_write (regcache, tdep->ppc_vsr0_upper_regnum +
+       regcache->raw_write (tdep->ppc_vsr0_upper_regnum +
                        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,
+efpr_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
                           int reg_nr, gdb_byte *buffer)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
@@ -2792,9 +2729,9 @@ efpr_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
   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 (tdep->ppc_vr0_regnum + reg_index,
+                                 offset, register_size (gdbarch, reg_nr),
+                                 buffer);
 }
 
 /* Write method for POWER7 Extended FP pseudo-registers.  */
@@ -2807,17 +2744,16 @@ efpr_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
   int offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8;
 
   /* 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 (tdep->ppc_vr0_regnum + 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);
@@ -2842,7 +2778,7 @@ 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);
@@ -2862,6 +2798,62 @@ rs6000_pseudo_register_write (struct gdbarch *gdbarch,
                    gdbarch_register_name (gdbarch, reg_nr), reg_nr);
 }
 
+static int
+rs6000_ax_pseudo_register_collect (struct gdbarch *gdbarch,
+                                  struct agent_expr *ax, int reg_nr)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  if (IS_SPE_PSEUDOREG (tdep, reg_nr))
+    {
+      int reg_index = reg_nr - tdep->ppc_ev0_regnum;
+      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))
+    {
+      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);
+    }
+  else if (IS_VSX_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);
+        }
+    }
+  else if (IS_EFP_PSEUDOREG (tdep, reg_nr))
+    {
+      int reg_index = reg_nr - tdep->ppc_efpr0_regnum;
+      ax_reg_mask (ax, tdep->ppc_vr0_regnum + reg_index);
+    }
+  else
+    internal_error (__FILE__, __LINE__,
+                   _("rs6000_pseudo_register_collect: "
+                   "called on unexpected register '%s' (%d)"),
+                   gdbarch_register_name (gdbarch, reg_nr), reg_nr);
+  return 0;
+}
+
+
+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)
@@ -3019,10 +3011,10 @@ rs6000_adjust_frame_regnum (struct gdbarch *gdbarch, int num, int eh_frame_p)
 struct 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;
@@ -3087,7 +3079,7 @@ static struct variant variants[] =
   {"rs2", "IBM POWER RS2", bfd_arch_rs6000,
    bfd_mach_rs6k_rs2, &tdesc_rs6000},
 
-  {0, 0, 0, 0, 0}
+  {0, 0, (enum bfd_architecture) 0, 0, 0}
 };
 
 /* Return the variant corresponding to architecture ARCH and machine number
@@ -3105,14 +3097,6 @@ 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)
@@ -3134,6 +3118,13 @@ struct rs6000_frame_cache
   CORE_ADDR base;
   CORE_ADDR initial_sp;
   struct trad_frame_saved_reg *saved_regs;
+
+  /* Set BASE_P to true if this frame cache is properly initialized.
+     Otherwise set to false because some registers or memory cannot
+     collected.  */
+  int base_p;
+  /* Cache PC for building unavailable frame.  */
+  CORE_ADDR pc;
 };
 
 static struct rs6000_frame_cache *
@@ -3145,27 +3136,39 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct rs6000_framedata fdata;
   int wordsize = tdep->wordsize;
-  CORE_ADDR func, pc;
+  CORE_ADDR func = 0, pc = 0;
 
   if ((*this_cache) != NULL)
-    return (*this_cache);
+    return (struct rs6000_frame_cache *) (*this_cache);
   cache = FRAME_OBSTACK_ZALLOC (struct rs6000_frame_cache);
   (*this_cache) = cache;
+  cache->pc = 0;
   cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
 
-  func = get_frame_func (this_frame);
-  pc = get_frame_pc (this_frame);
-  skip_prologue (gdbarch, func, pc, &fdata);
-
-  /* Figure out the parent's stack pointer.  */
-
-  /* NOTE: cagney/2002-04-14: The ->frame points to the inner-most
-     address of the current frame.  Things might be easier if the
-     ->frame pointed to the outer-most address of the frame.  In
-     the mean time, the address of the prev frame is used as the
-     base address of this frame.  */
-  cache->base = get_frame_register_unsigned
-               (this_frame, gdbarch_sp_regnum (gdbarch));
+  TRY
+    {
+      func = get_frame_func (this_frame);
+      cache->pc = func;
+      pc = get_frame_pc (this_frame);
+      skip_prologue (gdbarch, func, pc, &fdata);
+
+      /* Figure out the parent's stack pointer.  */
+
+      /* NOTE: cagney/2002-04-14: The ->frame points to the inner-most
+        address of the current frame.  Things might be easier if the
+        ->frame pointed to the outer-most address of the frame.  In
+        the mean time, the address of the prev frame is used as the
+        base address of this frame.  */
+      cache->base = get_frame_register_unsigned
+       (this_frame, gdbarch_sp_regnum (gdbarch));
+    }
+  CATCH (ex, RETURN_MASK_ERROR)
+    {
+      if (ex.error != NOT_AVAILABLE_ERROR)
+       throw_exception (ex);
+      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.
@@ -3201,10 +3204,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;
     }
 
@@ -3314,6 +3317,7 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
     cache->initial_sp
       = get_frame_register_unsigned (this_frame, fdata.alloca_reg);
 
+  cache->base_p = 1;
   return cache;
 }
 
@@ -3323,6 +3327,13 @@ rs6000_frame_this_id (struct frame_info *this_frame, void **this_cache,
 {
   struct rs6000_frame_cache *info = rs6000_frame_cache (this_frame,
                                                        this_cache);
+
+  if (!info->base_p)
+    {
+      (*this_id) = frame_id_build_unavailable_stack (info->pc);
+      return;
+    }
+
   /* This marks the outermost frame.  */
   if (info->base == 0)
     return;
@@ -3349,23 +3360,24 @@ static const struct frame_unwind rs6000_frame_unwind =
   default_frame_sniffer
 };
 
+/* Allocate and initialize a frame cache for an epilogue frame.
+   SP is restored and prev-PC is stored in LR.  */
+
 static struct rs6000_frame_cache *
 rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
 {
-  volatile struct gdb_exception ex;
   struct rs6000_frame_cache *cache;
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  CORE_ADDR sp;
 
   if (*this_cache)
-    return *this_cache;
+    return (struct rs6000_frame_cache *) *this_cache;
 
   cache = FRAME_OBSTACK_ZALLOC (struct rs6000_frame_cache);
   (*this_cache) = cache;
   cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
 
-  TRY_CATCH (ex, RETURN_MASK_ERROR)
+  TRY
     {
       /* At this point the stack looks as if we just entered the
         function, and the return address is stored in LR.  */
@@ -3380,12 +3392,19 @@ rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
       trad_frame_set_value (cache->saved_regs,
                            gdbarch_pc_regnum (gdbarch), lr);
     }
-  if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
-    throw_exception (ex);
+  CATCH (ex, RETURN_MASK_ERROR)
+    {
+      if (ex.error != NOT_AVAILABLE_ERROR)
+       throw_exception (ex);
+    }
+  END_CATCH
 
   return cache;
 }
 
+/* Implementation of frame_unwind.this_id, as defined in frame_unwind.h.
+   Return the frame ID of an epilogue frame.  */
+
 static void
 rs6000_epilogue_frame_this_id (struct frame_info *this_frame,
                               void **this_cache, struct frame_id *this_id)
@@ -3401,6 +3420,9 @@ rs6000_epilogue_frame_this_id (struct frame_info *this_frame,
     (*this_id) = frame_id_build (info->base, pc);
 }
 
+/* Implementation of frame_unwind.prev_register, as defined in frame_unwind.h.
+   Return the register value of REGNUM in previous frame.  */
+
 static struct value *
 rs6000_epilogue_frame_prev_register (struct frame_info *this_frame,
                                     void **this_cache, int regnum)
@@ -3410,6 +3432,9 @@ rs6000_epilogue_frame_prev_register (struct frame_info *this_frame,
   return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
 }
 
+/* Implementation of frame_unwind.sniffer, as defined in frame_unwind.h.
+   Check whether this an epilogue frame.  */
+
 static int
 rs6000_epilogue_frame_sniffer (const struct frame_unwind *self,
                               struct frame_info *this_frame,
@@ -3423,6 +3448,9 @@ rs6000_epilogue_frame_sniffer (const struct frame_unwind *self,
     return 0;
 }
 
+/* Frame unwinder for epilogue frame.  This is required for reverse step-over
+   a function without debug information.  */
+
 static const struct frame_unwind rs6000_epilogue_frame_unwind =
 {
   NORMAL_FRAME,
@@ -3530,7 +3558,6 @@ bfd_uses_spe_extensions (bfd *abfd)
   bfd_size_type size;
   gdb_byte *ptr;
   int success = 0;
-  int vector_abi;
 
   if (!abfd)
     return 0;
@@ -3539,8 +3566,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
@@ -3550,7 +3577,7 @@ bfd_uses_spe_extensions (bfd *abfd)
     return 0;
 
   size = bfd_get_section_size (sect);
-  contents = xmalloc (size);
+  contents = (gdb_byte *) xmalloc (size);
   if (!bfd_get_section_contents (abfd, sect, contents, 0, size))
     {
       xfree (contents);
@@ -3658,6 +3685,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)
@@ -3669,7 +3697,9 @@ bfd_uses_spe_extensions (bfd *abfd)
 #define PPC_XT(insn)   ((PPC_TX (insn) << 5) | PPC_T (insn))
 #define PPC_XER_NB(xer)        (xer & 0x7f)
 
-/* Record Vector-Scalar Registers.  */
+/* Record Vector-Scalar Registers.
+   For VSR less than 32, it's represented by an FPR and an VSR-upper register.
+   Otherwise, it's just a VR register.  Record them accordingly.  */
 
 static int
 ppc_record_vsr (struct regcache *regcache, struct gdbarch_tdep *tdep, int vsr)
@@ -3694,14 +3724,16 @@ ppc_record_vsr (struct regcache *regcache, struct gdbarch_tdep *tdep, int vsr)
   return 0;
 }
 
-/* Parse instructions of primary opcode-4.  */
+/* Parse and record instructions primary opcode-4 at ADDR.
+   Return 0 if successful.  */
 
 static int
 ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
-                          CORE_ADDR addr, uint32_t insn)
+                       CORE_ADDR addr, uint32_t insn)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int ext = PPC_FIELD (insn, 21, 11);
+  int vra = PPC_FIELD (insn, 11, 5);
 
   switch (ext & 0x3f)
     {
@@ -3713,6 +3745,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 */
@@ -3720,6 +3753,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 */
@@ -3729,14 +3763,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;
@@ -3766,6 +3824,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,
@@ -3773,6 +3837,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 */
@@ -3944,10 +4040,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;
@@ -3955,14 +4085,20 @@ 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 at %08lx, 4-%d.\n", insn, addr, ext);
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
+                     "at %s, 4-%d.\n", insn, paddress (gdbarch, addr), ext);
   return -1;
 }
 
-/* Parse instructions of primary opcode-19.  */
+/* Parse and record instructions of primary opcode-19 at ADDR.
+   Return 0 if successful.  */
 
 static int
 ppc_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache,
@@ -3971,6 +4107,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 */
@@ -4000,12 +4144,13 @@ ppc_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache,
       return 0;
     }
 
-  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
-                     "%08x at %08lx, 19-%d.\n", insn, addr, ext);
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
+                     "at %s, 19-%d.\n", insn, paddress (gdbarch, addr), ext);
   return -1;
 }
 
-/* Parse instructions of primary opcode-31.  */
+/* Parse and record instructions of primary opcode-31 at ADDR.
+   Return 0 if successful.  */
 
 static int
 ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
@@ -4075,6 +4220,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 */
@@ -4093,6 +4247,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;
@@ -4109,6 +4266,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;
@@ -4127,6 +4285,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;
 
@@ -4153,6 +4317,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;
@@ -4231,6 +4401,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;
 
@@ -4252,6 +4432,10 @@ 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 (PPC_RC (insn))
        record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
       record_full_arch_list_add_reg (regcache,
@@ -4294,6 +4478,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);
 
@@ -4323,6 +4512,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 */
@@ -4330,6 +4520,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 */
@@ -4347,6 +4538,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:
@@ -4373,10 +4567,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);
@@ -4390,7 +4621,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);
@@ -4398,7 +4630,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);
        }
@@ -4438,6 +4672,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 */
@@ -4446,26 +4681,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 %08lx, 31-%d.\n", insn, 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);
@@ -4477,12 +4716,13 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
     }
 
 UNKNOWN_OP:
-  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
-                     "%08x at %08lx, 31-%d.\n", insn, addr, ext);
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
+                     "at %s, 31-%d.\n", insn, paddress (gdbarch, addr), ext);
   return -1;
 }
 
-/* Parse instructions of primary opcode-59.  */
+/* Parse and record instructions of primary opcode-59 at ADDR.
+   Return 0 if successful.  */
 
 static int
 ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
@@ -4542,6 +4782,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;
@@ -4569,12 +4810,13 @@ ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
       return 0;
     }
 
-  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
-                     "%08x at %08lx, 59-%d.\n", insn, addr, ext);
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
+                     "at %s, 59-%d.\n", insn, paddress (gdbarch, addr), ext);
   return -1;
 }
 
-/* Parse instructions of primary opcode-60.  */
+/* Parse and record instructions of primary opcode-60 at ADDR.
+   Return 0 if successful.  */
 
 static int
 ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
@@ -4582,7 +4824,6 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int ext = PPC_EXTOP (insn);
-  int tmp;
 
   switch (ext >> 2)
     {
@@ -4641,7 +4882,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 */
@@ -4662,6 +4912,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;
 
@@ -4673,6 +4931,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;
@@ -4819,6 +5078,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 */
@@ -4833,9 +5093,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
@@ -4844,6 +5110,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 */
@@ -4852,12 +5172,72 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
       return 0;
     }
 
-  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
-                     "%08x at %08lx, 60-%d.\n", insn, addr, ext);
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
+                     "at %s, 60-%d.\n", insn, paddress (gdbarch, addr), ext);
+  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 instructions of primary opcode-63.  */
+/* Parse and record instructions of primary opcode-63 at ADDR.
+   Return 0 if successful.  */
 
 static int
 ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
@@ -4892,6 +5272,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)
@@ -4923,6 +5314,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;
@@ -4944,7 +5336,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,
@@ -4979,7 +5371,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 */
@@ -5004,11 +5416,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 */
@@ -5016,10 +5432,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 %08lx, 59-%d.\n", insn, addr, ext);
+  fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
+                     "at %s, 63-%d.\n", insn, paddress (gdbarch, addr), ext);
   return -1;
 }
 
@@ -5230,12 +5701,21 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
        }
       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 */
@@ -5261,7 +5741,11 @@ 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 */
@@ -5270,7 +5754,7 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
          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)
@@ -5278,7 +5762,7 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
                                        tdep->ppc_gp0_regnum + PPC_RA (insn),
                                        &addr);
 
-         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);
@@ -5298,8 +5782,8 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 
     default:
 UNKNOWN_OP:
-      fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record "
-                         "%08x at %08lx, %d.\n", insn, addr, op6);
+      fprintf_unfiltered (gdb_stdlog, "Warning: Don't know how to record %08x "
+                         "at %s, %d.\n", insn, paddress (gdbarch, addr), op6);
       return -1;
     }
 
@@ -5328,6 +5812,7 @@ 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,
@@ -5375,8 +5860,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   else
     {
       if (info.bfd_arch_info != NULL && info.bfd_arch_info->bits_per_word != 0)
-       wordsize = info.bfd_arch_info->bits_per_word /
-         info.bfd_arch_info->bits_per_byte;
+       wordsize = (info.bfd_arch_info->bits_per_word
+                   / info.bfd_arch_info->bits_per_byte);
       else
        wordsize = 4;
     }
@@ -5467,7 +5952,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;
 
@@ -5494,14 +5979,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)
@@ -5650,7 +6137,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;
@@ -5663,6 +6150,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,
@@ -5744,6 +6247,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)
@@ -5766,6 +6271,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);
@@ -5790,7 +6296,6 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   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);
 
@@ -5815,15 +6320,13 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       set_gdbarch_pseudo_register_read (gdbarch, rs6000_pseudo_register_read);
       set_gdbarch_pseudo_register_write (gdbarch,
                                         rs6000_pseudo_register_write);
+      set_gdbarch_ax_pseudo_register_collect (gdbarch,
+             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);
 
@@ -5865,11 +6368,15 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     set_gdbarch_push_dummy_call (gdbarch, ppc64_sysv_abi_push_dummy_call);
 
   set_gdbarch_skip_prologue (gdbarch, rs6000_skip_prologue);
-  set_gdbarch_in_function_epilogue_p (gdbarch, rs6000_in_function_epilogue_p);
+  set_gdbarch_stack_frame_destroyed_p (gdbarch, rs6000_stack_frame_destroyed_p);
   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.  */
@@ -5898,12 +6405,10 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Setup displaced stepping.  */
   set_gdbarch_displaced_step_copy_insn (gdbarch,
-                                       simple_displaced_step_copy_insn);
+                                       ppc_displaced_step_copy_insn);
   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);
 
@@ -5911,14 +6416,13 @@ 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 = (void *) 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);
@@ -5980,6 +6484,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;
 }
 
@@ -5997,7 +6505,7 @@ rs6000_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
 /* PowerPC-specific commands.  */
 
 static void
-set_powerpc_command (char *args, int from_tty)
+set_powerpc_command (const char *args, int from_tty)
 {
   printf_unfiltered (_("\
 \"set powerpc\" must be followed by an appropriate subcommand.\n"));
@@ -6005,13 +6513,13 @@ set_powerpc_command (char *args, int from_tty)
 }
 
 static void
-show_powerpc_command (char *args, int from_tty)
+show_powerpc_command (const 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;
@@ -6023,11 +6531,11 @@ 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;
-  enum powerpc_vector_abi vector_abi;
+  int vector_abi;
 
   for (vector_abi = POWERPC_VEC_AUTO;
        vector_abi != POWERPC_VEC_LAST;
@@ -6035,7 +6543,7 @@ powerpc_set_vector_abi (char *args, int from_tty,
     if (strcmp (powerpc_vector_abi_string,
                powerpc_vector_strings[vector_abi]) == 0)
       {
-       powerpc_vector_abi_global = vector_abi;
+       powerpc_vector_abi_global = (enum powerpc_vector_abi) vector_abi;
        break;
       }
 
@@ -6075,17 +6583,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;
@@ -6130,9 +6638,6 @@ ppc_insn_ds_field (unsigned int insn)
 
 /* Initialization code.  */
 
-/* -Wmissing-prototypes */
-extern initialize_file_ftype _initialize_rs6000_tdep;
-
 void
 _initialize_rs6000_tdep (void)
 {
This page took 0.061936 seconds and 4 git commands to generate.