This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] libffi linux-ppc-32/64 long double
- From: Andreas Tobler <toa at pop dot agri dot ch>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 15 Nov 2007 20:49:15 +0100
- Subject: [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);
+}