* infrun.c (adjust_pc_after_break): Do not assume software single-step
[deliverable/binutils-gdb.git] / gdb / rs6000-tdep.c
index 19a4bc9d0d03cda2aaae05fc82f43ed847079eae..ac5b091afca238e0c4808792c597a7e30f86b7df 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
+   Copyright (C) 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -40,6 +40,7 @@
 #include "sim-regno.h"
 #include "gdb/sim-ppc.h"
 #include "reggroups.h"
+#include "dwarf2-frame.h"
 
 #include "libbfd.h"            /* for bfd_default_set_arch_mach */
 #include "coff/internal.h"     /* for libcoff.h */
@@ -59,7 +60,7 @@
 #include "frame-unwind.h"
 #include "frame-base.h"
 
-#include "reggroups.h"
+#include "rs6000-tdep.h"
 
 /* If the kernel has to deliver a signal, it pushes a sigcontext
    structure on the stack and then calls the signal handler, passing
@@ -109,32 +110,16 @@ struct reg
                                    register number.  */
   };
 
-/* Breakpoint shadows for the single step instructions will be kept here. */
-
-static struct sstep_breaks
-{
-  /* Address, or 0 if this is not in use.  */
-  CORE_ADDR address;
-  /* Shadow contents.  */
-  gdb_byte data[4];
-}
-stepBreaks[2];
-
 /* 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;
 
-/* Hook to set the current architecture when starting a child process. 
-   rs6000-nat.c sets this. */
-
-void (*rs6000_set_host_arch_hook) (int) = NULL;
-
 /* Static function prototypes */
 
-static CORE_ADDR branch_dest (int opcode, int instr, CORE_ADDR pc,
-                             CORE_ADDR safety);
+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 *);
 
@@ -304,7 +289,9 @@ rs6000_register_sim_regno (int reg)
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
   int sim_regno;
 
-  gdb_assert (0 <= reg && reg <= NUM_REGS + NUM_PSEUDO_REGS);
+  gdb_assert (0 <= reg 
+             && reg <= gdbarch_num_regs (current_gdbarch)
+                       + gdbarch_num_pseudo_regs (current_gdbarch));
   sim_regno = tdep->sim_regno[reg];
 
   if (sim_regno >= 0)
@@ -355,8 +342,9 @@ ppc_supply_gregset (const struct regset *regset, struct regcache *regcache,
        ppc_supply_reg (regcache, i, gregs, offset);
     }
 
-  if (regnum == -1 || regnum == PC_REGNUM)
-    ppc_supply_reg (regcache, PC_REGNUM, gregs, offsets->pc_offset);
+  if (regnum == -1 || regnum == gdbarch_pc_regnum (current_gdbarch))
+    ppc_supply_reg (regcache, gdbarch_pc_regnum (current_gdbarch),
+                   gregs, offsets->pc_offset);
   if (regnum == -1 || regnum == tdep->ppc_ps_regnum)
     ppc_supply_reg (regcache, tdep->ppc_ps_regnum,
                    gregs, offsets->ps_offset);
@@ -431,8 +419,9 @@ ppc_collect_gregset (const struct regset *regset,
        ppc_collect_reg (regcache, i, gregs, offset);
     }
 
-  if (regnum == -1 || regnum == PC_REGNUM)
-    ppc_collect_reg (regcache, PC_REGNUM, gregs, offsets->pc_offset);
+  if (regnum == -1 || regnum == gdbarch_pc_regnum (current_gdbarch))
+    ppc_collect_reg (regcache, gdbarch_pc_regnum (current_gdbarch),
+                    gregs, offsets->pc_offset);
   if (regnum == -1 || regnum == tdep->ppc_ps_regnum)
     ppc_collect_reg (regcache, tdep->ppc_ps_regnum,
                     gregs, offsets->ps_offset);
@@ -498,7 +487,29 @@ static CORE_ADDR
 rs6000_skip_prologue (CORE_ADDR pc)
 {
   struct rs6000_framedata frame;
-  pc = skip_prologue (pc, 0, &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;
 }
 
@@ -581,7 +592,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_signed_integer (insn_buf, PPC_INSN_SIZE);
+      insn = extract_unsigned_integer (insn_buf, PPC_INSN_SIZE);
       if (insn == 0x4e800020)
         break;
       if (insn_changes_sp_or_jumps (insn))
@@ -596,7 +607,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_signed_integer (insn_buf, PPC_INSN_SIZE);
+      insn = extract_unsigned_integer (insn_buf, PPC_INSN_SIZE);
       if (insn_changes_sp_or_jumps (insn))
         return 1;
     }
@@ -604,19 +615,6 @@ rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
   return 0;
 }
 
-
-/* Fill in fi->saved_regs */
-
-struct frame_extra_info
-{
-  /* Functions calling alloca() change the value of the stack
-     pointer. We need to use initial stack pointer (which is saved in
-     r31 by gcc) in such cases. If a compiler emits traceback table,
-     then we should use the alloca register specified in traceback
-     table. FIXME. */
-  CORE_ADDR initial_sp;                /* initial stack pointer. */
-};
-
 /* Get the ith function argument for the current function.  */
 static CORE_ADDR
 rs6000_fetch_pointer_argument (struct frame_info *frame, int argi, 
@@ -628,8 +626,10 @@ rs6000_fetch_pointer_argument (struct frame_info *frame, int argi,
 /* Calculate the destination of a branch/jump.  Return -1 if not a branch.  */
 
 static CORE_ADDR
-branch_dest (int opcode, int instr, CORE_ADDR pc, CORE_ADDR safety)
+branch_dest (struct frame_info *frame, int opcode, int instr,
+            CORE_ADDR pc, CORE_ADDR safety)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
   CORE_ADDR dest;
   int immediate;
   int absolute;
@@ -660,32 +660,26 @@ branch_dest (int opcode, int instr, CORE_ADDR pc, CORE_ADDR safety)
 
       if (ext_op == 16)                /* br conditional register */
        {
-          dest = read_register (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum) & ~3;
+          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 < TEXT_SEGMENT_BASE)
-           {
-             struct frame_info *fi;
-
-             fi = get_current_frame ();
-             if (fi != NULL)
-               dest = read_memory_addr (get_frame_base (fi) + SIG_FRAME_PC_OFFSET,
-                                        gdbarch_tdep (current_gdbarch)->wordsize);
-           }
+         if (dest < tdep->text_segment_base)
+           dest = read_memory_addr (get_frame_base (frame) + SIG_FRAME_PC_OFFSET,
+                                    tdep->wordsize);
        }
 
       else if (ext_op == 528)  /* br cond to count reg */
        {
-          dest = read_register (gdbarch_tdep (current_gdbarch)->ppc_ctr_regnum) & ~3;
+          dest = get_frame_register_unsigned (frame, tdep->ppc_ctr_regnum) & ~3;
 
          /* 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 < TEXT_SEGMENT_BASE)
-            dest = read_register (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum) & ~3;
+         if (dest < tdep->text_segment_base)
+            dest = get_frame_register_unsigned (frame, tdep->ppc_lr_regnum) & ~3;
        }
       else
        return -1;
@@ -694,7 +688,7 @@ branch_dest (int opcode, int instr, CORE_ADDR pc, CORE_ADDR safety)
     default:
       return -1;
     }
-  return (dest < TEXT_SEGMENT_BASE) ? safety : dest;
+  return (dest < tdep->text_segment_base) ? safety : dest;
 }
 
 
@@ -706,18 +700,112 @@ rs6000_breakpoint_from_pc (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 (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+  if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
     return big_breakpoint;
   else
     return little_breakpoint;
 }
 
 
-/* AIX does not support PT_STEP. Simulate it. */
+/* Instruction masks used during single-stepping of atomic sequences.  */
+#define LWARX_MASK 0xfc0007fe
+#define LWARX_INSTRUCTION 0x7c000028
+#define LDARX_INSTRUCTION 0x7c0000A8
+#define STWCX_MASK 0xfc0007ff
+#define STWCX_INSTRUCTION 0x7c00012d
+#define STDCX_INSTRUCTION 0x7c0001ad
+#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)
+{
+  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;
+  int index;
+  int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed).  */  
+  const int atomic_sequence_length = 16; /* Instruction sequence length.  */
+  int opcode; /* Branch instruction's OPcode.  */
+  int bc_insn_count = 0; /* Conditional branch instruction count.  */
+
+  /* Assume all atomic sequences start with a lwarx/ldarx instruction.  */
+  if ((insn & LWARX_MASK) != LWARX_INSTRUCTION
+      && (insn & LWARX_MASK) != LDARX_INSTRUCTION)
+    return 0;
+
+  /* Assume that no atomic sequence is longer than "atomic_sequence_length" 
+     instructions.  */
+  for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count)
+    {
+      loc += PPC_INSN_SIZE;
+      insn = read_memory_integer (loc, PPC_INSN_SIZE);
 
-void
-rs6000_software_single_step (enum target_signal signal,
-                            int insert_breakpoints_p)
+      /* 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 (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 ((insn & STWCX_MASK) == STWCX_INSTRUCTION
+          || (insn & STWCX_MASK) == STDCX_INSTRUCTION)
+        break;
+    }
+
+  /* Assume that the atomic sequence ends with a stwcx/stdcx instruction.  */
+  if ((insn & STWCX_MASK) != STWCX_INSTRUCTION
+      && (insn & STWCX_MASK) != STDCX_INSTRUCTION)
+    return 0;
+
+  closing_insn = loc;
+  loc += PPC_INSN_SIZE;
+  insn = read_memory_integer (loc, PPC_INSN_SIZE);
+
+  /* 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)))
+    last_breakpoint = 0;
+
+  /* Effectively inserts the breakpoints.  */
+  for (index = 0; index <= last_breakpoint; index++)
+    insert_single_step_breakpoint (breaks[index]);
+
+  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;
@@ -727,45 +815,32 @@ rs6000_software_single_step (enum target_signal signal,
   CORE_ADDR breaks[2];
   int opcode;
 
-  if (insert_breakpoints_p)
-    {
-
-      loc = read_pc ();
-
-      insn = read_memory_integer (loc, 4);
+  loc = get_frame_pc (frame);
 
-      breaks[0] = loc + breakp_sz;
-      opcode = insn >> 26;
-      breaks[1] = branch_dest (opcode, insn, loc, breaks[0]);
+  insn = read_memory_integer (loc, 4);
 
-      /* Don't put two breakpoints on the same address. */
-      if (breaks[1] == breaks[0])
-       breaks[1] = -1;
-
-      stepBreaks[1].address = 0;
-
-      for (ii = 0; ii < 2; ++ii)
-       {
+  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]);
 
-         /* ignore invalid breakpoint. */
-         if (breaks[ii] == -1)
-           continue;
-         target_insert_breakpoint (breaks[ii], stepBreaks[ii].data);
-         stepBreaks[ii].address = breaks[ii];
-       }
+  /* Don't put two breakpoints on the same address. */
+  if (breaks[1] == breaks[0])
+    breaks[1] = -1;
 
-    }
-  else
+  for (ii = 0; ii < 2; ++ii)
     {
-
-      /* remove step breakpoints. */
-      for (ii = 0; ii < 2; ++ii)
-       if (stepBreaks[ii].address != 0)
-         target_remove_breakpoint (stepBreaks[ii].address,
-                                   stepBreaks[ii].data);
+      /* 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;
 }
 
 
@@ -803,57 +878,6 @@ rs6000_software_single_step (enum target_signal signal,
    of the prologue is expensive.  */
 static int max_skip_non_prologue_insns = 10;
 
-/* Given PC representing the starting address of a function, and
-   LIM_PC which is the (sloppy) limit to which to scan when looking
-   for a prologue, attempt to further refine this limit by using
-   the line data in the symbol table.  If successful, a better guess
-   on where the prologue ends is returned, otherwise the previous
-   value of lim_pc is returned.  */
-
-/* FIXME: cagney/2004-02-14: This function and logic have largely been
-   superseded by skip_prologue_using_sal.  */
-
-static CORE_ADDR
-refine_prologue_limit (CORE_ADDR pc, CORE_ADDR lim_pc)
-{
-  struct symtab_and_line prologue_sal;
-
-  prologue_sal = find_pc_line (pc, 0);
-  if (prologue_sal.line != 0)
-    {
-      int i;
-      CORE_ADDR addr = prologue_sal.end;
-
-      /* Handle the case in which compiler's optimizer/scheduler
-         has moved instructions into the prologue.  We scan ahead
-        in the function looking for address ranges whose corresponding
-        line number is less than or equal to the first one that we
-        found for the function.  (It can be less than when the
-        scheduler puts a body instruction before the first prologue
-        instruction.)  */
-      for (i = 2 * max_skip_non_prologue_insns; 
-           i > 0 && (lim_pc == 0 || addr < lim_pc);
-          i--)
-        {
-         struct symtab_and_line sal;
-
-         sal = find_pc_line (addr, 0);
-         if (sal.line == 0)
-           break;
-         if (sal.line <= prologue_sal.line 
-             && sal.symtab == prologue_sal.symtab)
-           {
-             prologue_sal = sal;
-           }
-         addr = sal.end;
-       }
-
-      if (lim_pc == 0 || prologue_sal.end < lim_pc)
-       lim_pc = prologue_sal.end;
-    }
-  return lim_pc;
-}
-
 /* Return nonzero if the given instruction OP can be part of the prologue
    of a function and saves a parameter on the stack.  FRAMEP should be
    set if one of the previous instructions in the function has set the
@@ -925,6 +949,35 @@ store_param_on_stack_p (unsigned long op, int framep, int *r0_contains_arg)
   return 0;
 }
 
+/* Assuming that INSN is a "bl" instruction located at PC, return
+   nonzero if the destination of the branch is a "blrl" instruction.
+   
+   This sequence is sometimes found in certain function prologues.
+   It allows the function to load the LR register with a value that
+   they can use to access PIC data using PC-relative offsets.  */
+
+static int
+bl_to_blrl_insn_p (CORE_ADDR pc, int insn)
+{
+  CORE_ADDR dest;
+  int immediate;
+  int absolute;
+  int dest_insn;
+
+  absolute = (int) ((insn >> 1) & 1);
+  immediate = ((insn & ~3) << 6) >> 6;
+  if (absolute)
+    dest = immediate;
+  else
+    dest = pc + immediate;
+
+  dest_insn = read_memory_integer (dest, 4);
+  if ((dest_insn & 0xfc00ffff) == 0x4c000021) /* blrl */
+    return 1;
+
+  return 0;
+}
+
 static CORE_ADDR
 skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
 {
@@ -949,21 +1002,6 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
   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);
-  
-  /* Attempt to find the end of the prologue when no limit is specified.
-     Note that refine_prologue_limit() has been written so that it may
-     be used to "refine" the limits of non-zero PC values too, but this
-     is only safe if we 1) trust the line information provided by the
-     compiler and 2) iterate enough to actually find the end of the
-     prologue.  
-     
-     It may become a good idea at some point (for both performance and
-     accuracy) to unconditionally call refine_prologue_limit().  But,
-     until we can make a clear determination that this is beneficial,
-     we'll play it safe and only use it to obtain a limit when none
-     has been specified.  */
-  if (lim_pc == 0)
-    lim_pc = refine_prologue_limit (pc, lim_pc);
 
   memset (fdata, 0, sizeof (struct rs6000_framedata));
   fdata->saved_gpr = -1;
@@ -984,7 +1022,7 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
        last_prologue_pc = pc;
 
       /* Stop scanning if we've hit the limit.  */
-      if (lim_pc != 0 && pc >= lim_pc)
+      if (pc >= lim_pc)
        break;
 
       prev_insn_was_prologue_insn = 1;
@@ -992,7 +1030,7 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
       /* Fetch the instruction and convert it to an integer.  */
       if (target_read_memory (pc, buf, 4))
        break;
-      op = extract_signed_integer (buf, 4);
+      op = extract_unsigned_integer (buf, 4);
 
       if ((op & 0xfc1fffff) == 0x7c0802a6)
        {                       /* mflr Rx */
@@ -1156,6 +1194,12 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
                                   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))
+           continue;
+
          /* Don't skip over the subroutine call if it is not within
             the first three instructions of the prologue and either
             we have no line table information or the line info tells
@@ -1212,9 +1256,18 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
          offset = fdata->offset;
          continue;
        }
-      /* Load up minimal toc pointer */
+      else if ((op & 0xffff0000) == 0x38210000)
+       {                       /* addi r1,r1,SIMM */
+         fdata->frameless = 0;
+         fdata->offset += SIGNED_SHORT (op);
+         offset = fdata->offset;
+         continue;
+       }
+      /* Load up minimal toc pointer.  Do not treat an epilogue restore
+        of r31 as a minimal TOC load.  */
       else if (((op >> 22) == 0x20f    ||      /* l r31,... or l r30,... */
               (op >> 22) == 0x3af)             /* ld r31,... or ld r30,... */
+              && !framep
               && !minimal_toc_loaded)
        {
          minimal_toc_loaded = 1;
@@ -1437,8 +1490,7 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
             Handle optimizer code motions into the prologue by continuing
             the search if we have no valid frame yet or if the return
             address is not yet saved in the frame.  */
-         if (fdata->frameless == 0
-             && (lr_reg == -1 || fdata->nosavedpc == 0))
+         if (fdata->frameless == 0 && fdata->nosavedpc == 0)
            break;
 
          if (op == 0x4e800020          /* blr */
@@ -1544,7 +1596,7 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   struct value *arg = 0;
   struct type *type;
 
-  CORE_ADDR saved_sp;
+  ULONGEST saved_sp;
 
   /* The calling convention this function implements assumes the
      processor has floating-point registers.  We shouldn't be using it
@@ -1634,7 +1686,8 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       else
        {
          /* Argument can fit in one register.  No problem.  */
-         int adj = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? reg_size - len : 0;
+         int adj = gdbarch_byte_order (current_gdbarch)
+                   == BFD_ENDIAN_BIG ? reg_size - len : 0;
          gdb_byte word[MAX_REGISTER_SIZE];
 
          memset (word, 0, reg_size);
@@ -1646,7 +1699,9 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
 ran_out_of_registers_for_arguments:
 
-  saved_sp = read_sp ();
+  regcache_cooked_read_unsigned (regcache,
+                                gdbarch_sp_regnum (current_gdbarch),
+                                &saved_sp);
 
   /* Location for 8 parameters are always reserved.  */
   sp -= wordsize * 8;
@@ -1688,7 +1743,8 @@ ran_out_of_registers_for_arguments:
          to use this area.  So, update %sp first before doing anything
          else.  */
 
-      regcache_raw_write_signed (regcache, SP_REGNUM, sp);
+      regcache_raw_write_signed (regcache,
+                                gdbarch_sp_regnum (current_gdbarch), sp);
 
       /* If the last argument copied into the registers didn't fit there 
          completely, push the rest of it into stack.  */
@@ -1735,7 +1791,7 @@ ran_out_of_registers_for_arguments:
      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, SP_REGNUM, sp);
+  regcache_raw_write_signed (regcache, gdbarch_sp_regnum (current_gdbarch), sp);
 
   /* Set back chain properly.  */
   store_unsigned_integer (tmp_buffer, wordsize, saved_sp);
@@ -1753,65 +1809,128 @@ ran_out_of_registers_for_arguments:
       regcache_raw_write_signed (regcache, tdep->ppc_toc_regnum, tocvalue);
     }
 
-  target_store_registers (-1);
+  target_store_registers (regcache, -1);
   return sp;
 }
 
-/* PowerOpen always puts structures in memory.  Vectors, which were
-   added later, do get returned in a register though.  */
-
-static int     
-rs6000_use_struct_convention (int gcc_p, struct type *value_type)
-{  
-  if ((TYPE_LENGTH (value_type) == 16 || TYPE_LENGTH (value_type) == 8)
-      && TYPE_VECTOR (value_type))
-    return 0;                            
-  return 1;
-}
-
-static void
-rs6000_extract_return_value (struct type *valtype, gdb_byte *regbuf,
-                            gdb_byte *valbuf)
+static enum return_value_convention
+rs6000_return_value (struct gdbarch *gdbarch, struct type *valtype,
+                    struct regcache *regcache, gdb_byte *readbuf,
+                    const gdb_byte *writebuf)
 {
-  int offset = 0;
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_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 PPC variants that lack them.  */
+     on PowerPC variants that lack them.  */
   gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
 
-  if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
+  /* 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);
 
-      /* floats and doubles are returned in fpr1. fpr's have a size of 8 bytes.
-         We need to truncate the return value into float size (4 byte) if
-         necessary.  */
-
-      convert_typed_floating (&regbuf[DEPRECATED_REGISTER_BYTE
-                                      (tdep->ppc_fp0_regnum + 1)],
-                              builtin_type_double,
-                              valbuf,
-                              valtype);
+      return RETURN_VALUE_REGISTER_CONVENTION;
     }
-  else if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY
-           && TYPE_LENGTH (valtype) == 16
-           && TYPE_VECTOR (valtype))
+
+  /* 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))
     {
-      memcpy (valbuf, regbuf + DEPRECATED_REGISTER_BYTE (tdep->ppc_vr0_regnum + 2),
-             TYPE_LENGTH (valtype));
+      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;
     }
-  else
+
+  /* Eight-byte non-floating-point scalar values must be returned in
+     GPR3:GPR4.  */
+
+  if (TYPE_LENGTH (valtype) == 8)
     {
-      /* return value is copied starting from r3. */
-      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
-         && TYPE_LENGTH (valtype) < register_size (current_gdbarch, 3))
-       offset = register_size (current_gdbarch, 3) - TYPE_LENGTH (valtype);
-
-      memcpy (valbuf,
-             regbuf + DEPRECATED_REGISTER_BYTE (3) + offset,
-             TYPE_LENGTH (valtype));
+      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;
 }
 
 /* Return whether handle_inferior_event() should proceed through code
@@ -1833,8 +1952,8 @@ rs6000_extract_return_value (struct type *valtype, gdb_byte *regbuf,
    branches, meaning that the link register doesn't get set.
    Therefore, GDB's usual step_over_function () mechanism won't work.
 
-   Instead, use the IN_SOLIB_RETURN_TRAMPOLINE and
-   SKIP_TRAMPOLINE_CODE hooks in handle_inferior_event() to skip past
+   Instead, use the gdbarch_skip_trampoline_code and
+   gdbarch_skip_trampoline_code hooks in handle_inferior_event() to skip past
    @FIX code.  */
 
 int
@@ -1858,7 +1977,7 @@ rs6000_in_solib_return_trampoline (CORE_ADDR pc, char *name)
    code that should be skipped.  */
 
 CORE_ADDR
-rs6000_skip_trampoline_code (CORE_ADDR pc)
+rs6000_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
 {
   unsigned int ii, op;
   int rel;
@@ -1895,7 +2014,7 @@ rs6000_skip_trampoline_code (CORE_ADDR pc)
     }
 
   /* If pc is in a shared library trampoline, return its target.  */
-  solib_target_pc = find_solib_trampoline_target (pc);
+  solib_target_pc = find_solib_trampoline_target (frame, pc);
   if (solib_target_pc)
     return solib_target_pc;
 
@@ -1905,11 +2024,93 @@ rs6000_skip_trampoline_code (CORE_ADDR pc)
       if (op != trampoline_code[ii])
        return 0;
     }
-  ii = read_register (11);     /* r11 holds destination addr   */
+  ii = get_frame_register_unsigned (frame, 11);        /* r11 holds destination addr   */
   pc = read_memory_addr (ii, gdbarch_tdep (current_gdbarch)->wordsize); /* (r11) value */
   return pc;
 }
 
+/* ISA-specific vector types.  */
+
+static struct type *
+rs6000_builtin_type_vec64 (struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (!tdep->ppc_builtin_type_vec64)
+    {
+      /* The type we're building is this: */
+#if 0
+      union __gdb_builtin_type_vec64
+       {
+         int64_t uint64;
+         float v2_float[2];
+         int32_t v2_int32[2];
+         int16_t v4_int16[4];
+         int8_t v8_int8[8];
+       };
+#endif
+
+      struct type *t;
+
+      t = init_composite_type ("__ppc_builtin_type_vec64", TYPE_CODE_UNION);
+      append_composite_type_field (t, "uint64", builtin_type_int64);
+      append_composite_type_field (t, "v2_float",
+                                  init_vector_type (builtin_type_float, 2));
+      append_composite_type_field (t, "v2_int32",
+                                  init_vector_type (builtin_type_int32, 2));
+      append_composite_type_field (t, "v4_int16",
+                                  init_vector_type (builtin_type_int16, 4));
+      append_composite_type_field (t, "v8_int8",
+                                  init_vector_type (builtin_type_int8, 8));
+
+      TYPE_FLAGS (t) |= TYPE_FLAG_VECTOR;
+      TYPE_NAME (t) = "ppc_builtin_type_vec64";
+      tdep->ppc_builtin_type_vec64 = t;
+    }
+
+  return tdep->ppc_builtin_type_vec64;
+}
+
+static struct type *
+rs6000_builtin_type_vec128 (struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (!tdep->ppc_builtin_type_vec128)
+    {
+      /* The type we're building is this: */
+#if 0
+      union __gdb_builtin_type_vec128
+       {
+         int128_t uint128;
+         float v4_float[4];
+         int32_t v4_int32[4];
+         int16_t v8_int16[8];
+         int8_t v16_int8[16];
+       };
+#endif
+
+      struct type *t;
+
+      t = init_composite_type ("__ppc_builtin_type_vec128", TYPE_CODE_UNION);
+      append_composite_type_field (t, "uint128", builtin_type_int128);
+      append_composite_type_field (t, "v4_float",
+                                  init_vector_type (builtin_type_float, 4));
+      append_composite_type_field (t, "v4_int32",
+                                  init_vector_type (builtin_type_int32, 4));
+      append_composite_type_field (t, "v8_int16",
+                                  init_vector_type (builtin_type_int16, 8));
+      append_composite_type_field (t, "v16_int8",
+                                  init_vector_type (builtin_type_int8, 16));
+
+      TYPE_FLAGS (t) |= TYPE_FLAG_VECTOR;
+      TYPE_NAME (t) = "ppc_builtin_type_vec128";
+      tdep->ppc_builtin_type_vec128 = t;
+    }
+
+  return tdep->ppc_builtin_type_vec128;
+}
+
 /* Return the size of register REG when words are WORDSIZE bytes long.  If REG
    isn't available with that word size, return 0.  */
 
@@ -1955,12 +2156,12 @@ rs6000_register_type (struct gdbarch *gdbarch, int n)
          return builtin_type_uint32;
        case 8:
          if (tdep->ppc_ev0_regnum <= n && n <= tdep->ppc_ev31_regnum)
-           return builtin_type_vec64;
+           return rs6000_builtin_type_vec64 (gdbarch);
          else
            return builtin_type_uint64;
          break;
        case 16:
-         return builtin_type_vec128;
+         return rs6000_builtin_type_vec128 (gdbarch);
          break;
        default:
          internal_error (__FILE__, __LINE__, _("Register %d size %d unknown"),
@@ -1979,8 +2180,8 @@ rs6000_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
   int vector_p;
   int general_p;
 
-  if (REGISTER_NAME (regnum) == NULL
-      || *REGISTER_NAME (regnum) == '\0')
+  if (gdbarch_register_name (current_gdbarch, regnum) == NULL
+      || *gdbarch_register_name (current_gdbarch, regnum) == '\0')
     return 0;
   if (group == all_reggroup)
     return 1;
@@ -2014,7 +2215,7 @@ rs6000_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
               || regnum == tdep->ppc_lr_regnum
               || regnum == tdep->ppc_ctr_regnum
               || regnum == tdep->ppc_xer_regnum
-              || regnum == PC_REGNUM);
+              || regnum == gdbarch_pc_regnum (current_gdbarch));
   if (group == general_reggroup)
     return general_p;
 
@@ -2108,7 +2309,7 @@ e500_move_ev_register (void (*move) (struct regcache *regcache,
 
   reg_index = ev_reg - tdep->ppc_ev0_regnum;
 
-  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+  if (gdbarch_byte_order (current_gdbarch) == 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);
@@ -2244,6 +2445,8 @@ rs6000_dwarf2_reg_to_regnum (int num)
   else
     switch (num)
       {
+      case 64:
+       return tdep->ppc_cr_regnum;
       case 67:
         return tdep->ppc_vrsave_regnum - 1; /* vscr */
       case 99:
@@ -2265,86 +2468,68 @@ rs6000_dwarf2_reg_to_regnum (int num)
       }
 }
 
+/* Translate a .eh_frame register to DWARF register, or adjust a
+   .debug_frame register.  */
 
-static void
-rs6000_store_return_value (struct type *type,
-                           struct regcache *regcache,
-                           const gdb_byte *valbuf)
-{
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  int regnum = -1;
-
-  /* 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));
-
-  if (TYPE_CODE (type) == TYPE_CODE_FLT)
-    /* Floating point values are returned starting from FPR1 and up.
-       Say a double_double_double type could be returned in
-       FPR1/FPR2/FPR3 triple.  */
-    regnum = tdep->ppc_fp0_regnum + 1;
-  else if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+static int
+rs6000_adjust_frame_regnum (struct gdbarch *gdbarch, int num, int eh_frame_p)
+{
+  /* GCC releases before 3.4 use GCC internal register numbering in
+     .debug_frame (and .debug_info, et cetera).  The numbering is
+     different from the standard SysV numbering for everything except
+     for GPRs and FPRs.  We can not detect this problem in most cases
+     - to get accurate debug info for variables living in lr, ctr, v0,
+     et cetera, use a newer version of GCC.  But we must detect
+     one important case - lr is in column 65 in .debug_frame output,
+     instead of 108.
+
+     GCC 3.4, and the "hammer" branch, have a related problem.  They
+     record lr register saves in .debug_frame as 108, but still record
+     the return column as 65.  We fix that up too.
+
+     We can do this because 65 is assigned to fpsr, and GCC never
+     generates debug info referring to it.  To add support for
+     handwritten debug info that restores fpsr, we would need to add a
+     producer version check to this.  */
+  if (!eh_frame_p)
     {
-      if (TYPE_LENGTH (type) == 16
-          && TYPE_VECTOR (type))
-        regnum = tdep->ppc_vr0_regnum + 2;
+      if (num == 65)
+       return 108;
       else
-        internal_error (__FILE__, __LINE__,
-                        _("rs6000_store_return_value: "
-                        "unexpected array return type"));
+       return num;
     }
-  else
-    /* Everything else is returned in GPR3 and up.  */
-    regnum = tdep->ppc_gp0_regnum + 3;
-
-  {
-    size_t bytes_written = 0;
 
-    while (bytes_written < TYPE_LENGTH (type))
+  /* .eh_frame is GCC specific.  For binary compatibility, it uses GCC
+     internal register numbering; translate that to the standard DWARF2
+     register numbering.  */
+  if (0 <= num && num <= 63)   /* r0-r31,fp0-fp31 */
+    return num;
+  else if (68 <= num && num <= 75) /* cr0-cr8 */
+    return num - 68 + 86;
+  else if (77 <= num && num <= 108) /* vr0-vr31 */
+    return num - 77 + 1124;
+  else
+    switch (num)
       {
-        /* How much of this value can we write to this register?  */
-        size_t bytes_to_write = min (TYPE_LENGTH (type) - bytes_written,
-                                     register_size (gdbarch, regnum));
-        regcache_cooked_write_part (regcache, regnum,
-                                    0, bytes_to_write,
-                                    valbuf + bytes_written);
-        regnum++;
-        bytes_written += bytes_to_write;
+      case 64: /* mq */
+       return 100;
+      case 65: /* lr */
+       return 108;
+      case 66: /* ctr */
+       return 109;
+      case 76: /* xer */
+       return 101;
+      case 109: /* vrsave */
+       return 356;
+      case 110: /* vscr */
+       return 67;
+      case 111: /* spe_acc */
+       return 99;
+      case 112: /* spefscr */
+       return 612;
+      default:
+       return num;
       }
-  }
-}
-
-
-/* Extract from an array REGBUF containing the (raw) register state
-   the address in which a function should return its structure value,
-   as a CORE_ADDR (or an expression that can be used as one).  */
-
-static CORE_ADDR
-rs6000_extract_struct_value_address (struct regcache *regcache)
-{
-  /* FIXME: cagney/2002-09-26: PR gdb/724: When making an inferior
-     function call GDB knows the address of the struct return value
-     and hence, should not need to call this function.  Unfortunately,
-     the current call_function_by_hand() code only saves the most
-     recent struct address leading to occasional calls.  The code
-     should instead maintain a stack of such addresses (in the dummy
-     frame object).  */
-  /* NOTE: cagney/2002-09-26: Return 0 which indicates that we've
-     really got no idea where the return value is being stored.  While
-     r3, on function entry, contained the address it will have since
-     been reused (scratch) and hence wouldn't be valid */
-  return 0;
-}
-
-/* Hook called when a new child process is started.  */
-
-void
-rs6000_create_inferior (int pid)
-{
-  if (rs6000_set_host_arch_hook)
-    rs6000_set_host_arch_hook (pid);
 }
 \f
 /* Support for CONVERT_FROM_FUNC_PTR_ADDR (ARCH, ADDR, TARG).
@@ -2378,7 +2563,7 @@ rs6000_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
     return addr;
 
   /* ADDR is in the data space, so it's a special function pointer. */
-  return read_memory_addr (addr, gdbarch_tdep (current_gdbarch)->wordsize);
+  return read_memory_addr (addr, gdbarch_tdep (gdbarch)->wordsize);
 }
 \f
 
@@ -2927,7 +3112,10 @@ find_variant_by_arch (enum bfd_architecture arch, unsigned long mach)
 static int
 gdb_print_insn_powerpc (bfd_vma memaddr, disassemble_info *info)
 {
-  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+  if (!info->disassembler_options)
+    info->disassembler_options = "any";
+
+  if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
     return print_insn_big_powerpc (memaddr, info);
   else
     return print_insn_little_powerpc (memaddr, info);
@@ -2936,15 +3124,16 @@ gdb_print_insn_powerpc (bfd_vma memaddr, disassemble_info *info)
 static CORE_ADDR
 rs6000_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
-  return frame_unwind_register_unsigned (next_frame, PC_REGNUM);
+  return frame_unwind_register_unsigned (next_frame,
+                                        gdbarch_pc_regnum (current_gdbarch));
 }
 
 static struct frame_id
 rs6000_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
-  return frame_id_build (frame_unwind_register_unsigned (next_frame,
-                                                        SP_REGNUM),
-                        frame_pc_unwind (next_frame));
+  return frame_id_build (frame_unwind_register_unsigned
+                        (next_frame, gdbarch_sp_regnum (current_gdbarch)),
+                       frame_pc_unwind (next_frame));
 }
 
 struct rs6000_frame_cache
@@ -2970,7 +3159,7 @@ rs6000_frame_cache (struct frame_info *next_frame, void **this_cache)
   (*this_cache) = cache;
   cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
 
-  func = frame_func_unwind (next_frame);
+  func = frame_func_unwind (next_frame, NORMAL_FRAME);
   pc = frame_pc_unwind (next_frame);
   skip_prologue (func, pc, &fdata);
 
@@ -2981,7 +3170,8 @@ 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, SP_REGNUM);
+  cache->base = frame_unwind_register_unsigned
+               (next_frame, gdbarch_sp_regnum (current_gdbarch));
 
   /* If the function appears to be frameless, check a couple of likely
      indicators that we have simply failed to find the frame setup.
@@ -3011,7 +3201,7 @@ rs6000_frame_cache (struct frame_info *next_frame, void **this_cache)
       if (make_frame)
        {
          fdata.frameless = 0;
-         fdata.lr_offset = wordsize;
+         fdata.lr_offset = tdep->lr_frame_offset;
        }
     }
 
@@ -3019,7 +3209,8 @@ rs6000_frame_cache (struct frame_info *next_frame, void **this_cache)
     /* Frameless really means stackless.  */
     cache->base = read_memory_addr (cache->base, wordsize);
 
-  trad_frame_set_value (cache->saved_regs, SP_REGNUM, cache->base);
+  trad_frame_set_value (cache->saved_regs,
+                       gdbarch_sp_regnum (current_gdbarch), cache->base);
 
   /* if != -1, fdata.saved_fpr is the smallest number of saved_fpr.
      All fpr's from saved_fpr to fp31 are saved.  */
@@ -3098,7 +3289,8 @@ rs6000_frame_cache (struct frame_info *next_frame, void **this_cache)
   if (fdata.lr_offset != 0)
     cache->saved_regs[tdep->ppc_lr_regnum].addr = cache->base + fdata.lr_offset;
   /* The PC is found in the link register.  */
-  cache->saved_regs[PC_REGNUM] = cache->saved_regs[tdep->ppc_lr_regnum];
+  cache->saved_regs[gdbarch_pc_regnum (current_gdbarch)] =
+    cache->saved_regs[tdep->ppc_lr_regnum];
 
   /* If != 0, fdata.vrsave_offset is the offset from the frame that
      holds the VRSAVE.  */
@@ -3108,7 +3300,8 @@ 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, SP_REGNUM);
+    cache->initial_sp = frame_unwind_register_unsigned
+                       (next_frame, gdbarch_sp_regnum (current_gdbarch));
   else
     cache->initial_sp = frame_unwind_register_unsigned (next_frame,
                                                        fdata.alloca_reg);
@@ -3122,7 +3315,8 @@ rs6000_frame_this_id (struct frame_info *next_frame, void **this_cache,
 {
   struct rs6000_frame_cache *info = rs6000_frame_cache (next_frame,
                                                        this_cache);
-  (*this_id) = frame_id_build (info->base, frame_func_unwind (next_frame));
+  (*this_id) = frame_id_build (info->base,
+                              frame_func_unwind (next_frame, NORMAL_FRAME));
 }
 
 static void
@@ -3262,7 +3456,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       info.bfd_arch_info = bfd_get_arch_info (&abfd);
       mach = info.bfd_arch_info->mach;
     }
-  tdep = xmalloc (sizeof (struct gdbarch_tdep));
+  tdep = XCALLOC (1, struct gdbarch_tdep);
   tdep->wordsize = wordsize;
 
   /* For e500 executables, the apuinfo section is of help here.  Such
@@ -3324,16 +3518,14 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_pc_regnum (gdbarch, 64);
   set_gdbarch_sp_regnum (gdbarch, 1);
   set_gdbarch_deprecated_fp_regnum (gdbarch, 1);
+  set_gdbarch_fp0_regnum (gdbarch, 32);
   set_gdbarch_register_sim_regno (gdbarch, rs6000_register_sim_regno);
   if (sysv_abi && 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_deprecated_extract_return_value (gdbarch, rs6000_extract_return_value);
-      set_gdbarch_store_return_value (gdbarch, rs6000_store_return_value);
-    }
+    set_gdbarch_return_value (gdbarch, rs6000_return_value);
 
   /* Set lr_frame_offset.  */
   if (wordsize == 8)
@@ -3398,8 +3590,6 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   else
     set_gdbarch_print_insn (gdbarch, gdb_print_insn_powerpc);
 
-  set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
-
   set_gdbarch_num_regs (gdbarch, v->nregs);
   set_gdbarch_num_pseudo_regs (gdbarch, v->npregs);
   set_gdbarch_register_name (gdbarch, rs6000_register_name);
@@ -3436,13 +3626,7 @@ 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);
-  /* Note: kevinb/2002-04-12: I'm not convinced that rs6000_push_arguments()
-     is correct for the SysV ABI when the wordsize is 8, but I'm also
-     fairly certain that ppc_sysv_abi_push_arguments() will give even
-     worse results since it only works for 32-bit code.  So, for the moment,
-     we're better off calling rs6000_push_arguments() since it works for
-     64-bit code.  At some point in the future, this matter needs to be
-     revisited.  */
+
   if (sysv_abi && wordsize == 4)
     set_gdbarch_push_dummy_call (gdbarch, ppc_sysv_abi_push_dummy_call);
   else if (sysv_abi && wordsize == 8)
@@ -3450,14 +3634,15 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   else
     set_gdbarch_push_dummy_call (gdbarch, rs6000_push_dummy_call);
 
-  set_gdbarch_deprecated_extract_struct_value_address (gdbarch, rs6000_extract_struct_value_address);
-
   set_gdbarch_skip_prologue (gdbarch, rs6000_skip_prologue);
   set_gdbarch_in_function_epilogue_p (gdbarch, rs6000_in_function_epilogue_p);
 
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
   set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc);
 
+  /* Handles single stepping of atomic sequences.  */
+  set_gdbarch_software_single_step (gdbarch, 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
@@ -3470,9 +3655,6 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Not sure on this. FIXMEmgo */
   set_gdbarch_frame_args_skip (gdbarch, 8);
 
-  if (!sysv_abi)
-    set_gdbarch_deprecated_use_struct_convention (gdbarch, rs6000_use_struct_convention);
-
   if (!sysv_abi)
     {
       /* Handle RS/6000 function pointers (which are really function
@@ -3484,6 +3666,15 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Helpers for function argument information.  */
   set_gdbarch_fetch_pointer_argument (gdbarch, rs6000_fetch_pointer_argument);
 
+  /* Trampoline.  */
+  set_gdbarch_in_solib_return_trampoline
+    (gdbarch, rs6000_in_solib_return_trampoline);
+  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_frame_set_adjust_regnum (gdbarch, rs6000_adjust_frame_regnum);
+
   /* Hook in ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
 
@@ -3518,16 +3709,6 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer);
     }
 
-  if (from_xcoff_exec)
-    {
-      /* NOTE: jimix/2003-06-09: This test should really check for
-        GDB_OSABI_AIX when that is defined and becomes
-        available. (Actually, once things are properly split apart,
-        the test goes away.) */
-       /* RS6000/AIX does not support PT_STEP.  Has to be simulated.  */
-       set_gdbarch_software_single_step (gdbarch, rs6000_software_single_step);
-    }
-
   init_sim_regno_table (gdbarch);
 
   return gdbarch;
This page took 0.037978 seconds and 4 git commands to generate.