Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: "Tiago Stürmer Daitx" <tdaitx@linux.vnet.ibm.com>
To: Sergio Durigan Junior <sergiodj@redhat.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH] Fix complex argument handling in ppc64 dummy function call
Date: Fri, 01 Mar 2013 17:50:00 -0000	[thread overview]
Message-ID: <20130301170811.EFEA2300943@igoo.rch.stglabs.ibm.com> (raw)
In-Reply-To: <m37glrj0bn.fsf@redhat.com>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 7705 bytes --]

Sergio, many thanks for the thorough review and the tips. There's no better 
way to get these rules to stick in my head. ^_^

Let me know if there is still something amiss.

Cheers,
Tiago

gdb/ChangeLog
2013-03-01  Tiago Stürmer Daitx  <tdaitx@linux.vnet.ibm.com>

	* ppc-sysv-tdep.c (ppc64_sysv_abi_push_float): New function.
	(ppc64_sysv_abi_push_dummy_call): Handle complex arguments. 

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


  reply	other threads:[~2013-03-01 17:50 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-02-28 18:30 Tiago Stürmer Daitx
2013-03-01  2:55 ` Sergio Durigan Junior
2013-03-01 17:50   ` Tiago Stürmer Daitx [this message]
2013-03-01 18:57     ` Sergio Durigan Junior
2013-03-01 20:07       ` Tiago Stürmer Daitx
2013-03-01 21:24     ` Pedro Alves
2013-03-01 23:42       ` Tiago Stürmer Daitx
2013-03-11 16:12     ` Ulrich Weigand
2013-04-01  4:15       ` Tiago Stürmer Daitx
2013-04-02 13:41         ` Ulrich Weigand

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130301170811.EFEA2300943@igoo.rch.stglabs.ibm.com \
    --to=tdaitx@linux.vnet.ibm.com \
    --cc=gdb-patches@sourceware.org \
    --cc=sergiodj@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox