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

01917d
commit d81e75c0756f21d2c3d45ce86d8b45c65f01ef67
01917d
Author: Tiago Daitx <tdaitx@sourceware.org>
01917d
Date:   Mon Apr 1 04:05:35 2013 +0000
01917d
01917d
    gdb/ChangeLog
01917d
    2013-03-01  Tiago Stürmer Daitx  <tdaitx@linux.vnet.ibm.com>
01917d
    
01917d
    	* ppc-sysv-tdep.c (ppc64_sysv_abi_push_float): New function.
01917d
    	(ppc64_sysv_abi_push_dummy_call): Handle complex arguments.
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
@@ -1101,6 +1101,83 @@ convert_code_addr_to_desc_addr (CORE_ADD
01917d
   return 1;
01917d
 }
01917d
 
01917d
+/* Push a float in either registers, or in the stack.  Using the ppc 64 bit
01917d
+   SysV ABI.
01917d
+
01917d
+   This implements a dumbed down version of the ABI.  It always writes
01917d
+   values to memory, GPR and FPR, even when not necessary.  Doing this
01917d
+   greatly simplifies the logic.  */
01917d
+
01917d
+static void
01917d
+ppc64_sysv_abi_push_float (struct gdbarch *gdbarch, struct regcache *regcache,
01917d
+			   struct gdbarch_tdep *tdep, struct type *type, 
01917d
+			   const bfd_byte *val, int freg, int greg,
01917d
+			   CORE_ADDR gparam)
01917d
+{
01917d
+  gdb_byte regval[MAX_REGISTER_SIZE];
01917d
+  const gdb_byte *p;
01917d
+
01917d
+  if (TYPE_LENGTH (type) <= 8)
01917d
+    {
01917d
+      /* Version 1.7 of the 64-bit PowerPC ELF ABI says:
01917d
+
01917d
+	 "Single precision floating point values are mapped to
01917d
+	 the first word in a single doubleword."
01917d
+
01917d
+	 And version 1.9 says:
01917d
+
01917d
+	 "Single precision floating point values are mapped to
01917d
+	 the second word in a single doubleword."
01917d
+
01917d
+	 GDB then writes single precision floating point values
01917d
+	 at both words in a doubleword, to support both ABIs.  */
01917d
+      if (TYPE_LENGTH (type) == 4)
01917d
+	{
01917d
+	  memcpy (regval, val, 4);
01917d
+	  memcpy (regval + 4, val, 4);
01917d
+	  p = regval;
01917d
+	}
01917d
+      else
01917d
+	p = val;
01917d
+
01917d
+      /* Write value in the stack's parameter save area.  */
01917d
+      write_memory (gparam, p, 8);
01917d
+
01917d
+      /* Floats and Doubles go in f1 .. f13.  They also consume a left aligned
01917d
+	 GREG, and can end up in memory.  */
01917d
+      if (freg <= 13)
01917d
+	{
01917d
+	  struct type *regtype;
01917d
+
01917d
+	  regtype = register_type (gdbarch, tdep->ppc_fp0_regnum + freg);
01917d
+	  convert_typed_floating (val, type, regval, regtype);
01917d
+	  regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg, regval);
01917d
+	}
01917d
+      if (greg <= 10)
01917d
+	regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg, regval);
01917d
+    }
01917d
+  else
01917d
+    {
01917d
+      /* IBM long double stored in two doublewords of the
01917d
+	 parameter save area and corresponding registers.  */
01917d
+      if (!tdep->soft_float && freg <= 13)
01917d
+	{
01917d
+	  regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg, val);
01917d
+	  if (freg <= 12)
01917d
+	    regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg + 1,
01917d
+				   val + 8);
01917d
+	}
01917d
+      if (greg <= 10)
01917d
+	{
01917d
+	  regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg, val);
01917d
+	  if (greg <= 9)
01917d
+	    regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg + 1,
01917d
+				   val + 8);
01917d
+	}
01917d
+      write_memory (gparam, val, TYPE_LENGTH (type));
01917d
+    }
01917d
+}
01917d
+
01917d
 /* Pass the arguments in either registers, or in the stack.  Using the
01917d
    ppc 64 bit SysV ABI.
01917d
 
01917d
@@ -1218,53 +1295,9 @@ ppc64_sysv_abi_push_dummy_call (struct g
01917d
 
01917d
 	  if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) <= 8)
01917d
 	    {
01917d
-	      /* Floats and Doubles go in f1 .. f13.  They also
01917d
-	         consume a left aligned GREG,, and can end up in
01917d
-	         memory.  */
01917d
 	      if (write_pass)
01917d
-		{
01917d
-		  gdb_byte regval[MAX_REGISTER_SIZE];
01917d
-		  const gdb_byte *p;
01917d
-
01917d
-		  /* Version 1.7 of the 64-bit PowerPC ELF ABI says:
01917d
-
01917d
-		     "Single precision floating point values are mapped to
01917d
-		     the first word in a single doubleword."
01917d
-
01917d
-		     And version 1.9 says:
01917d
-
01917d
-		     "Single precision floating point values are mapped to
01917d
-		     the second word in a single doubleword."
01917d
-
01917d
-		     GDB then writes single precision floating point values
01917d
-		     at both words in a doubleword, to support both ABIs.  */
01917d
-		  if (TYPE_LENGTH (type) == 4)
01917d
-		    {
01917d
-		      memcpy (regval, val, 4);
01917d
-		      memcpy (regval + 4, val, 4);
01917d
-		      p = regval;
01917d
-		    }
01917d
-		  else
01917d
-		    p = val;
01917d
-
01917d
-		  /* Write value in the stack's parameter save area.  */
01917d
-		  write_memory (gparam, p, 8);
01917d
-
01917d
-		  if (freg <= 13)
01917d
-		    {
01917d
-		      struct type *regtype
01917d
-                        = register_type (gdbarch, tdep->ppc_fp0_regnum);
01917d
-
01917d
-		      convert_typed_floating (val, type, regval, regtype);
01917d
-		      regcache_cooked_write (regcache,
01917d
-                                             tdep->ppc_fp0_regnum + freg,
01917d
-					     regval);
01917d
-		    }
01917d
-		  if (greg <= 10)
01917d
-		    regcache_cooked_write (regcache,
01917d
-					   tdep->ppc_gp0_regnum + greg,
01917d
-					   regval);
01917d
-		}
01917d
+		  ppc64_sysv_abi_push_float (gdbarch, regcache, tdep, type,
01917d
+					     val, freg, greg, gparam);
01917d
 
01917d
 	      freg++;
01917d
 	      greg++;
01917d
@@ -1276,35 +1309,58 @@ ppc64_sysv_abi_push_dummy_call (struct g
01917d
 		   && (gdbarch_long_double_format (gdbarch)
01917d
 		       == floatformats_ibm_long_double))
01917d
 	    {
01917d
-	      /* IBM long double stored in two doublewords of the
01917d
-		 parameter save area and corresponding registers.  */
01917d
 	      if (write_pass)
01917d
+		ppc64_sysv_abi_push_float (gdbarch, regcache, tdep, type,
01917d
+					   val, freg, greg, gparam);
01917d
+	      freg += 2;
01917d
+	      greg += 2;
01917d
+	      gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize);
01917d
+	    }
01917d
+	  else if (TYPE_CODE (type) == TYPE_CODE_COMPLEX
01917d
+	      && (TYPE_LENGTH (type) == 8 || TYPE_LENGTH (type) == 16))
01917d
+	    {
01917d
+	      int i;
01917d
+
01917d
+	      for (i = 0; i < 2; i++)
01917d
 		{
01917d
-		  if (!tdep->soft_float && freg <= 13)
01917d
-		    {
01917d
-		      regcache_cooked_write (regcache,
01917d
-                                             tdep->ppc_fp0_regnum + freg,
01917d
-					     val);
01917d
-		      if (freg <= 12)
01917d
-			regcache_cooked_write (regcache,
01917d
-					       tdep->ppc_fp0_regnum + freg + 1,
01917d
-					       val + 8);
01917d
-		    }
01917d
-		  if (greg <= 10)
01917d
+		  if (write_pass)
01917d
 		    {
01917d
-		      regcache_cooked_write (regcache,
01917d
-					     tdep->ppc_gp0_regnum + greg,
01917d
-					     val);
01917d
-		      if (greg <= 9)
01917d
-			regcache_cooked_write (regcache,
01917d
-					       tdep->ppc_gp0_regnum + greg + 1,
01917d
-					       val + 8);
01917d
+		      struct type *target_type;
01917d
+
01917d
+		      target_type = check_typedef (TYPE_TARGET_TYPE (type));
01917d
+		      ppc64_sysv_abi_push_float (gdbarch, regcache, tdep,
01917d
+						 target_type, val + i *
01917d
+						 TYPE_LENGTH (target_type),
01917d
+						 freg, greg, gparam);
01917d
 		    }
01917d
-		  write_memory (gparam, val, TYPE_LENGTH (type));
01917d
+		  freg++;
01917d
+		  greg++;
01917d
+		  /* Always consume parameter stack space.  */
01917d
+		  gparam = align_up (gparam + 8, tdep->wordsize);
01917d
+		}
01917d
+	    }
01917d
+	  else if (TYPE_CODE (type) == TYPE_CODE_COMPLEX
01917d
+		   && TYPE_LENGTH (type) == 32
01917d
+		   && (gdbarch_long_double_format (gdbarch)
01917d
+		       == floatformats_ibm_long_double))
01917d
+	    {
01917d
+	      int i;
01917d
+
01917d
+	      for (i = 0; i < 2; i++)
01917d
+		{
01917d
+		  struct type *target_type;
01917d
+
01917d
+		  target_type = check_typedef (TYPE_TARGET_TYPE (type));
01917d
+		  if (write_pass)
01917d
+		    ppc64_sysv_abi_push_float (gdbarch, regcache, tdep,
01917d
+					       target_type, val + i *
01917d
+					       TYPE_LENGTH (target_type),
01917d
+					       freg, greg, gparam);
01917d
+		  freg += 2;
01917d
+		  greg += 2;
01917d
+		  gparam = align_up (gparam + TYPE_LENGTH (target_type),
01917d
+				     tdep->wordsize);
01917d
 		}
01917d
-	      freg += 2;
01917d
-	      greg += 2;
01917d
-	      gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize);
01917d
 	    }
01917d
 	  else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT
01917d
 		   && TYPE_LENGTH (type) <= 8)