* acinclude.m4: Include ../config/tcl.m4 to pick up
[deliverable/binutils-gdb.git] / gdb / rs6000-tdep.c
index 198f2c84cf930fb92204bf1ff2516e3ae530b834..08f926e91f637a0eeccbb08415e7ce37162957aa 100644 (file)
@@ -1,7 +1,7 @@
 /* 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
+   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -61,9 +61,8 @@
 #include "frame-unwind.h"
 #include "frame-base.h"
 
-#include "rs6000-tdep.h"
-
 #include "features/rs6000/powerpc-32.c"
+#include "features/rs6000/powerpc-altivec32.c"
 #include "features/rs6000/powerpc-403.c"
 #include "features/rs6000/powerpc-403gc.c"
 #include "features/rs6000/powerpc-505.c"
 #include "features/rs6000/powerpc-603.c"
 #include "features/rs6000/powerpc-604.c"
 #include "features/rs6000/powerpc-64.c"
+#include "features/rs6000/powerpc-altivec64.c"
 #include "features/rs6000/powerpc-7400.c"
 #include "features/rs6000/powerpc-750.c"
 #include "features/rs6000/powerpc-860.c"
 #include "features/rs6000/powerpc-e500.c"
 #include "features/rs6000/rs6000.c"
 
+/* Determine if regnum is an SPE pseudo-register.  */
+#define IS_SPE_PSEUDOREG(tdep, regnum) ((tdep)->ppc_ev0_regnum >= 0 \
+    && (regnum) >= (tdep)->ppc_ev0_regnum \
+    && (regnum) < (tdep)->ppc_ev0_regnum + 32)
+
+/* Determine if regnum is a decimal float pseudo-register.  */
+#define IS_DFP_PSEUDOREG(tdep, regnum) ((tdep)->ppc_dl0_regnum >= 0 \
+    && (regnum) >= (tdep)->ppc_dl0_regnum \
+    && (regnum) < (tdep)->ppc_dl0_regnum + 16)
+
 /* The list of available "set powerpc ..." and "show powerpc ..."
    commands.  */
 static struct cmd_list_element *setpowerpccmdlist = NULL;
@@ -99,17 +109,6 @@ 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";
 
-/* If the kernel has to deliver a signal, it pushes a sigcontext
-   structure on the stack and then calls the signal handler, passing
-   the address of the sigcontext in an argument register. Usually
-   the signal handler doesn't save this register, so we have to
-   access the sigcontext structure via an offset from the signal handler
-   frame.
-   The following constants were determined by experimentation on AIX 3.2.  */
-#define SIG_FRAME_PC_OFFSET 96
-#define SIG_FRAME_LR_OFFSET 108
-#define SIG_FRAME_FP_OFFSET 284
-
 /* To be used by skip_prologue. */
 
 struct rs6000_framedata
@@ -133,38 +132,12 @@ struct rs6000_framedata
     int vrsave_offset;          /* offset of saved vrsave register */
   };
 
-/* Description of a single register. */
-
-struct reg
-  {
-    char *name;                        /* name of register */
-    unsigned char sz32;                /* size on 32-bit arch, 0 if nonexistent */
-    unsigned char sz64;                /* size on 64-bit arch, 0 if nonexistent */
-    unsigned char fpr;         /* whether register is floating-point */
-    unsigned char pseudo;       /* whether register is pseudo */
-    int spr_num;                /* PowerPC SPR number, or -1 if not an SPR.
-                                   This is an ISA SPR number, not a GDB
-                                   register number.  */
-  };
-
-/* Hook for determining the TOC address when calling functions in the
-   inferior under AIX. The initialization code in rs6000-nat.c sets
-   this hook to point to find_toc_address.  */
-
-CORE_ADDR (*rs6000_find_toc_address_hook) (CORE_ADDR) = NULL;
-
-/* Static function prototypes */
-
-static CORE_ADDR branch_dest (struct frame_info *frame, int opcode,
-                             int instr, CORE_ADDR pc, CORE_ADDR safety);
-static CORE_ADDR skip_prologue (CORE_ADDR, CORE_ADDR,
-                                struct rs6000_framedata *);
 
 /* Is REGNO an AltiVec register?  Return 1 if so, 0 otherwise.  */
 int
-altivec_register_p (int regno)
+altivec_register_p (struct gdbarch *gdbarch, int regno)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   if (tdep->ppc_vr0_regnum < 0 || tdep->ppc_vrsave_regnum < 0)
     return 0;
   else
@@ -174,14 +147,12 @@ altivec_register_p (int regno)
 
 /* Return true if REGNO is an SPE register, false otherwise.  */
 int
-spe_register_p (int regno)
+spe_register_p (struct gdbarch *gdbarch, int regno)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   
   /* Is it a reference to EV0 -- EV31, and do we have those?  */
-  if (tdep->ppc_ev0_regnum >= 0
-      && tdep->ppc_ev31_regnum >= 0
-      && tdep->ppc_ev0_regnum <= regno && regno <= tdep->ppc_ev31_regnum)
+  if (IS_SPE_PSEUDOREG (tdep, regno))
     return 1;
 
   /* Is it a reference to one of the raw upper GPR halves?  */
@@ -342,17 +313,17 @@ init_sim_regno_table (struct gdbarch *arch)
 /* Given a GDB register number REG, return the corresponding SIM
    register number.  */
 static int
-rs6000_register_sim_regno (int reg)
+rs6000_register_sim_regno (struct gdbarch *gdbarch, int reg)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int sim_regno;
 
   if (tdep->sim_regno == NULL)
-    init_sim_regno_table (current_gdbarch);
+    init_sim_regno_table (gdbarch);
 
   gdb_assert (0 <= reg 
-             && reg <= gdbarch_num_regs (current_gdbarch)
-                       + gdbarch_num_pseudo_regs (current_gdbarch));
+             && reg <= gdbarch_num_regs (gdbarch)
+                       + gdbarch_num_pseudo_regs (gdbarch));
   sim_regno = tdep->sim_regno[reg];
 
   if (sim_regno >= 0)
@@ -368,7 +339,7 @@ rs6000_register_sim_regno (int reg)
 /* REGS + OFFSET contains register REGNUM in a field REGSIZE wide.
    Write the register to REGCACHE.  */
 
-static void
+void
 ppc_supply_reg (struct regcache *regcache, int regnum, 
                const gdb_byte *regs, size_t offset, int regsize)
 {
@@ -389,7 +360,7 @@ ppc_supply_reg (struct regcache *regcache, int regnum,
 /* Read register REGNUM from REGCACHE and store to REGS + OFFSET
    in a field REGSIZE wide.  Zero pad as necessary.  */
 
-static void
+void
 ppc_collect_reg (const struct regcache *regcache, int regnum,
                 gdb_byte *regs, size_t offset, int regsize)
 {
@@ -745,44 +716,6 @@ ppc_collect_vrregset (const struct regset *regset,
 }
 \f
 
-/* Read a LEN-byte address from debugged memory address MEMADDR. */
-
-static CORE_ADDR
-read_memory_addr (CORE_ADDR memaddr, int len)
-{
-  return read_memory_unsigned_integer (memaddr, len);
-}
-
-static CORE_ADDR
-rs6000_skip_prologue (CORE_ADDR pc)
-{
-  struct rs6000_framedata frame;
-  CORE_ADDR limit_pc, func_addr;
-
-  /* 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))
-    {
-      CORE_ADDR post_prologue_pc = skip_prologue_using_sal (func_addr);
-      if (post_prologue_pc != 0)
-       return max (pc, post_prologue_pc);
-    }
-
-  /* Can't determine prologue from the symbol table, need to examine
-     instructions.  */
-
-  /* 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);
-  if (limit_pc == 0)
-    limit_pc = pc + 100;          /* Magic.  */
-
-  pc = skip_prologue (pc, limit_pc, &frame);
-  return pc;
-}
-
 static int
 insn_changes_sp_or_jumps (unsigned long insn)
 {
@@ -893,91 +826,121 @@ rs6000_fetch_pointer_argument (struct frame_info *frame, int argi,
   return get_frame_register_unsigned (frame, 3 + argi);
 }
 
-/* Calculate the destination of a branch/jump.  Return -1 if not a branch.  */
+/* Sequence of bytes for breakpoint instruction.  */
 
-static CORE_ADDR
-branch_dest (struct frame_info *frame, int opcode, int instr,
-            CORE_ADDR pc, CORE_ADDR safety)
+const static unsigned char *
+rs6000_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
+                          int *bp_size)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
-  CORE_ADDR dest;
-  int immediate;
-  int absolute;
-  int ext_op;
+  static unsigned char big_breakpoint[] = { 0x7d, 0x82, 0x10, 0x08 };
+  static unsigned char little_breakpoint[] = { 0x08, 0x10, 0x82, 0x7d };
+  *bp_size = 4;
+  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+    return big_breakpoint;
+  else
+    return little_breakpoint;
+}
 
-  absolute = (int) ((instr >> 1) & 1);
+/* Instruction masks for displaced stepping.  */
+#define BRANCH_MASK 0xfc000000
+#define BP_MASK 0xFC0007FE
+#define B_INSN 0x48000000
+#define BC_INSN 0x40000000
+#define BXL_INSN 0x4c000000
+#define BP_INSN 0x7C000008
 
-  switch (opcode)
-    {
-    case 18:
-      immediate = ((instr & ~3) << 6) >> 6;    /* br unconditional */
-      if (absolute)
-       dest = immediate;
-      else
-       dest = pc + immediate;
-      break;
+/* Fix up the state of registers and memory after having single-stepped
+   a displaced instruction.  */
+void
+ppc_displaced_step_fixup (struct gdbarch *gdbarch,
+                          struct displaced_step_closure *closure,
+                          CORE_ADDR from, CORE_ADDR to,
+                          struct regcache *regs)
+{
+  /* 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);
+  ULONGEST opcode = 0;
+  /* Offset for non PC-relative instructions.  */
+  LONGEST offset = PPC_INSN_SIZE;
 
-    case 16:
-      immediate = ((instr & ~3) << 16) >> 16;  /* br conditional */
-      if (absolute)
-       dest = immediate;
-      else
-       dest = pc + immediate;
-      break;
+  opcode = insn & BRANCH_MASK;
+
+  if (debug_displaced)
+    fprintf_unfiltered (gdb_stdlog,
+                       "displaced: (ppc) fixup (0x%s, 0x%s)\n",
+                       paddr_nz (from), paddr_nz (to));
+
+
+  /* Handle PC-relative branch instructions.  */
+  if (opcode == B_INSN || opcode == BC_INSN || opcode == BXL_INSN)
+    {
+      ULONGEST current_pc;
 
-    case 19:
-      ext_op = (instr >> 1) & 0x3ff;
+      /* Read the current PC value after the instruction has been executed
+        in a displaced location.  Calculate the offset to be applied to the
+        original PC value before the displaced stepping.  */
+      regcache_cooked_read_unsigned (regs, gdbarch_pc_regnum (gdbarch),
+                                     &current_pc);
+      offset = current_pc - to;
 
-      if (ext_op == 16)                /* br conditional register */
+      if (opcode != BXL_INSN)
+       {
+         /* Check for AA bit indicating whether this is an absolute
+            addressing or PC-relative (1: absolute, 0: relative).  */
+         if (!(insn & 0x2))
+           {
+             /* PC-relative addressing is being used in the branch.  */
+             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));
+
+             regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch),
+                                             from + offset);
+           }
+       }
+      else
        {
-          dest = get_frame_register_unsigned (frame, tdep->ppc_lr_regnum) & ~3;
-
-         /* If we are about to return from a signal handler, dest is
-            something like 0x3c90.  The current frame is a signal handler
-            caller frame, upon completion of the sigreturn system call
-            execution will return to the saved PC in the frame.  */
-         if (dest < tdep->text_segment_base)
-           dest = read_memory_addr (get_frame_base (frame) + SIG_FRAME_PC_OFFSET,
-                                    tdep->wordsize);
+         /* If we're here, it means we have a branch to LR or CTR.  If the
+            branch was taken, the offset is probably greater than 4 (the next
+            instruction), so it's safe to assume that an offset of 4 means we
+            did not take the branch.  */
+         if (offset == PPC_INSN_SIZE)
+           regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch),
+                                           from + PPC_INSN_SIZE);
        }
 
-      else if (ext_op == 528)  /* br cond to count reg */
+      /* Check for LK bit indicating whether we should set the link
+        register to point to the next instruction
+        (1: Set, 0: Don't set).  */
+      if (insn & 0x1)
        {
-          dest = get_frame_register_unsigned (frame, tdep->ppc_ctr_regnum) & ~3;
+         /* Link register needs to be set to the next instruction's PC.  */
+         regcache_cooked_write_unsigned (regs,
+                                         gdbarch_tdep (gdbarch)->ppc_lr_regnum,
+                                         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));
 
-         /* If we are about to execute a system call, dest is something
-            like 0x22fc or 0x3b00.  Upon completion the system call
-            will return to the address in the link register.  */
-         if (dest < tdep->text_segment_base)
-            dest = get_frame_register_unsigned (frame, tdep->ppc_lr_regnum) & ~3;
        }
-      else
-       return -1;
-      break;
-
-    default:
-      return -1;
     }
-  return (dest < tdep->text_segment_base) ? safety : dest;
-}
-
-
-/* Sequence of bytes for breakpoint instruction.  */
-
-const static unsigned char *
-rs6000_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
-                          int *bp_size)
-{
-  static unsigned char big_breakpoint[] = { 0x7d, 0x82, 0x10, 0x08 };
-  static unsigned char little_breakpoint[] = { 0x08, 0x10, 0x82, 0x7d };
-  *bp_size = 4;
-  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
-    return big_breakpoint;
+  /* Check for breakpoints in the inferior.  If we've found one, place the PC
+     right at the breakpoint instruction.  */
+  else if ((insn & BP_MASK) == BP_INSN)
+    regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch), from);
   else
-    return little_breakpoint;
+  /* Handle any other instructions that do not fit in the categories above.  */
+    regcache_cooked_write_unsigned (regs, gdbarch_pc_regnum (gdbarch),
+                                   from + offset);
 }
 
-
 /* Instruction masks used during single-stepping of atomic sequences.  */
 #define LWARX_MASK 0xfc0007fe
 #define LWARX_INSTRUCTION 0x7c000028
@@ -985,21 +948,18 @@ rs6000_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
 #define STWCX_MASK 0xfc0007ff
 #define STWCX_INSTRUCTION 0x7c00012d
 #define STDCX_INSTRUCTION 0x7c0001ad
-#define BC_MASK 0xfc000000
-#define BC_INSTRUCTION 0x40000000
 
 /* Checks for an atomic sequence of instructions beginning with a LWARX/LDARX
    instruction and ending with a STWCX/STDCX instruction.  If such a sequence
    is found, attempt to step through it.  A breakpoint is placed at the end of 
    the sequence.  */
 
-static int 
-deal_with_atomic_sequence (struct frame_info *frame)
+int 
+ppc_deal_with_atomic_sequence (struct frame_info *frame)
 {
   CORE_ADDR pc = get_frame_pc (frame);
   CORE_ADDR breaks[2] = {-1, -1};
   CORE_ADDR loc = pc;
-  CORE_ADDR branch_bp; /* Breakpoint at branch instruction's destination.  */
   CORE_ADDR closing_insn; /* Instruction that closes the atomic sequence.  */
   int insn = read_memory_integer (loc, PPC_INSN_SIZE);
   int insn_count;
@@ -1024,21 +984,22 @@ deal_with_atomic_sequence (struct frame_info *frame)
       /* 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 & BC_MASK) == BC_INSTRUCTION)
+      if ((insn & BRANCH_MASK) == BC_INSN)
         {
+          int immediate = ((insn & ~3) << 16) >> 16;
+          int absolute = ((insn >> 1) & 1);
+
           if (bc_insn_count >= 1)
             return 0; /* More than one conditional branch found, fallback 
                          to the standard single-step code.  */
-          
-          opcode = insn >> 26;
-          branch_bp = branch_dest (frame, opcode, insn, pc, breaks[0]);
-          
-          if (branch_bp != -1)
-            {
-              breaks[1] = branch_bp;
-              bc_insn_count++;
-              last_breakpoint++;
-            }
+         if (absolute)
+           breaks[1] = immediate;
+         else
+           breaks[1] = pc + immediate;
+
+         bc_insn_count++;
+         last_breakpoint++;
         }
 
       if ((insn & STWCX_MASK) == STWCX_INSTRUCTION
@@ -1073,48 +1034,6 @@ deal_with_atomic_sequence (struct frame_info *frame)
   return 1;
 }
 
-/* AIX does not support PT_STEP.  Simulate it.  */
-
-int
-rs6000_software_single_step (struct frame_info *frame)
-{
-  CORE_ADDR dummy;
-  int breakp_sz;
-  const gdb_byte *breakp
-    = rs6000_breakpoint_from_pc (get_frame_arch (frame), &dummy, &breakp_sz);
-  int ii, insn;
-  CORE_ADDR loc;
-  CORE_ADDR breaks[2];
-  int opcode;
-
-  loc = get_frame_pc (frame);
-
-  insn = read_memory_integer (loc, 4);
-
-  if (deal_with_atomic_sequence (frame))
-    return 1;
-  
-  breaks[0] = loc + breakp_sz;
-  opcode = insn >> 26;
-  breaks[1] = branch_dest (frame, opcode, insn, loc, breaks[0]);
-
-  /* Don't put two breakpoints on the same address. */
-  if (breaks[1] == breaks[0])
-    breaks[1] = -1;
-
-  for (ii = 0; ii < 2; ++ii)
-    {
-      /* ignore invalid breakpoint. */
-      if (breaks[ii] == -1)
-       continue;
-      insert_single_step_breakpoint (breaks[ii]);
-    }
-
-  errno = 0;                   /* FIXME, don't ignore errors! */
-  /* What errors?  {read,write}_memory call error().  */
-  return 1;
-}
-
 
 #define SIGNED_SHORT(x)                                                \
   ((sizeof (short) == 2)                                               \
@@ -1251,7 +1170,8 @@ bl_to_blrl_insn_p (CORE_ADDR pc, int insn)
  */
 
 static CORE_ADDR
-skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
+skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
+              struct rs6000_framedata *fdata)
 {
   CORE_ADDR orig_pc = pc;
   CORE_ADDR last_prologue_pc = pc;
@@ -1272,8 +1192,8 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
   int prev_insn_was_prologue_insn = 1;
   int num_skip_non_prologue_insns = 0;
   int r0_contains_arg = 0;
-  const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (current_gdbarch);
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   memset (fdata, 0, sizeof (struct rs6000_framedata));
   fdata->saved_gpr = -1;
@@ -1819,390 +1739,42 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
   return last_prologue_pc;
 }
 
-
-/*************************************************************************
-  Support for creating pushing a dummy frame into the stack, and popping
-  frames, etc. 
-*************************************************************************/
-
-
-/* All the ABI's require 16 byte alignment.  */
-static CORE_ADDR
-rs6000_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
-{
-  return (addr & -16);
-}
-
-/* Pass the arguments in either registers, or in the stack. In RS/6000,
-   the first eight words of the argument list (that might be less than
-   eight parameters if some parameters occupy more than one word) are
-   passed in r3..r10 registers.  float and double parameters are
-   passed in fpr's, in addition to that.  Rest of the parameters if any
-   are passed in user stack.  There might be cases in which half of the
-   parameter is copied into registers, the other half is pushed into
-   stack.
-
-   Stack must be aligned on 64-bit boundaries when synthesizing
-   function calls.
-
-   If the function is returning a structure, then the return address is passed
-   in r3, then the first 7 words of the parameters can be passed in registers,
-   starting from r4.  */
-
 static CORE_ADDR
-rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
-                       struct regcache *regcache, CORE_ADDR bp_addr,
-                       int nargs, struct value **args, CORE_ADDR sp,
-                       int struct_return, CORE_ADDR struct_addr)
+rs6000_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  int ii;
-  int len = 0;
-  int argno;                   /* current argument number */
-  int argbytes;                        /* current argument byte */
-  gdb_byte tmp_buffer[50];
-  int f_argno = 0;             /* current floating point argno */
-  int wordsize = gdbarch_tdep (gdbarch)->wordsize;
-  CORE_ADDR func_addr = find_function_addr (function, NULL);
-
-  struct value *arg = 0;
-  struct type *type;
-
-  ULONGEST saved_sp;
-
-  /* The calling convention this function implements assumes the
-     processor has floating-point registers.  We shouldn't be using it
-     on PPC variants that lack them.  */
-  gdb_assert (ppc_floating_point_unit_p (gdbarch));
-
-  /* The first eight words of ther arguments are passed in registers.
-     Copy them appropriately.  */
-  ii = 0;
-
-  /* If the function is returning a `struct', then the first word
-     (which will be passed in r3) is used for struct return address.
-     In that case we should advance one word and start from r4
-     register to copy parameters.  */
-  if (struct_return)
-    {
-      regcache_raw_write_unsigned (regcache, tdep->ppc_gp0_regnum + 3,
-                                  struct_addr);
-      ii++;
-    }
-
-/* 
-   effectively indirect call... gcc does...
-
-   return_val example( float, int);
-
-   eabi: 
-   float in fp0, int in r3
-   offset of stack on overflow 8/16
-   for varargs, must go by type.
-   power open:
-   float in r3&r4, int in r5
-   offset of stack on overflow different 
-   both: 
-   return in r3 or f0.  If no float, must study how gcc emulates floats;
-   pay attention to arg promotion.  
-   User may have to cast\args to handle promotion correctly 
-   since gdb won't know if prototype supplied or not.
- */
+  struct rs6000_framedata frame;
+  CORE_ADDR limit_pc, func_addr;
 
-  for (argno = 0, argbytes = 0; argno < nargs && ii < 8; ++ii)
+  /* 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))
     {
-      int reg_size = register_size (gdbarch, ii + 3);
-
-      arg = args[argno];
-      type = check_typedef (value_type (arg));
-      len = TYPE_LENGTH (type);
-
-      if (TYPE_CODE (type) == TYPE_CODE_FLT)
-       {
-
-         /* Floating point arguments are passed in fpr's, as well as gpr's.
-            There are 13 fpr's reserved for passing parameters. At this point
-            there is no way we would run out of them.  */
-
-         gdb_assert (len <= 8);
-
-         regcache_cooked_write (regcache,
-                                tdep->ppc_fp0_regnum + 1 + f_argno,
-                                value_contents (arg));
-         ++f_argno;
-       }
-
-      if (len > reg_size)
-       {
-
-         /* Argument takes more than one register.  */
-         while (argbytes < len)
-           {
-             gdb_byte word[MAX_REGISTER_SIZE];
-             memset (word, 0, reg_size);
-             memcpy (word,
-                     ((char *) value_contents (arg)) + argbytes,
-                     (len - argbytes) > reg_size
-                       ? reg_size : len - argbytes);
-             regcache_cooked_write (regcache,
-                                   tdep->ppc_gp0_regnum + 3 + ii,
-                                   word);
-             ++ii, argbytes += reg_size;
-
-             if (ii >= 8)
-               goto ran_out_of_registers_for_arguments;
-           }
-         argbytes = 0;
-         --ii;
-       }
-      else
-       {
-         /* Argument can fit in one register.  No problem.  */
-         int adj = gdbarch_byte_order (gdbarch)
-                   == BFD_ENDIAN_BIG ? reg_size - len : 0;
-         gdb_byte word[MAX_REGISTER_SIZE];
-
-         memset (word, 0, reg_size);
-         memcpy (word, value_contents (arg), len);
-         regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3 +ii, word);
-       }
-      ++argno;
+      CORE_ADDR post_prologue_pc = skip_prologue_using_sal (func_addr);
+      if (post_prologue_pc != 0)
+       return max (pc, post_prologue_pc);
     }
 
-ran_out_of_registers_for_arguments:
-
-  regcache_cooked_read_unsigned (regcache,
-                                gdbarch_sp_regnum (gdbarch),
-                                &saved_sp);
-
-  /* Location for 8 parameters are always reserved.  */
-  sp -= wordsize * 8;
-
-  /* Another six words for back chain, TOC register, link register, etc.  */
-  sp -= wordsize * 6;
-
-  /* Stack pointer must be quadword aligned.  */
-  sp &= -16;
-
-  /* If there are more arguments, allocate space for them in 
-     the stack, then push them starting from the ninth one.  */
-
-  if ((argno < nargs) || argbytes)
-    {
-      int space = 0, jj;
-
-      if (argbytes)
-       {
-         space += ((len - argbytes + 3) & -4);
-         jj = argno + 1;
-       }
-      else
-       jj = argno;
-
-      for (; jj < nargs; ++jj)
-       {
-         struct value *val = args[jj];
-         space += ((TYPE_LENGTH (value_type (val))) + 3) & -4;
-       }
-
-      /* Add location required for the rest of the parameters.  */
-      space = (space + 15) & -16;
-      sp -= space;
-
-      /* This is another instance we need to be concerned about
-         securing our stack space. If we write anything underneath %sp
-         (r1), we might conflict with the kernel who thinks he is free
-         to use this area.  So, update %sp first before doing anything
-         else.  */
-
-      regcache_raw_write_signed (regcache,
-                                gdbarch_sp_regnum (gdbarch), sp);
-
-      /* If the last argument copied into the registers didn't fit there 
-         completely, push the rest of it into stack.  */
-
-      if (argbytes)
-       {
-         write_memory (sp + 24 + (ii * 4),
-                       value_contents (arg) + argbytes,
-                       len - argbytes);
-         ++argno;
-         ii += ((len - argbytes + 3) & -4) / 4;
-       }
-
-      /* Push the rest of the arguments into stack.  */
-      for (; argno < nargs; ++argno)
-       {
-
-         arg = args[argno];
-         type = check_typedef (value_type (arg));
-         len = TYPE_LENGTH (type);
-
-
-         /* Float types should be passed in fpr's, as well as in the
-             stack.  */
-         if (TYPE_CODE (type) == TYPE_CODE_FLT && f_argno < 13)
-           {
-
-             gdb_assert (len <= 8);
-
-             regcache_cooked_write (regcache,
-                                    tdep->ppc_fp0_regnum + 1 + f_argno,
-                                    value_contents (arg));
-             ++f_argno;
-           }
-
-         write_memory (sp + 24 + (ii * 4), value_contents (arg), len);
-         ii += ((len + 3) & -4) / 4;
-       }
-    }
+  /* Can't determine prologue from the symbol table, need to examine
+     instructions.  */
 
-  /* Set the stack pointer.  According to the ABI, the SP is meant to
-     be set _before_ the corresponding stack space is used.  On AIX,
-     this even applies when the target has been completely stopped!
-     Not doing this can lead to conflicts with the kernel which thinks
-     that it still has control over this not-yet-allocated stack
-     region.  */
-  regcache_raw_write_signed (regcache, gdbarch_sp_regnum (gdbarch), sp);
-
-  /* Set back chain properly.  */
-  store_unsigned_integer (tmp_buffer, wordsize, saved_sp);
-  write_memory (sp, tmp_buffer, wordsize);
-
-  /* Point the inferior function call's return address at the dummy's
-     breakpoint.  */
-  regcache_raw_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr);
-
-  /* Set the TOC register, get the value from the objfile reader
-     which, in turn, gets it from the VMAP table.  */
-  if (rs6000_find_toc_address_hook != NULL)
-    {
-      CORE_ADDR tocvalue = (*rs6000_find_toc_address_hook) (func_addr);
-      regcache_raw_write_signed (regcache, tdep->ppc_toc_regnum, tocvalue);
-    }
+  /* 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);
+  if (limit_pc == 0)
+    limit_pc = pc + 100;          /* Magic.  */
 
-  target_store_registers (regcache, -1);
-  return sp;
+  pc = skip_prologue (gdbarch, pc, limit_pc, &frame);
+  return pc;
 }
 
-static enum return_value_convention
-rs6000_return_value (struct gdbarch *gdbarch, struct type *valtype,
-                    struct regcache *regcache, gdb_byte *readbuf,
-                    const gdb_byte *writebuf)
-{
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  gdb_byte buf[8];
-
-  /* The calling convention this function implements assumes the
-     processor has floating-point registers.  We shouldn't be using it
-     on PowerPC variants that lack them.  */
-  gdb_assert (ppc_floating_point_unit_p (gdbarch));
-
-  /* AltiVec extension: Functions that declare a vector data type as a
-     return value place that return value in VR2.  */
-  if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY && TYPE_VECTOR (valtype)
-      && TYPE_LENGTH (valtype) == 16)
-    {
-      if (readbuf)
-       regcache_cooked_read (regcache, tdep->ppc_vr0_regnum + 2, readbuf);
-      if (writebuf)
-       regcache_cooked_write (regcache, tdep->ppc_vr0_regnum + 2, writebuf);
-
-      return RETURN_VALUE_REGISTER_CONVENTION;
-    }
-
-  /* If the called subprogram returns an aggregate, there exists an
-     implicit first argument, whose value is the address of a caller-
-     allocated buffer into which the callee is assumed to store its
-     return value. All explicit parameters are appropriately
-     relabeled.  */
-  if (TYPE_CODE (valtype) == TYPE_CODE_STRUCT
-      || TYPE_CODE (valtype) == TYPE_CODE_UNION
-      || TYPE_CODE (valtype) == TYPE_CODE_ARRAY)
-    return RETURN_VALUE_STRUCT_CONVENTION;
-
-  /* Scalar floating-point values are returned in FPR1 for float or
-     double, and in FPR1:FPR2 for quadword precision.  Fortran
-     complex*8 and complex*16 are returned in FPR1:FPR2, and
-     complex*32 is returned in FPR1:FPR4.  */
-  if (TYPE_CODE (valtype) == TYPE_CODE_FLT
-      && (TYPE_LENGTH (valtype) == 4 || TYPE_LENGTH (valtype) == 8))
-    {
-      struct type *regtype = register_type (gdbarch, tdep->ppc_fp0_regnum);
-      gdb_byte regval[8];
-
-      /* FIXME: kettenis/2007-01-01: Add support for quadword
-        precision and complex.  */
-
-      if (readbuf)
-       {
-         regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1, regval);
-         convert_typed_floating (regval, regtype, readbuf, valtype);
-       }
-      if (writebuf)
-       {
-         convert_typed_floating (writebuf, valtype, regval, regtype);
-         regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1, regval);
-       }
-
-      return RETURN_VALUE_REGISTER_CONVENTION;
-  }
-
-  /* Values of the types int, long, short, pointer, and char (length
-     is less than or equal to four bytes), as well as bit values of
-     lengths less than or equal to 32 bits, must be returned right
-     justified in GPR3 with signed values sign extended and unsigned
-     values zero extended, as necessary.  */
-  if (TYPE_LENGTH (valtype) <= tdep->wordsize)
-    {
-      if (readbuf)
-       {
-         ULONGEST regval;
-
-         /* For reading we don't have to worry about sign extension.  */
-         regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum + 3,
-                                        &regval);
-         store_unsigned_integer (readbuf, TYPE_LENGTH (valtype), regval);
-       }
-      if (writebuf)
-       {
-         /* For writing, use unpack_long since that should handle any
-            required sign extension.  */
-         regcache_cooked_write_unsigned (regcache, tdep->ppc_gp0_regnum + 3,
-                                         unpack_long (valtype, writebuf));
-       }
-
-      return RETURN_VALUE_REGISTER_CONVENTION;
-    }
-
-  /* Eight-byte non-floating-point scalar values must be returned in
-     GPR3:GPR4.  */
-
-  if (TYPE_LENGTH (valtype) == 8)
-    {
-      gdb_assert (TYPE_CODE (valtype) != TYPE_CODE_FLT);
-      gdb_assert (tdep->wordsize == 4);
-
-      if (readbuf)
-       {
-         gdb_byte regval[8];
-
-         regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, regval);
-         regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 4,
-                               regval + 4);
-         memcpy (readbuf, regval, 8);
-       }
-      if (writebuf)
-       {
-         regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3, writebuf);
-         regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 4,
-                                writebuf + 4);
-       }
 
-      return RETURN_VALUE_REGISTER_CONVENTION;
-    }
-
-  return RETURN_VALUE_STRUCT_CONVENTION;
+/* All the ABI's require 16 byte alignment.  */
+static CORE_ADDR
+rs6000_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+  return (addr & -16);
 }
 
 /* Return whether handle_inferior_event() should proceed through code
@@ -2251,6 +1823,7 @@ rs6000_in_solib_return_trampoline (CORE_ADDR pc, char *name)
 CORE_ADDR
 rs6000_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
   unsigned int ii, op;
   int rel;
   CORE_ADDR solib_target_pc;
@@ -2271,8 +1844,7 @@ 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, 
-                                           DEPRECATED_SYMBOL_NAME (msymbol)))
+      && rs6000_in_solib_return_trampoline (pc, SYMBOL_LINKAGE_NAME (msymbol)))
     {
       /* Double-check that the third instruction from PC is relative "b".  */
       op = read_memory_integer (pc + 8, 4);
@@ -2297,8 +1869,7 @@ rs6000_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
        return 0;
     }
   ii = get_frame_register_unsigned (frame, 11);        /* r11 holds destination addr   */
-  pc = read_memory_addr (ii,
-                        gdbarch_tdep (get_frame_arch (frame))->wordsize); /* (r11) value */
+  pc = read_memory_unsigned_integer (ii, tdep->wordsize); /* (r11) value */
   return pc;
 }
 
@@ -2344,15 +1915,6 @@ rs6000_builtin_type_vec64 (struct gdbarch *gdbarch)
   return tdep->ppc_builtin_type_vec64;
 }
 
-/* Return the size of register REG when words are WORDSIZE bytes long.  If REG
-   isn't available with that word size, return 0.  */
-
-static int
-regsize (const struct reg *reg, int wordsize)
-{
-  return wordsize == 8 ? reg->sz64 : reg->sz32;
-}
-
 /* Return the name of register number REGNO, or the empty string if it
    is an anonymous register.  */
 
@@ -2370,9 +1932,7 @@ rs6000_register_name (struct gdbarch *gdbarch, int regno)
     return "";
 
   /* Check if the SPE pseudo registers are available.  */
-  if (tdep->ppc_ev0_regnum >= 0
-      && tdep->ppc_ev0_regnum <= regno
-      && regno < tdep->ppc_ev0_regnum + ppc_num_gprs)
+  if (IS_SPE_PSEUDOREG (tdep, regno))
     {
       static const char *const spe_regnames[] = {
        "ev0", "ev1", "ev2", "ev3", "ev4", "ev5", "ev6", "ev7",
@@ -2383,6 +1943,18 @@ rs6000_register_name (struct gdbarch *gdbarch, int regno)
       return spe_regnames[regno - tdep->ppc_ev0_regnum];
     }
 
+  /* Check if the decimal128 pseudo-registers are available.  */
+  if (IS_DFP_PSEUDOREG (tdep, regno))
+    {
+      static const char *const dfp128_regnames[] = {
+       "dl0", "dl1", "dl2", "dl3",
+       "dl4", "dl5", "dl6", "dl7",
+       "dl8", "dl9", "dl10", "dl11",
+       "dl12", "dl13", "dl14", "dl15"
+      };
+      return dfp128_regnames[regno - tdep->ppc_dl0_regnum];
+    }
+
   return tdesc_register_name (gdbarch, regno);
 }
 
@@ -2395,11 +1967,15 @@ rs6000_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   /* These are the only pseudo-registers we support.  */
-  gdb_assert (tdep->ppc_ev0_regnum >= 0
-             && regnum >= tdep->ppc_ev0_regnum
-             && regnum < tdep->ppc_ev0_regnum + 32);
+  gdb_assert (IS_SPE_PSEUDOREG (tdep, regnum)
+             || IS_DFP_PSEUDOREG (tdep, regnum));
 
-  return rs6000_builtin_type_vec64 (gdbarch);
+  /* These are the e500 pseudo-registers.  */
+  if (IS_SPE_PSEUDOREG (tdep, regnum))
+    return rs6000_builtin_type_vec64 (gdbarch);
+  else
+    /* Could only be the ppc decimal128 pseudo-registers.  */
+    return builtin_type (gdbarch)->builtin_declong;
 }
 
 /* Is REGNUM a member of REGGROUP?  */
@@ -2410,14 +1986,15 @@ rs6000_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   /* These are the only pseudo-registers we support.  */
-  gdb_assert (tdep->ppc_ev0_regnum >= 0
-             && regnum >= tdep->ppc_ev0_regnum
-             && regnum < tdep->ppc_ev0_regnum + 32);
+  gdb_assert (IS_SPE_PSEUDOREG (tdep, regnum)
+             || IS_DFP_PSEUDOREG (tdep, regnum));
 
-  if (group == all_reggroup || group == vector_reggroup)
-    return 1;
+  /* These are the e500 pseudo-registers.  */
+  if (IS_SPE_PSEUDOREG (tdep, regnum))
+    return group == all_reggroup || group == vector_reggroup;
   else
-    return 0;
+    /* Could only be the ppc decimal128 pseudo-registers.  */
+    return group == all_reggroup || group == float_reggroup;
 }
 
 /* The register format for RS/6000 floating point registers is always
@@ -2498,8 +2075,7 @@ e500_move_ev_register (void (*move) (struct regcache *regcache,
   int reg_index;
   gdb_byte *byte_buffer = buffer;
 
-  gdb_assert (tdep->ppc_ev0_regnum <= ev_reg
-              && ev_reg < tdep->ppc_ev0_regnum + ppc_num_gprs);
+  gdb_assert (IS_SPE_PSEUDOREG (tdep, ev_reg));
 
   reg_index = ev_reg - tdep->ppc_ev0_regnum;
 
@@ -2518,48 +2094,118 @@ e500_move_ev_register (void (*move) (struct regcache *regcache,
 static void
 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);
+}
+
+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);
+}
+
+/* Read method for PPC pseudo-registers. Currently this is handling the
+   16 decimal128 registers that map into 16 pairs of FP registers.  */
+static void
+ppc_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;
+
+  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);
+    }
+  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);
+    }
+}
+
+/* Write method for PPC pseudo-registers. Currently this is handling the
+   16 decimal128 registers that map into 16 pairs of FP registers.  */
+static void
+ppc_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
+                           int reg_nr, const gdb_byte *buffer)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int reg_index = reg_nr - tdep->ppc_dl0_regnum;
+
+  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+    {
+      /* Write each half of the dl register into a separate
+      FP register.  */
+      regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+                         2 * reg_index, buffer);
+      regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+                         2 * reg_index + 1, buffer + 8);
+    }
+  else
+    {
+      regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+                         2 * reg_index + 1, buffer + 8);
+      regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+                         2 * reg_index, buffer);
+    }
+}
+
+static void
+rs6000_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+                            int reg_nr, gdb_byte *buffer)
 {
   struct gdbarch *regcache_arch = get_regcache_arch (regcache);
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 
 
   gdb_assert (regcache_arch == gdbarch);
-  if (tdep->ppc_ev0_regnum <= reg_nr
-      && reg_nr < tdep->ppc_ev0_regnum + ppc_num_gprs)
-    e500_move_ev_register (regcache_raw_read, regcache, reg_nr, buffer);
+
+  if (IS_SPE_PSEUDOREG (tdep, reg_nr))
+    e500_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
+  else if (IS_DFP_PSEUDOREG (tdep, reg_nr))
+    ppc_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
   else
     internal_error (__FILE__, __LINE__,
-                    _("e500_pseudo_register_read: "
-                    "called on unexpected register '%s' (%d)"),
-                    gdbarch_register_name (gdbarch, reg_nr), reg_nr);
+                   _("rs6000_pseudo_register_read: "
+                   "called on unexpected register '%s' (%d)"),
+                   gdbarch_register_name (gdbarch, reg_nr), reg_nr);
 }
 
 static void
-e500_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
-                           int reg_nr, const gdb_byte *buffer)
+rs6000_pseudo_register_write (struct gdbarch *gdbarch,
+                             struct regcache *regcache,
+                             int reg_nr, const gdb_byte *buffer)
 {
   struct gdbarch *regcache_arch = get_regcache_arch (regcache);
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 
 
   gdb_assert (regcache_arch == gdbarch);
-  if (tdep->ppc_ev0_regnum <= reg_nr
-      && reg_nr < tdep->ppc_ev0_regnum + ppc_num_gprs)
-    e500_move_ev_register ((void (*) (struct regcache *, int, gdb_byte *))
-                           regcache_raw_write,
-                           regcache, reg_nr, (gdb_byte *) buffer);
+
+  if (IS_SPE_PSEUDOREG (tdep, reg_nr))
+    e500_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
+  else if (IS_DFP_PSEUDOREG (tdep, reg_nr))
+    ppc_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
   else
     internal_error (__FILE__, __LINE__,
-                    _("e500_pseudo_register_read: "
-                    "called on unexpected register '%s' (%d)"),
-                    gdbarch_register_name (gdbarch, reg_nr), reg_nr);
+                   _("rs6000_pseudo_register_write: "
+                   "called on unexpected register '%s' (%d)"),
+                   gdbarch_register_name (gdbarch, reg_nr), reg_nr);
 }
 
 /* Convert a DBX STABS register number to a GDB register number.  */
 static int
-rs6000_stab_reg_to_regnum (int num)
+rs6000_stab_reg_to_regnum (struct gdbarch *gdbarch, int num)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   if (0 <= num && num <= 31)
     return tdep->ppc_gp0_regnum + num;
@@ -2599,9 +2245,9 @@ rs6000_stab_reg_to_regnum (int num)
 
 /* Convert a Dwarf 2 register number to a GDB register number.  */
 static int
-rs6000_dwarf2_reg_to_regnum (int num)
+rs6000_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int num)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   if (0 <= num && num <= 31)
     return tdep->ppc_gp0_regnum + num;
@@ -2704,40 +2350,6 @@ rs6000_adjust_frame_regnum (struct gdbarch *gdbarch, int num, int eh_frame_p)
       }
 }
 \f
-/* Support for CONVERT_FROM_FUNC_PTR_ADDR (ARCH, ADDR, TARG).
-
-   Usually a function pointer's representation is simply the address
-   of the function. On the RS/6000 however, a function pointer is
-   represented by a pointer to an OPD entry. This OPD entry contains
-   three words, the first word is the address of the function, the
-   second word is the TOC pointer (r2), and the third word is the
-   static chain value.  Throughout GDB it is currently assumed that a
-   function pointer contains the address of the function, which is not
-   easy to fix.  In addition, the conversion of a function address to
-   a function pointer would require allocation of an OPD entry in the
-   inferior's memory space, with all its drawbacks.  To be able to
-   call C++ virtual methods in the inferior (which are called via
-   function pointers), find_function_addr uses this function to get the
-   function address from a function pointer.  */
-
-/* Return real function address if ADDR (a function pointer) is in the data
-   space and is therefore a special function pointer.  */
-
-static CORE_ADDR
-rs6000_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
-                                  CORE_ADDR addr,
-                                  struct target_ops *targ)
-{
-  struct obj_section *s;
-
-  s = find_pc_section (addr);
-  if (s && s->the_bfd_section->flags & SEC_CODE)
-    return addr;
-
-  /* ADDR is in the data space, so it's a special function pointer. */
-  return read_memory_addr (addr, gdbarch_tdep (gdbarch)->wordsize);
-}
-\f
 
 /* Handling the various POWER/PowerPC variants.  */
 
@@ -2764,7 +2376,7 @@ struct variant
 static struct variant variants[] =
 {
   {"powerpc", "PowerPC user-level", bfd_arch_powerpc,
-   bfd_mach_ppc, &tdesc_powerpc_32},
+   bfd_mach_ppc, &tdesc_powerpc_altivec32},
   {"power", "POWER user-level", bfd_arch_rs6000,
    bfd_mach_rs6k, &tdesc_rs6000},
   {"403", "IBM PowerPC 403", bfd_arch_powerpc,
@@ -2792,7 +2404,7 @@ static struct variant variants[] =
 
   /* 64-bit */
   {"powerpc64", "PowerPC 64-bit user-level", bfd_arch_powerpc,
-   bfd_mach_ppc64, &tdesc_powerpc_64},
+   bfd_mach_ppc64, &tdesc_powerpc_altivec64},
   {"620", "Motorola PowerPC 620", bfd_arch_powerpc,
    bfd_mach_ppc_620, &tdesc_powerpc_64},
   {"630", "Motorola PowerPC 630", bfd_arch_powerpc,
@@ -2836,7 +2448,7 @@ gdb_print_insn_powerpc (bfd_vma memaddr, disassemble_info *info)
   if (!info->disassembler_options)
     info->disassembler_options = "any";
 
-  if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
+  if (info->endian == BFD_ENDIAN_BIG)
     return print_insn_big_powerpc (memaddr, info);
   else
     return print_insn_little_powerpc (memaddr, info);
@@ -2850,11 +2462,11 @@ rs6000_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 }
 
 static struct frame_id
-rs6000_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
+rs6000_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 {
-  return frame_id_build (frame_unwind_register_unsigned
-                        (next_frame, gdbarch_sp_regnum (gdbarch)),
-                       frame_pc_unwind (next_frame));
+  return frame_id_build (get_frame_register_unsigned
+                         (this_frame, gdbarch_sp_regnum (gdbarch)),
+                        get_frame_pc (this_frame));
 }
 
 struct rs6000_frame_cache
@@ -2865,10 +2477,10 @@ struct rs6000_frame_cache
 };
 
 static struct rs6000_frame_cache *
-rs6000_frame_cache (struct frame_info *next_frame, void **this_cache)
+rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
 {
   struct rs6000_frame_cache *cache;
-  struct gdbarch *gdbarch = get_frame_arch (next_frame);
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   struct rs6000_framedata fdata;
   int wordsize = tdep->wordsize;
@@ -2878,11 +2490,11 @@ rs6000_frame_cache (struct frame_info *next_frame, void **this_cache)
     return (*this_cache);
   cache = FRAME_OBSTACK_ZALLOC (struct rs6000_frame_cache);
   (*this_cache) = cache;
-  cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
+  cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
 
-  func = frame_func_unwind (next_frame, NORMAL_FRAME);
-  pc = frame_pc_unwind (next_frame);
-  skip_prologue (func, pc, &fdata);
+  func = get_frame_func (this_frame);
+  pc = get_frame_pc (this_frame);
+  skip_prologue (gdbarch, func, pc, &fdata);
 
   /* Figure out the parent's stack pointer.  */
 
@@ -2891,13 +2503,13 @@ rs6000_frame_cache (struct frame_info *next_frame, void **this_cache)
      ->frame pointed to the outer-most address of the frame.  In
      the mean time, the address of the prev frame is used as the
      base address of this frame.  */
-  cache->base = frame_unwind_register_unsigned
-               (next_frame, gdbarch_sp_regnum (gdbarch));
+  cache->base = get_frame_register_unsigned
+               (this_frame, gdbarch_sp_regnum (gdbarch));
 
   /* If the function appears to be frameless, check a couple of likely
      indicators that we have simply failed to find the frame setup.
      Two common cases of this are missing symbols (i.e.
-     frame_func_unwind returns the wrong address or 0), and assembly
+     get_frame_func returns the wrong address or 0), and assembly
      stubs which have a fast exit path but set up a frame on the slow
      path.
 
@@ -2908,8 +2520,7 @@ rs6000_frame_cache (struct frame_info *next_frame, void **this_cache)
       CORE_ADDR saved_lr;
       int make_frame = 0;
 
-      saved_lr = frame_unwind_register_unsigned (next_frame,
-                                                tdep->ppc_lr_regnum);
+      saved_lr = get_frame_register_unsigned (this_frame, tdep->ppc_lr_regnum);
       if (func == 0 && saved_lr == pc)
        make_frame = 1;
       else if (func != 0)
@@ -2928,7 +2539,7 @@ rs6000_frame_cache (struct frame_info *next_frame, void **this_cache)
 
   if (!fdata.frameless)
     /* Frameless really means stackless.  */
-    cache->base = read_memory_addr (cache->base, wordsize);
+    cache->base = read_memory_unsigned_integer (cache->base, wordsize);
 
   trad_frame_set_value (cache->saved_regs,
                        gdbarch_sp_regnum (gdbarch), cache->base);
@@ -2985,7 +2596,7 @@ rs6000_frame_cache (struct frame_info *next_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. ????? */
-  if (tdep->ppc_ev0_regnum != -1 && tdep->ppc_ev31_regnum != -1)
+  if (tdep->ppc_ev0_regnum != -1)
     {
       if (fdata.saved_ev >= 0)
        {
@@ -3021,58 +2632,51 @@ rs6000_frame_cache (struct frame_info *next_frame, void **this_cache)
   if (fdata.alloca_reg < 0)
     /* If no alloca register used, then fi->frame is the value of the
        %sp for this frame, and it is good enough.  */
-    cache->initial_sp = frame_unwind_register_unsigned
-                       (next_frame, gdbarch_sp_regnum (gdbarch));
+    cache->initial_sp
+      = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch));
   else
-    cache->initial_sp = frame_unwind_register_unsigned (next_frame,
-                                                       fdata.alloca_reg);
+    cache->initial_sp
+      = get_frame_register_unsigned (this_frame, fdata.alloca_reg);
 
   return cache;
 }
 
 static void
-rs6000_frame_this_id (struct frame_info *next_frame, void **this_cache,
+rs6000_frame_this_id (struct frame_info *this_frame, void **this_cache,
                      struct frame_id *this_id)
 {
-  struct rs6000_frame_cache *info = rs6000_frame_cache (next_frame,
+  struct rs6000_frame_cache *info = rs6000_frame_cache (this_frame,
                                                        this_cache);
-  (*this_id) = frame_id_build (info->base,
-                              frame_func_unwind (next_frame, NORMAL_FRAME));
+  /* This marks the outermost frame.  */
+  if (info->base == 0)
+    return;
+
+  (*this_id) = frame_id_build (info->base, get_frame_func (this_frame));
 }
 
-static void
-rs6000_frame_prev_register (struct frame_info *next_frame,
-                                void **this_cache,
-                                int regnum, int *optimizedp,
-                                enum lval_type *lvalp, CORE_ADDR *addrp,
-                                int *realnump, gdb_byte *valuep)
+static struct value *
+rs6000_frame_prev_register (struct frame_info *this_frame,
+                           void **this_cache, int regnum)
 {
-  struct rs6000_frame_cache *info = rs6000_frame_cache (next_frame,
+  struct rs6000_frame_cache *info = rs6000_frame_cache (this_frame,
                                                        this_cache);
-  trad_frame_get_prev_register (next_frame, info->saved_regs, regnum,
-                               optimizedp, lvalp, addrp, realnump, valuep);
+  return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
 }
 
 static const struct frame_unwind rs6000_frame_unwind =
 {
   NORMAL_FRAME,
   rs6000_frame_this_id,
-  rs6000_frame_prev_register
+  rs6000_frame_prev_register,
+  NULL,
+  default_frame_sniffer
 };
-
-static const struct frame_unwind *
-rs6000_frame_sniffer (struct frame_info *next_frame)
-{
-  return &rs6000_frame_unwind;
-}
-
 \f
 
 static CORE_ADDR
-rs6000_frame_base_address (struct frame_info *next_frame,
-                               void **this_cache)
+rs6000_frame_base_address (struct frame_info *this_frame, void **this_cache)
 {
-  struct rs6000_frame_cache *info = rs6000_frame_cache (next_frame,
+  struct rs6000_frame_cache *info = rs6000_frame_cache (this_frame,
                                                        this_cache);
   return info->initial_sp;
 }
@@ -3085,7 +2689,7 @@ static const struct frame_base rs6000_frame_base = {
 };
 
 static const struct frame_base *
-rs6000_frame_base_sniffer (struct frame_info *next_frame)
+rs6000_frame_base_sniffer (struct frame_info *this_frame)
 {
   return &rs6000_frame_base;
 }
@@ -3096,7 +2700,7 @@ rs6000_frame_base_sniffer (struct frame_info *next_frame)
 static void
 ppc_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
                            struct dwarf2_frame_state_reg *reg,
-                           struct frame_info *next_frame)
+                           struct frame_info *this_frame)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
@@ -3168,16 +2772,15 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   enum bfd_architecture arch;
   unsigned long mach;
   bfd abfd;
-  int sysv_abi;
   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;
-  int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0;
+  int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0, have_dfp = 0;
   int tdesc_wordsize = -1;
   const struct target_desc *tdesc = info.target_desc;
   struct tdesc_arch_data *tdesc_data = NULL;
-  int num_sprs = 0;
+  int num_pseudoregs = 0;
 
   from_xcoff_exec = info.abfd && info.abfd->format == bfd_object &&
     bfd_get_flavour (info.abfd) == bfd_target_xcoff_flavour;
@@ -3185,8 +2788,6 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   from_elf_exec = info.abfd && info.abfd->format == bfd_object &&
     bfd_get_flavour (info.abfd) == bfd_target_elf_flavour;
 
-  sysv_abi = info.abfd && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour;
-
   /* Check word size.  If INFO is from a binary file, infer it from
      that, else choose a likely default.  */
   if (from_xcoff_exec)
@@ -3214,18 +2815,9 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        wordsize = 4;
     }
 
-  if (!from_xcoff_exec)
-    {
-      arch = info.bfd_arch_info->arch;
-      mach = info.bfd_arch_info->mach;
-    }
-  else
-    {
-      arch = bfd_arch_powerpc;
-      bfd_default_set_arch_mach (&abfd, arch, 0);
-      info.bfd_arch_info = bfd_get_arch_info (&abfd);
-      mach = info.bfd_arch_info->mach;
-    }
+  /* Get the architecture and machine from the BFD.  */
+  arch = info.bfd_arch_info->arch;
+  mach = info.bfd_arch_info->mach;
 
   /* For e500 executables, the apuinfo section is of help here.  Such
      section contains the identifier and revision number of each
@@ -3348,6 +2940,10 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       else
        have_fpu = 0;
 
+      /* The DFP pseudo-registers will be available when there are floating
+         point registers.  */
+      have_dfp = have_fpu;
+
       feature = tdesc_find_feature (tdesc,
                                    "org.gnu.gdb.power.altivec");
       if (feature != NULL)
@@ -3579,25 +3175,21 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      alias.  */
   set_gdbarch_ps_regnum (gdbarch, tdep->ppc_ps_regnum);
 
-  if (sysv_abi && wordsize == 8)
+  if (wordsize == 8)
     set_gdbarch_return_value (gdbarch, ppc64_sysv_abi_return_value);
-  else if (sysv_abi && wordsize == 4)
-    set_gdbarch_return_value (gdbarch, ppc_sysv_abi_return_value);
   else
-    set_gdbarch_return_value (gdbarch, rs6000_return_value);
+    set_gdbarch_return_value (gdbarch, ppc_sysv_abi_return_value);
 
   /* Set lr_frame_offset.  */
   if (wordsize == 8)
     tdep->lr_frame_offset = 16;
-  else if (sysv_abi)
-    tdep->lr_frame_offset = 4;
   else
-    tdep->lr_frame_offset = 8;
+    tdep->lr_frame_offset = 4;
 
-  if (have_spe)
+  if (have_spe || have_dfp)
     {
-      set_gdbarch_pseudo_register_read (gdbarch, e500_pseudo_register_read);
-      set_gdbarch_pseudo_register_write (gdbarch, e500_pseudo_register_write);
+      set_gdbarch_pseudo_register_read (gdbarch, rs6000_pseudo_register_read);
+      set_gdbarch_pseudo_register_write (gdbarch, rs6000_pseudo_register_write);
     }
 
   set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
@@ -3608,8 +3200,14 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   else
     set_gdbarch_print_insn (gdbarch, gdb_print_insn_powerpc);
 
-  set_gdbarch_num_regs (gdbarch, PPC_NUM_REGS + num_sprs);
-  set_gdbarch_num_pseudo_regs (gdbarch, have_spe ? 32 : 0);
+  set_gdbarch_num_regs (gdbarch, PPC_NUM_REGS);
+
+  if (have_spe)
+    num_pseudoregs += 32;
+  if (have_dfp)
+    num_pseudoregs += 16;
+
+  set_gdbarch_num_pseudo_regs (gdbarch, num_pseudoregs);
 
   set_gdbarch_ptr_bit (gdbarch, wordsize * TARGET_CHAR_BIT);
   set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
@@ -3618,22 +3216,13 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
   set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT);
   set_gdbarch_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
-  if (sysv_abi)
-    set_gdbarch_long_double_bit (gdbarch, 16 * TARGET_CHAR_BIT);
-  else
-    set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
+  set_gdbarch_long_double_bit (gdbarch, 16 * TARGET_CHAR_BIT);
   set_gdbarch_char_signed (gdbarch, 0);
 
   set_gdbarch_frame_align (gdbarch, rs6000_frame_align);
-  if (sysv_abi && wordsize == 8)
+  if (wordsize == 8)
     /* PPC64 SYSV.  */
     set_gdbarch_frame_red_zone_size (gdbarch, 288);
-  else if (!sysv_abi && wordsize == 4)
-    /* PowerOpen / AIX 32 bit.  The saved area or red zone consists of
-       19 4 byte GPRS + 18 8 byte FPRs giving a total of 220 bytes.
-       Problem is, 220 isn't frame (16 byte) aligned.  Round it up to
-       224.  */
-    set_gdbarch_frame_red_zone_size (gdbarch, 224);
 
   set_gdbarch_convert_register_p (gdbarch, rs6000_convert_register_p);
   set_gdbarch_register_to_value (gdbarch, rs6000_register_to_value);
@@ -3642,12 +3231,10 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_stab_reg_to_regnum (gdbarch, rs6000_stab_reg_to_regnum);
   set_gdbarch_dwarf2_reg_to_regnum (gdbarch, rs6000_dwarf2_reg_to_regnum);
 
-  if (sysv_abi && wordsize == 4)
+  if (wordsize == 4)
     set_gdbarch_push_dummy_call (gdbarch, ppc_sysv_abi_push_dummy_call);
-  else if (sysv_abi && wordsize == 8)
+  else if (wordsize == 8)
     set_gdbarch_push_dummy_call (gdbarch, ppc64_sysv_abi_push_dummy_call);
-  else
-    set_gdbarch_push_dummy_call (gdbarch, rs6000_push_dummy_call);
 
   set_gdbarch_skip_prologue (gdbarch, rs6000_skip_prologue);
   set_gdbarch_in_function_epilogue_p (gdbarch, rs6000_in_function_epilogue_p);
@@ -3660,28 +3247,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_sofun_address_maybe_missing (gdbarch, 1);
 
   /* Handles single stepping of atomic sequences.  */
-  set_gdbarch_software_single_step (gdbarch, deal_with_atomic_sequence);
+  set_gdbarch_software_single_step (gdbarch, ppc_deal_with_atomic_sequence);
   
-  /* Handle the 64-bit SVR4 minimal-symbol convention of using "FN"
-     for the descriptor and ".FN" for the entry-point -- a user
-     specifying "break FN" will unexpectedly end up with a breakpoint
-     on the descriptor and not the function.  This architecture method
-     transforms any breakpoints on descriptors into breakpoints on the
-     corresponding entry point.  */
-  if (sysv_abi && wordsize == 8)
-    set_gdbarch_adjust_breakpoint_address (gdbarch, ppc64_sysv_abi_adjust_breakpoint_address);
-
   /* Not sure on this. FIXMEmgo */
   set_gdbarch_frame_args_skip (gdbarch, 8);
 
-  if (!sysv_abi)
-    {
-      /* Handle RS/6000 function pointers (which are really function
-         descriptors).  */
-      set_gdbarch_convert_from_func_ptr_addr (gdbarch,
-       rs6000_convert_from_func_ptr_addr);
-    }
-
   /* Helpers for function argument information.  */
   set_gdbarch_fetch_pointer_argument (gdbarch, rs6000_fetch_pointer_argument);
 
@@ -3691,13 +3261,15 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_skip_trampoline_code (gdbarch, rs6000_skip_trampoline_code);
 
   /* Hook in the DWARF CFI frame unwinder.  */
-  frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
+  dwarf2_append_unwinders (gdbarch);
   dwarf2_frame_set_adjust_regnum (gdbarch, rs6000_adjust_frame_regnum);
 
   /* Frame handling.  */
   dwarf2_frame_set_init_reg (gdbarch, ppc_dwarf2_frame_init_reg);
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
+  info.target_desc = tdesc;
+  info.tdep_info = (void *) tdesc_data;
   gdbarch_init_osabi (info, gdbarch);
 
   switch (info.osabi)
@@ -3707,16 +3279,16 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     case GDB_OSABI_NETBSD_ELF:
     case GDB_OSABI_UNKNOWN:
       set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc);
-      frame_unwind_append_sniffer (gdbarch, rs6000_frame_sniffer);
-      set_gdbarch_unwind_dummy_id (gdbarch, rs6000_unwind_dummy_id);
+      frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind);
+      set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id);
       frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer);
       break;
     default:
       set_gdbarch_believe_pcc_promotion (gdbarch, 1);
 
       set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc);
-      frame_unwind_append_sniffer (gdbarch, rs6000_frame_sniffer);
-      set_gdbarch_unwind_dummy_id (gdbarch, rs6000_unwind_dummy_id);
+      frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind);
+      set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id);
       frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer);
     }
 
@@ -3731,7 +3303,24 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Recording the numbering of pseudo registers.  */
   tdep->ppc_ev0_regnum = have_spe ? gdbarch_num_regs (gdbarch) : -1;
-  tdep->ppc_ev31_regnum = have_spe ? tdep->ppc_ev0_regnum + 31 : -1;
+
+  /* Set the register number for _Decimal128 pseudo-registers.  */
+  tdep->ppc_dl0_regnum = have_dfp? gdbarch_num_regs (gdbarch) : -1;
+
+  if (have_dfp && have_spe)
+    /* Put the _Decimal128 pseudo-registers after the SPE registers.  */
+    tdep->ppc_dl0_regnum += 32;
+
+  /* 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);
 
   return gdbarch;
 }
@@ -3814,6 +3403,7 @@ _initialize_rs6000_tdep (void)
 
   /* Initialize the standard target descriptions.  */
   initialize_tdesc_powerpc_32 ();
+  initialize_tdesc_powerpc_altivec32 ();
   initialize_tdesc_powerpc_403 ();
   initialize_tdesc_powerpc_403gc ();
   initialize_tdesc_powerpc_505 ();
@@ -3822,6 +3412,7 @@ _initialize_rs6000_tdep (void)
   initialize_tdesc_powerpc_603 ();
   initialize_tdesc_powerpc_604 ();
   initialize_tdesc_powerpc_64 ();
+  initialize_tdesc_powerpc_altivec64 ();
   initialize_tdesc_powerpc_7400 ();
   initialize_tdesc_powerpc_750 ();
   initialize_tdesc_powerpc_860 ();
This page took 0.04684 seconds and 4 git commands to generate.