]> 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 fa00cc4543759376478d611d6a2229e1c62b48c6..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
-   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"
@@ -66,6 +67,7 @@
 #include "features/rs6000/powerpc-vsx32.c"
 #include "features/rs6000/powerpc-403.c"
 #include "features/rs6000/powerpc-403gc.c"
+#include "features/rs6000/powerpc-405.c"
 #include "features/rs6000/powerpc-505.c"
 #include "features/rs6000/powerpc-601.c"
 #include "features/rs6000/powerpc-602.c"
 /* 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.  */
@@ -108,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",
@@ -121,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
   {
@@ -134,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 */
@@ -216,7 +218,7 @@ ppc_floating_point_unit_p (struct gdbarch *gdbarch)
 
 /* Return non-zero if the architecture described by GDBARCH has
    VSX registers (vsr0 --- vsr63).  */
-int
+static int
 ppc_vsx_support_p (struct gdbarch *gdbarch)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
@@ -874,6 +876,7 @@ static int
 rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   struct gdbarch_tdep *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;
   unsigned long insn;
@@ -898,7 +901,7 @@ rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
     {
       if (!safe_frame_unwind_memory (curfrm, scan_pc, insn_buf, PPC_INSN_SIZE))
         return 0;
-      insn = extract_unsigned_integer (insn_buf, PPC_INSN_SIZE);
+      insn = extract_unsigned_integer (insn_buf, PPC_INSN_SIZE, byte_order);
       if (insn == 0x4e800020)
         break;
       /* Assume a bctr is a tail call unless it points strictly within
@@ -924,7 +927,7 @@ rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
     {
       if (!safe_frame_unwind_memory (curfrm, scan_pc, insn_buf, PPC_INSN_SIZE))
         return 0;
-      insn = extract_unsigned_integer (insn_buf, PPC_INSN_SIZE);
+      insn = extract_unsigned_integer (insn_buf, PPC_INSN_SIZE, byte_order);
       if (insn_changes_sp_or_jumps (insn))
         return 1;
     }
@@ -942,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)
 {
@@ -965,16 +968,17 @@ rs6000_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
 
 /* Fix up the state of registers and memory after having single-stepped
    a displaced instruction.  */
-void
+static void
 ppc_displaced_step_fixup (struct gdbarch *gdbarch,
-                          struct displaced_step_closure *closure,
-                          CORE_ADDR from, CORE_ADDR to,
-                          struct regcache *regs)
+                         struct displaced_step_closure *closure,
+                         CORE_ADDR from, CORE_ADDR to,
+                         struct regcache *regs)
 {
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   /* Since we use simple_displaced_step_copy_insn, our closure is a
      copy of the instruction.  */
   ULONGEST insn  = extract_unsigned_integer ((gdb_byte *) closure,
-                                             PPC_INSN_SIZE);
+                                             PPC_INSN_SIZE, byte_order);
   ULONGEST opcode = 0;
   /* Offset for non PC-relative instructions.  */
   LONGEST offset = PPC_INSN_SIZE;
@@ -983,8 +987,8 @@ ppc_displaced_step_fixup (struct gdbarch *gdbarch,
 
   if (debug_displaced)
     fprintf_unfiltered (gdb_stdlog,
-                       "displaced: (ppc) fixup (0x%s, 0x%s)\n",
-                       paddr_nz (from), paddr_nz (to));
+                       "displaced: (ppc) fixup (%s, %s)\n",
+                       paddress (gdbarch, from), paddress (gdbarch, to));
 
 
   /* Handle PC-relative branch instructions.  */
@@ -1009,12 +1013,13 @@ ppc_displaced_step_fixup (struct gdbarch *gdbarch,
              if (debug_displaced)
                fprintf_unfiltered
                  (gdb_stdlog,
-                  "displaced: (ppc) branch instruction: 0x%s\n"
-                  "displaced: (ppc) adjusted PC from 0x%s to 0x%s\n",
-                  paddr_nz (insn), paddr_nz (current_pc),
-                  paddr_nz (from + offset));
+                  "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));
 
-             regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch),
+             regcache_cooked_write_unsigned (regs,
+                                             gdbarch_pc_regnum (gdbarch),
                                              from + offset);
            }
        }
@@ -1040,8 +1045,8 @@ ppc_displaced_step_fixup (struct gdbarch *gdbarch,
                                          from + PPC_INSN_SIZE);
          if (debug_displaced)
                fprintf_unfiltered (gdb_stdlog,
-                                   "displaced: (ppc) adjusted LR to 0x%s\n",
-                                   paddr_nz (from + PPC_INSN_SIZE));
+                                   "displaced: (ppc) adjusted LR to %s\n",
+                                   paddress (gdbarch, from + PPC_INSN_SIZE));
 
        }
     }
@@ -1055,6 +1060,15 @@ ppc_displaced_step_fixup (struct gdbarch *gdbarch,
                                    from + offset);
 }
 
+/* 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)
+{
+  return 1;
+}
+
 /* Instruction masks used during single-stepping of atomic sequences.  */
 #define LWARX_MASK 0xfc0007fe
 #define LWARX_INSTRUCTION 0x7c000028
@@ -1071,11 +1085,14 @@ ppc_displaced_step_fixup (struct gdbarch *gdbarch,
 int 
 ppc_deal_with_atomic_sequence (struct frame_info *frame)
 {
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  struct address_space *aspace = get_frame_address_space (frame);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   CORE_ADDR pc = get_frame_pc (frame);
   CORE_ADDR breaks[2] = {-1, -1};
   CORE_ADDR loc = pc;
   CORE_ADDR closing_insn; /* Instruction that closes the atomic sequence.  */
-  int insn = read_memory_integer (loc, PPC_INSN_SIZE);
+  int insn = read_memory_integer (loc, PPC_INSN_SIZE, byte_order);
   int insn_count;
   int index;
   int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed).  */  
@@ -1093,15 +1110,15 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame)
   for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count)
     {
       loc += PPC_INSN_SIZE;
-      insn = read_memory_integer (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 & ~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 
@@ -1110,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++;
@@ -1128,22 +1145,21 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame)
 
   closing_insn = loc;
   loc += PPC_INSN_SIZE;
-  insn = read_memory_integer (loc, PPC_INSN_SIZE);
+  insn = read_memory_integer (loc, PPC_INSN_SIZE, byte_order);
 
   /* Insert a breakpoint right after the end of the atomic sequence.  */
   breaks[0] = loc;
 
   /* 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.  */
   for (index = 0; index <= last_breakpoint; index++)
-    insert_single_step_breakpoint (breaks[index]);
+    insert_single_step_breakpoint (gdbarch, aspace, breaks[index]);
 
   return 1;
 }
@@ -1239,7 +1255,7 @@ store_param_on_stack_p (unsigned long op, int framep, int *r0_contains_arg)
    they can use to access PIC data using PC-relative offsets.  */
 
 static int
-bl_to_blrl_insn_p (CORE_ADDR pc, int insn)
+bl_to_blrl_insn_p (CORE_ADDR pc, int insn, enum bfd_endian byte_order)
 {
   CORE_ADDR dest;
   int immediate;
@@ -1253,14 +1269,14 @@ bl_to_blrl_insn_p (CORE_ADDR pc, int insn)
   else
     dest = pc + immediate;
 
-  dest_insn = read_memory_integer (dest, 4);
+  dest_insn = read_memory_integer (dest, 4, byte_order);
   if ((dest_insn & 0xfc00ffff) == 0x4c000021) /* blrl */
     return 1;
 
   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
@@ -1274,6 +1290,186 @@ bl_to_blrl_insn_p (CORE_ADDR pc, int insn)
 #define BL_INSTRUCTION 0x48000001
 #define BL_DISPLACEMENT_MASK 0x03fffffc
 
+static unsigned long
+rs6000_fetch_instruction (struct gdbarch *gdbarch, const CORE_ADDR pc)
+{
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  gdb_byte buf[4];
+  unsigned long op;
+
+  /* Fetch the instruction and convert it to an integer.  */
+  if (target_read_memory (pc, buf, 4))
+    return 0;
+  op = extract_unsigned_integer (buf, 4, byte_order);
+
+  return op;
+}
+
+/* GCC generates several well-known sequences of instructions at the begining
+   of each function prologue when compiling with -fstack-check.  If one of
+   such sequences starts at START_PC, then return the address of the
+   instruction immediately past this sequence.  Otherwise, return START_PC.  */
+   
+static CORE_ADDR
+rs6000_skip_stack_check (struct gdbarch *gdbarch, const CORE_ADDR start_pc)
+{
+  CORE_ADDR pc = 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].  */
+  
+  if ((op & 0xffff0000) == 0x90010000)
+    {
+      while ((op & 0xffff0000) == 0x90010000)
+        {
+          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)].  */
+
+  while (1)
+    {
+      /* addi 12,1,-<some immediate> */
+      if ((op & 0xffff0000) != 0x39810000)
+        break;
+
+      /* lis 0,-<some immediate> */
+      pc = pc + 4;
+      op = rs6000_fetch_instruction (gdbarch, pc);
+      if ((op & 0xffff0000) != 0x3c000000)
+        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);
+        }
+      /* add 0,12,0 */
+      if (op != 0x7c0c0214)
+        break;
+
+      /* cmpw 0,12,0 */
+      pc = pc + 4;
+      op = rs6000_fetch_instruction (gdbarch, pc);
+      if (op != 0x7c0c0000)
+        break;
+
+      /* beq 0,<disp> */
+      pc = pc + 4;
+      op = rs6000_fetch_instruction (gdbarch, pc);
+      if ((op & 0xff9f0001) != 0x41820000)
+        break;
+
+      /* addi 12,12,-<some immediate> */
+      pc = pc + 4;
+      op = rs6000_fetch_instruction (gdbarch, pc);
+      if ((op & 0xffff0000) != 0x398c0000)
+        break;
+
+      /* stw 0,0(12) */
+      pc = pc + 4;
+      op = rs6000_fetch_instruction (gdbarch, pc);
+      if (op != 0x900c0000)
+        break;
+
+      /* b <disp> */
+      pc = pc + 4;
+      op = rs6000_fetch_instruction (gdbarch, pc);
+      if ((op & 0xfc000001) != 0x48000000)
+        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);
+        }
+
+      /* We found a valid stack-check sequence, return the new PC.  */
+      return pc;
+    }
+
+  /* Third sequence: No probe; instead, a comparizon 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
+
+     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
+  */
+  while (1)
+    {
+      /* addi 0,1,-<some immediate> */
+      if ((op & 0xffff0000) != 0x38010000)
+        {
+          /* small stack frame variant not recognized; try the
+             big stack frame variant: */
+
+          /* 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;
+        }
+
+      /* lis 12,<some immediate> */
+      pc = pc + 4;
+      op = rs6000_fetch_instruction (gdbarch, pc);
+      if ((op & 0xffff0000) != 0x3d800000)
+        break;
+      
+      /* lwz 12,<some immediate>(12) */
+      pc = pc + 4;
+      op = rs6000_fetch_instruction (gdbarch, pc);
+      if ((op & 0xffff0000) != 0x818c0000)
+        break;
+
+      /* twllt 0,12 */
+      pc = pc + 4;
+      op = rs6000_fetch_instruction (gdbarch, pc);
+      if ((op & 0xfffffffe) != 0x7c406008)
+        break;
+
+      /* We found a valid stack-check sequence, return the new PC.  */
+      return pc;
+    }
+
+  /* No stack check code in our prologue, return the start_pc.  */
+  return start_pc;
+}
+
 /* return pc value after skipping a function prologue and also return
    information about a function frame.
 
@@ -1294,8 +1490,7 @@ bl_to_blrl_insn_p (CORE_ADDR pc, int insn)
    - 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,
@@ -1322,6 +1517,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
   int r0_contains_arg = 0;
   const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (gdbarch);
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
 
   memset (fdata, 0, sizeof (struct rs6000_framedata));
   fdata->saved_gpr = -1;
@@ -1333,12 +1529,16 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
   fdata->nosavedpc = 1;
   fdata->lr_register = -1;
 
+  pc = rs6000_skip_stack_check (gdbarch, pc);
+  if (pc >= lim_pc)
+    pc = 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
         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;
 
@@ -1351,7 +1551,7 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
       /* Fetch the instruction and convert it to an integer.  */
       if (target_read_memory (pc, buf, 4))
        break;
-      op = extract_unsigned_integer (buf, 4);
+      op = extract_unsigned_integer (buf, 4, byte_order);
 
       if ((op & 0xfc1fffff) == 0x7c0802a6)
        {                       /* mflr Rx */
@@ -1418,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;
@@ -1438,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;
@@ -1517,13 +1727,13 @@ 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;
 
          /* 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))
+          if (lr_reg != -1 && bl_to_blrl_insn_p (pc, op, byte_order))
            {
              fdata->used_bl = 1;
              continue;
@@ -1539,20 +1749,21 @@ 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;
            }
 
-         op = read_memory_integer (pc + 4, 4);
+         op = read_memory_integer (pc + 4, 4, byte_order);
 
          /* 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;
@@ -1567,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;
@@ -1581,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;
@@ -1595,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)
        {
@@ -1609,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;
 
@@ -1622,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 */
@@ -1691,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;
        }
@@ -1849,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,
@@ -1860,8 +2081,8 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
 
 
   if ((op & 0xfc000001) == 0x48000001)
-    {                          /* bl foo, an initializer function? */
-      op = read_memory_integer (pc + 4, 4);
+    {                          /* bl foo, an initializer function?  */
+      op = read_memory_integer (pc + 4, 4, byte_order);
 
       if (op == 0x4def7b82)
        {                       /* cror 0xf, 0xf, 0xf (nop) */
@@ -1888,14 +2109,15 @@ 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 (func_addr);
+      CORE_ADDR post_prologue_pc
+       = skip_prologue_using_sal (gdbarch, func_addr);
       if (post_prologue_pc != 0)
        return max (pc, post_prologue_pc);
     }
@@ -1906,10 +2128,15 @@ rs6000_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
   /* Find an upper limit on the function prologue using the debug
      information.  If the debug information could not be used to provide
      that bound, then use an arbitrary large number as the upper bound.  */
-  limit_pc = skip_prologue_using_sal (pc);
+  limit_pc = skip_prologue_using_sal (gdbarch, 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;
 }
@@ -1922,29 +2149,30 @@ rs6000_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
    address of the instruction following that call.  Otherwise, it simply
    returns PC.  */
 
-CORE_ADDR
+static CORE_ADDR
 rs6000_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   gdb_byte buf[4];
   unsigned long op;
 
   if (target_read_memory (pc, buf, 4))
     return pc;
-  op = extract_unsigned_integer (buf, 4);
+  op = extract_unsigned_integer (buf, 4, byte_order);
 
   if ((op & BL_MASK) == BL_INSTRUCTION)
     {
       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;
@@ -1980,8 +2208,9 @@ rs6000_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
    gdbarch_skip_trampoline_code hooks in handle_inferior_event() to skip past
    @FIX code.  */
 
-int
-rs6000_in_solib_return_trampoline (CORE_ADDR pc, char *name)
+static int
+rs6000_in_solib_return_trampoline (struct gdbarch *gdbarch,
+                                  CORE_ADDR pc, const char *name)
 {
   return name && !strncmp (name, "@FIX", 4);
 }
@@ -2000,14 +2229,16 @@ rs6000_in_solib_return_trampoline (CORE_ADDR pc, char *name)
    Result is desired PC to step until, or NULL if we are not in
    code that should be skipped.  */
 
-CORE_ADDR
+static CORE_ADDR
 rs6000_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   unsigned int ii, op;
   int rel;
   CORE_ADDR solib_target_pc;
-  struct minimal_symbol *msymbol;
+  struct bound_minimal_symbol msymbol;
 
   static unsigned trampoline_code[] =
   {
@@ -2023,11 +2254,12 @@ 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 
-      && rs6000_in_solib_return_trampoline (pc, SYMBOL_LINKAGE_NAME (msymbol)))
+  if (msymbol.minsym
+      && rs6000_in_solib_return_trampoline (gdbarch, pc,
+                                           MSYMBOL_LINKAGE_NAME (msymbol.minsym)))
     {
       /* Double-check that the third instruction from PC is relative "b".  */
-      op = read_memory_integer (pc + 8, 4);
+      op = read_memory_integer (pc + 8, 4, byte_order);
       if ((op & 0xfc000003) == 0x48000000)
        {
          /* Extract bits 6-29 as a signed 24-bit relative word address and
@@ -2044,12 +2276,13 @@ rs6000_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
 
   for (ii = 0; trampoline_code[ii]; ++ii)
     {
-      op = read_memory_integer (pc + (ii * 4), 4);
+      op = read_memory_integer (pc + (ii * 4), 4, byte_order);
       if (op != trampoline_code[ii])
        return 0;
     }
-  ii = get_frame_register_unsigned (frame, 11);        /* r11 holds destination addr   */
-  pc = read_memory_unsigned_integer (ii, tdep->wordsize); /* (r11) value */
+  ii = get_frame_register_unsigned (frame, 11);        /* r11 holds destination
+                                                  addr.  */
+  pc = read_memory_unsigned_integer (ii, tdep->wordsize, byte_order);
   return pc;
 }
 
@@ -2062,6 +2295,8 @@ rs6000_builtin_type_vec64 (struct gdbarch *gdbarch)
 
   if (!tdep->ppc_builtin_type_vec64)
     {
+      const struct builtin_type *bt = builtin_type (gdbarch);
+
       /* The type we're building is this: */
 #if 0
       union __gdb_builtin_type_vec64
@@ -2076,16 +2311,17 @@ rs6000_builtin_type_vec64 (struct gdbarch *gdbarch)
 
       struct type *t;
 
-      t = init_composite_type ("__ppc_builtin_type_vec64", TYPE_CODE_UNION);
-      append_composite_type_field (t, "uint64", builtin_type_int64);
+      t = arch_composite_type (gdbarch,
+                              "__ppc_builtin_type_vec64", TYPE_CODE_UNION);
+      append_composite_type_field (t, "uint64", bt->builtin_int64);
       append_composite_type_field (t, "v2_float",
-                                  init_vector_type (builtin_type_float, 2));
+                                  init_vector_type (bt->builtin_float, 2));
       append_composite_type_field (t, "v2_int32",
-                                  init_vector_type (builtin_type_int32, 2));
+                                  init_vector_type (bt->builtin_int32, 2));
       append_composite_type_field (t, "v4_int16",
-                                  init_vector_type (builtin_type_int16, 4));
+                                  init_vector_type (bt->builtin_int16, 4));
       append_composite_type_field (t, "v8_int8",
-                                  init_vector_type (builtin_type_int8, 8));
+                                  init_vector_type (bt->builtin_int8, 8));
 
       TYPE_VECTOR (t) = 1;
       TYPE_NAME (t) = "ppc_builtin_type_vec64";
@@ -2104,10 +2340,13 @@ rs6000_builtin_type_vec128 (struct gdbarch *gdbarch)
 
   if (!tdep->ppc_builtin_type_vec128)
     {
+      const struct builtin_type *bt = builtin_type (gdbarch);
+
       /* The type we're building is this
 
         type = union __ppc_builtin_type_vec128 {
             uint128_t uint128;
+            double v2_double[2];
             float v4_float[4];
             int32_t v4_int32[4];
             int16_t v8_int16[8];
@@ -2117,18 +2356,21 @@ rs6000_builtin_type_vec128 (struct gdbarch *gdbarch)
 
       struct type *t;
 
-      t = init_composite_type ("__ppc_builtin_type_vec128", TYPE_CODE_UNION);
-      append_composite_type_field (t, "uint128", builtin_type_uint128);
+      t = arch_composite_type (gdbarch,
+                              "__ppc_builtin_type_vec128", TYPE_CODE_UNION);
+      append_composite_type_field (t, "uint128", bt->builtin_uint128);
+      append_composite_type_field (t, "v2_double",
+                                  init_vector_type (bt->builtin_double, 2));
       append_composite_type_field (t, "v4_float",
-                                  init_vector_type (builtin_type (gdbarch)->builtin_float, 4));
+                                  init_vector_type (bt->builtin_float, 4));
       append_composite_type_field (t, "v4_int32",
-                                  init_vector_type (builtin_type_int32, 4));
+                                  init_vector_type (bt->builtin_int32, 4));
       append_composite_type_field (t, "v8_int16",
-                                  init_vector_type (builtin_type_int16, 8));
+                                  init_vector_type (bt->builtin_int16, 8));
       append_composite_type_field (t, "v16_int8",
-                                  init_vector_type (builtin_type_int8, 16));
+                                  init_vector_type (bt->builtin_int8, 16));
 
-      TYPE_FLAGS (t) |= TYPE_FLAG_VECTOR;
+      TYPE_VECTOR (t) = 1;
       TYPE_NAME (t) = "ppc_builtin_type_vec128";
       tdep->ppc_builtin_type_vec128 = t;
     }
@@ -2277,21 +2519,31 @@ rs6000_convert_register_p (struct gdbarch *gdbarch, int regnum,
          && regnum >= tdep->ppc_fp0_regnum
          && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs
          && TYPE_CODE (type) == TYPE_CODE_FLT
-         && TYPE_LENGTH (type) != TYPE_LENGTH (builtin_type_double));
+         && TYPE_LENGTH (type)
+            != 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);
-  convert_typed_floating (from, builtin_type_double, to, type);
+  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
@@ -2300,14 +2552,21 @@ rs6000_value_to_register (struct frame_info *frame,
                           struct type *type,
                           const gdb_byte *from)
 {
+  struct gdbarch *gdbarch = get_frame_arch (frame);
   gdb_byte to[MAX_REGISTER_SIZE];
 
   gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
 
-  convert_typed_floating (from, type, to, builtin_type_double);
+  convert_typed_floating (from, type,
+                         to, builtin_type (gdbarch)->builtin_double);
   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
@@ -2331,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));
 
@@ -2348,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.  */
@@ -2419,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.  */
@@ -2486,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.  */
@@ -2505,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);
@@ -2521,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: "
@@ -2576,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)
       {
@@ -2618,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)
       {
@@ -2740,6 +3034,8 @@ static struct variant variants[] =
    bfd_mach_rs6k, &tdesc_rs6000},
   {"403", "IBM PowerPC 403", bfd_arch_powerpc,
    bfd_mach_ppc_403, &tdesc_powerpc_403},
+  {"405", "IBM PowerPC 405", bfd_arch_powerpc,
+   bfd_mach_ppc_405, &tdesc_powerpc_405},
   {"601", "Motorola PowerPC 601", bfd_arch_powerpc,
    bfd_mach_ppc_601, &tdesc_powerpc_601},
   {"602", "Motorola PowerPC 602", bfd_arch_powerpc,
@@ -2804,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
@@ -2841,6 +3134,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);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct rs6000_framedata fdata;
   int wordsize = tdep->wordsize;
   CORE_ADDR func, pc;
@@ -2898,7 +3192,8 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
 
   if (!fdata.frameless)
     /* Frameless really means stackless.  */
-    cache->base = read_memory_unsigned_integer (cache->base, wordsize);
+    cache->base
+      = read_memory_unsigned_integer (cache->base, wordsize, byte_order);
 
   trad_frame_set_value (cache->saved_regs,
                        gdbarch_sp_regnum (gdbarch), cache->base);
@@ -2956,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.  */
@@ -2990,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
@@ -3029,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,
@@ -3119,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.
@@ -3135,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;
@@ -3147,6 +3567,16 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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;
 
@@ -3189,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
@@ -3229,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" };
@@ -3439,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,
@@ -3475,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)
@@ -3517,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)
@@ -3537,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;
 
@@ -3587,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);
@@ -3645,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.  */
@@ -3669,6 +4125,19 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Frame handling.  */
   dwarf2_frame_set_init_reg (gdbarch, ppc_dwarf2_frame_init_reg);
 
+  /* Setup displaced stepping.  */
+  set_gdbarch_displaced_step_copy_insn (gdbarch,
+                                       simple_displaced_step_copy_insn);
+  set_gdbarch_displaced_step_hw_singlestep (gdbarch,
+                                           ppc_displaced_step_hw_singlestep);
+  set_gdbarch_displaced_step_fixup (gdbarch, ppc_displaced_step_fixup);
+  set_gdbarch_displaced_step_free_closure (gdbarch,
+                                          simple_displaced_step_free_closure);
+  set_gdbarch_displaced_step_location (gdbarch,
+                                      displaced_step_at_entry_point);
+
+  set_gdbarch_max_insn_length (gdbarch, PPC_INSN_SIZE);
+
   /* Hook in ABI-specific overrides, if they have been registered.  */
   info.target_desc = tdesc;
   info.tdep_info = (void *) tdesc_data;
@@ -3732,16 +4201,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   gdb_assert (gdbarch_num_regs (gdbarch)
              + gdbarch_num_pseudo_regs (gdbarch) == cur_reg);
 
-  /* Setup displaced stepping.  */
-  set_gdbarch_displaced_step_copy_insn (gdbarch,
-                                       simple_displaced_step_copy_insn);
-  set_gdbarch_displaced_step_fixup (gdbarch, ppc_displaced_step_fixup);
-  set_gdbarch_displaced_step_free_closure (gdbarch,
-                                          simple_displaced_step_free_closure);
-  set_gdbarch_displaced_step_location (gdbarch,
-                                      displaced_step_at_entry_point);
-
-  set_gdbarch_max_insn_length (gdbarch, PPC_INSN_SIZE);
+  /* Register the ravenscar_arch_ops.  */
+  if (mach == bfd_mach_ppc_e500)
+    register_e500_ravenscar_ops (gdbarch);
+  else
+    register_ppc_ravenscar_ops (gdbarch);
 
   return gdbarch;
 }
@@ -3782,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
@@ -3809,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)
@@ -3828,6 +4372,7 @@ _initialize_rs6000_tdep (void)
   initialize_tdesc_powerpc_vsx32 ();
   initialize_tdesc_powerpc_403 ();
   initialize_tdesc_powerpc_403gc ();
+  initialize_tdesc_powerpc_405 ();
   initialize_tdesc_powerpc_505 ();
   initialize_tdesc_powerpc_601 ();
   initialize_tdesc_powerpc_602 ();
@@ -3867,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);
 }