Blame SOURCES/gdb-rhbz1125820-ppc64le-enablement-28of37.patch

01917d
commit 0ff3e01fdc67a3842ee54224cf197e9a55f0a750
01917d
Author: Ulrich Weigand <ulrich.weigand@de.ibm.com>
01917d
Date:   Tue Feb 4 18:34:19 2014 +0100
01917d
01917d
    PowerPC64 little-endian fixes: 128-bit DFP parameters / registers
01917d
    
01917d
    The powerpc64le-linux ABI specifies that when a 128-bit DFP value is
01917d
    passed in a pair of floating-point registers, the first register holds
01917d
    the most-significant part of the value.  This is as opposed to the
01917d
    usual rule on little-endian systems, where the first register would
01917d
    hold the least-significant part.
01917d
    
01917d
    This affects two places in GDB, the read/write routines for the
01917d
    128-bit DFP pseudo-registers, and the function call / return
01917d
    sequence.  For the former, current code already distinguishes
01917d
    between big- and little-endian targets, but gets the latter
01917d
    wrong.  This is presumably because *GCC* also got it wrong,
01917d
    and GDB matches the old GCC behavior.  But GCC is now fixed:
01917d
    http://gcc.gnu.org/ml/gcc-patches/2013-11/msg02145.html
01917d
    so GDB needs to be fixed too.  (Old code shouldn't really be
01917d
    an issue since there is no code "out there" so far that uses
01917d
    dfp128 on little-endian ...)
01917d
    
01917d
    gdb/ChangeLog:
01917d
    
01917d
    	* ppc-sysv-tdep.c (ppc64_sysv_abi_push_freg): Use correct order
01917d
    	within a register pair holding a DFP 128-bit value on little-endian.
01917d
    	(ppc64_sysv_abi_return_value_base): Likewise.
01917d
    	* rs6000-tdep.c (dfp_pseudo_register_read): Likewise.
01917d
    	(dfp_pseudo_register_write): Likewise.
01917d
    
01917d
    gdb/testsuite/ChangeLog:
01917d
    
01917d
    	* gdb.arch/powerpc-d128-regs.exp: Enable on powerpc64*-*.
01917d
01917d
Index: gdb-7.6.1/gdb/ppc-sysv-tdep.c
01917d
===================================================================
01917d
--- gdb-7.6.1.orig/gdb/ppc-sysv-tdep.c
01917d
+++ gdb-7.6.1/gdb/ppc-sysv-tdep.c
01917d
@@ -1269,9 +1269,11 @@ ppc64_sysv_abi_push_freg (struct gdbarch
01917d
       if (argpos->regcache && argpos->freg <= 12)
01917d
 	{
01917d
 	  int regnum = tdep->ppc_fp0_regnum + argpos->freg;
01917d
+	  int lopart = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 8 : 0;
01917d
+	  int hipart = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8;
01917d
 
01917d
-	  regcache_cooked_write (argpos->regcache, regnum, val);
01917d
-	  regcache_cooked_write (argpos->regcache, regnum + 1, val + 8);
01917d
+	  regcache_cooked_write (argpos->regcache, regnum, val + hipart);
01917d
+	  regcache_cooked_write (argpos->regcache, regnum + 1, val + lopart);
01917d
 	}
01917d
 
01917d
       argpos->freg += 2;
01917d
@@ -1684,16 +1686,18 @@ ppc64_sysv_abi_return_value_base (struct
01917d
       && TYPE_CODE (valtype) == TYPE_CODE_DECFLOAT)
01917d
     {
01917d
       int regnum = tdep->ppc_fp0_regnum + 2 + 2 * index;
01917d
+      int lopart = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 8 : 0;
01917d
+      int hipart = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8;
01917d
 
01917d
       if (writebuf != NULL)
01917d
 	{
01917d
-	  regcache_cooked_write (regcache, regnum, writebuf);
01917d
-	  regcache_cooked_write (regcache, regnum + 1, writebuf + 8);
01917d
+	  regcache_cooked_write (regcache, regnum, writebuf + hipart);
01917d
+	  regcache_cooked_write (regcache, regnum + 1, writebuf + lopart);
01917d
 	}
01917d
       if (readbuf != NULL)
01917d
 	{
01917d
-	  regcache_cooked_read (regcache, regnum, readbuf);
01917d
-	  regcache_cooked_read (regcache, regnum + 1, readbuf + 8);
01917d
+	  regcache_cooked_read (regcache, regnum, readbuf + hipart);
01917d
+	  regcache_cooked_read (regcache, regnum + 1, readbuf + lopart);
01917d
 	}
01917d
       return 1;
01917d
     }
01917d
Index: gdb-7.6.1/gdb/rs6000-tdep.c
01917d
===================================================================
01917d
--- gdb-7.6.1.orig/gdb/rs6000-tdep.c
01917d
+++ gdb-7.6.1/gdb/rs6000-tdep.c
01917d
@@ -2723,10 +2723,10 @@ dfp_pseudo_register_read (struct gdbarch
01917d
   else
01917d
     {
01917d
       status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
01917d
-				  2 * reg_index + 1, buffer + 8);
01917d
+				  2 * reg_index + 1, buffer);
01917d
       if (status == REG_VALID)
01917d
 	status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
01917d
-				    2 * reg_index, buffer);
01917d
+				    2 * reg_index, buffer + 8);
01917d
     }
01917d
 
01917d
   return status;
01917d
@@ -2752,9 +2752,9 @@ dfp_pseudo_register_write (struct gdbarc
01917d
   else
01917d
     {
01917d
       regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
01917d
-			  2 * reg_index + 1, buffer + 8);
01917d
+			  2 * reg_index + 1, buffer);
01917d
       regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
01917d
-			  2 * reg_index, buffer);
01917d
+			  2 * reg_index, buffer + 8);
01917d
     }
01917d
 }
01917d
 
01917d
Index: gdb-7.6.1/gdb/testsuite/gdb.arch/powerpc-d128-regs.exp
01917d
===================================================================
01917d
--- gdb-7.6.1.orig/gdb/testsuite/gdb.arch/powerpc-d128-regs.exp
01917d
+++ gdb-7.6.1/gdb/testsuite/gdb.arch/powerpc-d128-regs.exp
01917d
@@ -20,7 +20,7 @@
01917d
 
01917d
 # Testcase for ppc decimal128 pseudo-registers.
01917d
 
01917d
-if ![istarget "powerpc64-*"] then {
01917d
+if ![istarget "powerpc64*-*"] then {
01917d
     verbose "Skipping powerpc Decimal128 pseudo-registers testcase."
01917d
     return
01917d
 }