PR 5646
[deliverable/binutils-gdb.git] / gdb / ppc-sysv-tdep.c
index 01438c159a288efdb2810f14eb3c7f81832abf42..c2952f5c8b8b4a57865c32ca7c3dc747b2bd09eb 100644 (file)
@@ -1,13 +1,14 @@
 /* Target-dependent code for PowerPC systems using the SVR4 ABI
    for GDB, the GNU debugger.
 
-   Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002, 2003, 2005, 2007, 2008
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -16,9 +17,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "gdbcore.h"
@@ -29,6 +28,8 @@
 #include "gdb_assert.h"
 #include "ppc-tdep.h"
 #include "target.h"
+#include "objfiles.h"
+#include "infcall.h"
 
 /* Pass the arguments in either registers, or in the stack. Using the
    ppc sysv ABI, the first eight words of the argument list (that might
    starting from r4. */
 
 CORE_ADDR
-ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
+ppc_sysv_abi_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)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
-  const CORE_ADDR saved_sp = read_sp ();
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ULONGEST saved_sp;
   int argspace = 0;            /* 0 is an initial wrong guess.  */
   int write_pass;
 
+  gdb_assert (tdep->wordsize == 4);
+
+  regcache_cooked_read_unsigned (regcache, gdbarch_sp_regnum (gdbarch),
+                                &saved_sp);
+
   /* Go through the argument list twice.
 
      Pass 1: Figure out how much new stack space is required for
@@ -95,12 +101,12 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
       for (argno = 0; argno < nargs; argno++)
        {
          struct value *arg = args[argno];
-         struct type *type = check_typedef (VALUE_TYPE (arg));
+         struct type *type = check_typedef (value_type (arg));
          int len = TYPE_LENGTH (type);
-         char *val = VALUE_CONTENTS (arg);
+         const bfd_byte *val = value_contents (arg);
 
-         if (TYPE_CODE (type) == TYPE_CODE_FLT
-             && ppc_floating_point_unit_p (current_gdbarch) && len <= 8)
+         if (TYPE_CODE (type) == TYPE_CODE_FLT && len <= 8
+             && !tdep->soft_float)
            {
              /* Floating point value converted to "double" then
                 passed in an FP register, when the registers run out,
@@ -111,11 +117,12 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
                    {
                      /* Always store the floating point value using
                         the register's floating-point format.  */
-                     char regval[MAX_REGISTER_SIZE];
+                     gdb_byte regval[MAX_REGISTER_SIZE];
                      struct type *regtype
-                       = register_type (gdbarch, FP0_REGNUM + freg);
+                       = register_type (gdbarch, tdep->ppc_fp0_regnum + freg);
                      convert_typed_floating (val, type, regval, regtype);
-                     regcache_cooked_write (regcache, FP0_REGNUM + freg,
+                     regcache_cooked_write (regcache,
+                                             tdep->ppc_fp0_regnum + freg,
                                             regval);
                    }
                  freg++;
@@ -128,28 +135,47 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
                  if (write_pass)
                    {
                      char memval[8];
-                     struct type *memtype;
-                     switch (TARGET_BYTE_ORDER)
-                       {
-                       case BFD_ENDIAN_BIG:
-                         memtype = builtin_type_ieee_double_big;
-                         break;
-                       case BFD_ENDIAN_LITTLE:
-                         memtype = builtin_type_ieee_double_little;
-                         break;
-                       default:
-                         internal_error (__FILE__, __LINE__, "bad switch");
-                       }
-                     convert_typed_floating (val, type, memval, memtype);
+                     convert_typed_floating (val, type, memval,
+                                             builtin_type_ieee_double);
                      write_memory (sp + argoffset, val, len);
                    }
                  argoffset += 8;
                }
            }
-         else if (len == 8 && (TYPE_CODE (type) == TYPE_CODE_INT       /* long long */
-                               || (!ppc_floating_point_unit_p (current_gdbarch) && TYPE_CODE (type) == TYPE_CODE_FLT)))        /* double */
+         else if (TYPE_CODE (type) == TYPE_CODE_FLT
+                  && len == 16
+                  && !tdep->soft_float
+                  && (gdbarch_long_double_format (gdbarch)
+                      == floatformats_ibm_long_double))
+           {
+             /* IBM long double passed in two FP registers if
+                available, otherwise 8-byte aligned stack.  */
+             if (freg <= 7)
+               {
+                 if (write_pass)
+                   {
+                     regcache_cooked_write (regcache,
+                                            tdep->ppc_fp0_regnum + freg,
+                                            val);
+                     regcache_cooked_write (regcache,
+                                            tdep->ppc_fp0_regnum + freg + 1,
+                                            val + 8);
+                   }
+                 freg += 2;
+               }
+             else
+               {
+                 argoffset = align_up (argoffset, 8);
+                 if (write_pass)
+                   write_memory (sp + argoffset, val, len);
+                 argoffset += 16;
+               }
+           }
+         else if (len == 8
+                  && (TYPE_CODE (type) == TYPE_CODE_INT        /* long long */
+                      || TYPE_CODE (type) == TYPE_CODE_FLT))   /* double */
            {
-             /* "long long" or "double" passed in an odd/even
+             /* "long long" or soft-float "double" passed in an odd/even
                 register pair with the low addressed word in the odd
                 register and the high addressed word in the even
                 register, or when the registers run out an 8 byte
@@ -163,13 +189,6 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
                    write_memory (sp + argoffset, val, len);
                  argoffset += 8;
                }
-             else if (tdep->wordsize == 8)
-               {
-                 if (write_pass)
-                   regcache_cooked_write (regcache,
-                                          tdep->ppc_gp0_regnum + greg, val);
-                 greg += 1;
-               }
              else
                {
                  /* Must start on an odd register - r3/r4 etc.  */
@@ -187,16 +206,52 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
                  greg += 2;
                }
            }
+         else if (len == 16 && TYPE_CODE (type) == TYPE_CODE_FLT
+                  && (gdbarch_long_double_format (gdbarch)
+                      == floatformats_ibm_long_double))
+           {
+             /* Soft-float IBM long double passed in four consecutive
+                registers, or on the stack.  The registers are not
+                necessarily odd/even pairs.  */
+             if (greg > 7)
+               {
+                 greg = 11;
+                 argoffset = align_up (argoffset, 8);
+                 if (write_pass)
+                   write_memory (sp + argoffset, val, len);
+                 argoffset += 16;
+               }
+             else
+               {
+                 if (write_pass)
+                   {
+                     regcache_cooked_write (regcache,
+                                            tdep->ppc_gp0_regnum + greg + 0,
+                                            val + 0);
+                     regcache_cooked_write (regcache,
+                                            tdep->ppc_gp0_regnum + greg + 1,
+                                            val + 4);
+                     regcache_cooked_write (regcache,
+                                            tdep->ppc_gp0_regnum + greg + 2,
+                                            val + 8);
+                     regcache_cooked_write (regcache,
+                                            tdep->ppc_gp0_regnum + greg + 3,
+                                            val + 12);
+                   }
+                 greg += 4;
+               }
+           }
          else if (len == 16
                   && TYPE_CODE (type) == TYPE_CODE_ARRAY
-                  && TYPE_VECTOR (type) && tdep->ppc_vr0_regnum >= 0)
+                  && TYPE_VECTOR (type)
+                  && tdep->vector_abi == POWERPC_VEC_ALTIVEC)
            {
              /* Vector parameter passed in an Altivec register, or
                 when that runs out, 16 byte aligned stack location.  */
              if (vreg <= 13)
                {
                  if (write_pass)
-                   regcache_cooked_write (current_regcache,
+                   regcache_cooked_write (regcache,
                                           tdep->ppc_vr0_regnum + vreg, val);
                  vreg++;
                }
@@ -210,7 +265,8 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
            }
          else if (len == 8
                   && TYPE_CODE (type) == TYPE_CODE_ARRAY
-                  && TYPE_VECTOR (type) && tdep->ppc_ev0_regnum >= 0)
+                  && TYPE_VECTOR (type)
+                  && tdep->vector_abi == POWERPC_VEC_SPE)
            {
              /* Vector parameter passed in an e500 register, or when
                 that runs out, 8 byte aligned stack location.  Note
@@ -222,7 +278,7 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
              if (greg <= 10)
                {
                  if (write_pass)
-                   regcache_cooked_write (current_regcache,
+                   regcache_cooked_write (regcache,
                                           tdep->ppc_ev0_regnum + greg, val);
                  greg++;
                }
@@ -238,15 +294,21 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
            {
              /* Reduce the parameter down to something that fits in a
                 "word".  */
-             char word[MAX_REGISTER_SIZE];
+             gdb_byte word[MAX_REGISTER_SIZE];
              memset (word, 0, MAX_REGISTER_SIZE);
              if (len > tdep->wordsize
                  || TYPE_CODE (type) == TYPE_CODE_STRUCT
                  || TYPE_CODE (type) == TYPE_CODE_UNION)
                {
-                 /* Structs and large values are put on an 8 byte
-                    aligned stack ... */
-                 structoffset = align_up (structoffset, 8);
+                 /* Structs and large values are put in an
+                    aligned stack slot ... */
+                 if (TYPE_CODE (type) == TYPE_CODE_ARRAY
+                     && TYPE_VECTOR (type)
+                     && len >= 16)
+                   structoffset = align_up (structoffset, 16);
+                 else
+                   structoffset = align_up (structoffset, 8);
+
                  if (write_pass)
                    write_memory (sp + structoffset, val, len);
                  /* ... and then a "word" pointing to that address is
@@ -291,10 +353,28 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
          /* Ensure that the stack is still 16 byte aligned.  */
          sp = align_down (sp, 16);
        }
+
+      /* The psABI says that "A caller of a function that takes a
+        variable argument list shall set condition register bit 6 to
+        1 if it passes one or more arguments in the floating-point
+        registers. It is strongly recommended that the caller set the
+        bit to 0 otherwise..."  Doing this for normal functions too
+        shouldn't hurt.  */
+      if (write_pass)
+       {
+         ULONGEST cr;
+
+         regcache_cooked_read_unsigned (regcache, tdep->ppc_cr_regnum, &cr);
+         if (freg > 1)
+           cr |= 0x02000000;
+         else
+           cr &= ~0x02000000;
+         regcache_cooked_write_unsigned (regcache, tdep->ppc_cr_regnum, cr);
+       }
     }
 
   /* Update %sp.   */
-  regcache_cooked_write_signed (regcache, SP_REGNUM, sp);
+  regcache_cooked_write_signed (regcache, gdbarch_sp_regnum (gdbarch), sp);
 
   /* Write the backchain (it occupies WORDSIZED bytes).  */
   write_memory_signed_integer (sp, tdep->wordsize, saved_sp);
@@ -323,32 +403,80 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
 
 static enum return_value_convention
 do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *type,
-                         struct regcache *regcache, void *readbuf,
-                         const void *writebuf, int broken_gcc)
+                         struct regcache *regcache, gdb_byte *readbuf,
+                         const gdb_byte *writebuf, int broken_gcc)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   gdb_assert (tdep->wordsize == 4);
   if (TYPE_CODE (type) == TYPE_CODE_FLT
       && TYPE_LENGTH (type) <= 8
-      && ppc_floating_point_unit_p (gdbarch))
+      && !tdep->soft_float)
     {
       if (readbuf)
        {
          /* Floats and doubles stored in "f1".  Convert the value to
             the required type.  */
-         char regval[MAX_REGISTER_SIZE];
-         struct type *regtype = register_type (gdbarch, FP0_REGNUM + 1);
-         regcache_cooked_read (regcache, FP0_REGNUM + 1, regval);
+         gdb_byte regval[MAX_REGISTER_SIZE];
+         struct type *regtype = register_type (gdbarch,
+                                                tdep->ppc_fp0_regnum + 1);
+         regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1, regval);
          convert_typed_floating (regval, regtype, readbuf, type);
        }
       if (writebuf)
        {
          /* Floats and doubles stored in "f1".  Convert the value to
             the register's "double" type.  */
-         char regval[MAX_REGISTER_SIZE];
-         struct type *regtype = register_type (gdbarch, FP0_REGNUM);
+         gdb_byte regval[MAX_REGISTER_SIZE];
+         struct type *regtype = register_type (gdbarch, tdep->ppc_fp0_regnum);
          convert_typed_floating (writebuf, type, regval, regtype);
-         regcache_cooked_write (regcache, FP0_REGNUM + 1, regval);
+         regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1, regval);
+       }
+      return RETURN_VALUE_REGISTER_CONVENTION;
+    }
+  if (TYPE_CODE (type) == TYPE_CODE_FLT
+      && TYPE_LENGTH (type) == 16
+      && !tdep->soft_float
+      && (gdbarch_long_double_format (gdbarch) == floatformats_ibm_long_double))
+    {
+      /* IBM long double stored in f1 and f2.  */
+      if (readbuf)
+       {
+         regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1, readbuf);
+         regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 2,
+                               readbuf + 8);
+       }
+      if (writebuf)
+       {
+         regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1, writebuf);
+         regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 2,
+                                writebuf + 8);
+       }
+      return RETURN_VALUE_REGISTER_CONVENTION;
+    }
+  if (TYPE_CODE (type) == TYPE_CODE_FLT
+      && TYPE_LENGTH (type) == 16
+      && (gdbarch_long_double_format (gdbarch) == floatformats_ibm_long_double))
+    {
+      /* Soft-float IBM long double stored in r3, r4, r5, r6.  */
+      if (readbuf)
+       {
+         regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, readbuf);
+         regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 4,
+                               readbuf + 4);
+         regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 5,
+                               readbuf + 8);
+         regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 6,
+                               readbuf + 12);
+       }
+      if (writebuf)
+       {
+         regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3, writebuf);
+         regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 4,
+                                writebuf + 4);
+         regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 5,
+                                writebuf + 8);
+         regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 6,
+                                writebuf + 12);
        }
       return RETURN_VALUE_REGISTER_CONVENTION;
     }
@@ -359,22 +487,27 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *type,
        {
          /* A long long, or a double stored in the 32 bit r3/r4.  */
          regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3,
-                               (bfd_byte *) readbuf + 0);
+                               readbuf + 0);
          regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 4,
-                               (bfd_byte *) readbuf + 4);
+                               readbuf + 4);
        }
       if (writebuf)
        {
          /* A long long, or a double stored in the 32 bit r3/r4.  */
          regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3,
-                                (const bfd_byte *) writebuf + 0);
+                                writebuf + 0);
          regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 4,
-                                (const bfd_byte *) writebuf + 4);
+                                writebuf + 4);
        }
       return RETURN_VALUE_REGISTER_CONVENTION;
     }
-  if (TYPE_CODE (type) == TYPE_CODE_INT
-      && TYPE_LENGTH (type) <= tdep->wordsize)
+  else if ((TYPE_CODE (type) == TYPE_CODE_INT
+           || TYPE_CODE (type) == TYPE_CODE_CHAR
+           || TYPE_CODE (type) == TYPE_CODE_BOOL
+           || TYPE_CODE (type) == TYPE_CODE_PTR
+           || TYPE_CODE (type) == TYPE_CODE_REF
+           || TYPE_CODE (type) == TYPE_CODE_ENUM)
+          && TYPE_LENGTH (type) <= tdep->wordsize)
     {
       if (readbuf)
        {
@@ -397,7 +530,8 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *type,
     }
   if (TYPE_LENGTH (type) == 16
       && TYPE_CODE (type) == TYPE_CODE_ARRAY
-      && TYPE_VECTOR (type) && tdep->ppc_vr0_regnum >= 0)
+      && TYPE_VECTOR (type)
+      && tdep->vector_abi == POWERPC_VEC_ALTIVEC)
     {
       if (readbuf)
        {
@@ -411,9 +545,42 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *type,
        }
       return RETURN_VALUE_REGISTER_CONVENTION;
     }
+  if (TYPE_LENGTH (type) == 16
+      && TYPE_CODE (type) == TYPE_CODE_ARRAY
+      && TYPE_VECTOR (type)
+      && tdep->vector_abi == POWERPC_VEC_GENERIC)
+    {
+      /* GCC -maltivec -mabi=no-altivec returns vectors in r3/r4/r5/r6.
+        GCC without AltiVec returns them in memory, but it warns about
+        ABI risks in that case; we don't try to support it.  */
+      if (readbuf)
+       {
+         regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3,
+                               readbuf + 0);
+         regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 4,
+                               readbuf + 4);
+         regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 5,
+                               readbuf + 8);
+         regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 6,
+                               readbuf + 12);
+       }
+      if (writebuf)
+       {
+         regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3,
+                                writebuf + 0);
+         regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 4,
+                                writebuf + 4);
+         regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 5,
+                                writebuf + 8);
+         regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 6,
+                                writebuf + 12);
+       }
+      return RETURN_VALUE_REGISTER_CONVENTION;
+    }
   if (TYPE_LENGTH (type) == 8
       && TYPE_CODE (type) == TYPE_CODE_ARRAY
-      && TYPE_VECTOR (type) && tdep->ppc_ev0_regnum >= 0)
+      && TYPE_VECTOR (type)
+      && tdep->vector_abi == POWERPC_VEC_SPE)
     {
       /* The e500 ABI places return values for the 64-bit DSP types
         (__ev64_opaque__) in r3.  However, in GDB-speak, ev3
@@ -428,52 +595,33 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *type,
     }
   if (broken_gcc && TYPE_LENGTH (type) <= 8)
     {
+      /* GCC screwed up for structures or unions whose size is less
+        than or equal to 8 bytes..  Instead of left-aligning, it
+        right-aligns the data into the buffer formed by r3, r4.  */
+      gdb_byte regvals[MAX_REGISTER_SIZE * 2];
+      int len = TYPE_LENGTH (type);
+      int offset = (2 * tdep->wordsize - len) % tdep->wordsize;
+
       if (readbuf)
        {
-         /* GCC screwed up.  The last register isn't "left" aligned.
-            Need to extract the least significant part of each
-            register and then store that.  */
-         /* Transfer any full words.  */
-         int word = 0;
-         while (1)
-           {
-             ULONGEST reg;
-             int len = TYPE_LENGTH (type) - word * tdep->wordsize;
-             if (len <= 0)
-               break;
-             if (len > tdep->wordsize)
-               len = tdep->wordsize;
-             regcache_cooked_read_unsigned (regcache,
-                                            tdep->ppc_gp0_regnum + 3 + word,
-                                            &reg);
-             store_unsigned_integer (((bfd_byte *) readbuf
-                                      + word * tdep->wordsize), len, reg);
-             word++;
-           }
+         regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3,
+                               regvals + 0 * tdep->wordsize);
+         if (len > tdep->wordsize)
+           regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 4,
+                                 regvals + 1 * tdep->wordsize);
+         memcpy (readbuf, regvals + offset, len);
        }
       if (writebuf)
        {
-         /* GCC screwed up.  The last register isn't "left" aligned.
-            Need to extract the least significant part of each
-            register and then store that.  */
-         /* Transfer any full words.  */
-         int word = 0;
-         while (1)
-           {
-             ULONGEST reg;
-             int len = TYPE_LENGTH (type) - word * tdep->wordsize;
-             if (len <= 0)
-               break;
-             if (len > tdep->wordsize)
-               len = tdep->wordsize;
-             reg = extract_unsigned_integer (((const bfd_byte *) writebuf
-                                              + word * tdep->wordsize), len);
-             regcache_cooked_write_unsigned (regcache,
-                                             tdep->ppc_gp0_regnum + 3 + word,
-                                             reg);
-             word++;
-           }
+         memset (regvals, 0, sizeof regvals);
+         memcpy (regvals + offset, writebuf, len);
+         regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3,
+                                regvals + 0 * tdep->wordsize);
+         if (len > tdep->wordsize)
+           regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 4,
+                                  regvals + 1 * tdep->wordsize);
        }
+
       return RETURN_VALUE_REGISTER_CONVENTION;
     }
   if (TYPE_LENGTH (type) <= 8)
@@ -483,7 +631,7 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *type,
          /* This matches SVr4 PPC, it does not match GCC.  */
          /* The value is right-padded to 8 bytes and then loaded, as
             two "words", into r3/r4.  */
-         char regvals[MAX_REGISTER_SIZE * 2];
+         gdb_byte regvals[MAX_REGISTER_SIZE * 2];
          regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3,
                                regvals + 0 * tdep->wordsize);
          if (TYPE_LENGTH (type) > tdep->wordsize)
@@ -496,7 +644,7 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *type,
          /* This matches SVr4 PPC, it does not match GCC.  */
          /* The value is padded out to 8 bytes and then loaded, as
             two "words" into r3/r4.  */
-         char regvals[MAX_REGISTER_SIZE * 2];
+         gdb_byte regvals[MAX_REGISTER_SIZE * 2];
          memset (regvals, 0, sizeof regvals);
          memcpy (regvals, writebuf, TYPE_LENGTH (type));
          regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3,
@@ -512,8 +660,8 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *type,
 
 enum return_value_convention
 ppc_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *valtype,
-                          struct regcache *regcache, void *readbuf,
-                          const void *writebuf)
+                          struct regcache *regcache, gdb_byte *readbuf,
+                          const gdb_byte *writebuf)
 {
   return do_ppc_sysv_return_value (gdbarch, valtype, regcache, readbuf,
                                   writebuf, 0);
@@ -523,12 +671,53 @@ enum return_value_convention
 ppc_sysv_abi_broken_return_value (struct gdbarch *gdbarch,
                                  struct type *valtype,
                                  struct regcache *regcache,
-                                 void *readbuf, const void *writebuf)
+                                 gdb_byte *readbuf, const gdb_byte *writebuf)
 {
   return do_ppc_sysv_return_value (gdbarch, valtype, regcache, readbuf,
                                   writebuf, 1);
 }
 
+/* The helper function for 64-bit SYSV push_dummy_call.  Converts the
+   function's code address back into the function's descriptor
+   address.
+
+   Find a value for the TOC register.  Every symbol should have both
+   ".FN" and "FN" in the minimal symbol table.  "FN" points at the
+   FN's descriptor, while ".FN" points at the entry point (which
+   matches FUNC_ADDR).  Need to reverse from FUNC_ADDR back to the
+   FN's descriptor address (while at the same time being careful to
+   find "FN" in the same object file as ".FN").  */
+
+static int
+convert_code_addr_to_desc_addr (CORE_ADDR code_addr, CORE_ADDR *desc_addr)
+{
+  struct obj_section *dot_fn_section;
+  struct minimal_symbol *dot_fn;
+  struct minimal_symbol *fn;
+  CORE_ADDR toc;
+  /* Find the minimal symbol that corresponds to CODE_ADDR (should
+     have a name of the form ".FN").  */
+  dot_fn = lookup_minimal_symbol_by_pc (code_addr);
+  if (dot_fn == NULL || SYMBOL_LINKAGE_NAME (dot_fn)[0] != '.')
+    return 0;
+  /* Get the section that contains CODE_ADDR.  Need this for the
+     "objfile" that it contains.  */
+  dot_fn_section = find_pc_section (code_addr);
+  if (dot_fn_section == NULL || dot_fn_section->objfile == NULL)
+    return 0;
+  /* Now find the corresponding "FN" (dropping ".") minimal symbol's
+     address.  Only look for the minimal symbol in ".FN"'s object file
+     - avoids problems when two object files (i.e., shared libraries)
+     contain a minimal symbol with the same name.  */
+  fn = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (dot_fn) + 1, NULL,
+                             dot_fn_section->objfile);
+  if (fn == NULL)
+    return 0;
+  /* Found a descriptor.  */
+  (*desc_addr) = SYMBOL_VALUE_ADDRESS (fn);
+  return 1;
+}
+
 /* Pass the arguments in either registers, or in the stack. Using the
    ppc 64 bit SysV ABI.
 
@@ -537,16 +726,14 @@ ppc_sysv_abi_broken_return_value (struct gdbarch *gdbarch,
    greatly simplifies the logic. */
 
 CORE_ADDR
-ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
+ppc64_sysv_abi_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)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
-  /* By this stage in the proceedings, SP has been decremented by "red
-     zone size" + "struct return size".  Fetch the stack-pointer from
-     before this and use that as the BACK_CHAIN.  */
-  const CORE_ADDR back_chain = read_sp ();
+  CORE_ADDR func_addr = find_function_addr (function, NULL);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  ULONGEST back_chain;
   /* See for-loop comment below.  */
   int write_pass;
   /* Size of the Altivec's vector parameter region, the final value is
@@ -564,6 +751,17 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
      the possible values of tdep->wordsize.  */
   gdb_assert (tdep->wordsize == 8);
 
+  /* This function exists to support a calling convention that
+     requires floating-point registers.  It shouldn't be used on
+     processors that lack them.  */
+  gdb_assert (ppc_floating_point_unit_p (gdbarch));
+
+  /* By this stage in the proceedings, SP has been decremented by "red
+     zone size" + "struct return size".  Fetch the stack-pointer from
+     before this and use that as the BACK_CHAIN.  */
+  regcache_cooked_read_unsigned (regcache, gdbarch_sp_regnum (gdbarch),
+                                &back_chain);
+
   /* Go through the argument list twice.
 
      Pass 1: Compute the function call's stack space and register
@@ -629,8 +827,8 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
       for (argno = 0; argno < nargs; argno++)
        {
          struct value *arg = args[argno];
-         struct type *type = check_typedef (VALUE_TYPE (arg));
-         char *val = VALUE_CONTENTS (arg);
+         struct type *type = check_typedef (value_type (arg));
+         const bfd_byte *val = value_contents (arg);
          if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) <= 8)
            {
              /* Floats and Doubles go in f1 .. f13.  They also
@@ -638,14 +836,14 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
                 memory.  */
              if (write_pass)
                {
-                 if (ppc_floating_point_unit_p (current_gdbarch)
-                     && freg <= 13)
+                 if (freg <= 13)
                    {
-                     char regval[MAX_REGISTER_SIZE];
-                     struct type *regtype = register_type (gdbarch,
-                                                           FP0_REGNUM);
+                     gdb_byte regval[MAX_REGISTER_SIZE];
+                     struct type *regtype
+                        = register_type (gdbarch, tdep->ppc_fp0_regnum);
                      convert_typed_floating (val, type, regval, regtype);
-                     regcache_cooked_write (regcache, FP0_REGNUM + freg,
+                     regcache_cooked_write (regcache,
+                                             tdep->ppc_fp0_regnum + freg,
                                             regval);
                    }
                  if (greg <= 10)
@@ -659,7 +857,7 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
 
                         This code interprets that to mean: store it,
                         left aligned, in the general register.  */
-                     char regval[MAX_REGISTER_SIZE];
+                     gdb_byte regval[MAX_REGISTER_SIZE];
                      memset (regval, 0, sizeof regval);
                      memcpy (regval, val, TYPE_LENGTH (type));
                      regcache_cooked_write (regcache,
@@ -673,6 +871,41 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
              greg++;
              gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize);
            }
+         else if (TYPE_CODE (type) == TYPE_CODE_FLT
+                  && TYPE_LENGTH (type) == 16
+                  && (gdbarch_long_double_format (gdbarch)
+                      == floatformats_ibm_long_double))
+           {
+             /* IBM long double stored in two doublewords of the
+                parameter save area and corresponding registers.  */
+             if (write_pass)
+               {
+                 if (!tdep->soft_float && freg <= 13)
+                   {
+                     regcache_cooked_write (regcache,
+                                             tdep->ppc_fp0_regnum + freg,
+                                            val);
+                     if (freg <= 12)
+                       regcache_cooked_write (regcache,
+                                              tdep->ppc_fp0_regnum + freg + 1,
+                                              val + 8);
+                   }
+                 if (greg <= 10)
+                   {
+                     regcache_cooked_write (regcache,
+                                            tdep->ppc_gp0_regnum + greg,
+                                            val);
+                     if (greg <= 9)
+                       regcache_cooked_write (regcache,
+                                              tdep->ppc_gp0_regnum + greg + 1,
+                                              val + 8);
+                   }
+                 write_memory (gparam, val, TYPE_LENGTH (type));
+               }
+             freg += 2;
+             greg += 2;
+             gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize);
+           }
          else if (TYPE_LENGTH (type) == 16 && TYPE_VECTOR (type)
                   && TYPE_CODE (type) == TYPE_CODE_ARRAY
                   && tdep->ppc_vr0_regnum >= 0)
@@ -697,15 +930,25 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
                }
            }
          else if ((TYPE_CODE (type) == TYPE_CODE_INT
-                   || TYPE_CODE (type) == TYPE_CODE_ENUM)
+                   || TYPE_CODE (type) == TYPE_CODE_ENUM
+                   || TYPE_CODE (type) == TYPE_CODE_PTR)
                   && TYPE_LENGTH (type) <= 8)
            {
-             /* Scalars get sign[un]extended and go in gpr3 .. gpr10.
-                They can also end up in memory.  */
+             /* Scalars and Pointers get sign[un]extended and go in
+                gpr3 .. gpr10.  They can also end up in memory.  */
              if (write_pass)
                {
                  /* Sign extend the value, then store it unsigned.  */
                  ULONGEST word = unpack_long (type, val);
+                 /* Convert any function code addresses into
+                    descriptors.  */
+                 if (TYPE_CODE (type) == TYPE_CODE_PTR
+                     && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC)
+                   {
+                     CORE_ADDR desc = word;
+                     convert_code_addr_to_desc_addr (word, &desc);
+                     word = desc;
+                   }
                  if (greg <= 10)
                    regcache_cooked_write_unsigned (regcache,
                                                    tdep->ppc_gp0_regnum +
@@ -724,27 +967,22 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
                {
                  if (write_pass && greg <= 10)
                    {
-                     char regval[MAX_REGISTER_SIZE];
+                     gdb_byte regval[MAX_REGISTER_SIZE];
                      int len = TYPE_LENGTH (type) - byte;
                      if (len > tdep->wordsize)
                        len = tdep->wordsize;
                      memset (regval, 0, sizeof regval);
-                     /* WARNING: cagney/2003-09-21: As best I can
-                        tell, the ABI specifies that the value should
-                        be left aligned.  Unfortunately, GCC doesn't
-                        do this - it instead right aligns even sized
-                        values and puts odd sized values on the
-                        stack.  Work around that by putting both a
-                        left and right aligned value into the
-                        register (hopefully no one notices :-^).
-                        Arrrgh!  */
-                     /* Left aligned (8 byte values such as pointers
-                        fill the buffer).  */
-                     memcpy (regval, val + byte, len);
-                     /* Right aligned (but only if even).  */
-                     if (len == 1 || len == 2 || len == 4)
+                     /* The ABI (version 1.9) specifies that values
+                        smaller than one doubleword are right-aligned
+                        and those larger are left-aligned.  GCC
+                        versions before 3.4 implemented this
+                        incorrectly; see
+                        <http://gcc.gnu.org/gcc-3.4/powerpc-abi.html>.  */
+                     if (byte == 0)
                        memcpy (regval + tdep->wordsize - len,
                                val + byte, len);
+                     else
+                       memcpy (regval, val + byte, len);
                      regcache_cooked_write (regcache, greg, regval);
                    }
                  greg++;
@@ -758,6 +996,57 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
                   value to memory.  Fortunately, doing this
                   simplifies the code.  */
                write_memory (gparam, val, TYPE_LENGTH (type));
+             if (freg <= 13
+                 && TYPE_CODE (type) == TYPE_CODE_STRUCT
+                 && TYPE_NFIELDS (type) == 1
+                 && TYPE_LENGTH (type) <= 16)
+               {
+                 /* The ABI (version 1.9) specifies that structs
+                    containing a single floating-point value, at any
+                    level of nesting of single-member structs, are
+                    passed in floating-point registers.  */
+                 while (TYPE_CODE (type) == TYPE_CODE_STRUCT
+                        && TYPE_NFIELDS (type) == 1)
+                   type = check_typedef (TYPE_FIELD_TYPE (type, 0));
+                 if (TYPE_CODE (type) == TYPE_CODE_FLT)
+                   {
+                     if (TYPE_LENGTH (type) <= 8)
+                       {
+                         if (write_pass)
+                           {
+                             gdb_byte regval[MAX_REGISTER_SIZE];
+                             struct type *regtype
+                               = register_type (gdbarch,
+                                                tdep->ppc_fp0_regnum);
+                             convert_typed_floating (val, type, regval,
+                                                     regtype);
+                             regcache_cooked_write (regcache,
+                                                    (tdep->ppc_fp0_regnum
+                                                     + freg),
+                                                    regval);
+                           }
+                         freg++;
+                       }
+                     else if (TYPE_LENGTH (type) == 16
+                              && (gdbarch_long_double_format (gdbarch)
+                                  == floatformats_ibm_long_double))
+                       {
+                         if (write_pass)
+                           {
+                             regcache_cooked_write (regcache,
+                                                    (tdep->ppc_fp0_regnum
+                                                     + freg),
+                                                    val);
+                             if (freg <= 12)
+                               regcache_cooked_write (regcache,
+                                                      (tdep->ppc_fp0_regnum
+                                                       + freg + 1),
+                                                      val + 8);
+                           }
+                         freg += 2;
+                       }
+                   }
+               }
              /* Always consume parameter stack space.  */
              gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize);
            }
@@ -777,7 +1066,7 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
     }
 
   /* Update %sp.   */
-  regcache_cooked_write_signed (regcache, SP_REGNUM, sp);
+  regcache_cooked_write_signed (regcache, gdbarch_sp_regnum (gdbarch), sp);
 
   /* Write the backchain (it occupies WORDSIZED bytes).  */
   write_memory_signed_integer (sp, tdep->wordsize, back_chain);
@@ -786,32 +1075,18 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
      breakpoint.  */
   regcache_cooked_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr);
 
-  /* Find a value for the TOC register.  Every symbol should have both
-     ".FN" and "FN" in the minimal symbol table.  "FN" points at the
-     FN's descriptor, while ".FN" points at the entry point (which
-     matches FUNC_ADDR).  Need to reverse from FUNC_ADDR back to the
-     FN's descriptor address.  */
+  /* Use the func_addr to find the descriptor, and use that to find
+     the TOC.  */
   {
-    /* Find the minimal symbol that corresponds to FUNC_ADDR (should
-       have the name ".FN").  */
-    struct minimal_symbol *dot_fn = lookup_minimal_symbol_by_pc (func_addr);
-    if (dot_fn != NULL && SYMBOL_LINKAGE_NAME (dot_fn)[0] == '.')
+    CORE_ADDR desc_addr;
+    if (convert_code_addr_to_desc_addr (func_addr, &desc_addr))
       {
-       /* Now find the corresponding "FN" (dropping ".") minimal
-          symbol's address.  */
-       struct minimal_symbol *fn =
-         lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (dot_fn) + 1, NULL,
-                                NULL);
-       if (fn != NULL)
-         {
-           /* Got the address of that descriptor.  The TOC is the
-              second double word.  */
-           CORE_ADDR toc =
-             read_memory_unsigned_integer (SYMBOL_VALUE_ADDRESS (fn) +
-                                           tdep->wordsize, tdep->wordsize);
-           regcache_cooked_write_unsigned (regcache,
-                                           tdep->ppc_gp0_regnum + 2, toc);
-         }
+       /* The TOC is the second double word in the descriptor.  */
+       CORE_ADDR toc =
+         read_memory_unsigned_integer (desc_addr + tdep->wordsize,
+                                       tdep->wordsize);
+       regcache_cooked_write_unsigned (regcache,
+                                       tdep->ppc_gp0_regnum + 2, toc);
       }
   }
 
@@ -819,7 +1094,7 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
 }
 
 
-/* The 64 bit ABI retun value convention.
+/* The 64 bit ABI return value convention.
 
    Return non-zero if the return-value is stored in a register, return
    0 if the return-value is instead stored on the stack (a.k.a.,
@@ -831,30 +1106,38 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
    corresponding register return-value location.  */
 enum return_value_convention
 ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *valtype,
-                            struct regcache *regcache, void *readbuf,
-                            const void *writebuf)
+                            struct regcache *regcache, gdb_byte *readbuf,
+                            const gdb_byte *writebuf)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  /* This function exists to support a calling convention that
+     requires floating-point registers.  It shouldn't be used on
+     processors that lack them.  */
+  gdb_assert (ppc_floating_point_unit_p (gdbarch));
+
   /* Floats and doubles in F1.  */
   if (TYPE_CODE (valtype) == TYPE_CODE_FLT && TYPE_LENGTH (valtype) <= 8)
     {
-      char regval[MAX_REGISTER_SIZE];
-      struct type *regtype = register_type (gdbarch, FP0_REGNUM);
+      gdb_byte regval[MAX_REGISTER_SIZE];
+      struct type *regtype = register_type (gdbarch, tdep->ppc_fp0_regnum);
       if (writebuf != NULL)
        {
          convert_typed_floating (writebuf, valtype, regval, regtype);
-         regcache_cooked_write (regcache, FP0_REGNUM + 1, regval);
+         regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1, regval);
        }
       if (readbuf != NULL)
        {
-         regcache_cooked_read (regcache, FP0_REGNUM + 1, regval);
+         regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1, regval);
          convert_typed_floating (regval, regtype, readbuf, valtype);
        }
       return RETURN_VALUE_REGISTER_CONVENTION;
     }
-  if (TYPE_CODE (valtype) == TYPE_CODE_INT && TYPE_LENGTH (valtype) <= 8)
+  /* Integers in r3.  */
+  if ((TYPE_CODE (valtype) == TYPE_CODE_INT
+       || TYPE_CODE (valtype) == TYPE_CODE_ENUM)
+      && TYPE_LENGTH (valtype) <= 8)
     {
-      /* Integers in r3.  */
       if (writebuf != NULL)
        {
          /* Be careful to sign extend the value.  */
@@ -882,24 +1165,37 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *valtype,
        regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, readbuf);
       return RETURN_VALUE_REGISTER_CONVENTION;
     }
-  if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY
-      && TYPE_LENGTH (valtype) <= 8
-      && TYPE_CODE (TYPE_TARGET_TYPE (valtype)) == TYPE_CODE_INT
-      && TYPE_LENGTH (TYPE_TARGET_TYPE (valtype)) == 1)
+  /* Array type has more than one use.  */
+  if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY)
     {
       /* Small character arrays are returned, right justified, in r3.  */
-      int offset = (register_size (gdbarch, tdep->ppc_gp0_regnum + 3)
-                   - TYPE_LENGTH (valtype));
-      if (writebuf != NULL)
-       regcache_cooked_write_part (regcache, tdep->ppc_gp0_regnum + 3,
-                                   offset, TYPE_LENGTH (valtype), writebuf);
-      if (readbuf != NULL)
-       regcache_cooked_read_part (regcache, tdep->ppc_gp0_regnum + 3,
-                                  offset, TYPE_LENGTH (valtype), readbuf);
-      return RETURN_VALUE_REGISTER_CONVENTION;
+      if (TYPE_LENGTH (valtype) <= 8
+        && TYPE_CODE (TYPE_TARGET_TYPE (valtype)) == TYPE_CODE_INT
+        && TYPE_LENGTH (TYPE_TARGET_TYPE (valtype)) == 1)
+        {
+          int offset = (register_size (gdbarch, tdep->ppc_gp0_regnum + 3)
+                       - TYPE_LENGTH (valtype));
+          if (writebuf != NULL)
+           regcache_cooked_write_part (regcache, tdep->ppc_gp0_regnum + 3,
+                                      offset, TYPE_LENGTH (valtype), writebuf);
+          if (readbuf != NULL)
+           regcache_cooked_read_part (regcache, tdep->ppc_gp0_regnum + 3,
+                                      offset, TYPE_LENGTH (valtype), readbuf);
+          return RETURN_VALUE_REGISTER_CONVENTION;
+       }
+      /* A VMX vector is returned in v2.  */
+      if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY
+        && TYPE_VECTOR (valtype) && tdep->ppc_vr0_regnum >= 0)
+        {
+          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;
+        }
     }
   /* Big floating point values get stored in adjacent floating
-     point registers.  */
+     point registers, starting with F1.  */
   if (TYPE_CODE (valtype) == TYPE_CODE_FLT
       && (TYPE_LENGTH (valtype) == 16 || TYPE_LENGTH (valtype) == 32))
     {
@@ -909,10 +1205,10 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *valtype,
          for (i = 0; i < TYPE_LENGTH (valtype) / 8; i++)
            {
              if (writebuf != NULL)
-               regcache_cooked_write (regcache, FP0_REGNUM + 1 + i,
+               regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1 + i,
                                       (const bfd_byte *) writebuf + i * 8);
              if (readbuf != NULL)
-               regcache_cooked_read (regcache, FP0_REGNUM + 1 + i,
+               regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1 + i,
                                      (bfd_byte *) readbuf + i * 8);
            }
        }
@@ -927,20 +1223,23 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *valtype,
          int i;
          for (i = 0; i < 2; i++)
            {
-             char regval[MAX_REGISTER_SIZE];
+             gdb_byte regval[MAX_REGISTER_SIZE];
              struct type *regtype =
-               register_type (current_gdbarch, FP0_REGNUM);
+               register_type (gdbarch, tdep->ppc_fp0_regnum);
              if (writebuf != NULL)
                {
                  convert_typed_floating ((const bfd_byte *) writebuf +
                                          i * (TYPE_LENGTH (valtype) / 2),
                                          valtype, regval, regtype);
-                 regcache_cooked_write (regcache, FP0_REGNUM + 1 + i,
+                 regcache_cooked_write (regcache,
+                                         tdep->ppc_fp0_regnum + 1 + i,
                                         regval);
                }
              if (readbuf != NULL)
                {
-                 regcache_cooked_read (regcache, FP0_REGNUM + 1 + i, regval);
+                 regcache_cooked_read (regcache,
+                                        tdep->ppc_fp0_regnum + 1 + i,
+                                        regval);
                  convert_typed_floating (regval, regtype,
                                          (bfd_byte *) readbuf +
                                          i * (TYPE_LENGTH (valtype) / 2),
@@ -959,10 +1258,10 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *valtype,
          for (i = 0; i < 4; i++)
            {
              if (writebuf != NULL)
-               regcache_cooked_write (regcache, FP0_REGNUM + 1 + i,
+               regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1 + i,
                                       (const bfd_byte *) writebuf + i * 8);
              if (readbuf != NULL)
-               regcache_cooked_read (regcache, FP0_REGNUM + 1 + i,
+               regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1 + i,
                                      (bfd_byte *) readbuf + i * 8);
            }
        }
This page took 0.04453 seconds and 4 git commands to generate.