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

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