This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix complex type handling on amd64


Fixes issues with calling functions that take complex numbers as
arguments or return complex numbers.  Those cases simply weren't handled.

Committed.


2012-10-23  Mark Kettenis  <kettenis@gnu.org>

	PR gdb/12796
	PR gdb/12798
	PR gdb/12800
	* amd64-tdep.h (enum amd64_regnum): Add AMD64_ST1_REGNUM and
	AMD64_FTAG_REGNUM.
	* amd64-tdep.c (amd64_classify): Classify complex types.
	(amd64_return_value): Handle the COMPLEX_X87 class.

Index: amd64-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/amd64-tdep.c,v
retrieving revision 1.113
diff -u -p -r1.113 amd64-tdep.c
--- amd64-tdep.c	15 Oct 2012 20:37:38 -0000	1.113
+++ amd64-tdep.c	23 Oct 2012 18:05:01 -0000
@@ -586,6 +586,23 @@ amd64_classify (struct type *type, enum 
     /* Class X87 and X87UP.  */
     class[0] = AMD64_X87, class[1] = AMD64_X87UP;
 
+  /* Arguments of complex T where T is one of the types float or
+     double get treated as if they are implemented as:
+
+     struct complexT {
+       T real;
+       T imag;
+     };  */
+  else if (code == TYPE_CODE_COMPLEX && len == 8)
+    class[0] = AMD64_SSE;
+  else if (code == TYPE_CODE_COMPLEX && len == 16)
+    class[0] = class[1] = AMD64_SSE;
+
+  /* A variable of type complex long double is classified as type
+     COMPLEX_X87.  */
+  else if (code == TYPE_CODE_COMPLEX && len == 32)
+    class[0] = AMD64_COMPLEX_X87;
+
   /* Aggregates.  */
   else if (code == TYPE_CODE_ARRAY || code == TYPE_CODE_STRUCT
 	   || code == TYPE_CODE_UNION)
@@ -636,6 +653,30 @@ amd64_return_value (struct gdbarch *gdba
       return RETURN_VALUE_ABI_RETURNS_ADDRESS;
     }
 
+  /* 8. If the class is COMPLEX_X87, the real part of the value is
+        returned in %st0 and the imaginary part in %st1.  */
+  if (class[0] == AMD64_COMPLEX_X87)
+    {
+      if (readbuf)
+	{
+	  regcache_raw_read (regcache, AMD64_ST0_REGNUM, readbuf);
+	  regcache_raw_read (regcache, AMD64_ST1_REGNUM, readbuf + 16);
+	}
+
+      if (writebuf)
+	{
+	  i387_return_value (gdbarch, regcache);
+	  regcache_raw_write (regcache, AMD64_ST0_REGNUM, writebuf);
+	  regcache_raw_write (regcache, AMD64_ST1_REGNUM, writebuf + 16);
+
+	  /* Fix up the tag word such that both %st(0) and %st(1) are
+	     marked as valid.  */
+	  regcache_raw_write_unsigned (regcache, AMD64_FTAG_REGNUM, 0xfff);
+	}
+
+      return RETURN_VALUE_REGISTER_CONVENTION;
+    }
+
   gdb_assert (class[1] != AMD64_MEMORY);
   gdb_assert (len <= 16);
 
Index: amd64-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/amd64-tdep.h,v
retrieving revision 1.22
diff -u -p -r1.22 amd64-tdep.h
--- amd64-tdep.h	13 Jun 2012 20:29:15 -0000	1.22
+++ amd64-tdep.h	23 Oct 2012 18:05:01 -0000
@@ -57,8 +57,10 @@ enum amd64_regnum
   AMD64_FS_REGNUM,		/* %fs */
   AMD64_GS_REGNUM,		/* %gs */
   AMD64_ST0_REGNUM = 24,	/* %st0 */
+  AMD64_ST1_REGNUM,		/* %st1 */
   AMD64_FCTRL_REGNUM = AMD64_ST0_REGNUM + 8,
   AMD64_FSTAT_REGNUM = AMD64_ST0_REGNUM + 9,
+  AMD64_FTAG_REGNUM = AMD64_ST0_REGNUM + 10,
   AMD64_XMM0_REGNUM = 40,	/* %xmm0 */
   AMD64_XMM1_REGNUM,		/* %xmm1 */
   AMD64_MXCSR_REGNUM = AMD64_XMM0_REGNUM + 16,


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]