From 4243752ca1ab399389152e9f6e09a06452db8ada Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 9 Feb 2004 03:39:48 +0000 Subject: [PATCH] ffi.c (ffi_prep_args64): Correct long double handling. * src/powerpc/ffi.c (ffi_prep_args64): Correct long double handling. (ffi_closure_helper_LINUX64): Fix typo. * testsuite/libffi.call/cls_align_longdouble.c: Pass -mlong-double-128 for powerpc64-*-*. * testsuite/libffi.call/float.c: Likewise. * testsuite/libffi.call/float2.c: Likewise. From-SVN: r77522 --- libffi/ChangeLog | 9 ++++++++ libffi/src/powerpc/ffi.c | 21 +++++++++++++++++-- .../libffi.call/cls_align_longdouble.c | 2 ++ libffi/testsuite/libffi.call/float.c | 17 +++++++-------- libffi/testsuite/libffi.call/float2.c | 18 +++++++++------- 5 files changed, 48 insertions(+), 19 deletions(-) diff --git a/libffi/ChangeLog b/libffi/ChangeLog index 4d931c9d58e..76de0068a03 100644 --- a/libffi/ChangeLog +++ b/libffi/ChangeLog @@ -1,3 +1,12 @@ +2004-02-09 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_args64): Correct long double handling. + (ffi_closure_helper_LINUX64): Fix typo. + * testsuite/libffi.call/cls_align_longdouble.c: Pass -mlong-double-128 + for powerpc64-*-*. + * testsuite/libffi.call/float.c: Likewise. + * testsuite/libffi.call/float2.c: Likewise. + 2004-02-08 Alan Modra * src/powerpc/ffi.c (ffi_prep_cif_machdep ): Correct diff --git a/libffi/src/powerpc/ffi.c b/libffi/src/powerpc/ffi.c index a2fb2d2e89d..454c7ac35e5 100644 --- a/libffi/src/powerpc/ffi.c +++ b/libffi/src/powerpc/ffi.c @@ -369,10 +369,27 @@ void hidden ffi_prep_args64(extended_cif *ecif, unsigned long *const stack) FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); break; - case FFI_TYPE_STRUCT: #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE case FFI_TYPE_LONGDOUBLE: + double_tmp = ((double *) *p_argv)[0]; + *(double *) next_arg = double_tmp; + if (++next_arg == gpr_end) + next_arg = rest; + if (fparg_count < NUM_FPR_ARG_REGISTERS64) + *fpr_base++ = double_tmp; + fparg_count++; + double_tmp = ((double *) *p_argv)[1]; + *(double *) next_arg = double_tmp; + if (++next_arg == gpr_end) + next_arg = rest; + if (fparg_count < NUM_FPR_ARG_REGISTERS64) + *fpr_base++ = double_tmp; + fparg_count++; + FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); + break; #endif + + case FFI_TYPE_STRUCT: words = ((*ptr)->size + 7) / 8; if (next_arg >= gpr_base && next_arg + words > gpr_end) { @@ -1079,7 +1096,7 @@ ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue, #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE case FFI_TYPE_LONGDOUBLE: - if (prf + 1 < end_pfr) + if (pfr + 1 < end_pfr) { avalue[i] = pfr; pfr += 2; diff --git a/libffi/testsuite/libffi.call/cls_align_longdouble.c b/libffi/testsuite/libffi.call/cls_align_longdouble.c index a4c33481c8a..aacfcbafd8c 100644 --- a/libffi/testsuite/libffi.call/cls_align_longdouble.c +++ b/libffi/testsuite/libffi.call/cls_align_longdouble.c @@ -5,6 +5,8 @@ Originator: 20031203 */ /* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ +/* { dg-options -mlong-double-128 { target powerpc64*-*-* } } */ + #include "ffitest.h" typedef struct cls_struct_align { diff --git a/libffi/testsuite/libffi.call/float.c b/libffi/testsuite/libffi.call/float.c index e5ee05b1464..d712fb1021a 100644 --- a/libffi/testsuite/libffi.call/float.c +++ b/libffi/testsuite/libffi.call/float.c @@ -5,6 +5,8 @@ Originator: From the original ffitest.c */ /* { dg-do run } */ +/* { dg-options -mlong-double-128 { target powerpc64*-*-* } } */ + #include "ffitest.h" static int floating(int a, float b, double c, long double d, int e) @@ -28,8 +30,6 @@ int main (void) double d; long double ld; signed int si2; - - args[0] = &ffi_type_sint; values[0] = &si1; @@ -41,7 +41,7 @@ int main (void) values[3] = &ld; args[4] = &ffi_type_sint; values[4] = &si2; - + /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 5, &ffi_type_sint, args) == FFI_OK); @@ -51,15 +51,14 @@ int main (void) d = (double)1.0/(double)3.0; ld = 2.71828182846L; si2 = 10; - + floating (si1, f, d, ld, si2); - + ffi_call(&cif, FFI_FN(floating), &rint, values); - + printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld, si2)); - + CHECK(rint == floating(si1, f, d, ld, si2)); - + exit (0); } - diff --git a/libffi/testsuite/libffi.call/float2.c b/libffi/testsuite/libffi.call/float2.c index 413521280a3..4de41d356c4 100644 --- a/libffi/testsuite/libffi.call/float2.c +++ b/libffi/testsuite/libffi.call/float2.c @@ -5,6 +5,8 @@ Originator: From the original ffitest.c */ /* { dg-do run } */ +/* { dg-options -mlong-double-128 { target powerpc64*-*-* } } */ + #include "ffitest.h" #include "float.h" @@ -23,14 +25,14 @@ int main (void) args[0] = &ffi_type_float; values[0] = &f; - + /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_longdouble, args) == FFI_OK); - + f = 3.14159; - -#if 1 + +#if 1 /* This is ifdef'd out for now. long double support under SunOS/gcc is pretty much non-existent. You'll get the odd bus error in library routines like printf(). */ @@ -38,14 +40,14 @@ int main (void) #endif ld = 666; ffi_call(&cif, FFI_FN(ldblit), &ld, values); - -#if 1 + +#if 1 /* This is ifdef'd out for now. long double support under SunOS/gcc is pretty much non-existent. You'll get the odd bus error in library routines like printf(). */ printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON); #endif - + /* These are not always the same!! Check for a reasonable delta */ /*@-realcompare@*/ if (ld - ldblit(f) < LDBL_EPSILON) -- 2.30.2