This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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] libffi linux-ppc-32/64 long double


Hi all,

this patch fixes a problem when we have long doubles in ffi_call. We were doing the comparison wrong.

Obvious enough to commit on trunk?

The ppc64 part was kindly tested by Janis, thanks again.


Thanks, Andreas

2007-11-15 Andreas Tobler <a.tobler@schweiz.org>

	* src/powerpc/sysv.S: Load correct cr to compare if we have long double.
	* src/powerpc/linux64.S: Likewise.
	* src/powerpc/ffi.c: Add a comment to show which part goes into cr6.
	* testsuite/libffi.call/return_ldl.c: New test.

Index: src/powerpc/sysv.S
===================================================================
--- src/powerpc/sysv.S	(revision 130207)
+++ src/powerpc/sysv.S	(working copy)
@@ -121,6 +121,7 @@
 L(fp_return_value):
 	bf	28,L(float_return_value)
 	stfd	%f1,0(%r30)
+	mtcrf   0x02,%r31 /* cr6  */
 	bf	27,L(done_return_value)
 	stfd	%f2,8(%r30)
 	b	L(done_return_value)
Index: src/powerpc/linux64.S
===================================================================
--- src/powerpc/linux64.S	(revision 130207)
+++ src/powerpc/linux64.S	(working copy)
@@ -125,6 +125,7 @@
 .Lfp_return_value:
 	bf	28, .Lfloat_return_value
 	stfd	%f1, 0(%r30)
+	mtcrf	0x02, %r31 /* cr6  */
 	bf	27, .Ldone_return_value
 	stfd	%f2, 8(%r30)
 	b	.Ldone_return_value
Index: src/powerpc/ffi.c
===================================================================
--- src/powerpc/ffi.c	(revision 130207)
+++ src/powerpc/ffi.c	(working copy)
@@ -40,8 +40,9 @@
   FLAG_RETURNS_NOTHING  = 1 << (31-30), /* These go in cr7 */
   FLAG_RETURNS_FP       = 1 << (31-29),
   FLAG_RETURNS_64BITS   = 1 << (31-28),
-  FLAG_RETURNS_128BITS  = 1 << (31-27),
 
+  FLAG_RETURNS_128BITS  = 1 << (31-27), /* cr6  */
+
   FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
   FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI */
   FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),
Index: testsuite/libffi.call/return_ldl.c
===================================================================
--- testsuite/libffi.call/return_ldl.c	(revision 0)
+++ testsuite/libffi.call/return_ldl.c	(revision 0)
@@ -0,0 +1,34 @@
+/* Area:	ffi_call
+   Purpose:	Check return value long double.
+   Limitations:	none.
+   PR:		none.
+   Originator:	<andreast@gcc.gnu.org> 20071113  */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static long double return_ldl(long double ldl)
+{
+  return 2*ldl;
+}
+int main (void)
+{
+  ffi_cif cif;
+  ffi_type *args[MAX_ARGS];
+  void *values[MAX_ARGS];
+  long double ldl, rldl;
+
+  args[0] = &ffi_type_longdouble;
+  values[0] = &ldl;
+
+  /* Initialize the cif */
+  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+		     &ffi_type_longdouble, args) == FFI_OK);
+
+  for (ldl = -127.0; ldl <  127.0; ldl++)
+    {
+      ffi_call(&cif, FFI_FN(return_ldl), &rldl, values);
+      CHECK(rldl ==  2 * ldl);
+    }
+  exit(0);
+}

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