x86: Adjust linker tests for --disable-separate-code
[binutils-gdb.git] / gdb / rs6000-tdep.c
index e875ad953663c2a8c2c05e0637740140d16c3b0d..ce98dc2f88438eb76df8ec2d95986754b1716c12 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2019 Free Software Foundation, Inc.
+   Copyright (C) 1986-2021 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -37,7 +37,7 @@
 #include "sim-regno.h"
 #include "gdb/sim-ppc.h"
 #include "reggroups.h"
-#include "dwarf2-frame.h"
+#include "dwarf2/frame.h"
 #include "target-descriptions.h"
 #include "user-regs.h"
 #include "record-full.h"
@@ -153,6 +153,23 @@ static const char *const powerpc_vector_strings[] =
 static enum powerpc_vector_abi powerpc_vector_abi_global = POWERPC_VEC_AUTO;
 static const char *powerpc_vector_abi_string = "auto";
 
+/* PowerPC-related per-inferior data.  */
+
+static inferior_key<ppc_inferior_data> ppc_inferior_data_key;
+
+/* Get the per-inferior PowerPC data for INF.  */
+
+ppc_inferior_data *
+get_ppc_per_inferior (inferior *inf)
+{
+  ppc_inferior_data *per_inf = ppc_inferior_data_key.get (inf);
+
+  if (per_inf == nullptr)
+    per_inf = ppc_inferior_data_key.emplace (inf);
+
+  return per_inf;
+}
+
 /* To be used by skip_prologue.  */
 
 struct rs6000_framedata
@@ -184,7 +201,7 @@ struct rs6000_framedata
 int
 vsx_register_p (struct gdbarch *gdbarch, int regno)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   if (tdep->ppc_vsr0_regnum < 0)
     return 0;
   else
@@ -196,7 +213,7 @@ vsx_register_p (struct gdbarch *gdbarch, int regno)
 int
 altivec_register_p (struct gdbarch *gdbarch, int regno)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   if (tdep->ppc_vr0_regnum < 0 || tdep->ppc_vrsave_regnum < 0)
     return 0;
   else
@@ -208,7 +225,7 @@ altivec_register_p (struct gdbarch *gdbarch, int regno)
 int
 spe_register_p (struct gdbarch *gdbarch, int regno)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   
   /* Is it a reference to EV0 -- EV31, and do we have those?  */
   if (IS_SPE_PSEUDOREG (tdep, regno))
@@ -240,10 +257,10 @@ spe_register_p (struct gdbarch *gdbarch, int regno)
 int
 ppc_floating_point_unit_p (struct gdbarch *gdbarch)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   return (tdep->ppc_fp0_regnum >= 0
-          && tdep->ppc_fpscr_regnum >= 0);
+         && tdep->ppc_fpscr_regnum >= 0);
 }
 
 /* Return non-zero if the architecture described by GDBARCH has
@@ -251,10 +268,10 @@ ppc_floating_point_unit_p (struct gdbarch *gdbarch)
 int
 ppc_altivec_support_p (struct gdbarch *gdbarch)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   return (tdep->ppc_vr0_regnum >= 0
-          && tdep->ppc_vrsave_regnum >= 0);
+         && tdep->ppc_vrsave_regnum >= 0);
 }
 
 /* Check that TABLE[GDB_REGNO] is not already initialized, and then
@@ -280,7 +297,7 @@ set_sim_regno (int *table, int gdb_regno, int sim_regno)
 static void
 init_sim_regno_table (struct gdbarch *arch)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (arch);
   int total_regs = gdbarch_num_regs (arch);
   int *sim_regno = GDBARCH_OBSTACK_CALLOC (arch, total_regs, int);
   int i;
@@ -302,8 +319,8 @@ init_sim_regno_table (struct gdbarch *arch)
   if (tdep->ppc_fp0_regnum >= 0)
     for (i = 0; i < ppc_num_fprs; i++)
       set_sim_regno (sim_regno,
-                     tdep->ppc_fp0_regnum + i,
-                     sim_ppc_f0_regnum + i);
+                    tdep->ppc_fp0_regnum + i,
+                    sim_ppc_f0_regnum + i);
   if (tdep->ppc_fpscr_regnum >= 0)
     set_sim_regno (sim_regno, tdep->ppc_fpscr_regnum, sim_ppc_fpscr_regnum);
 
@@ -325,15 +342,15 @@ init_sim_regno_table (struct gdbarch *arch)
   if (tdep->ppc_vr0_regnum >= 0)
     {
       for (i = 0; i < ppc_num_vrs; i++)
-        set_sim_regno (sim_regno,
-                       tdep->ppc_vr0_regnum + i,
-                       sim_ppc_vr0_regnum + i);
+       set_sim_regno (sim_regno,
+                      tdep->ppc_vr0_regnum + i,
+                      sim_ppc_vr0_regnum + i);
 
       /* FIXME: jimb/2004-07-15: when we have tdep->ppc_vscr_regnum,
-         we can treat this more like the other cases.  */
+        we can treat this more like the other cases.  */
       set_sim_regno (sim_regno,
-                     tdep->ppc_vr0_regnum + ppc_num_vrs,
-                     sim_ppc_vscr_regnum);
+                    tdep->ppc_vr0_regnum + ppc_num_vrs,
+                    sim_ppc_vscr_regnum);
     }
   /* vsave is a special-purpose register, so the code below handles it.  */
 
@@ -341,8 +358,8 @@ init_sim_regno_table (struct gdbarch *arch)
   if (tdep->ppc_ev0_upper_regnum >= 0)
     for (i = 0; i < ppc_num_gprs; i++)
       set_sim_regno (sim_regno,
-                     tdep->ppc_ev0_upper_regnum + i,
-                     sim_ppc_rh0_regnum + i);
+                    tdep->ppc_ev0_upper_regnum + i,
+                    sim_ppc_rh0_regnum + i);
   if (tdep->ppc_acc_regnum >= 0)
     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.  */
@@ -374,7 +391,7 @@ init_sim_regno_table (struct gdbarch *arch)
 static int
 rs6000_register_sim_regno (struct gdbarch *gdbarch, int reg)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int sim_regno;
 
   if (tdep->sim_regno == NULL)
@@ -445,7 +462,7 @@ ppc_collect_reg (const struct regcache *regcache, int regnum,
     
 static int
 ppc_greg_offset (struct gdbarch *gdbarch,
-                struct gdbarch_tdep *tdep,
+                ppc_gdbarch_tdep *tdep,
                 const struct ppc_reg_offsets *offsets,
                 int regnum,
                 int *regsize)
@@ -482,7 +499,7 @@ ppc_greg_offset (struct gdbarch *gdbarch,
 }
 
 static int
-ppc_fpreg_offset (struct gdbarch_tdep *tdep,
+ppc_fpreg_offset (ppc_gdbarch_tdep *tdep,
                  const struct ppc_reg_offsets *offsets,
                  int regnum)
 {
@@ -505,7 +522,7 @@ ppc_supply_gregset (const struct regset *regset, struct regcache *regcache,
                    int regnum, const void *gregs, size_t len)
 {
   struct gdbarch *gdbarch = regcache->arch ();
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   const struct ppc_reg_offsets *offsets
     = (const struct ppc_reg_offsets *) regset->regmap;
   size_t offset;
@@ -555,14 +572,13 @@ ppc_supply_fpregset (const struct regset *regset, struct regcache *regcache,
                     int regnum, const void *fpregs, size_t len)
 {
   struct gdbarch *gdbarch = regcache->arch ();
-  struct gdbarch_tdep *tdep;
   const struct ppc_reg_offsets *offsets;
   size_t offset;
 
   if (!ppc_floating_point_unit_p (gdbarch))
     return;
 
-  tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   offsets = (const struct ppc_reg_offsets *) regset->regmap;
   if (regnum == -1)
     {
@@ -595,7 +611,7 @@ ppc_collect_gregset (const struct regset *regset,
                     int regnum, void *gregs, size_t len)
 {
   struct gdbarch *gdbarch = regcache->arch ();
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   const struct ppc_reg_offsets *offsets
     = (const struct ppc_reg_offsets *) regset->regmap;
   size_t offset;
@@ -646,14 +662,13 @@ ppc_collect_fpregset (const struct regset *regset,
                      int regnum, void *fpregs, size_t len)
 {
   struct gdbarch *gdbarch = regcache->arch ();
-  struct gdbarch_tdep *tdep;
   const struct ppc_reg_offsets *offsets;
   size_t offset;
 
   if (!ppc_floating_point_unit_p (gdbarch))
     return;
 
-  tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   offsets = (const struct ppc_reg_offsets *) regset->regmap;
   if (regnum == -1)
     {
@@ -686,8 +701,8 @@ insn_changes_sp_or_jumps (unsigned long insn)
   /* Changes the stack pointer.  */
 
   /* NOTE: There are many ways to change the value of a given register.
-           The ways below are those used when the register is R1, the SP,
-           in a funtion's epilogue.  */
+          The ways below are those used when the register is R1, the SP,
+          in a funtion's epilogue.  */
 
   if (opcode == 31 && subcode == 444 && a == 1)
     return 1;  /* mr R1,Rn */
@@ -715,23 +730,23 @@ insn_changes_sp_or_jumps (unsigned long insn)
 
    1) scan forward from the point of execution:
        a) If you find an instruction that modifies the stack pointer
-          or transfers control (except a return), execution is not in
-          an epilogue, return.
+         or transfers control (except a return), execution is not in
+         an epilogue, return.
        b) Stop scanning if you find a return instruction or reach the
-          end of the function or reach the hard limit for the size of
-          an epilogue.
+         end of the function or reach the hard limit for the size of
+         an epilogue.
    2) scan backward from the point of execution:
-        a) If you find an instruction that modifies the stack pointer,
-            execution *is* in an epilogue, return.
-        b) Stop scanning if you reach an instruction that transfers
-           control or the beginning of the function or reach the hard
-           limit for the size of an epilogue.  */
+       a) If you find an instruction that modifies the stack pointer,
+           execution *is* in an epilogue, return.
+       b) Stop scanning if you reach an instruction that transfers
+          control or the beginning of the function or reach the hard
+          limit for the size of an epilogue.  */
 
 static int
 rs6000_in_function_epilogue_frame_p (struct frame_info *curfrm,
                                     struct gdbarch *gdbarch, CORE_ADDR pc)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   bfd_byte insn_buf[PPC_INSN_SIZE];
   CORE_ADDR scan_pc, func_start, func_end, epilogue_start, epilogue_end;
@@ -752,11 +767,12 @@ rs6000_in_function_epilogue_frame_p (struct frame_info *curfrm,
 
   for (scan_pc = pc; scan_pc < epilogue_end; scan_pc += PPC_INSN_SIZE)
     {
-      if (!safe_frame_unwind_memory (curfrm, scan_pc, insn_buf, PPC_INSN_SIZE))
-        return 0;
+      if (!safe_frame_unwind_memory (curfrm, scan_pc,
+                                    {insn_buf, PPC_INSN_SIZE}))
+       return 0;
       insn = extract_unsigned_integer (insn_buf, PPC_INSN_SIZE, byte_order);
       if (insn == 0x4e800020)
-        break;
+       break;
       /* Assume a bctr is a tail call unless it points strictly within
         this function.  */
       if (insn == 0x4e800420)
@@ -769,7 +785,7 @@ rs6000_in_function_epilogue_frame_p (struct frame_info *curfrm,
            break;
        }
       if (insn_changes_sp_or_jumps (insn))
-        return 0;
+       return 0;
     }
 
   /* Scan backward until adjustment to stack pointer (R1).  */
@@ -778,11 +794,12 @@ rs6000_in_function_epilogue_frame_p (struct frame_info *curfrm,
        scan_pc >= epilogue_start;
        scan_pc -= PPC_INSN_SIZE)
     {
-      if (!safe_frame_unwind_memory (curfrm, scan_pc, insn_buf, PPC_INSN_SIZE))
-        return 0;
+      if (!safe_frame_unwind_memory (curfrm, scan_pc,
+                                    {insn_buf, PPC_INSN_SIZE}))
+       return 0;
       insn = extract_unsigned_integer (insn_buf, PPC_INSN_SIZE, byte_order);
       if (insn_changes_sp_or_jumps (insn))
-        return 1;
+       return 1;
     }
 
   return 0;
@@ -807,14 +824,14 @@ rs6000_fetch_pointer_argument (struct frame_info *frame, int argi,
 
 /* Sequence of bytes for breakpoint instruction.  */
 
-constexpr gdb_byte big_breakpoint[] = { 0x7d, 0x82, 0x10, 0x08 };
-constexpr gdb_byte little_breakpoint[] = { 0x08, 0x10, 0x82, 0x7d };
+constexpr gdb_byte big_breakpoint[] = { 0x7f, 0xe0, 0x00, 0x08 };
+constexpr gdb_byte little_breakpoint[] = { 0x08, 0x00, 0xe0, 0x7f };
 
 typedef BP_MANIPULATION_ENDIAN (little_breakpoint, big_breakpoint)
   rs6000_breakpoint;
 
 /* Instruction masks for displaced stepping.  */
-#define BRANCH_MASK 0xfc000000
+#define OP_MASK 0xfc000000
 #define BP_MASK 0xFC0007FE
 #define B_INSN 0x48000000
 #define BC_INSN 0x40000000
@@ -836,6 +853,17 @@ typedef BP_MANIPULATION_ENDIAN (little_breakpoint, big_breakpoint)
 #define STHCX_INSTRUCTION 0x7c0005ad
 #define STQCX_INSTRUCTION 0x7c00016d
 
+/* Instruction masks for single-stepping of addpcis/lnia.  */
+#define ADDPCIS_INSN            0x4c000004
+#define ADDPCIS_INSN_MASK       0xfc00003e
+#define ADDPCIS_TARGET_REGISTER 0x03F00000
+#define ADDPCIS_INSN_REGSHIFT   21
+
+#define PNOP_MASK 0xfff3ffff
+#define PNOP_INSN 0x07000000
+#define R_MASK 0x00100000
+#define R_ZERO 0x00000000
+
 /* 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 \
@@ -851,79 +879,124 @@ typedef BP_MANIPULATION_ENDIAN (little_breakpoint, big_breakpoint)
                                         || (insn & STORE_CONDITIONAL_MASK) == STHCX_INSTRUCTION \
                                         || (insn & STORE_CONDITIONAL_MASK) == STQCX_INSTRUCTION)
 
-typedef buf_displaced_step_closure ppc_displaced_step_closure;
+typedef buf_displaced_step_copy_insn_closure
+  ppc_displaced_step_copy_insn_closure;
 
 /* We can't displaced step atomic sequences.  */
 
-static struct displaced_step_closure *
+static displaced_step_copy_insn_closure_up
 ppc_displaced_step_copy_insn (struct gdbarch *gdbarch,
                              CORE_ADDR from, CORE_ADDR to,
                              struct regcache *regs)
 {
   size_t len = gdbarch_max_insn_length (gdbarch);
-  std::unique_ptr<ppc_displaced_step_closure> closure
-    (new ppc_displaced_step_closure (len));
+  std::unique_ptr<ppc_displaced_step_copy_insn_closure> closure
+    (new ppc_displaced_step_copy_insn_closure (len));
   gdb_byte *buf = closure->buf.data ();
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int insn;
 
-  read_memory (from, buf, len);
+  len = target_read (current_inferior()->top_target(), TARGET_OBJECT_MEMORY, NULL,
+                    buf, from, len);
+  if ((ssize_t) len < PPC_INSN_SIZE)
+    memory_error (TARGET_XFER_E_IO, from);
 
   insn = extract_signed_integer (buf, PPC_INSN_SIZE, byte_order);
 
+  /* Check for PNOP and for prefixed instructions with R=0.  Those
+     instructions are safe to displace.  Prefixed instructions with R=1
+     will read/write data to/from locations relative to the current PC.
+     We would not be able to fixup after an instruction has written data
+    into a displaced location, so decline to displace those instructions.  */
+  if ((insn & OP_MASK) == 1 << 26)
+    {
+      if (((insn & PNOP_MASK) != PNOP_INSN)
+         && ((insn & R_MASK) != R_ZERO))
+       {
+         displaced_debug_printf ("Not displacing prefixed instruction %08x at %s",
+                                 insn, paddress (gdbarch, from));
+         return NULL;
+       }
+    }
+  else
+    /* Non-prefixed instructions..  */
+    {
+      /* Set the instruction length to 4 to match the actual instruction
+        length.  */
+      len = 4;
+    }
+
   /* 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",
+      displaced_debug_printf ("can't displaced step atomic sequence at %s",
                              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);
-    }
+  displaced_debug_printf ("copy %s->%s: %s",
+                         paddress (gdbarch, from), paddress (gdbarch, to),
+                         displaced_step_dump_bytes (buf, len).c_str ());
 
-  return closure.release ();
+  /* This is a work around for a problem with g++ 4.8.  */
+  return displaced_step_copy_insn_closure_up (closure.release ());
 }
 
 /* Fix up the state of registers and memory after having single-stepped
    a displaced instruction.  */
 static void
 ppc_displaced_step_fixup (struct gdbarch *gdbarch,
-                         struct displaced_step_closure *closure_,
+                         struct displaced_step_copy_insn_closure *closure_,
                          CORE_ADDR from, CORE_ADDR to,
                          struct regcache *regs)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   /* Our closure is a copy of the instruction.  */
-  ppc_displaced_step_closure *closure = (ppc_displaced_step_closure *) closure_;
+  ppc_displaced_step_copy_insn_closure *closure
+    = (ppc_displaced_step_copy_insn_closure *) closure_;
   ULONGEST insn  = extract_unsigned_integer (closure->buf.data (),
                                             PPC_INSN_SIZE, byte_order);
-  ULONGEST opcode = 0;
+  ULONGEST opcode;
   /* Offset for non PC-relative instructions.  */
-  LONGEST offset = PPC_INSN_SIZE;
-
-  opcode = insn & BRANCH_MASK;
-
-  if (debug_displaced)
-    fprintf_unfiltered (gdb_stdlog,
-                       "displaced: (ppc) fixup (%s, %s)\n",
-                       paddress (gdbarch, from), paddress (gdbarch, to));
+  LONGEST offset;
 
+  opcode = insn & OP_MASK;
 
+  /* Set offset to 8 if this is an 8-byte (prefixed) instruction.  */
+  if ((opcode) == 1 << 26)
+    offset = 2 * PPC_INSN_SIZE;
+  else
+    offset = PPC_INSN_SIZE;
+
+  displaced_debug_printf ("(ppc) fixup (%s, %s)",
+                         paddress (gdbarch, from), paddress (gdbarch, to));
+
+  /* Handle the addpcis/lnia instruction.  */
+  if ((insn & ADDPCIS_INSN_MASK) == ADDPCIS_INSN)
+    {
+      LONGEST displaced_offset;
+      ULONGEST current_val;
+      /* Measure the displacement.  */
+      displaced_offset = from - to;
+      /* Identify the target register that was updated by the instruction.  */
+      int regnum = (insn & ADDPCIS_TARGET_REGISTER) >> ADDPCIS_INSN_REGSHIFT;
+      /* Read and update the target value.  */
+      regcache_cooked_read_unsigned (regs, regnum , &current_val);
+      displaced_debug_printf ("addpcis target regnum %d was %s now %s",
+                             regnum, paddress (gdbarch, current_val),
+                             paddress (gdbarch, current_val
+                                       + displaced_offset));
+      regcache_cooked_write_unsigned (regs, regnum,
+                                       current_val + displaced_offset);
+      /* point the PC back at the non-displaced instruction.  */
+      regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch),
+                                   from + offset);
+    }
   /* Handle PC-relative branch instructions.  */
-  if (opcode == B_INSN || opcode == BC_INSN || opcode == BXL_INSN)
+  else if (opcode == B_INSN || opcode == BC_INSN || opcode == BXL_INSN)
     {
       ULONGEST current_pc;
 
@@ -941,13 +1014,11 @@ ppc_displaced_step_fixup (struct gdbarch *gdbarch,
          if (!(insn & 0x2))
            {
              /* PC-relative addressing is being used in the branch.  */
-             if (debug_displaced)
-               fprintf_unfiltered
-                 (gdb_stdlog,
-                  "displaced: (ppc) branch instruction: %s\n"
-                  "displaced: (ppc) adjusted PC from %s to %s\n",
-                  paddress (gdbarch, insn), paddress (gdbarch, current_pc),
-                  paddress (gdbarch, from + offset));
+             displaced_debug_printf ("(ppc) branch instruction: %s",
+                                     paddress (gdbarch, insn));
+             displaced_debug_printf ("(ppc) adjusted PC from %s to %s",
+                                     paddress (gdbarch, current_pc),
+                                     paddress (gdbarch, from + offset));
 
              regcache_cooked_write_unsigned (regs,
                                              gdbarch_pc_regnum (gdbarch),
@@ -971,13 +1042,12 @@ ppc_displaced_step_fixup (struct gdbarch *gdbarch,
       if (insn & 0x1)
        {
          /* Link register needs to be set to the next instruction's PC.  */
+         ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
          regcache_cooked_write_unsigned (regs,
-                                         gdbarch_tdep (gdbarch)->ppc_lr_regnum,
+                                         tdep->ppc_lr_regnum,
                                          from + PPC_INSN_SIZE);
-         if (debug_displaced)
-               fprintf_unfiltered (gdb_stdlog,
-                                   "displaced: (ppc) adjusted LR to %s\n",
-                                   paddress (gdbarch, from + PPC_INSN_SIZE));
+         displaced_debug_printf ("(ppc) adjusted LR to %s",
+                                 paddress (gdbarch, from + PPC_INSN_SIZE));
 
        }
     }
@@ -986,18 +1056,67 @@ ppc_displaced_step_fixup (struct gdbarch *gdbarch,
   else if ((insn & BP_MASK) == BP_INSN)
     regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch), from);
   else
-  /* Handle any other instructions that do not fit in the categories above.  */
-    regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch),
-                                   from + offset);
+    {
+      /* Handle any other instructions that do not fit in the categories
+         above.  */
+      regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch),
+                                     from + offset);
+    }
+}
+
+/* Implementation of gdbarch_displaced_step_prepare.  */
+
+static displaced_step_prepare_status
+ppc_displaced_step_prepare  (gdbarch *arch, thread_info *thread,
+                            CORE_ADDR &displaced_pc)
+{
+  ppc_inferior_data *per_inferior = get_ppc_per_inferior (thread->inf);
+
+  if (!per_inferior->disp_step_buf.has_value ())
+    {
+      /* Figure out where the displaced step buffer is.  */
+      CORE_ADDR disp_step_buf_addr
+       = displaced_step_at_entry_point (thread->inf->gdbarch);
+
+      per_inferior->disp_step_buf.emplace (disp_step_buf_addr);
+    }
+
+  return per_inferior->disp_step_buf->prepare (thread, displaced_pc);
+}
+
+/* Implementation of gdbarch_displaced_step_finish.  */
+
+static displaced_step_finish_status
+ppc_displaced_step_finish (gdbarch *arch, thread_info *thread,
+                          gdb_signal sig)
+{
+  ppc_inferior_data *per_inferior = get_ppc_per_inferior (thread->inf);
+
+  gdb_assert (per_inferior->disp_step_buf.has_value ());
+
+  return per_inferior->disp_step_buf->finish (arch, thread, sig);
+}
+
+/* Implementation of gdbarch_displaced_step_restore_all_in_ptid.  */
+
+static void
+ppc_displaced_step_restore_all_in_ptid (inferior *parent_inf, ptid_t ptid)
+{
+  ppc_inferior_data *per_inferior = ppc_inferior_data_key.get (parent_inf);
+
+  if (per_inferior == nullptr
+      || !per_inferior->disp_step_buf.has_value ())
+    return;
+
+  per_inferior->disp_step_buf->restore_in_ptid (ptid);
 }
 
 /* Always use hardware single-stepping to execute the
    displaced instruction.  */
-static int
-ppc_displaced_step_hw_singlestep (struct gdbarch *gdbarch,
-                                 struct displaced_step_closure *closure)
+static bool
+ppc_displaced_step_hw_singlestep (struct gdbarch *gdbarch)
 {
-  return 1;
+  return true;
 }
 
 /* Checks for an atomic sequence of instructions beginning with a
@@ -1028,20 +1147,23 @@ ppc_deal_with_atomic_sequence (struct regcache *regcache)
      instructions.  */
   for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count)
     {
-      loc += PPC_INSN_SIZE;
+      if ((insn & OP_MASK) == 1 << 26)
+       loc += 2 * PPC_INSN_SIZE;
+      else
+       loc += PPC_INSN_SIZE;
       insn = read_memory_integer (loc, PPC_INSN_SIZE, byte_order);
 
       /* Assume that there is at most one conditional branch in the atomic
-         sequence.  If a conditional branch is found, put a breakpoint in 
-         its destination address.  */
-      if ((insn & BRANCH_MASK) == BC_INSN)
-        {
-          int immediate = ((insn & 0xfffc) ^ 0x8000) - 0x8000;
-          int absolute = insn & 2;
-
-          if (bc_insn_count >= 1)
-            return {}; /* More than one conditional branch found, fallback
-                          to the standard single-step code.  */
+        sequence.  If a conditional branch is found, put a breakpoint in 
+        its destination address.  */
+      if ((insn & OP_MASK) == BC_INSN)
+       {
+         int immediate = ((insn & 0xfffc) ^ 0x8000) - 0x8000;
+         int absolute = insn & 2;
+
+         if (bc_insn_count >= 1)
+           return {}; /* More than one conditional branch found, fallback
+                         to the standard single-step code.  */
  
          if (absolute)
            breaks[1] = immediate;
@@ -1050,10 +1172,10 @@ ppc_deal_with_atomic_sequence (struct regcache *regcache)
 
          bc_insn_count++;
          last_breakpoint++;
-        }
+       }
 
       if (IS_STORE_CONDITIONAL_INSN (insn))
-        break;
+       break;
     }
 
   /* Assume that the atomic sequence ends with a Store Conditional
@@ -1111,12 +1233,12 @@ store_param_on_stack_p (unsigned long op, int framep, int *r0_contains_arg)
       const int ry_regno = GET_SRC_REG (op);
 
       if (rx_regno == 0 && ry_regno >= 3 && ry_regno <= 10)
-        {
-          *r0_contains_arg = 1;
-          return 1;
-        }
+       {
+         *r0_contains_arg = 1;
+         return 1;
+       }
       else
-        return 0;
+       return 0;
     }
 
   /* Save a General Purpose Register on stack.  */
@@ -1129,7 +1251,7 @@ store_param_on_stack_p (unsigned long op, int framep, int *r0_contains_arg)
 
       return (rx_regno >= 3 && rx_regno <= 10);
     }
-           
+          
   /* Save a General Purpose Register on stack via the Frame Pointer.  */
 
   if (framep &&
@@ -1138,11 +1260,11 @@ store_param_on_stack_p (unsigned long op, int framep, int *r0_contains_arg)
        (op & 0xfc1f0000) == 0xd81f0000))      /* stfd Rx,NUM(r31) */
     {
       /* Rx: Usually, only r3 - r10 are used for parameter passing.
-         However, the compiler sometimes uses r0 to hold an argument.  */
+        However, the compiler sometimes uses r0 to hold an argument.  */
       const int rx_regno = GET_SRC_REG (op);
 
       return ((rx_regno >= 3 && rx_regno <= 10)
-              || (rx_regno == 0 && *r0_contains_arg));
+             || (rx_regno == 0 && *r0_contains_arg));
     }
 
   if ((op & 0xfc1f0000) == 0xfc010000)         /* frsp, fp?,NUM(r1) */
@@ -1234,7 +1356,7 @@ store_insn_p (unsigned long op, unsigned long rs,
    this masking operation is equal to BL_INSTRUCTION, then the opcode in
    question is a ``bl'' instruction.
    
-   BL_DISPLACMENT_MASK is anded with the opcode in order to extract
+   BL_DISPLACEMENT_MASK is anded with the opcode in order to extract
    the branch displacement.  */
 
 #define BL_MASK 0xfc000001
@@ -1268,150 +1390,150 @@ rs6000_skip_stack_check (struct gdbarch *gdbarch, const CORE_ADDR start_pc)
   unsigned long op = rs6000_fetch_instruction (gdbarch, pc);
 
   /* First possible sequence: A small number of probes.
-         stw 0, -<some immediate>(1)
-         [repeat this instruction any (small) number of times].  */
+        stw 0, -<some immediate>(1)
+        [repeat this instruction any (small) number of times].  */
   
   if ((op & 0xffff0000) == 0x90010000)
     {
       while ((op & 0xffff0000) == 0x90010000)
-        {
-          pc = pc + 4;
-          op = rs6000_fetch_instruction (gdbarch, pc);
-        }
+       {
+         pc = pc + 4;
+         op = rs6000_fetch_instruction (gdbarch, pc);
+       }
       return pc;
     }
 
   /* Second sequence: A probing loop.
-         addi 12,1,-<some immediate>
-         lis 0,-<some immediate>
-         [possibly ori 0,0,<some immediate>]
-         add 0,12,0
-         cmpw 0,12,0
-         beq 0,<disp>
-         addi 12,12,-<some immediate>
-         stw 0,0(12)
-         b <disp>
-         [possibly one last probe: stw 0,<some immediate>(12)].  */
+        addi 12,1,-<some immediate>
+        lis 0,-<some immediate>
+        [possibly ori 0,0,<some immediate>]
+        add 0,12,0
+        cmpw 0,12,0
+        beq 0,<disp>
+        addi 12,12,-<some immediate>
+        stw 0,0(12)
+        b <disp>
+        [possibly one last probe: stw 0,<some immediate>(12)].  */
 
   while (1)
     {
       /* addi 12,1,-<some immediate> */
       if ((op & 0xffff0000) != 0x39810000)
-        break;
+       break;
 
       /* lis 0,-<some immediate> */
       pc = pc + 4;
       op = rs6000_fetch_instruction (gdbarch, pc);
       if ((op & 0xffff0000) != 0x3c000000)
-        break;
+       break;
 
       pc = pc + 4;
       op = rs6000_fetch_instruction (gdbarch, pc);
       /* [possibly ori 0,0,<some immediate>] */
       if ((op & 0xffff0000) == 0x60000000)
-        {
-          pc = pc + 4;
-          op = rs6000_fetch_instruction (gdbarch, pc);
-        }
+       {
+         pc = pc + 4;
+         op = rs6000_fetch_instruction (gdbarch, pc);
+       }
       /* add 0,12,0 */
       if (op != 0x7c0c0214)
-        break;
+       break;
 
       /* cmpw 0,12,0 */
       pc = pc + 4;
       op = rs6000_fetch_instruction (gdbarch, pc);
       if (op != 0x7c0c0000)
-        break;
+       break;
 
       /* beq 0,<disp> */
       pc = pc + 4;
       op = rs6000_fetch_instruction (gdbarch, pc);
       if ((op & 0xff9f0001) != 0x41820000)
-        break;
+       break;
 
       /* addi 12,12,-<some immediate> */
       pc = pc + 4;
       op = rs6000_fetch_instruction (gdbarch, pc);
       if ((op & 0xffff0000) != 0x398c0000)
-        break;
+       break;
 
       /* stw 0,0(12) */
       pc = pc + 4;
       op = rs6000_fetch_instruction (gdbarch, pc);
       if (op != 0x900c0000)
-        break;
+       break;
 
       /* b <disp> */
       pc = pc + 4;
       op = rs6000_fetch_instruction (gdbarch, pc);
       if ((op & 0xfc000001) != 0x48000000)
-        break;
+       break;
 
       /* [possibly one last probe: stw 0,<some immediate>(12)].  */
       pc = pc + 4;
       op = rs6000_fetch_instruction (gdbarch, pc);
       if ((op & 0xffff0000) == 0x900c0000)
-        {
-          pc = pc + 4;
-          op = rs6000_fetch_instruction (gdbarch, pc);
-        }
+       {
+         pc = pc + 4;
+         op = rs6000_fetch_instruction (gdbarch, pc);
+       }
 
       /* We found a valid stack-check sequence, return the new PC.  */
       return pc;
     }
 
-  /* Third sequence: No probe; instead, a comparizon between the stack size
+  /* Third sequence: No probe; instead, a comparison between the stack size
      limit (saved in a run-time global variable) and the current stack
      pointer:
 
-        addi 0,1,-<some immediate>
-        lis 12,__gnat_stack_limit@ha
-        lwz 12,__gnat_stack_limit@l(12)
-        twllt 0,12
+       addi 0,1,-<some immediate>
+       lis 12,__gnat_stack_limit@ha
+       lwz 12,__gnat_stack_limit@l(12)
+       twllt 0,12
 
      or, with a small variant in the case of a bigger stack frame:
-        addis 0,1,<some immediate>
-        addic 0,0,-<some immediate>
-        lis 12,__gnat_stack_limit@ha
-        lwz 12,__gnat_stack_limit@l(12)
-        twllt 0,12
+       addis 0,1,<some immediate>
+       addic 0,0,-<some immediate>
+       lis 12,__gnat_stack_limit@ha
+       lwz 12,__gnat_stack_limit@l(12)
+       twllt 0,12
   */
   while (1)
     {
       /* addi 0,1,-<some immediate> */
       if ((op & 0xffff0000) != 0x38010000)
-        {
-          /* small stack frame variant not recognized; try the
-             big stack frame variant: */
+       {
+         /* small stack frame variant not recognized; try the
+            big stack frame variant: */
 
-          /* addis 0,1,<some immediate> */
-          if ((op & 0xffff0000) != 0x3c010000)
-            break;
+         /* addis 0,1,<some immediate> */
+         if ((op & 0xffff0000) != 0x3c010000)
+           break;
 
-          /* addic 0,0,-<some immediate> */
-          pc = pc + 4;
-          op = rs6000_fetch_instruction (gdbarch, pc);
-          if ((op & 0xffff0000) != 0x30000000)
-            break;
-        }
+         /* addic 0,0,-<some immediate> */
+         pc = pc + 4;
+         op = rs6000_fetch_instruction (gdbarch, pc);
+         if ((op & 0xffff0000) != 0x30000000)
+           break;
+       }
 
       /* lis 12,<some immediate> */
       pc = pc + 4;
       op = rs6000_fetch_instruction (gdbarch, pc);
       if ((op & 0xffff0000) != 0x3d800000)
-        break;
+       break;
       
       /* lwz 12,<some immediate>(12) */
       pc = pc + 4;
       op = rs6000_fetch_instruction (gdbarch, pc);
       if ((op & 0xffff0000) != 0x818c0000)
-        break;
+       break;
 
       /* twllt 0,12 */
       pc = pc + 4;
       op = rs6000_fetch_instruction (gdbarch, pc);
       if ((op & 0xfffffffe) != 0x7c406008)
-        break;
+       break;
 
       /* We found a valid stack-check sequence, return the new PC.  */
       return pc;
@@ -1468,7 +1590,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
   int num_skip_non_prologue_insns = 0;
   int r0_contains_arg = 0;
   const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (gdbarch);
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
 
   memset (fdata, 0, sizeof (struct rs6000_framedata));
@@ -1488,7 +1610,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
   for (;; pc += 4)
     {
       /* Sometimes it isn't clear if an instruction is a prologue
-         instruction or not.  When we encounter one of these ambiguous
+        instruction or not.  When we encounter one of these ambiguous
         cases, we'll set prev_insn_was_prologue_insn to 0 (false).
         Otherwise, we'll assume that it really is a prologue instruction.  */
       if (prev_insn_was_prologue_insn)
@@ -1526,15 +1648,15 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
             ones.  */
          if (lr_reg == -1)
            lr_reg = (op & 0x03e00000) >> 21;
-          if (lr_reg == 0)
-            r0_contains_arg = 0;
+         if (lr_reg == 0)
+           r0_contains_arg = 0;
          continue;
        }
       else if ((op & 0xfc1fffff) == 0x7c000026)
        {                       /* mfcr Rx */
          cr_reg = (op & 0x03e00000) >> 21;
-          if (cr_reg == 0)
-            r0_contains_arg = 0;
+         if (cr_reg == 0)
+           r0_contains_arg = 0;
          continue;
 
        }
@@ -1583,7 +1705,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
          continue;
        }
       else if (op == 0x60000000)
-        {
+       {
          /* nop */
          /* Allow nops in the prologue, but do not consider them to
             be part of the prologue unless followed by other prologue
@@ -1596,7 +1718,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
        {                       /* addis 0,0,NUM, used for >= 32k frames */
          fdata->offset = (op & 0x0000ffff) << 16;
          fdata->frameless = 0;
-          r0_contains_arg = 0;
+         r0_contains_arg = 0;
          continue;
 
        }
@@ -1604,7 +1726,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
        {                       /* ori 0,0,NUM, 2nd half of >= 32k frames */
          fdata->offset |= (op & 0x0000ffff);
          fdata->frameless = 0;
-          r0_contains_arg = 0;
+         r0_contains_arg = 0;
          continue;
 
        }
@@ -1683,7 +1805,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
 
          /* If the return address has already been saved, we can skip
             calls to blrl (for PIC).  */
-          if (lr_reg != -1 && bl_to_blrl_insn_p (pc, op, byte_order))
+         if (lr_reg != -1 && bl_to_blrl_insn_p (pc, op, byte_order))
            {
              fdata->used_bl = 1;
              continue;
@@ -1741,12 +1863,12 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
          continue;
        }
       else if ((op & 0xffff0000) == 0x38210000)
-       {                       /* addi r1,r1,SIMM */
-         fdata->frameless = 0;
-         fdata->offset += SIGNED_SHORT (op);
-         offset = fdata->offset;
-         continue;
-       }
+       {                       /* addi r1,r1,SIMM */
+         fdata->frameless = 0;
+         fdata->offset += SIGNED_SHORT (op);
+         offset = fdata->offset;
+         continue;
+       }
       /* Load up minimal toc pointer.  Do not treat an epilogue restore
         of r31 as a minimal TOC load.  */
       else if (((op >> 22) == 0x20f    ||      /* l r31,... or l r30,...  */
@@ -1758,12 +1880,12 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
          continue;
 
          /* move parameters from argument registers to local variable
-             registers */
-       }
+            registers */
+       }
       else if ((op & 0xfc0007fe) == 0x7c000378 &&      /* mr(.)  Rx,Ry */
-               (((op >> 21) & 31) >= 3) &&              /* R3 >= Ry >= R10 */
-               (((op >> 21) & 31) <= 10) &&
-               ((long) ((op >> 16) & 31)
+              (((op >> 21) & 31) >= 3) &&              /* R3 >= Ry >= R10 */
+              (((op >> 21) & 31) <= 10) &&
+              ((long) ((op >> 16) & 31)
                >= fdata->saved_gpr)) /* Rx: local var reg */
        {
          continue;
@@ -1772,7 +1894,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
        }
       /* Move parameters from argument registers to temporary register.  */
       else if (store_param_on_stack_p (op, framep, &r0_contains_arg))
-        {
+       {
          continue;
 
          /* Set up frame pointer */
@@ -1817,28 +1939,28 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
         mtspr SPR256 Rn == 011111 nnnnn 0000001000 01110100110  */
       else if ((op & 0xfc1fffff) == 0x7c0042a6)    /* mfvrsave Rn */
        {
-          vrsave_reg = GET_SRC_REG (op);
+         vrsave_reg = GET_SRC_REG (op);
          continue;
        }
       else if ((op & 0xfc1fffff) == 0x7c0043a6)     /* mtvrsave Rn */
-        {
-          continue;
-        }
+       {
+         continue;
+       }
       /* Store the register where vrsave was saved to onto the stack:
-         rS is the register where vrsave was stored in a previous
+        rS is the register where vrsave was stored in a previous
         instruction.  */
       /* 100100 sssss 00001 dddddddd dddddddd */
       else if ((op & 0xfc1f0000) == 0x90010000)     /* stw rS, d(r1) */
-        {
-          if (vrsave_reg == GET_SRC_REG (op))
+       {
+         if (vrsave_reg == GET_SRC_REG (op))
            {
              fdata->vrsave_offset = SIGNED_SHORT (op) + offset;
              vrsave_reg = -1;
            }
-          continue;
-        }
+         continue;
+       }
       /* Compute the new value of vrsave, by modifying the register
-         where vrsave was saved to.  */
+        where vrsave was saved to.  */
       else if (((op & 0xfc000000) == 0x64000000)    /* oris Ra, Rs, UIMM */
               || ((op & 0xfc000000) == 0x60000000))/* ori Ra, Rs, UIMM */
        {
@@ -1850,22 +1972,22 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
       /* 001110 00000 00000 iiii iiii iiii iiii  */
       /* 001110 01110 00000 iiii iiii iiii iiii  */
       else if ((op & 0xffff0000) == 0x38000000         /* li r0, SIMM */
-               || (op & 0xffff0000) == 0x39c00000)     /* li r14, SIMM */
+              || (op & 0xffff0000) == 0x39c00000)     /* li r14, SIMM */
        {
-          if ((op & 0xffff0000) == 0x38000000)
-            r0_contains_arg = 0;
+         if ((op & 0xffff0000) == 0x38000000)
+           r0_contains_arg = 0;
          li_found_pc = pc;
          vr_saved_offset = SIGNED_SHORT (op);
 
-          /* This insn by itself is not part of the prologue, unless
-             if part of the pair of insns mentioned above.  So do not
-             record this insn as part of the prologue yet.  */
-          prev_insn_was_prologue_insn = 0;
+         /* This insn by itself is not part of the prologue, unless
+            if part of the pair of insns mentioned above.  So do not
+            record this insn as part of the prologue yet.  */
+         prev_insn_was_prologue_insn = 0;
        }
       /* Store vector register S at (r31+r0) aligned to 16 bytes.  */      
       /* 011111 sssss 11111 00000 00111001110 */
       else if ((op & 0xfc1fffff) == 0x7c1f01ce)   /* stvx Vs, R31, R0 */
-        {
+       {
          if (pc == (li_found_pc + 4))
            {
              vr_reg = GET_SRC_REG (op);
@@ -1886,16 +2008,16 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
 
       /* Start BookE related instructions.  */
       /* Store gen register S at (r31+uimm).
-         Any register less than r13 is volatile, so we don't care.  */
+        Any register less than r13 is volatile, so we don't care.  */
       /* 000100 sssss 11111 iiiii 01100100001 */
       else if (arch_info->mach == bfd_mach_ppc_e500
               && (op & 0xfc1f07ff) == 0x101f0321)    /* evstdd Rs,uimm(R31) */
        {
-          if ((op & 0x03e00000) >= 0x01a00000) /* Rs >= r13 */
+         if ((op & 0x03e00000) >= 0x01a00000)  /* Rs >= r13 */
            {
-              unsigned int imm;
+             unsigned int imm;
              ev_reg = GET_SRC_REG (op);
-              imm = (op >> 11) & 0x1f;
+             imm = (op >> 11) & 0x1f;
              ev_offset = imm * 8;
              /* If this is the first vector reg to be saved, or if
                 it has a lower number than others previously seen,
@@ -1906,40 +2028,40 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
                  fdata->ev_offset = ev_offset + offset;
                }
            }
-          continue;
-        }
+         continue;
+       }
       /* Store gen register rS at (r1+rB).  */
       /* 000100 sssss 00001 bbbbb 01100100000 */
       else if (arch_info->mach == bfd_mach_ppc_e500
               && (op & 0xffe007ff) == 0x13e00320)     /* evstddx RS,R1,Rb */
        {
-          if (pc == (li_found_pc + 4))
-            {
-              ev_reg = GET_SRC_REG (op);
+         if (pc == (li_found_pc + 4))
+           {
+             ev_reg = GET_SRC_REG (op);
              /* If this is the first vector reg to be saved, or if
-                 it has a lower number than others previously seen,
-                 reupdate the frame info.  */
-              /* We know the contents of rB from the previous instruction.  */
+                it has a lower number than others previously seen,
+                reupdate the frame info.  */
+             /* We know the contents of rB from the previous instruction.  */
              if (fdata->saved_ev == -1 || fdata->saved_ev > ev_reg)
                {
-                  fdata->saved_ev = ev_reg;
-                  fdata->ev_offset = vr_saved_offset + offset;
+                 fdata->saved_ev = ev_reg;
+                 fdata->ev_offset = vr_saved_offset + offset;
                }
              vr_saved_offset = -1;
              ev_reg = -1;
              li_found_pc = 0;
-            }
-          continue;
-        }
+           }
+         continue;
+       }
       /* Store gen register r31 at (rA+uimm).  */
       /* 000100 11111 aaaaa iiiii 01100100001 */
       else if (arch_info->mach == bfd_mach_ppc_e500
               && (op & 0xffe007ff) == 0x13e00321)   /* evstdd R31,Ra,UIMM */
-        {
-          /* Wwe know that the source register is 31 already, but
-             it can't hurt to compute it.  */
+       {
+         /* Wwe know that the source register is 31 already, but
+            it can't hurt to compute it.  */
          ev_reg = GET_SRC_REG (op);
-          ev_offset = ((op >> 11) & 0x1f) * 8;
+         ev_offset = ((op >> 11) & 0x1f) * 8;
          /* If this is the first vector reg to be saved, or if
             it has a lower number than others previously seen,
             reupdate the frame info.  */
@@ -1950,23 +2072,23 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
            }
 
          continue;
-       }
+       }
       /* Store gen register S at (r31+r0).
-         Store param on stack when offset from SP bigger than 4 bytes.  */
+        Store param on stack when offset from SP bigger than 4 bytes.  */
       /* 000100 sssss 11111 00000 01100100000 */
       else if (arch_info->mach == bfd_mach_ppc_e500
               && (op & 0xfc1fffff) == 0x101f0320)     /* evstddx Rs,R31,R0 */
        {
-          if (pc == (li_found_pc + 4))
-            {
-              if ((op & 0x03e00000) >= 0x01a00000)
+         if (pc == (li_found_pc + 4))
+           {
+             if ((op & 0x03e00000) >= 0x01a00000)
                {
                  ev_reg = GET_SRC_REG (op);
                  /* If this is the first vector reg to be saved, or if
                     it has a lower number than others previously seen,
                     reupdate the frame info.  */
-                  /* We know the contents of r0 from the previous
-                     instruction.  */
+                 /* We know the contents of r0 from the previous
+                    instruction.  */
                  if (fdata->saved_ev == -1 || fdata->saved_ev > ev_reg)
                    {
                      fdata->saved_ev = ev_reg;
@@ -1977,7 +2099,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
              vr_saved_offset = -1;
              li_found_pc = 0;
              continue;
-            }
+           }
        }
       /* End BookE related instructions.  */
 
@@ -2006,6 +2128,12 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
            /* Never skip branches.  */
            break;
 
+         /* Test based on opcode and mask values of
+            powerpc_opcodes[svc..svcla] in opcodes/ppc-opc.c.  */
+         if ((op & 0xffff0000) == 0x44000000)
+           /* Never skip system calls.  */
+           break;
+
          if (num_skip_non_prologue_insns++ > max_skip_non_prologue_insns)
            /* Do not scan too many insns, scanning insns is expensive with
               remote targets.  */
@@ -2116,12 +2244,12 @@ rs6000_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
       struct bound_minimal_symbol s = lookup_minimal_symbol_by_pc (call_dest);
 
       /* We check for ___eabi (three leading underscores) in addition
-         to __eabi in case the GCC option "-fleading-underscore" was
+        to __eabi in case the GCC option "-fleading-underscore" was
         used to compile the program.  */
       if (s.minsym != NULL
-          && MSYMBOL_LINKAGE_NAME (s.minsym) != NULL
-         && (strcmp (MSYMBOL_LINKAGE_NAME (s.minsym), "__eabi") == 0
-             || strcmp (MSYMBOL_LINKAGE_NAME (s.minsym), "___eabi") == 0))
+         && s.minsym->linkage_name () != NULL
+         && (strcmp (s.minsym->linkage_name (), "__eabi") == 0
+             || strcmp (s.minsym->linkage_name (), "___eabi") == 0))
        pc += 4;
     }
   return pc;
@@ -2182,7 +2310,7 @@ static CORE_ADDR
 rs6000_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   unsigned int ii, op;
   int rel;
@@ -2205,7 +2333,7 @@ rs6000_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
   msymbol = lookup_minimal_symbol_by_pc (pc);
   if (msymbol.minsym
       && rs6000_in_solib_return_trampoline (gdbarch, pc,
-                                           MSYMBOL_LINKAGE_NAME (msymbol.minsym)))
+                                           msymbol.minsym->linkage_name ()))
     {
       /* Double-check that the third instruction from PC is relative "b".  */
       op = read_memory_integer (pc + 8, 4, byte_order);
@@ -2240,7 +2368,7 @@ rs6000_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
 static struct type *
 rs6000_builtin_type_vec64 (struct gdbarch *gdbarch)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   if (!tdep->ppc_builtin_type_vec64)
     {
@@ -2272,8 +2400,8 @@ rs6000_builtin_type_vec64 (struct gdbarch *gdbarch)
       append_composite_type_field (t, "v8_int8",
                                   init_vector_type (bt->builtin_int8, 8));
 
-      TYPE_VECTOR (t) = 1;
-      TYPE_NAME (t) = "ppc_builtin_type_vec64";
+      t->set_is_vector (true);
+      t->set_name ("ppc_builtin_type_vec64");
       tdep->ppc_builtin_type_vec64 = t;
     }
 
@@ -2285,7 +2413,7 @@ rs6000_builtin_type_vec64 (struct gdbarch *gdbarch)
 static struct type *
 rs6000_builtin_type_vec128 (struct gdbarch *gdbarch)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   if (!tdep->ppc_builtin_type_vec128)
     {
@@ -2294,6 +2422,7 @@ rs6000_builtin_type_vec128 (struct gdbarch *gdbarch)
       /* The type we're building is this
 
         type = union __ppc_builtin_type_vec128 {
+            float128_t float128;
             uint128_t uint128;
             double v2_double[2];
             float v4_float[4];
@@ -2303,10 +2432,15 @@ rs6000_builtin_type_vec128 (struct gdbarch *gdbarch)
         }
       */
 
+      /* PPC specific type for IEEE 128-bit float field */
+      struct type *t_float128
+       = arch_float_type (gdbarch, 128, "float128_t", floatformats_ia64_quad);
+
       struct type *t;
 
       t = arch_composite_type (gdbarch,
                               "__ppc_builtin_type_vec128", TYPE_CODE_UNION);
+      append_composite_type_field (t, "float128", t_float128);
       append_composite_type_field (t, "uint128", bt->builtin_uint128);
       append_composite_type_field (t, "v2_double",
                                   init_vector_type (bt->builtin_double, 2));
@@ -2319,8 +2453,8 @@ rs6000_builtin_type_vec128 (struct gdbarch *gdbarch)
       append_composite_type_field (t, "v16_int8",
                                   init_vector_type (bt->builtin_int8, 16));
 
-      TYPE_VECTOR (t) = 1;
-      TYPE_NAME (t) = "ppc_builtin_type_vec128";
+      t->set_is_vector (true);
+      t->set_name ("ppc_builtin_type_vec128");
       tdep->ppc_builtin_type_vec128 = t;
     }
 
@@ -2333,7 +2467,7 @@ rs6000_builtin_type_vec128 (struct gdbarch *gdbarch)
 static const char *
 rs6000_register_name (struct gdbarch *gdbarch, int regno)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   /* The upper half "registers" have names in the XML description,
      but we present only the low GPRs and the full 64-bit registers
@@ -2471,7 +2605,7 @@ rs6000_register_name (struct gdbarch *gdbarch, int regno)
 static struct type *
 rs6000_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   /* These are the e500 pseudo-registers.  */
   if (IS_SPE_PSEUDOREG (tdep, regnum))
@@ -2510,7 +2644,7 @@ static int
 rs6000_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
                                   struct reggroup *group)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   if (IS_V_ALIAS_PSEUDOREG (tdep, regnum))
     return 0;
@@ -2525,31 +2659,33 @@ static int
 rs6000_convert_register_p (struct gdbarch *gdbarch, int regnum,
                           struct type *type)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   return (tdep->ppc_fp0_regnum >= 0
          && regnum >= tdep->ppc_fp0_regnum
          && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs
-         && TYPE_CODE (type) == TYPE_CODE_FLT
+         && type->code () == TYPE_CODE_FLT
          && TYPE_LENGTH (type)
             != TYPE_LENGTH (builtin_type (gdbarch)->builtin_double));
 }
 
 static int
 rs6000_register_to_value (struct frame_info *frame,
-                          int regnum,
-                          struct type *type,
-                          gdb_byte *to,
+                         int regnum,
+                         struct type *type,
+                         gdb_byte *to,
                          int *optimizedp, int *unavailablep)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   gdb_byte from[PPC_MAX_REGISTER_SIZE];
   
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
+  gdb_assert (type->code () == TYPE_CODE_FLT);
 
   if (!get_frame_register_bytes (frame, regnum, 0,
-                                register_size (gdbarch, regnum),
-                                from, optimizedp, unavailablep))
+                                gdb::make_array_view (from,
+                                                      register_size (gdbarch,
+                                                                     regnum)),
+                                optimizedp, unavailablep))
     return 0;
 
   target_float_convert (from, builtin_type (gdbarch)->builtin_double,
@@ -2560,14 +2696,14 @@ rs6000_register_to_value (struct frame_info *frame,
 
 static void
 rs6000_value_to_register (struct frame_info *frame,
-                          int regnum,
-                          struct type *type,
-                          const gdb_byte *from)
+                         int regnum,
+                         struct type *type,
+                         const gdb_byte *from)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   gdb_byte to[PPC_MAX_REGISTER_SIZE];
 
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
+  gdb_assert (type->code () == TYPE_CODE_FLT);
 
   target_float_convert (from, type,
                        to, builtin_type (gdbarch)->builtin_double);
@@ -2608,7 +2744,7 @@ e500_move_ev_register (move_ev_register_func move,
                       struct regcache *regcache, int ev_reg, void *buffer)
 {
   struct gdbarch *arch = regcache->arch ();
-  struct gdbarch_tdep *tdep = gdbarch_tdep (arch); 
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (arch);
   int reg_index;
   gdb_byte *byte_buffer = (gdb_byte *) buffer;
   enum register_status status;
@@ -2649,7 +2785,7 @@ e500_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
                           int ev_reg, gdb_byte *buffer)
 {
   struct gdbarch *arch = regcache->arch ();
-  struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int reg_index;
   enum register_status status;
 
@@ -2690,7 +2826,7 @@ static enum register_status
 dfp_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
                           int reg_nr, gdb_byte *buffer)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int reg_index, fp0;
   enum register_status status;
 
@@ -2730,7 +2866,7 @@ static void
 dfp_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
                            int reg_nr, const gdb_byte *buffer)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int reg_index, fp0;
 
   if (IS_DFP_PSEUDOREG (tdep, reg_nr))
@@ -2767,7 +2903,7 @@ v_alias_pseudo_register_read (struct gdbarch *gdbarch,
                              readable_regcache *regcache, int reg_nr,
                              gdb_byte *buffer)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   gdb_assert (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr));
 
   return regcache->raw_read (tdep->ppc_vr0_regnum
@@ -2782,7 +2918,7 @@ v_alias_pseudo_register_write (struct gdbarch *gdbarch,
                               struct regcache *regcache,
                               int reg_nr, const gdb_byte *buffer)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   gdb_assert (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr));
 
   regcache->raw_write (tdep->ppc_vr0_regnum
@@ -2794,7 +2930,7 @@ static enum register_status
 vsx_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
                           int reg_nr, gdb_byte *buffer)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int reg_index, vr0, fp0, vsr0_upper;
   enum register_status status;
 
@@ -2842,7 +2978,7 @@ static void
 vsx_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
                            int reg_nr, const gdb_byte *buffer)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int reg_index, vr0, fp0, vsr0_upper;
 
   if (IS_VSX_PSEUDOREG (tdep, reg_nr))
@@ -2884,7 +3020,7 @@ static enum register_status
 efp_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
                           int reg_nr, gdb_byte *buffer)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int reg_index, vr0;
 
   if (IS_EFP_PSEUDOREG (tdep, reg_nr))
@@ -2913,7 +3049,7 @@ static void
 efp_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
                            int reg_nr, const gdb_byte *buffer)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int reg_index, vr0;
   int offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8;
 
@@ -2949,7 +3085,7 @@ rs6000_pseudo_register_read (struct gdbarch *gdbarch,
                             int reg_nr, gdb_byte *buffer)
 {
   struct gdbarch *regcache_arch = regcache->arch ();
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   gdb_assert (regcache_arch == gdbarch);
 
@@ -2980,7 +3116,7 @@ rs6000_pseudo_register_write (struct gdbarch *gdbarch,
                              int reg_nr, const gdb_byte *buffer)
 {
   struct gdbarch *regcache_arch = regcache->arch ();
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   gdb_assert (regcache_arch == gdbarch);
 
@@ -3011,7 +3147,7 @@ static void
 dfp_ax_pseudo_register_collect (struct gdbarch *gdbarch,
                                struct agent_expr *ax, int reg_nr)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int reg_index, fp0;
 
   if (IS_DFP_PSEUDOREG (tdep, reg_nr))
@@ -3038,7 +3174,7 @@ static void
 v_alias_pseudo_register_collect (struct gdbarch *gdbarch,
                                 struct agent_expr *ax, int reg_nr)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   gdb_assert (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr));
 
   ax_reg_mask (ax, tdep->ppc_vr0_regnum
@@ -3052,7 +3188,7 @@ static void
 vsx_ax_pseudo_register_collect (struct gdbarch *gdbarch,
                                struct agent_expr *ax, int reg_nr)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int reg_index, vr0, fp0, vsr0_upper;
 
   if (IS_VSX_PSEUDOREG (tdep, reg_nr))
@@ -3090,7 +3226,7 @@ static void
 efp_ax_pseudo_register_collect (struct gdbarch *gdbarch,
                                struct agent_expr *ax, int reg_nr)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int reg_index, vr0;
 
   if (IS_EFP_PSEUDOREG (tdep, reg_nr))
@@ -3113,7 +3249,7 @@ static int
 rs6000_ax_pseudo_register_collect (struct gdbarch *gdbarch,
                                   struct agent_expr *ax, int reg_nr)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   if (IS_SPE_PSEUDOREG (tdep, reg_nr))
     {
       int reg_index = reg_nr - tdep->ppc_ev0_regnum;
@@ -3153,7 +3289,7 @@ 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);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_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;
@@ -3164,7 +3300,7 @@ rs6000_gen_return_address (struct gdbarch *gdbarch,
 static int
 rs6000_stab_reg_to_regnum (struct gdbarch *gdbarch, int num)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   if (0 <= num && num <= 31)
     return tdep->ppc_gp0_regnum + num;
@@ -3181,23 +3317,23 @@ rs6000_stab_reg_to_regnum (struct gdbarch *gdbarch, int num)
     switch (num)
       {
       case 64: 
-        return tdep->ppc_mq_regnum;
+       return tdep->ppc_mq_regnum;
       case 65:
-        return tdep->ppc_lr_regnum;
+       return tdep->ppc_lr_regnum;
       case 66: 
-        return tdep->ppc_ctr_regnum;
+       return tdep->ppc_ctr_regnum;
       case 76: 
-        return tdep->ppc_xer_regnum;
+       return tdep->ppc_xer_regnum;
       case 109:
-        return tdep->ppc_vrsave_regnum;
+       return tdep->ppc_vrsave_regnum;
       case 110:
-        return tdep->ppc_vrsave_regnum - 1; /* vscr */
+       return tdep->ppc_vrsave_regnum - 1; /* vscr */
       case 111:
-        return tdep->ppc_acc_regnum;
+       return tdep->ppc_acc_regnum;
       case 112:
-        return tdep->ppc_spefscr_regnum;
+       return tdep->ppc_spefscr_regnum;
       default: 
-        return num;
+       return num;
       }
 }
 
@@ -3206,7 +3342,7 @@ rs6000_stab_reg_to_regnum (struct gdbarch *gdbarch, int num)
 static int
 rs6000_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int num)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   if (0 <= num && num <= 31)
     return tdep->ppc_gp0_regnum + num;
@@ -3225,24 +3361,25 @@ rs6000_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int num)
       case 64:
        return tdep->ppc_cr_regnum;
       case 67:
-        return tdep->ppc_vrsave_regnum - 1; /* vscr */
+       return tdep->ppc_vrsave_regnum - 1; /* vscr */
       case 99:
-        return tdep->ppc_acc_regnum;
+       return tdep->ppc_acc_regnum;
       case 100:
-        return tdep->ppc_mq_regnum;
+       return tdep->ppc_mq_regnum;
       case 101:
-        return tdep->ppc_xer_regnum;
+       return tdep->ppc_xer_regnum;
       case 108:
-        return tdep->ppc_lr_regnum;
+       return tdep->ppc_lr_regnum;
       case 109:
-        return tdep->ppc_ctr_regnum;
+       return tdep->ppc_ctr_regnum;
       case 356:
-        return tdep->ppc_vrsave_regnum;
+       return tdep->ppc_vrsave_regnum;
       case 612:
-        return tdep->ppc_spefscr_regnum;
-      default:
-        return num;
+       return tdep->ppc_spefscr_regnum;
       }
+
+  /* Unknown DWARF register number.  */
+  return -1;
 }
 
 /* Translate a .eh_frame register to DWARF register, or adjust a
@@ -3314,7 +3451,7 @@ rs6000_adjust_frame_regnum (struct gdbarch *gdbarch, int num, int eh_frame_p)
 
 /* Information about a particular processor variant.  */
 
-struct variant
+struct ppc_variant
   {
     /* Name of this variant.  */
     const char *name;
@@ -3332,7 +3469,7 @@ struct variant
     struct target_desc **tdesc;
   };
 
-static struct variant variants[] =
+static struct ppc_variant variants[] =
 {
   {"powerpc", "PowerPC user-level", bfd_arch_powerpc,
    bfd_mach_ppc, &tdesc_powerpc_altivec32},
@@ -3391,10 +3528,10 @@ static struct variant variants[] =
 /* Return the variant corresponding to architecture ARCH and machine number
    MACH.  If no such variant exists, return null.  */
 
-static const struct variant *
+static const struct ppc_variant *
 find_variant_by_arch (enum bfd_architecture arch, unsigned long mach)
 {
-  const struct variant *v;
+  const struct ppc_variant *v;
 
   for (v = variants; v->name; v++)
     if (arch == v->arch && mach == v->mach)
@@ -3404,26 +3541,12 @@ find_variant_by_arch (enum bfd_architecture arch, unsigned long mach)
 }
 
 \f
-static CORE_ADDR
-rs6000_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  return frame_unwind_register_unsigned (next_frame,
-                                        gdbarch_pc_regnum (gdbarch));
-}
-
-static struct frame_id
-rs6000_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
-{
-  return frame_id_build (get_frame_register_unsigned
-                         (this_frame, gdbarch_sp_regnum (gdbarch)),
-                        get_frame_pc (this_frame));
-}
 
 struct rs6000_frame_cache
 {
   CORE_ADDR base;
   CORE_ADDR initial_sp;
-  struct trad_frame_saved_reg *saved_regs;
+  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
@@ -3438,7 +3561,7 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
 {
   struct rs6000_frame_cache *cache;
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct rs6000_framedata fdata;
   int wordsize = tdep->wordsize;
@@ -3451,7 +3574,7 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
   cache->pc = 0;
   cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
 
-  TRY
+  try
     {
       func = get_frame_func (this_frame);
       cache->pc = func;
@@ -3468,13 +3591,12 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
       cache->base = get_frame_register_unsigned
        (this_frame, gdbarch_sp_regnum (gdbarch));
     }
-  CATCH (ex, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &ex)
     {
       if (ex.error != NOT_AVAILABLE_ERROR)
-       throw_exception (ex);
+       throw;
       return (struct rs6000_frame_cache *) (*this_cache);
     }
-  END_CATCH
 
   /* If the function appears to be frameless, check a couple of likely
      indicators that we have simply failed to find the frame setup.
@@ -3514,11 +3636,10 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
 
       if (safe_read_memory_unsigned_integer (cache->base, wordsize,
                                             byte_order, &backchain))
-        cache->base = (CORE_ADDR) backchain;
+       cache->base = (CORE_ADDR) backchain;
     }
 
-  trad_frame_set_value (cache->saved_regs,
-                       gdbarch_sp_regnum (gdbarch), cache->base);
+  cache->saved_regs[gdbarch_sp_regnum (gdbarch)].set_value (cache->base);
 
   /* if != -1, fdata.saved_fpr is the smallest number of saved_fpr.
      All fpr's from saved_fpr to fp31 are saved.  */
@@ -3529,15 +3650,15 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
       CORE_ADDR fpr_addr = cache->base + fdata.fpr_offset;
 
       /* If skip_prologue says floating-point registers were saved,
-         but the current architecture has no floating-point registers,
-         then that's strange.  But we have no indices to even record
-         the addresses under, so we just ignore it.  */
+        but the current architecture has no floating-point registers,
+        then that's strange.  But we have no indices to even record
+        the addresses under, so we just ignore it.  */
       if (ppc_floating_point_unit_p (gdbarch))
-        for (i = fdata.saved_fpr; i < ppc_num_fprs; i++)
-          {
-            cache->saved_regs[tdep->ppc_fp0_regnum + i].addr = fpr_addr;
-            fpr_addr += 8;
-          }
+       for (i = fdata.saved_fpr; i < ppc_num_fprs; i++)
+         {
+           cache->saved_regs[tdep->ppc_fp0_regnum + i].set_addr (fpr_addr);
+           fpr_addr += 8;
+         }
     }
 
   /* if != -1, fdata.saved_gpr is the smallest number of saved_gpr.
@@ -3551,7 +3672,7 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
       for (i = fdata.saved_gpr; i < ppc_num_gprs; i++)
        {
          if (fdata.gpr_mask & (1U << i))
-           cache->saved_regs[tdep->ppc_gp0_regnum + i].addr = gpr_addr;
+           cache->saved_regs[tdep->ppc_gp0_regnum + i].set_addr (gpr_addr);
          gpr_addr += wordsize;
        }
     }
@@ -3566,7 +3687,7 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
          CORE_ADDR vr_addr = cache->base + fdata.vr_offset;
          for (i = fdata.saved_vr; i < 32; i++)
            {
-             cache->saved_regs[tdep->ppc_vr0_regnum + i].addr = vr_addr;
+             cache->saved_regs[tdep->ppc_vr0_regnum + i].set_addr (vr_addr);
              vr_addr += register_size (gdbarch, tdep->ppc_vr0_regnum);
            }
        }
@@ -3584,8 +3705,9 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
 
          for (i = fdata.saved_ev; i < ppc_num_gprs; i++)
            {
-             cache->saved_regs[tdep->ppc_ev0_regnum + i].addr = ev_addr;
-             cache->saved_regs[tdep->ppc_gp0_regnum + i].addr = ev_addr + off;
+             cache->saved_regs[tdep->ppc_ev0_regnum + i].set_addr (ev_addr);
+             cache->saved_regs[tdep->ppc_gp0_regnum + i].set_addr (ev_addr
+                                                                   + off);
              ev_addr += register_size (gdbarch, tdep->ppc_ev0_regnum);
            }
        }
@@ -3594,16 +3716,16 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
   /* If != 0, fdata.cr_offset is the offset from the frame that
      holds the CR.  */
   if (fdata.cr_offset != 0)
-    cache->saved_regs[tdep->ppc_cr_regnum].addr
-      = cache->base + fdata.cr_offset;
+    cache->saved_regs[tdep->ppc_cr_regnum].set_addr (cache->base
+                                                    + fdata.cr_offset);
 
   /* If != 0, fdata.lr_offset is the offset from the frame that
      holds the LR.  */
   if (fdata.lr_offset != 0)
-    cache->saved_regs[tdep->ppc_lr_regnum].addr
-      = cache->base + fdata.lr_offset;
+    cache->saved_regs[tdep->ppc_lr_regnum].set_addr (cache->base
+                                                    + fdata.lr_offset);
   else if (fdata.lr_register != -1)
-    cache->saved_regs[tdep->ppc_lr_regnum].realreg = fdata.lr_register;
+    cache->saved_regs[tdep->ppc_lr_regnum].set_realreg (fdata.lr_register);
   /* The PC is found in the link register.  */
   cache->saved_regs[gdbarch_pc_regnum (gdbarch)] =
     cache->saved_regs[tdep->ppc_lr_regnum];
@@ -3611,8 +3733,8 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
   /* If != 0, fdata.vrsave_offset is the offset from the frame that
      holds the VRSAVE.  */
   if (fdata.vrsave_offset != 0)
-    cache->saved_regs[tdep->ppc_vrsave_regnum].addr
-      = cache->base + fdata.vrsave_offset;
+    cache->saved_regs[tdep->ppc_vrsave_regnum].set_addr (cache->base
+                                                        + fdata.vrsave_offset);
 
   if (fdata.alloca_reg < 0)
     /* If no alloca register used, then fi->frame is the value of the
@@ -3658,6 +3780,7 @@ rs6000_frame_prev_register (struct frame_info *this_frame,
 
 static const struct frame_unwind rs6000_frame_unwind =
 {
+  "rs6000 prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   rs6000_frame_this_id,
@@ -3674,7 +3797,7 @@ rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
 {
   struct rs6000_frame_cache *cache;
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   if (*this_cache)
     return (struct rs6000_frame_cache *) *this_cache;
@@ -3683,7 +3806,7 @@ rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
   (*this_cache) = cache;
   cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
 
-  TRY
+  try
     {
       /* At this point the stack looks as if we just entered the
         function, and the return address is stored in LR.  */
@@ -3695,15 +3818,13 @@ rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
       cache->base = sp;
       cache->initial_sp = sp;
 
-      trad_frame_set_value (cache->saved_regs,
-                           gdbarch_pc_regnum (gdbarch), lr);
+      cache->saved_regs[gdbarch_pc_regnum (gdbarch)].set_value (lr);
     }
-  CATCH (ex, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &ex)
     {
       if (ex.error != NOT_AVAILABLE_ERROR)
-       throw_exception (ex);
+       throw;
     }
-  END_CATCH
 
   return cache;
 }
@@ -3759,6 +3880,7 @@ rs6000_epilogue_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind rs6000_epilogue_frame_unwind =
 {
+  "rs6000 epilogue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   rs6000_epilogue_frame_this_id, rs6000_epilogue_frame_prev_register,
@@ -3796,7 +3918,7 @@ ppc_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
                            struct dwarf2_frame_state_reg *reg,
                            struct frame_info *this_frame)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   /* PPC32 and PPC64 ABI's are the same regarding volatile and
      non-volatile registers.  We will use the same code for both.  */
@@ -3882,7 +4004,7 @@ bfd_uses_spe_extensions (bfd *abfd)
   if (!sect)
     return 0;
 
-  size = bfd_get_section_size (sect);
+  size = bfd_section_size (sect);
   contents = (gdb_byte *) xmalloc (size);
   if (!bfd_get_section_contents (abfd, sect, contents, 0, size))
     {
@@ -4008,7 +4130,7 @@ bfd_uses_spe_extensions (bfd *abfd)
    Otherwise, it's just a VR register.  Record them accordingly.  */
 
 static int
-ppc_record_vsr (struct regcache *regcache, struct gdbarch_tdep *tdep, int vsr)
+ppc_record_vsr (struct regcache *regcache, ppc_gdbarch_tdep *tdep, int vsr)
 {
   if (vsr < 0 || vsr >= 64)
     return -1;
@@ -4037,7 +4159,7 @@ static int
 ppc_process_record_op4 (struct gdbarch *gdbarch, struct regcache *regcache,
                        CORE_ADDR addr, uint32_t insn)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int ext = PPC_FIELD (insn, 21, 11);
   int vra = PPC_FIELD (insn, 11, 5);
 
@@ -4410,7 +4532,7 @@ static int
 ppc_process_record_op19 (struct gdbarch *gdbarch, struct regcache *regcache,
                           CORE_ADDR addr, uint32_t insn)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int ext = PPC_EXTOP (insn);
 
   switch (ext & 0x01f)
@@ -4462,7 +4584,7 @@ static int
 ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
                           CORE_ADDR addr, uint32_t insn)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int ext = PPC_EXTOP (insn);
   int tmp, nr, nb, i;
   CORE_ADDR at_dcsz, ea = 0;
@@ -4868,20 +4990,20 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       switch (ext)
        {
        case 167:       /* Store Vector Element Halfword Indexed */
-         addr = addr & ~0x1ULL;
+         ea = ea & ~0x1ULL;
          break;
 
        case 199:       /* Store Vector Element Word Indexed */
-         addr = addr & ~0x3ULL;
+         ea = ea & ~0x3ULL;
          break;
 
        case 231:       /* Store Vector Indexed */
        case 487:       /* Store Vector Indexed LRU */
-         addr = addr & ~0xfULL;
+         ea = ea & ~0xfULL;
          break;
        }
 
-      record_full_arch_list_add_mem (addr, size);
+      record_full_arch_list_add_mem (ea, size);
       return 0;
 
     case 397:          /* Store VSX Vector with Length */
@@ -5030,7 +5152,8 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       return 0;
 
     case 1014:         /* Data Cache Block set to Zero */
-      if (target_auxv_search (current_top_target (), AT_DCACHEBSIZE, &at_dcsz) <= 0
+      if (target_auxv_search (current_inferior ()->top_target (),
+                             AT_DCACHEBSIZE, &at_dcsz) <= 0
          || at_dcsz == 0)
        at_dcsz = 128; /* Assume 128-byte cache line size (POWER8)  */
 
@@ -5058,7 +5181,7 @@ static int
 ppc_process_record_op59 (struct gdbarch *gdbarch, struct regcache *regcache,
                           CORE_ADDR addr, uint32_t insn)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int ext = PPC_EXTOP (insn);
 
   switch (ext & 0x1f)
@@ -5152,7 +5275,7 @@ static int
 ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
                           CORE_ADDR addr, uint32_t insn)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int ext = PPC_EXTOP (insn);
 
   switch (ext >> 2)
@@ -5446,7 +5569,7 @@ ppc_process_record_op60 (struct gdbarch *gdbarch, struct regcache *regcache,
        {
        case 0:         /* VSX Scalar Extract Exponent Double-Precision */
        case 1:         /* VSX Scalar Extract Significand Double-Precision */
-          record_full_arch_list_add_reg (regcache,
+         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
@@ -5514,7 +5637,7 @@ 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);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   ULONGEST ea = 0;
   int size;
 
@@ -5573,7 +5696,7 @@ static int
 ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
                           CORE_ADDR addr, uint32_t insn)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int ext = PPC_EXTOP (insn);
   int tmp;
 
@@ -5703,7 +5826,7 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
 
     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 */
@@ -5719,7 +5842,7 @@ ppc_process_record_op63 (struct gdbarch *gdbarch, struct regcache *regcache,
                                           tdep->ppc_fp0_regnum
                                           + PPC_FRT (insn));
            return 0;
-        }
+       }
       break;
 
     case 8:            /* Floating Copy Sign */
@@ -5832,7 +5955,7 @@ int
 ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
                      CORE_ADDR addr)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   uint32_t insn;
   int op6, tmp, i;
@@ -6033,7 +6156,7 @@ ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 
     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);
@@ -6124,6 +6247,69 @@ UNKNOWN_OP:
   return 0;
 }
 
+/* Used for matching tw, twi, td and tdi instructions for POWER.  */
+
+static constexpr uint32_t TX_INSN_MASK = 0xFC0007FF;
+static constexpr uint32_t TW_INSN = 0x7C000008;
+static constexpr uint32_t TD_INSN = 0x7C000088;
+
+static constexpr uint32_t TXI_INSN_MASK = 0xFC000000;
+static constexpr uint32_t TWI_INSN = 0x0C000000;
+static constexpr uint32_t TDI_INSN = 0x08000000;
+
+static inline bool
+is_tw_insn (uint32_t insn)
+{
+  return (insn & TX_INSN_MASK) == TW_INSN;
+}
+
+static inline bool
+is_twi_insn (uint32_t insn)
+{
+  return (insn & TXI_INSN_MASK) == TWI_INSN;
+}
+
+static inline bool
+is_td_insn (uint32_t insn)
+{
+  return (insn & TX_INSN_MASK) == TD_INSN;
+}
+
+static inline bool
+is_tdi_insn (uint32_t insn)
+{
+  return (insn & TXI_INSN_MASK) == TDI_INSN;
+}
+
+/* Implementation of gdbarch_program_breakpoint_here_p for POWER.  */
+
+static bool
+rs6000_program_breakpoint_here_p (gdbarch *gdbarch, CORE_ADDR address)
+{
+  gdb_byte target_mem[PPC_INSN_SIZE];
+
+  /* Enable the automatic memory restoration from breakpoints while
+     we read the memory.  Otherwise we may find temporary breakpoints, ones
+     inserted by GDB, and flag them as permanent breakpoints.  */
+  scoped_restore restore_memory
+    = make_scoped_restore_show_memory_breakpoints (0);
+
+  if (target_read_memory (address, target_mem, PPC_INSN_SIZE) == 0)
+    {
+      uint32_t insn = (uint32_t) extract_unsigned_integer
+        (target_mem, PPC_INSN_SIZE, gdbarch_byte_order_for_code (gdbarch));
+
+      /* Check if INSN is a TW, TWI, TD or TDI instruction.  There
+         are multiple choices of such instructions with different registers
+         and / or immediate values but they all cause a break. */
+      if (is_tw_insn (insn) || is_twi_insn (insn) || is_td_insn (insn)
+          || is_tdi_insn (insn))
+        return true;
+    }
+
+  return false;
+}
+
 /* Initialize the current architecture based on INFO.  If possible, re-use an
    architecture from ARCHES, which is a list of architectures already created
    during this debugging session.
@@ -6135,7 +6321,6 @@ static struct gdbarch *
 rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
   struct gdbarch *gdbarch;
-  struct gdbarch_tdep *tdep;
   int wordsize, from_xcoff_exec, from_elf_exec;
   enum bfd_architecture arch;
   unsigned long mach;
@@ -6153,20 +6338,10 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   int have_htm_tar = 0;
   int tdesc_wordsize = -1;
   const struct target_desc *tdesc = info.target_desc;
-  struct tdesc_arch_data *tdesc_data = NULL;
+  tdesc_arch_data_up tdesc_data;
   int num_pseudoregs = 0;
   int cur_reg;
 
-  /* INFO may refer to a binary that is not of the PowerPC architecture,
-     e.g. when debugging a stand-alone SPE executable on a Cell/B.E. system.
-     In this case, we must not attempt to infer properties of the (PowerPC
-     side) of the target system from properties of that executable.  Trust
-     the target description instead.  */
-  if (info.abfd
-      && bfd_get_arch (info.abfd) != bfd_arch_powerpc
-      && bfd_get_arch (info.abfd) != bfd_arch_rs6000)
-    info.abfd = NULL;
-
   from_xcoff_exec = info.abfd && info.abfd->format == bfd_object &&
     bfd_get_flavour (info.abfd) == bfd_target_xcoff_flavour;
 
@@ -6224,7 +6399,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      layout, if we do not already have one.  */
   if (! tdesc_has_registers (tdesc))
     {
-      const struct variant *v;
+      const struct ppc_variant *v;
 
       /* Choose variant.  */
       v = find_variant_by_arch (arch, mach);
@@ -6260,31 +6435,29 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
       valid_p = 1;
       for (i = 0; i < ppc_num_gprs; i++)
-       valid_p &= tdesc_numbered_register (feature, tdesc_data, i, gprs[i]);
-      valid_p &= tdesc_numbered_register (feature, tdesc_data, PPC_PC_REGNUM,
-                                         "pc");
-      valid_p &= tdesc_numbered_register (feature, tdesc_data, PPC_LR_REGNUM,
-                                         "lr");
-      valid_p &= tdesc_numbered_register (feature, tdesc_data, PPC_XER_REGNUM,
-                                         "xer");
+       valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
+                                           i, gprs[i]);
+      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
+                                         PPC_PC_REGNUM, "pc");
+      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
+                                         PPC_LR_REGNUM, "lr");
+      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
+                                         PPC_XER_REGNUM, "xer");
 
       /* Allow alternate names for these registers, to accomodate GDB's
         historic naming.  */
-      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data,
+      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (),
                                                  PPC_MSR_REGNUM, msr_names);
-      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data,
+      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (),
                                                  PPC_CR_REGNUM, cr_names);
-      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data,
+      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (),
                                                  PPC_CTR_REGNUM, ctr_names);
 
       if (!valid_p)
-       {
-         tdesc_data_cleanup (tdesc_data);
-         return NULL;
-       }
+       return NULL;
 
-      have_mq = tdesc_numbered_register (feature, tdesc_data, PPC_MQ_REGNUM,
-                                        "mq");
+      have_mq = tdesc_numbered_register (feature, tdesc_data.get (),
+                                        PPC_MQ_REGNUM, "mq");
 
       tdesc_wordsize = tdesc_register_bitsize (feature, "pc") / 8;
       if (wordsize == -1)
@@ -6302,16 +6475,13 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
          };
          valid_p = 1;
          for (i = 0; i < ppc_num_fprs; i++)
-           valid_p &= tdesc_numbered_register (feature, tdesc_data,
+           valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                                PPC_F0_REGNUM + i, fprs[i]);
-         valid_p &= tdesc_numbered_register (feature, tdesc_data,
+         valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                              PPC_FPSCR_REGNUM, "fpscr");
 
          if (!valid_p)
-           {
-             tdesc_data_cleanup (tdesc_data);
-             return NULL;
-           }
+           return NULL;
          have_fpu = 1;
 
          /* The fpscr register was expanded in isa 2.05 to 64 bits
@@ -6336,19 +6506,16 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
          valid_p = 1;
          for (i = 0; i < ppc_num_gprs; i++)
-           valid_p &= tdesc_numbered_register (feature, tdesc_data,
+           valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                                PPC_VR0_REGNUM + i,
                                                vector_regs[i]);
-         valid_p &= tdesc_numbered_register (feature, tdesc_data,
+         valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                              PPC_VSCR_REGNUM, "vscr");
-         valid_p &= tdesc_numbered_register (feature, tdesc_data,
+         valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                              PPC_VRSAVE_REGNUM, "vrsave");
 
          if (have_spe || !valid_p)
-           {
-             tdesc_data_cleanup (tdesc_data);
-             return NULL;
-           }
+           return NULL;
          have_altivec = 1;
        }
       else
@@ -6372,15 +6539,12 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
          valid_p = 1;
 
          for (i = 0; i < ppc_num_vshrs; i++)
-           valid_p &= tdesc_numbered_register (feature, tdesc_data,
+           valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                                PPC_VSR0_UPPER_REGNUM + i,
                                                vsx_regs[i]);
 
          if (!valid_p || !have_fpu || !have_altivec)
-           {
-             tdesc_data_cleanup (tdesc_data);
-             return NULL;
-           }
+           return NULL;
 
          have_vsx = 1;
        }
@@ -6417,19 +6581,16 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
          valid_p = 1;
          for (i = 0; i < ppc_num_gprs; i++)
-           valid_p &= tdesc_numbered_register (feature, tdesc_data,
+           valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                                PPC_SPE_UPPER_GP0_REGNUM + i,
                                                upper_spe[i]);
-         valid_p &= tdesc_numbered_register (feature, tdesc_data,
+         valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                              PPC_SPE_ACC_REGNUM, "acc");
-         valid_p &= tdesc_numbered_register (feature, tdesc_data,
+         valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                              PPC_SPE_FSCR_REGNUM, "spefscr");
 
          if (have_mq || have_fpu || !valid_p)
-           {
-             tdesc_data_cleanup (tdesc_data);
-             return NULL;
-           }
+           return NULL;
          have_spe = 1;
        }
       else
@@ -6441,14 +6602,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       if (feature != NULL)
        {
          valid_p = 1;
-         valid_p &= tdesc_numbered_register (feature, tdesc_data,
+         valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                              PPC_PPR_REGNUM, "ppr");
 
          if (!valid_p)
-           {
-             tdesc_data_cleanup (tdesc_data);
-             return NULL;
-           }
+           return NULL;
          have_ppr = 1;
        }
       else
@@ -6460,14 +6618,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       if (feature != NULL)
        {
          valid_p = 1;
-         valid_p &= tdesc_numbered_register (feature, tdesc_data,
+         valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                              PPC_DSCR_REGNUM, "dscr");
 
          if (!valid_p)
-           {
-             tdesc_data_cleanup (tdesc_data);
-             return NULL;
-           }
+           return NULL;
          have_dscr = 1;
        }
       else
@@ -6479,14 +6634,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       if (feature != NULL)
        {
          valid_p = 1;
-         valid_p &= tdesc_numbered_register (feature, tdesc_data,
+         valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                              PPC_TAR_REGNUM, "tar");
 
          if (!valid_p)
-           {
-             tdesc_data_cleanup (tdesc_data);
-             return NULL;
-           }
+           return NULL;
          have_tar = 1;
        }
       else
@@ -6503,14 +6655,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
          valid_p = 1;
          for (i = 0; i < ARRAY_SIZE (ebb_regs); i++)
-           valid_p &= tdesc_numbered_register (feature, tdesc_data,
+           valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                                PPC_BESCR_REGNUM + i,
                                                ebb_regs[i]);
          if (!valid_p)
-           {
-             tdesc_data_cleanup (tdesc_data);
-             return NULL;
-           }
+           return NULL;
          have_ebb = 1;
        }
       else
@@ -6524,27 +6673,24 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        {
          valid_p = 1;
 
-         valid_p &= tdesc_numbered_register (feature, tdesc_data,
+         valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                              PPC_MMCR0_REGNUM,
                                              "mmcr0");
-         valid_p &= tdesc_numbered_register (feature, tdesc_data,
+         valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                              PPC_MMCR2_REGNUM,
                                              "mmcr2");
-         valid_p &= tdesc_numbered_register (feature, tdesc_data,
+         valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                              PPC_SIAR_REGNUM,
                                              "siar");
-         valid_p &= tdesc_numbered_register (feature, tdesc_data,
+         valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                              PPC_SDAR_REGNUM,
                                              "sdar");
-         valid_p &= tdesc_numbered_register (feature, tdesc_data,
+         valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                              PPC_SIER_REGNUM,
                                              "sier");
 
          if (!valid_p)
-           {
-             tdesc_data_cleanup (tdesc_data);
-             return NULL;
-           }
+           return NULL;
          have_pmu = 1;
        }
       else
@@ -6561,14 +6707,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
          valid_p = 1;
          for (i = 0; i < ARRAY_SIZE (tm_spr_regs); i++)
-           valid_p &= tdesc_numbered_register (feature, tdesc_data,
+           valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                                PPC_TFHAR_REGNUM + i,
                                                tm_spr_regs[i]);
          if (!valid_p)
-           {
-             tdesc_data_cleanup (tdesc_data);
-             return NULL;
-           }
+           return NULL;
 
          have_htm_spr = 1;
        }
@@ -6590,14 +6733,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
          valid_p = 1;
 
          for (i = 0; i < ARRAY_SIZE (cgprs); i++)
-           valid_p &= tdesc_numbered_register (feature, tdesc_data,
+           valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                                PPC_CR0_REGNUM + i,
                                                cgprs[i]);
          if (!valid_p)
-           {
-             tdesc_data_cleanup (tdesc_data);
-             return NULL;
-           }
+           return NULL;
 
          have_htm_core = 1;
        }
@@ -6619,15 +6759,12 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
          };
 
          for (i = 0; i < ARRAY_SIZE (cfprs); i++)
-           valid_p &= tdesc_numbered_register (feature, tdesc_data,
+           valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                                PPC_CF0_REGNUM + i,
                                                cfprs[i]);
 
          if (!valid_p)
-           {
-             tdesc_data_cleanup (tdesc_data);
-             return NULL;
-           }
+           return NULL;
          have_htm_fpu = 1;
        }
       else
@@ -6649,15 +6786,12 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
          };
 
          for (i = 0; i < ARRAY_SIZE (cvmx); i++)
-           valid_p &= tdesc_numbered_register (feature, tdesc_data,
+           valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                                PPC_CVR0_REGNUM + i,
                                                cvmx[i]);
 
          if (!valid_p)
-           {
-             tdesc_data_cleanup (tdesc_data);
-             return NULL;
-           }
+           return NULL;
          have_htm_altivec = 1;
        }
       else
@@ -6679,16 +6813,13 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
          };
 
          for (i = 0; i < ARRAY_SIZE (cvsx); i++)
-           valid_p &= tdesc_numbered_register (feature, tdesc_data,
+           valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                                (PPC_CVSR0_UPPER_REGNUM
                                                 + i),
                                                cvsx[i]);
 
          if (!valid_p || !have_htm_fpu || !have_htm_altivec)
-           {
-             tdesc_data_cleanup (tdesc_data);
-             return NULL;
-           }
+           return NULL;
          have_htm_vsx = 1;
        }
       else
@@ -6698,14 +6829,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
                                    "org.gnu.gdb.power.htm.ppr");
       if (feature != NULL)
        {
-         valid_p = tdesc_numbered_register (feature, tdesc_data,
+         valid_p = tdesc_numbered_register (feature, tdesc_data.get (),
                                             PPC_CPPR_REGNUM, "cppr");
 
          if (!valid_p)
-           {
-             tdesc_data_cleanup (tdesc_data);
-             return NULL;
-           }
+           return NULL;
          have_htm_ppr = 1;
        }
       else
@@ -6715,14 +6843,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
                                    "org.gnu.gdb.power.htm.dscr");
       if (feature != NULL)
        {
-         valid_p = tdesc_numbered_register (feature, tdesc_data,
+         valid_p = tdesc_numbered_register (feature, tdesc_data.get (),
                                             PPC_CDSCR_REGNUM, "cdscr");
 
          if (!valid_p)
-           {
-             tdesc_data_cleanup (tdesc_data);
-             return NULL;
-           }
+           return NULL;
          have_htm_dscr = 1;
        }
       else
@@ -6732,14 +6857,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
                                    "org.gnu.gdb.power.htm.tar");
       if (feature != NULL)
        {
-         valid_p = tdesc_numbered_register (feature, tdesc_data,
+         valid_p = tdesc_numbered_register (feature, tdesc_data.get (),
                                             PPC_CTAR_REGNUM, "ctar");
 
          if (!valid_p)
-           {
-             tdesc_data_cleanup (tdesc_data);
-             return NULL;
-           }
+           return NULL;
          have_htm_tar = 1;
        }
       else
@@ -6758,10 +6880,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      supplies a 64-bit description while debugging a 32-bit
      binary.  */
   if (tdesc_wordsize != -1 && tdesc_wordsize != wordsize)
-    {
-      tdesc_data_cleanup (tdesc_data);
-      return NULL;
-    }
+    return NULL;
 
 #ifdef HAVE_ELF
   if (from_elf_exec)
@@ -6841,9 +6960,9 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   if (elf_abi == POWERPC_ELF_AUTO)
     {
       if (wordsize == 8 && info.byte_order == BFD_ENDIAN_LITTLE)
-        elf_abi = POWERPC_ELF_V2;
+       elf_abi = POWERPC_ELF_V2;
       else
-        elf_abi = POWERPC_ELF_V1;
+       elf_abi = POWERPC_ELF_V1;
     }
 
   if (soft_float_flag == AUTO_BOOLEAN_TRUE)
@@ -6885,9 +7004,10 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        arches = gdbarch_list_lookup_by_info (arches->next, &info))
     {
       /* Word size in the various PowerPC bfd_arch_info structs isn't
-         meaningful, because 64-bit CPUs can run in 32-bit mode.  So, perform
-         separate word size check.  */
-      tdep = gdbarch_tdep (arches->gdbarch);
+        meaningful, because 64-bit CPUs can run in 32-bit mode.  So, perform
+        separate word size check.  */
+      ppc_gdbarch_tdep *tdep
+       = (ppc_gdbarch_tdep *) gdbarch_tdep (arches->gdbarch);
       if (tdep && tdep->elf_abi != elf_abi)
        continue;
       if (tdep && tdep->soft_float != soft_float)
@@ -6897,11 +7017,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       if (tdep && tdep->vector_abi != vector_abi)
        continue;
       if (tdep && tdep->wordsize == wordsize)
-       {
-         if (tdesc_data != NULL)
-           tdesc_data_cleanup (tdesc_data);
-         return arches->gdbarch;
-       }
+       return arches->gdbarch;
     }
 
   /* None found, create a new architecture from INFO, whose bfd_arch_info
@@ -6912,7 +7028,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        - "set arch"            trust blindly
        - GDB startup           useless but harmless */
 
-  tdep = XCNEW (struct gdbarch_tdep);
+  ppc_gdbarch_tdep *tdep = new ppc_gdbarch_tdep;
   tdep->wordsize = wordsize;
   tdep->elf_abi = elf_abi;
   tdep->soft_float = soft_float;
@@ -7056,6 +7172,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
                                       rs6000_breakpoint::kind_from_pc);
   set_gdbarch_sw_breakpoint_from_kind (gdbarch,
                                       rs6000_breakpoint::bp_from_kind);
+  set_gdbarch_program_breakpoint_here_p (gdbarch,
+                                         rs6000_program_breakpoint_here_p);
 
   /* The value of symbols of type N_SO and N_FUN maybe null when
      it shouldn't be.  */
@@ -7088,14 +7206,16 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_displaced_step_hw_singlestep (gdbarch,
                                            ppc_displaced_step_hw_singlestep);
   set_gdbarch_displaced_step_fixup (gdbarch, ppc_displaced_step_fixup);
-  set_gdbarch_displaced_step_location (gdbarch,
-                                      displaced_step_at_entry_point);
+  set_gdbarch_displaced_step_prepare (gdbarch, ppc_displaced_step_prepare);
+  set_gdbarch_displaced_step_finish (gdbarch, ppc_displaced_step_finish);
+  set_gdbarch_displaced_step_restore_all_in_ptid
+    (gdbarch, ppc_displaced_step_restore_all_in_ptid);
 
-  set_gdbarch_max_insn_length (gdbarch, PPC_INSN_SIZE);
+  set_gdbarch_max_insn_length (gdbarch, 2 * PPC_INSN_SIZE);
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
   info.target_desc = tdesc;
-  info.tdesc_data = tdesc_data;
+  info.tdesc_data = tdesc_data.get ();
   gdbarch_init_osabi (info, gdbarch);
 
   switch (info.osabi)
@@ -7103,26 +7223,22 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     case GDB_OSABI_LINUX:
     case GDB_OSABI_NETBSD:
     case GDB_OSABI_UNKNOWN:
-      set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc);
       frame_unwind_append_unwinder (gdbarch, &rs6000_epilogue_frame_unwind);
       frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind);
-      set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id);
       frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer);
       break;
     default:
       set_gdbarch_believe_pcc_promotion (gdbarch, 1);
 
-      set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc);
       frame_unwind_append_unwinder (gdbarch, &rs6000_epilogue_frame_unwind);
       frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind);
-      set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id);
       frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer);
     }
 
   set_tdesc_pseudo_register_type (gdbarch, rs6000_pseudo_register_type);
   set_tdesc_pseudo_register_reggroup_p (gdbarch,
                                        rs6000_pseudo_register_reggroup_p);
-  tdesc_use_registers (gdbarch, tdesc, tdesc_data);
+  tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
 
   /* Override the normal target description method to make the SPE upper
      halves anonymous.  */
@@ -7193,7 +7309,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 static void
 rs6000_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   if (tdep == NULL)
     return;
@@ -7201,22 +7317,6 @@ rs6000_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
   /* FIXME: Dump gdbarch_tdep.  */
 }
 
-/* PowerPC-specific commands.  */
-
-static void
-set_powerpc_command (const char *args, int from_tty)
-{
-  printf_unfiltered (_("\
-\"set powerpc\" must be followed by an appropriate subcommand.\n"));
-  help_list (setpowerpccmdlist, "set powerpc ", all_commands, gdb_stdout);
-}
-
-static void
-show_powerpc_command (const char *args, int from_tty)
-{
-  cmd_show_list (showpowerpccmdlist, from_tty, "");
-}
-
 static void
 powerpc_set_soft_float (const char *args, int from_tty,
                        struct cmd_list_element *c)
@@ -7224,7 +7324,6 @@ powerpc_set_soft_float (const char *args, int from_tty,
   struct gdbarch_info info;
 
   /* Update the architecture.  */
-  gdbarch_info_init (&info);
   if (!gdbarch_update_p (info))
     internal_error (__FILE__, __LINE__, _("could not update architecture"));
 }
@@ -7233,7 +7332,6 @@ static void
 powerpc_set_vector_abi (const char *args, int from_tty,
                        struct cmd_list_element *c)
 {
-  struct gdbarch_info info;
   int vector_abi;
 
   for (vector_abi = POWERPC_VEC_AUTO;
@@ -7251,7 +7349,7 @@ powerpc_set_vector_abi (const char *args, int from_tty,
                    powerpc_vector_abi_string);
 
   /* Update the architecture.  */
-  gdbarch_info_init (&info);
+  gdbarch_info info;
   if (!gdbarch_update_p (info))
     internal_error (__FILE__, __LINE__, _("could not update architecture"));
 }
@@ -7335,10 +7433,19 @@ ppc_insn_ds_field (unsigned int insn)
   return ((((CORE_ADDR) insn & 0xfffc) ^ 0x8000) - 0x8000);
 }
 
+CORE_ADDR
+ppc_insn_prefix_dform (unsigned int insn1, unsigned int insn2)
+{
+  /* result is 34-bits  */
+  return (CORE_ADDR) ((((insn1 & 0x3ffff) ^ 0x20000) - 0x20000) << 16)
+    | (CORE_ADDR)(insn2 & 0xffff);
+}
+
 /* Initialization code.  */
 
+void _initialize_rs6000_tdep ();
 void
-_initialize_rs6000_tdep (void)
+_initialize_rs6000_tdep ()
 {
   gdbarch_register (bfd_arch_rs6000, rs6000_gdbarch_init, rs6000_dump_tdep);
   gdbarch_register (bfd_arch_powerpc, rs6000_gdbarch_init, rs6000_dump_tdep);
@@ -7366,13 +7473,11 @@ _initialize_rs6000_tdep (void)
 
   /* Add root prefix command for all "set powerpc"/"show powerpc"
      commands.  */
-  add_prefix_cmd ("powerpc", no_class, set_powerpc_command,
-                 _("Various PowerPC-specific commands."),
-                 &setpowerpccmdlist, "set powerpc ", 0, &setlist);
-
-  add_prefix_cmd ("powerpc", no_class, show_powerpc_command,
-                 _("Various PowerPC-specific commands."),
-                 &showpowerpccmdlist, "show powerpc ", 0, &showlist);
+  add_setshow_prefix_cmd ("powerpc", no_class,
+                         _("Various PowerPC-specific commands."),
+                         _("Various PowerPC-specific commands."),
+                         &setpowerpccmdlist, &showpowerpccmdlist,
+                         &setlist, &showlist);
 
   /* Add a command to allow the user to force the ABI.  */
   add_setshow_auto_boolean_cmd ("soft-float", class_support,