]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/rs6000-tdep.c
Add new infrun.h header.
[thirdparty/binutils-gdb.git] / gdb / rs6000-tdep.c
index 09c7f8ff9c4fdadb95720c54efe4aa8de4d33948..c4ce51c5430217a923d8f13c23cd5908ad192df7 100644 (file)
@@ -1,8 +1,6 @@
 /* Target-dependent code for GDB, the GNU debugger.
 
-   Copyright (C) 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
-   2010 Free Software Foundation, Inc.
+   Copyright (C) 1986-2014 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -22,6 +20,7 @@
 #include "defs.h"
 #include "frame.h"
 #include "inferior.h"
+#include "infrun.h"
 #include "symtab.h"
 #include "target.h"
 #include "gdbcore.h"
 
 #include "elf-bfd.h"
 #include "elf/ppc.h"
+#include "elf/ppc64.h"
 
 #include "solib-svr4.h"
 #include "ppc-tdep.h"
+#include "ppc-ravenscar-thread.h"
 
 #include "gdb_assert.h"
 #include "dis-asm.h"
 /* Determine if regnum is a POWER7 Extended FP register.  */
 #define IS_EFP_PSEUDOREG(tdep, regnum) ((tdep)->ppc_efpr0_regnum >= 0 \
     && (regnum) >= (tdep)->ppc_efpr0_regnum \
-    && (regnum) < (tdep)->ppc_efpr0_regnum + ppc_num_fprs)
+    && (regnum) < (tdep)->ppc_efpr0_regnum + ppc_num_efprs)
 
 /* The list of available "set powerpc ..." and "show powerpc ..."
    commands.  */
@@ -109,7 +110,7 @@ static struct cmd_list_element *showpowerpccmdlist = NULL;
 static enum auto_boolean powerpc_soft_float_global = AUTO_BOOLEAN_AUTO;
 
 /* The vector ABI to use.  Keep this in sync with powerpc_vector_abi.  */
-static const char *powerpc_vector_strings[] =
+static const char *const powerpc_vector_strings[] =
 {
   "auto",
   "generic",
@@ -122,7 +123,7 @@ static const char *powerpc_vector_strings[] =
 static enum powerpc_vector_abi powerpc_vector_abi_global = POWERPC_VEC_AUTO;
 static const char *powerpc_vector_abi_string = "auto";
 
-/* To be used by skip_prologue. */
+/* To be used by skip_prologue.  */
 
 struct rs6000_framedata
   {
@@ -135,8 +136,8 @@ struct rs6000_framedata
     int saved_vr;               /* smallest # of saved vr */
     int saved_ev;               /* smallest # of saved ev */
     int alloca_reg;            /* alloca register number (frame ptr) */
-    char frameless;            /* true if frameless functions. */
-    char nosavedpc;            /* true if pc not saved. */
+    char frameless;            /* true if frameless functions.  */
+    char nosavedpc;            /* true if pc not saved.  */
     char used_bl;              /* true if link register clobbered */
     int gpr_offset;            /* offset of saved gprs from prev sp */
     int fpr_offset;            /* offset of saved fprs from prev sp */
@@ -944,7 +945,7 @@ rs6000_fetch_pointer_argument (struct frame_info *frame, int argi,
 
 /* Sequence of bytes for breakpoint instruction.  */
 
-const static unsigned char *
+static const unsigned char *
 rs6000_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
                           int *bp_size)
 {
@@ -1017,7 +1018,8 @@ ppc_displaced_step_fixup (struct gdbarch *gdbarch,
                   paddress (gdbarch, insn), paddress (gdbarch, current_pc),
                   paddress (gdbarch, from + offset));
 
-             regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch),
+             regcache_cooked_write_unsigned (regs,
+                                             gdbarch_pc_regnum (gdbarch),
                                              from + offset);
            }
        }
@@ -1115,8 +1117,8 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame)
          its destination address.  */
       if ((insn & BRANCH_MASK) == BC_INSN)
         {
-          int immediate = ((insn & ~3) << 16) >> 16;
-          int absolute = ((insn >> 1) & 1);
+          int immediate = ((insn & 0xfffc) ^ 0x8000) - 0x8000;
+          int absolute = insn & 2;
 
           if (bc_insn_count >= 1)
             return 0; /* More than one conditional branch found, fallback 
@@ -1125,7 +1127,7 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame)
          if (absolute)
            breaks[1] = immediate;
          else
-           breaks[1] = pc + immediate;
+           breaks[1] = loc + immediate;
 
          bc_insn_count++;
          last_breakpoint++;
@@ -1149,11 +1151,10 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame)
   breaks[0] = loc;
 
   /* Check for duplicated breakpoints.  Check also for a breakpoint
-     placed (branch instruction's destination) at the stwcx/stdcx 
-     instruction, this resets the reservation and take us back to the 
-     lwarx/ldarx instruction at the beginning of the atomic sequence.  */
-  if (last_breakpoint && ((breaks[1] == breaks[0]) 
-      || (breaks[1] == closing_insn)))
+     placed (branch instruction's destination) anywhere in sequence.  */
+  if (last_breakpoint
+      && (breaks[1] == breaks[0]
+         || (breaks[1] >= pc && breaks[1] <= closing_insn)))
     last_breakpoint = 0;
 
   /* Effectively inserts the breakpoints.  */
@@ -1275,7 +1276,7 @@ bl_to_blrl_insn_p (CORE_ADDR pc, int insn, enum bfd_endian byte_order)
   return 0;
 }
 
-/* Masks for decoding a branch-and-link (bl) instruction.  
+/* Masks for decoding a branch-and-link (bl) instruction.
 
    BL_MASK and BL_INSTRUCTION are used in combination with each other.
    The former is anded with the opcode in question; if the result of
@@ -1317,8 +1318,7 @@ rs6000_skip_stack_check (struct gdbarch *gdbarch, const CORE_ADDR start_pc)
 
   /* First possible sequence: A small number of probes.
          stw 0, -<some immediate>(1)
-         [repeat this instruction any (small) number of times]
-  */
+         [repeat this instruction any (small) number of times].  */
   
   if ((op & 0xffff0000) == 0x90010000)
     {
@@ -1340,8 +1340,7 @@ rs6000_skip_stack_check (struct gdbarch *gdbarch, const CORE_ADDR start_pc)
          addi 12,12,-<some immediate>
          stw 0,0(12)
          b <disp>
-         [possibly one last probe: stw 0,<some immediate>(12)]
-  */
+         [possibly one last probe: stw 0,<some immediate>(12)].  */
 
   while (1)
     {
@@ -1397,7 +1396,7 @@ rs6000_skip_stack_check (struct gdbarch *gdbarch, const CORE_ADDR start_pc)
       if ((op & 0xfc000001) != 0x48000000)
         break;
 
-      /* [possibly one last probe: stw 0,<some immediate>(12)] */
+      /* [possibly one last probe: stw 0,<some immediate>(12)] */
       pc = pc + 4;
       op = rs6000_fetch_instruction (gdbarch, pc);
       if ((op & 0xffff0000) == 0x900c0000)
@@ -1491,8 +1490,7 @@ rs6000_skip_stack_check (struct gdbarch *gdbarch, const CORE_ADDR start_pc)
    - ev_offset is the offset of the first saved ev from the previous frame.
    - lr_offset is the offset of the saved lr
    - cr_offset is the offset of the saved cr
-   - vrsave_offset is the offset of the saved vrsave register
- */
+   - vrsave_offset is the offset of the saved vrsave register.  */
 
 static CORE_ADDR
 skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
@@ -1540,7 +1538,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
       /* Sometimes it isn't clear if an instruction is a prologue
          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. */
+        Otherwise, we'll assume that it really is a prologue instruction.  */
       if (prev_insn_was_prologue_insn)
        last_prologue_pc = pc;
 
@@ -1620,19 +1618,30 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
          continue;
 
        }
-      else if ((op & 0xffff0000) == 0x60000000)
+      else if ((op & 0xffff0000) == 0x3c4c0000
+              || (op & 0xffff0000) == 0x3c400000
+              || (op & 0xffff0000) == 0x38420000)
+       {
+         /* .  0:      addis 2,12,.TOC.-0b@ha
+            .          addi 2,2,.TOC.-0b@l
+            or
+            .          lis 2,.TOC.@ha
+            .          addi 2,2,.TOC.@l
+            used by ELFv2 global entry points to set up r2.  */
+         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
-            instructions. */
+            instructions.  */
          prev_insn_was_prologue_insn = 0;
          continue;
 
        }
       else if ((op & 0xffff0000) == 0x3c000000)
-       {                       /* addis 0,0,NUM, used
-                                  for >= 32k frames */
+       {                       /* addis 0,0,NUM, used for >= 32k frames */
          fdata->offset = (op & 0x0000ffff) << 16;
          fdata->frameless = 0;
           r0_contains_arg = 0;
@@ -1640,8 +1649,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
 
        }
       else if ((op & 0xffff0000) == 0x60000000)
-       {                       /* ori 0,0,NUM, 2nd ha
-                                  lf of >= 32k frames */
+       {                       /* ori 0,0,NUM, 2nd half of >= 32k frames */
          fdata->offset |= (op & 0x0000ffff);
          fdata->frameless = 0;
           r0_contains_arg = 0;
@@ -1719,7 +1727,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
        }
       else if ((op & 0xfc000001) == 0x48000001)
        {                       /* bl foo, 
-                                  to save fprs??? */
+                                  to save fprs???  */
 
          fdata->frameless = 0;
 
@@ -1741,7 +1749,8 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
              struct symtab_and_line prologue_sal = find_pc_line (orig_pc, 0);
              struct symtab_and_line this_sal = find_pc_line (pc, 0);
 
-             if ((prologue_sal.line == 0) || (prologue_sal.line != this_sal.line))
+             if ((prologue_sal.line == 0)
+                 || (prologue_sal.line != this_sal.line))
                break;
            }
 
@@ -1750,11 +1759,11 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
          /* At this point, make sure this is not a trampoline
             function (a function that simply calls another functions,
             and nothing else).  If the next is not a nop, this branch
-            was part of the function prologue. */
+            was part of the function prologue.  */
 
          if (op == 0x4def7b82 || op == 0)      /* crorc 15, 15, 15 */
-           break;              /* don't skip over 
-                                  this branch */
+           break;              /* Don't skip over 
+                                  this branch */
 
          fdata->used_bl = 1;
          continue;
@@ -1769,7 +1778,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
        }
       else if ((op & 0xfc1f016a) == 0x7c01016e)
        {                       /* stwux rX,r1,rY */
-         /* no way to figure out what r1 is going to be */
+         /* No way to figure out what r1 is going to be.  */
          fdata->frameless = 0;
          offset = fdata->offset;
          continue;
@@ -1783,7 +1792,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
        }
       else if ((op & 0xfc1f016a) == 0x7c01016a)
        {                       /* stdux rX,r1,rY */
-         /* no way to figure out what r1 is going to be */
+         /* No way to figure out what r1 is going to be.  */
          fdata->frameless = 0;
          offset = fdata->offset;
          continue;
@@ -1797,8 +1806,8 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
        }
       /* 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,... */
-              (op >> 22) == 0x3af)             /* ld r31,... or ld r30,... */
+      else if (((op >> 22) == 0x20f    ||      /* l r31,... or l r30,...  */
+              (op >> 22) == 0x3af)             /* ld r31,... or ld r30,...  */
               && !framep
               && !minimal_toc_loaded)
        {
@@ -1811,7 +1820,8 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
       else if ((op & 0xfc0007fe) == 0x7c000378 &&      /* mr(.)  Rx,Ry */
                (((op >> 21) & 31) >= 3) &&              /* R3 >= Ry >= R10 */
                (((op >> 21) & 31) <= 10) &&
-               ((long) ((op >> 16) & 31) >= fdata->saved_gpr)) /* Rx: local var reg */
+               ((long) ((op >> 16) & 31)
+               >= fdata->saved_gpr)) /* Rx: local var reg */
        {
          continue;
 
@@ -1824,6 +1834,15 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
 
          /* Set up frame pointer */
        }
+      else if (op == 0x603d0000)       /* oril r29, r1, 0x0 */
+       {
+         fdata->frameless = 0;
+         framep = 1;
+         fdata->alloca_reg = (tdep->ppc_gp0_regnum + 29);
+         continue;
+
+         /* Another way to set up the frame pointer.  */
+       }
       else if (op == 0x603f0000        /* oril r31, r1, 0x0 */
               || op == 0x7c3f0b78)
        {                       /* mr r31, r1 */
@@ -1893,7 +1912,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_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
+             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;
        }
@@ -2051,7 +2070,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
 
 #if 0
 /* I have problems with skipping over __main() that I need to address
- * sometime. Previously, I used to use misc_function_vector which
+ * sometime.  Previously, I used to use misc_function_vector which
  * didn't work as well as I wanted to be.  -MGO */
 
   /* If the first thing after skipping a prolog is a branch to a function,
@@ -2062,7 +2081,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
 
 
   if ((op & 0xfc000001) == 0x48000001)
-    {                          /* bl foo, an initializer function? */
+    {                          /* bl foo, an initializer function?  */
       op = read_memory_integer (pc + 4, 4, byte_order);
 
       if (op == 0x4def7b82)
@@ -2090,12 +2109,12 @@ static CORE_ADDR
 rs6000_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   struct rs6000_framedata frame;
-  CORE_ADDR limit_pc, func_addr;
+  CORE_ADDR limit_pc, func_addr, func_end_addr = 0;
 
   /* See if we can determine the end of the prologue via the symbol table.
      If so, then return either PC, or the PC after the prologue, whichever
      is greater.  */
-  if (find_pc_partial_function (pc, NULL, &func_addr, NULL))
+  if (find_pc_partial_function (pc, NULL, &func_addr, &func_end_addr))
     {
       CORE_ADDR post_prologue_pc
        = skip_prologue_using_sal (gdbarch, func_addr);
@@ -2113,6 +2132,11 @@ rs6000_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
   if (limit_pc == 0)
     limit_pc = pc + 100;          /* Magic.  */
 
+  /* Do not allow limit_pc to be past the function end, if we know
+     where that end is...  */
+  if (func_end_addr && limit_pc > func_end_addr)
+    limit_pc = func_end_addr;
+
   pc = skip_prologue (gdbarch, pc, limit_pc, &frame);
   return pc;
 }
@@ -2140,15 +2164,15 @@ rs6000_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
     {
       CORE_ADDR displ = op & BL_DISPLACEMENT_MASK;
       CORE_ADDR call_dest = pc + 4 + displ;
-      struct minimal_symbol *s = lookup_minimal_symbol_by_pc (call_dest);
+      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
         used to compile the program.  */
-      if (s != NULL
-          && SYMBOL_LINKAGE_NAME (s) != NULL
-         && (strcmp (SYMBOL_LINKAGE_NAME (s), "__eabi") == 0
-             || strcmp (SYMBOL_LINKAGE_NAME (s), "___eabi") == 0))
+      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))
        pc += 4;
     }
   return pc;
@@ -2186,7 +2210,7 @@ rs6000_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
 
 static int
 rs6000_in_solib_return_trampoline (struct gdbarch *gdbarch,
-                                  CORE_ADDR pc, char *name)
+                                  CORE_ADDR pc, const char *name)
 {
   return name && !strncmp (name, "@FIX", 4);
 }
@@ -2214,7 +2238,7 @@ rs6000_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
   unsigned int ii, op;
   int rel;
   CORE_ADDR solib_target_pc;
-  struct minimal_symbol *msymbol;
+  struct bound_minimal_symbol msymbol;
 
   static unsigned trampoline_code[] =
   {
@@ -2230,9 +2254,9 @@ rs6000_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
 
   /* Check for bigtoc fixup code.  */
   msymbol = lookup_minimal_symbol_by_pc (pc);
-  if (msymbol 
+  if (msymbol.minsym
       && rs6000_in_solib_return_trampoline (gdbarch, pc,
-                                           SYMBOL_LINKAGE_NAME (msymbol)))
+                                           MSYMBOL_LINKAGE_NAME (msymbol.minsym)))
     {
       /* Double-check that the third instruction from PC is relative "b".  */
       op = read_memory_integer (pc + 8, 4, byte_order);
@@ -2256,7 +2280,8 @@ rs6000_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
       if (op != trampoline_code[ii])
        return 0;
     }
-  ii = get_frame_register_unsigned (frame, 11);        /* r11 holds destination addr   */
+  ii = get_frame_register_unsigned (frame, 11);        /* r11 holds destination
+                                                  addr.  */
   pc = read_memory_unsigned_integer (ii, tdep->wordsize, byte_order);
   return pc;
 }
@@ -2498,20 +2523,27 @@ rs6000_convert_register_p (struct gdbarch *gdbarch, int regnum,
             != TYPE_LENGTH (builtin_type (gdbarch)->builtin_double));
 }
 
-static void
+static int
 rs6000_register_to_value (struct frame_info *frame,
                           int regnum,
                           struct type *type,
-                          gdb_byte *to)
+                          gdb_byte *to,
+                         int *optimizedp, int *unavailablep)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   gdb_byte from[MAX_REGISTER_SIZE];
   
   gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
 
-  get_frame_register (frame, regnum, from);
+  if (!get_frame_register_bytes (frame, regnum, 0,
+                                register_size (gdbarch, regnum),
+                                from, optimizedp, unavailablep))
+    return 0;
+
   convert_typed_floating (from, builtin_type (gdbarch)->builtin_double,
                          to, type);
+  *optimizedp = *unavailablep = 0;
+  return 1;
 }
 
 static void
@@ -2530,6 +2562,11 @@ rs6000_value_to_register (struct frame_info *frame,
   put_frame_register (frame, regnum, to);
 }
 
+ /* The type of a function that moves the value of REG between CACHE
+    or BUF --- in either direction.  */
+typedef enum register_status (*move_ev_register_func) (struct regcache *,
+                                                      int, void *);
+
 /* Move SPE vector register values between a 64-bit buffer and the two
    32-bit raw register halves in a regcache.  This function handles
    both splitting a 64-bit value into two 32-bit halves, and joining
@@ -2553,16 +2590,16 @@ rs6000_value_to_register (struct frame_info *frame,
    MOVE, since this function can't tell at compile-time which of
    REGCACHE or BUFFER is acting as the source of the data.  If C had
    co-variant type qualifiers, ...  */
-static void
-e500_move_ev_register (void (*move) (struct regcache *regcache,
-                                     int regnum, gdb_byte *buf),
-                       struct regcache *regcache, int ev_reg,
-                       gdb_byte *buffer)
+
+static enum register_status
+e500_move_ev_register (move_ev_register_func move,
+                      struct regcache *regcache, int ev_reg, void *buffer)
 {
   struct gdbarch *arch = get_regcache_arch (regcache);
   struct gdbarch_tdep *tdep = gdbarch_tdep (arch); 
   int reg_index;
   gdb_byte *byte_buffer = buffer;
+  enum register_status status;
 
   gdb_assert (IS_SPE_PSEUDOREG (tdep, ev_reg));
 
@@ -2570,55 +2607,80 @@ e500_move_ev_register (void (*move) (struct regcache *regcache,
 
   if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG)
     {
-      move (regcache, tdep->ppc_ev0_upper_regnum + reg_index, byte_buffer);
-      move (regcache, tdep->ppc_gp0_regnum + reg_index, byte_buffer + 4);
+      status = move (regcache, tdep->ppc_ev0_upper_regnum + reg_index,
+                    byte_buffer);
+      if (status == REG_VALID)
+       status = move (regcache, tdep->ppc_gp0_regnum + reg_index,
+                      byte_buffer + 4);
     }
   else
     {
-      move (regcache, tdep->ppc_gp0_regnum + reg_index, byte_buffer);
-      move (regcache, tdep->ppc_ev0_upper_regnum + reg_index, byte_buffer + 4);
+      status = move (regcache, tdep->ppc_gp0_regnum + reg_index, byte_buffer);
+      if (status == REG_VALID)
+       status = move (regcache, tdep->ppc_ev0_upper_regnum + reg_index,
+                      byte_buffer + 4);
     }
+
+  return status;
 }
 
-static void
+static enum register_status
+do_regcache_raw_read (struct regcache *regcache, int regnum, void *buffer)
+{
+  return regcache_raw_read (regcache, regnum, buffer);
+}
+
+static enum register_status
+do_regcache_raw_write (struct regcache *regcache, int regnum, void *buffer)
+{
+  regcache_raw_write (regcache, regnum, buffer);
+
+  return REG_VALID;
+}
+
+static enum register_status
 e500_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
                           int reg_nr, gdb_byte *buffer)
 {
-  e500_move_ev_register (regcache_raw_read, regcache, reg_nr, buffer);
+  return e500_move_ev_register (do_regcache_raw_read, regcache, reg_nr, buffer);
 }
 
 static void
 e500_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
                            int reg_nr, const gdb_byte *buffer)
 {
-  e500_move_ev_register ((void (*) (struct regcache *, int, gdb_byte *))
-                        regcache_raw_write,
-                        regcache, reg_nr, (gdb_byte *) buffer);
+  e500_move_ev_register (do_regcache_raw_write, regcache,
+                        reg_nr, (void *) buffer);
 }
 
 /* Read method for DFP pseudo-registers.  */
-static void
+static enum register_status
 dfp_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
                           int reg_nr, gdb_byte *buffer)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int reg_index = reg_nr - tdep->ppc_dl0_regnum;
+  enum register_status status;
 
   if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
     {
       /* Read two FP registers to form a whole dl register.  */
-      regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
-                        2 * reg_index, buffer);
-      regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
-                        2 * reg_index + 1, buffer + 8);
+      status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+                                 2 * reg_index, buffer);
+      if (status == REG_VALID)
+       status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+                                   2 * reg_index + 1, buffer + 8);
     }
   else
     {
-      regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
-                        2 * reg_index + 1, buffer + 8);
-      regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
-                        2 * reg_index, buffer);
+      status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+                                 2 * reg_index + 1, buffer);
+      if (status == REG_VALID)
+       status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+                                   2 * reg_index, buffer + 8);
     }
+
+  return status;
 }
 
 /* Write method for DFP pseudo-registers.  */
@@ -2641,40 +2703,45 @@ dfp_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
   else
     {
       regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
-                         2 * reg_index + 1, buffer + 8);
+                         2 * reg_index + 1, buffer);
       regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
-                         2 * reg_index, buffer);
+                         2 * reg_index, buffer + 8);
     }
 }
 
 /* Read method for POWER7 VSX pseudo-registers.  */
-static void
+static enum register_status
 vsx_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
                           int reg_nr, gdb_byte *buffer)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int reg_index = reg_nr - tdep->ppc_vsr0_regnum;
+  enum register_status status;
 
   /* Read the portion that overlaps the VMX registers.  */
   if (reg_index > 31)
-    regcache_raw_read (regcache, tdep->ppc_vr0_regnum +
-                       reg_index - 32, buffer);
+    status = regcache_raw_read (regcache, tdep->ppc_vr0_regnum +
+                               reg_index - 32, buffer);
   else
     /* Read the portion that overlaps the FPR registers.  */
     if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
       {
-       regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
-                       reg_index, buffer);
-       regcache_raw_read (regcache, tdep->ppc_vsr0_upper_regnum +
-                       reg_index, buffer + 8);
+       status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+                                   reg_index, buffer);
+       if (status == REG_VALID)
+         status = regcache_raw_read (regcache, tdep->ppc_vsr0_upper_regnum +
+                                     reg_index, buffer + 8);
       }
     else
       {
-       regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
-                       reg_index, buffer + 8);
-       regcache_raw_read (regcache, tdep->ppc_vsr0_upper_regnum +
-                       reg_index, buffer);
+       status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+                                   reg_index, buffer + 8);
+       if (status == REG_VALID)
+         status = regcache_raw_read (regcache, tdep->ppc_vsr0_upper_regnum +
+                                     reg_index, buffer);
       }
+
+  return status;
 }
 
 /* Write method for POWER7 VSX pseudo-registers.  */
@@ -2708,16 +2775,18 @@ vsx_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 }
 
 /* Read method for POWER7 Extended FP pseudo-registers.  */
-static void
+static enum register_status
 efpr_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
                           int reg_nr, gdb_byte *buffer)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int reg_index = reg_nr - tdep->ppc_efpr0_regnum;
+  int offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8;
 
-  /* Read the portion that overlaps the VMX registers.  */
-  regcache_raw_read (regcache, tdep->ppc_vr0_regnum +
-                    reg_index, buffer);
+  /* Read the portion that overlaps the VMX register.  */
+  return regcache_raw_read_part (regcache, tdep->ppc_vr0_regnum + reg_index,
+                                offset, register_size (gdbarch, reg_nr),
+                                buffer);
 }
 
 /* Write method for POWER7 Extended FP pseudo-registers.  */
@@ -2727,14 +2796,17 @@ efpr_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int reg_index = reg_nr - tdep->ppc_efpr0_regnum;
+  int offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8;
 
-  /* Write the portion that overlaps the VMX registers.  */
-  regcache_raw_write (regcache, tdep->ppc_vr0_regnum +
-                     reg_index, buffer);
+  /* Write the portion that overlaps the VMX register.  */
+  regcache_raw_write_part (regcache, tdep->ppc_vr0_regnum + reg_index,
+                          offset, register_size (gdbarch, reg_nr),
+                          buffer);
 }
 
-static void
-rs6000_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+static enum register_status
+rs6000_pseudo_register_read (struct gdbarch *gdbarch,
+                            struct regcache *regcache,
                             int reg_nr, gdb_byte *buffer)
 {
   struct gdbarch *regcache_arch = get_regcache_arch (regcache);
@@ -2743,13 +2815,13 @@ rs6000_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
   gdb_assert (regcache_arch == gdbarch);
 
   if (IS_SPE_PSEUDOREG (tdep, reg_nr))
-    e500_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
+    return e500_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
   else if (IS_DFP_PSEUDOREG (tdep, reg_nr))
-    dfp_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
+    return dfp_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
   else if (IS_VSX_PSEUDOREG (tdep, reg_nr))
-    vsx_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
+    return vsx_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
   else if (IS_EFP_PSEUDOREG (tdep, reg_nr))
-    efpr_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
+    return efpr_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
   else
     internal_error (__FILE__, __LINE__,
                    _("rs6000_pseudo_register_read: "
@@ -2798,7 +2870,7 @@ rs6000_stab_reg_to_regnum (struct gdbarch *gdbarch, int num)
   else if (77 <= num && num <= 108)
     return tdep->ppc_vr0_regnum + (num - 77);
   else if (1200 <= num && num < 1200 + 32)
-    return tdep->ppc_ev0_regnum + (num - 1200);
+    return tdep->ppc_ev0_upper_regnum + (num - 1200);
   else
     switch (num)
       {
@@ -2840,7 +2912,7 @@ rs6000_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int num)
   else if (1124 <= num && num < 1124 + 32)
     return tdep->ppc_vr0_regnum + (num - 1124);
   else if (1200 <= num && num < 1200 + 32)
-    return tdep->ppc_ev0_regnum + (num - 1200);
+    return tdep->ppc_ev0_upper_regnum + (num - 1200);
   else
     switch (num)
       {
@@ -3028,9 +3100,6 @@ find_variant_by_arch (enum bfd_architecture arch, unsigned long mach)
 static int
 gdb_print_insn_powerpc (bfd_vma memaddr, disassemble_info *info)
 {
-  if (!info->disassembler_options)
-    info->disassembler_options = "any";
-
   if (info->endian == BFD_ENDIAN_BIG)
     return print_insn_big_powerpc (memaddr, info);
   else
@@ -3182,31 +3251,35 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
     }
 
   /* if != -1, fdata.saved_ev is the smallest number of saved_ev.
-     All vr's from saved_ev to ev31 are saved. ????? */
+     All vr's from saved_ev to ev31 are saved. ?????  */
   if (tdep->ppc_ev0_regnum != -1)
     {
       if (fdata.saved_ev >= 0)
        {
          int i;
          CORE_ADDR ev_addr = cache->base + fdata.ev_offset;
+         CORE_ADDR off = (byte_order == BFD_ENDIAN_BIG ? 4 : 0);
+
          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 + 4;
+             cache->saved_regs[tdep->ppc_gp0_regnum + i].addr = ev_addr + off;
              ev_addr += register_size (gdbarch, tdep->ppc_ev0_regnum);
-            }
+           }
        }
     }
 
   /* 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].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].addr
+      = cache->base + fdata.lr_offset;
   else if (fdata.lr_register != -1)
     cache->saved_regs[tdep->ppc_lr_regnum].realreg = fdata.lr_register;
   /* The PC is found in the link register.  */
@@ -3216,7 +3289,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].addr
+      = cache->base + fdata.vrsave_offset;
 
   if (fdata.alloca_reg < 0)
     /* If no alloca register used, then fi->frame is the value of the
@@ -3255,6 +3329,7 @@ rs6000_frame_prev_register (struct frame_info *this_frame,
 static const struct frame_unwind rs6000_frame_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   rs6000_frame_this_id,
   rs6000_frame_prev_register,
   NULL,
@@ -3345,6 +3420,125 @@ ppc_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
 }
 
 
+/* Return true if a .gnu_attributes section exists in BFD and it
+   indicates we are using SPE extensions OR if a .PPC.EMB.apuinfo
+   section exists in BFD and it indicates that SPE extensions are in
+   use.  Check the .gnu.attributes section first, as the binary might be
+   compiled for SPE, but not actually using SPE instructions.  */
+
+static int
+bfd_uses_spe_extensions (bfd *abfd)
+{
+  asection *sect;
+  gdb_byte *contents = NULL;
+  bfd_size_type size;
+  gdb_byte *ptr;
+  int success = 0;
+  int vector_abi;
+
+  if (!abfd)
+    return 0;
+
+#ifdef HAVE_ELF
+  /* Using Tag_GNU_Power_ABI_Vector here is a bit of a hack, as the user
+     could be using the SPE vector abi without actually using any spe
+     bits whatsoever.  But it's close enough for now.  */
+  vector_abi = bfd_elf_get_obj_attr_int (abfd, OBJ_ATTR_GNU,
+                                        Tag_GNU_Power_ABI_Vector);
+  if (vector_abi == 3)
+    return 1;
+#endif
+
+  sect = bfd_get_section_by_name (abfd, ".PPC.EMB.apuinfo");
+  if (!sect)
+    return 0;
+
+  size = bfd_get_section_size (sect);
+  contents = xmalloc (size);
+  if (!bfd_get_section_contents (abfd, sect, contents, 0, size))
+    {
+      xfree (contents);
+      return 0;
+    }
+
+  /* Parse the .PPC.EMB.apuinfo section.  The layout is as follows:
+
+     struct {
+       uint32 name_len;
+       uint32 data_len;
+       uint32 type;
+       char name[name_len rounded up to 4-byte alignment];
+       char data[data_len];
+     };
+
+     Technically, there's only supposed to be one such structure in a
+     given apuinfo section, but the linker is not always vigilant about
+     merging apuinfo sections from input files.  Just go ahead and parse
+     them all, exiting early when we discover the binary uses SPE
+     insns.
+
+     It's not specified in what endianness the information in this
+     section is stored.  Assume that it's the endianness of the BFD.  */
+  ptr = contents;
+  while (1)
+    {
+      unsigned int name_len;
+      unsigned int data_len;
+      unsigned int type;
+
+      /* If we can't read the first three fields, we're done.  */
+      if (size < 12)
+       break;
+
+      name_len = bfd_get_32 (abfd, ptr);
+      name_len = (name_len + 3) & ~3U; /* Round to 4 bytes.  */
+      data_len = bfd_get_32 (abfd, ptr + 4);
+      type = bfd_get_32 (abfd, ptr + 8);
+      ptr += 12;
+
+      /* The name must be "APUinfo\0".  */
+      if (name_len != 8
+         && strcmp ((const char *) ptr, "APUinfo") != 0)
+       break;
+      ptr += name_len;
+
+      /* The type must be 2.  */
+      if (type != 2)
+       break;
+
+      /* The data is stored as a series of uint32.  The upper half of
+        each uint32 indicates the particular APU used and the lower
+        half indicates the revision of that APU.  We just care about
+        the upper half.  */
+
+      /* Not 4-byte quantities.  */
+      if (data_len & 3U)
+       break;
+
+      while (data_len)
+       {
+         unsigned int apuinfo = bfd_get_32 (abfd, ptr);
+         unsigned int apu = apuinfo >> 16;
+         ptr += 4;
+         data_len -= 4;
+
+         /* The SPE APU is 0x100; the SPEFP APU is 0x101.  Accept
+            either.  */
+         if (apu == 0x100 || apu == 0x101)
+           {
+             success = 1;
+             data_len = 0;
+           }
+       }
+
+      if (success)
+       break;
+    }
+
+  xfree (contents);
+  return success;
+}
+
 /* 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.
@@ -3361,10 +3555,10 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   enum bfd_architecture arch;
   unsigned long mach;
   bfd abfd;
-  asection *sect;
   enum auto_boolean soft_float_flag = powerpc_soft_float_global;
   int soft_float;
   enum powerpc_vector_abi vector_abi = powerpc_vector_abi_global;
+  enum powerpc_elf_abi elf_abi = POWERPC_ELF_AUTO;
   int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0, have_dfp = 0,
       have_vsx = 0;
   int tdesc_wordsize = -1;
@@ -3425,19 +3619,15 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      Application-specific Processing Unit that is present on the
      chip.  The content of the section is determined by the assembler
      which looks at each instruction and determines which unit (and
-     which version of it) can execute it. In our case we just look for
-     the existance of the section.  */
+     which version of it) can execute it.  Grovel through the section
+     looking for relevant e500 APUs.  */
 
-  if (info.abfd)
+  if (bfd_uses_spe_extensions (info.abfd))
     {
-      sect = bfd_get_section_by_name (info.abfd, ".PPC.EMB.apuinfo");
-      if (sect)
-       {
-         arch = info.bfd_arch_info->arch;
-         mach = bfd_mach_ppc_e500;
-         bfd_default_set_arch_mach (&abfd, arch, mach);
-         info.bfd_arch_info = bfd_get_arch_info (&abfd);
-       }
+      arch = info.bfd_arch_info->arch;
+      mach = bfd_mach_ppc_e500;
+      bfd_default_set_arch_mach (&abfd, arch, mach);
+      info.bfd_arch_info = bfd_get_arch_info (&abfd);
     }
 
   /* Find a default target description which describes our register
@@ -3465,10 +3655,6 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
        "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
       };
-      static const char *const segment_regs[] = {
-       "sr0", "sr1", "sr2", "sr3", "sr4", "sr5", "sr6", "sr7",
-       "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15"
-      };
       const struct tdesc_feature *feature;
       int i, valid_p;
       static const char *const msr_names[] = { "msr", "ps" };
@@ -3675,6 +3861,21 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     }
 
 #ifdef HAVE_ELF
+  if (from_elf_exec)
+    {
+      switch (elf_elfheader (info.abfd)->e_flags & EF_PPC64_ABI)
+       {
+       case 1:
+         elf_abi = POWERPC_ELF_V1;
+         break;
+       case 2:
+         elf_abi = POWERPC_ELF_V2;
+         break;
+       default:
+         break;
+       }
+    }
+
   if (soft_float_flag == AUTO_BOOLEAN_AUTO && from_elf_exec)
     {
       switch (bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_GNU,
@@ -3711,6 +3912,21 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     }
 #endif
 
+  /* At this point, the only supported ELF-based 64-bit little-endian
+     operating system is GNU/Linux, and this uses the ELFv2 ABI by
+     default.  All other supported ELF-based operating systems use the
+     ELFv1 ABI by default.  Therefore, if the ABI marker is missing,
+     e.g. because we run a legacy binary, or have attached to a process
+     and have not found any associated binary file, set the default
+     according to this heuristic.  */
+  if (elf_abi == POWERPC_ELF_AUTO)
+    {
+      if (wordsize == 8 && info.byte_order == BFD_ENDIAN_LITTLE)
+        elf_abi = POWERPC_ELF_V2;
+      else
+        elf_abi = POWERPC_ELF_V1;
+    }
+
   if (soft_float_flag == AUTO_BOOLEAN_TRUE)
     soft_float = 1;
   else if (soft_float_flag == AUTO_BOOLEAN_FALSE)
@@ -3753,6 +3969,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
          meaningful, because 64-bit CPUs can run in 32-bit mode.  So, perform
          separate word size check.  */
       tdep = gdbarch_tdep (arches->gdbarch);
+      if (tdep && tdep->elf_abi != elf_abi)
+       continue;
       if (tdep && tdep->soft_float != soft_float)
        continue;
       if (tdep && tdep->vector_abi != vector_abi)
@@ -3773,8 +3991,9 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        - "set arch"            trust blindly
        - GDB startup           useless but harmless */
 
-  tdep = XCALLOC (1, struct gdbarch_tdep);
+  tdep = XCNEW (struct gdbarch_tdep);
   tdep->wordsize = wordsize;
+  tdep->elf_abi = elf_abi;
   tdep->soft_float = soft_float;
   tdep->vector_abi = vector_abi;
 
@@ -3823,7 +4042,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   if (have_spe || have_dfp || have_vsx)
     {
       set_gdbarch_pseudo_register_read (gdbarch, rs6000_pseudo_register_read);
-      set_gdbarch_pseudo_register_write (gdbarch, rs6000_pseudo_register_write);
+      set_gdbarch_pseudo_register_write (gdbarch,
+                                        rs6000_pseudo_register_write);
     }
 
   set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
@@ -3881,13 +4101,13 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc);
 
   /* The value of symbols of type N_SO and N_FUN maybe null when
-     it shouldn't be. */
+     it shouldn't be.  */
   set_gdbarch_sofun_address_maybe_missing (gdbarch, 1);
 
   /* Handles single stepping of atomic sequences.  */
   set_gdbarch_software_single_step (gdbarch, ppc_deal_with_atomic_sequence);
   
-  /* Not sure on this. FIXMEmgo */
+  /* Not sure on this.  FIXMEmgo */
   set_gdbarch_frame_args_skip (gdbarch, 8);
 
   /* Helpers for function argument information.  */
@@ -3981,6 +4201,12 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   gdb_assert (gdbarch_num_regs (gdbarch)
              + gdbarch_num_pseudo_regs (gdbarch) == cur_reg);
 
+  /* Register the ravenscar_arch_ops.  */
+  if (mach == bfd_mach_ppc_e500)
+    register_e500_ravenscar_ops (gdbarch);
+  else
+    register_ppc_ravenscar_ops (gdbarch);
+
   return gdbarch;
 }
 
@@ -4020,7 +4246,7 @@ powerpc_set_soft_float (char *args, int from_tty,
   /* Update the architecture.  */
   gdbarch_info_init (&info);
   if (!gdbarch_update_p (info))
-    internal_error (__FILE__, __LINE__, "could not update architecture");
+    internal_error (__FILE__, __LINE__, _("could not update architecture"));
 }
 
 static void
@@ -4047,12 +4273,92 @@ powerpc_set_vector_abi (char *args, int from_tty,
   /* Update the architecture.  */
   gdbarch_info_init (&info);
   if (!gdbarch_update_p (info))
-    internal_error (__FILE__, __LINE__, "could not update architecture");
+    internal_error (__FILE__, __LINE__, _("could not update architecture"));
+}
+
+/* Show the current setting of the exact watchpoints flag.  */
+
+static void
+show_powerpc_exact_watchpoints (struct ui_file *file, int from_tty,
+                               struct cmd_list_element *c,
+                               const char *value)
+{
+  fprintf_filtered (file, _("Use of exact watchpoints is %s.\n"), value);
+}
+
+/* Read a PPC instruction from memory.  */
+
+static unsigned int
+read_insn (struct frame_info *frame, CORE_ADDR pc)
+{
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
+  return read_memory_unsigned_integer (pc, 4, byte_order);
+}
+
+/* Return non-zero if the instructions at PC match the series
+   described in PATTERN, or zero otherwise.  PATTERN is an array of
+   'struct ppc_insn_pattern' objects, terminated by an entry whose
+   mask is zero.
+
+   When the match is successful, fill INSN[i] with what PATTERN[i]
+   matched.  If PATTERN[i] is optional, and the instruction wasn't
+   present, set INSN[i] to 0 (which is not a valid PPC instruction).
+   INSN should have as many elements as PATTERN.  Note that, if
+   PATTERN contains optional instructions which aren't present in
+   memory, then INSN will have holes, so INSN[i] isn't necessarily the
+   i'th instruction in memory.  */
+
+int
+ppc_insns_match_pattern (struct frame_info *frame, CORE_ADDR pc,
+                        struct ppc_insn_pattern *pattern,
+                        unsigned int *insns)
+{
+  int i;
+  unsigned int insn;
+
+  for (i = 0, insn = 0; pattern[i].mask; i++)
+    {
+      if (insn == 0)
+       insn = read_insn (frame, pc);
+      insns[i] = 0;
+      if ((insn & pattern[i].mask) == pattern[i].data)
+       {
+         insns[i] = insn;
+         pc += 4;
+         insn = 0;
+       }
+      else if (!pattern[i].optional)
+       return 0;
+    }
+
+  return 1;
+}
+
+/* Return the 'd' field of the d-form instruction INSN, properly
+   sign-extended.  */
+
+CORE_ADDR
+ppc_insn_d_field (unsigned int insn)
+{
+  return ((((CORE_ADDR) insn & 0xffff) ^ 0x8000) - 0x8000);
+}
+
+/* Return the 'ds' field of the ds-form instruction INSN, with the two
+   zero bits concatenated at the right, and properly
+   sign-extended.  */
+
+CORE_ADDR
+ppc_insn_ds_field (unsigned int insn)
+{
+  return ((((CORE_ADDR) insn & 0xfffc) ^ 0x8000) - 0x8000);
 }
 
 /* Initialization code.  */
 
-extern initialize_file_ftype _initialize_rs6000_tdep; /* -Wmissing-prototypes */
+/* -Wmissing-prototypes */
+extern initialize_file_ftype _initialize_rs6000_tdep;
 
 void
 _initialize_rs6000_tdep (void)
@@ -4106,4 +4412,17 @@ _initialize_rs6000_tdep (void)
                        _("Show the vector ABI."),
                        NULL, powerpc_set_vector_abi, NULL,
                        &setpowerpccmdlist, &showpowerpccmdlist);
+
+  add_setshow_boolean_cmd ("exact-watchpoints", class_support,
+                          &target_exact_watchpoints,
+                          _("\
+Set whether to use just one debug register for watchpoints on scalars."),
+                          _("\
+Show whether to use just one debug register for watchpoints on scalars."),
+                          _("\
+If true, GDB will use only one debug register when watching a variable of\n\
+scalar type, thus assuming that the variable is accessed through the address\n\
+of its first byte."),
+                          NULL, show_powerpc_exact_watchpoints,
+                          &setpowerpccmdlist, &showpowerpccmdlist);
 }