Commit 4243752c by Alan Modra Committed by Alan Modra

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
parent 3b4b85c9
2004-02-09 Alan Modra <amodra@bigpond.net.au>
* 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 <amodra@bigpond.net.au> 2004-02-08 Alan Modra <amodra@bigpond.net.au>
* src/powerpc/ffi.c (ffi_prep_cif_machdep <FFI_LINUX64>): Correct * src/powerpc/ffi.c (ffi_prep_cif_machdep <FFI_LINUX64>): Correct
......
...@@ -369,10 +369,27 @@ void hidden ffi_prep_args64(extended_cif *ecif, unsigned long *const stack) ...@@ -369,10 +369,27 @@ void hidden ffi_prep_args64(extended_cif *ecif, unsigned long *const stack)
FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
break; break;
case FFI_TYPE_STRUCT:
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
case FFI_TYPE_LONGDOUBLE: 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 #endif
case FFI_TYPE_STRUCT:
words = ((*ptr)->size + 7) / 8; words = ((*ptr)->size + 7) / 8;
if (next_arg >= gpr_base && next_arg + words > gpr_end) if (next_arg >= gpr_base && next_arg + words > gpr_end)
{ {
...@@ -1079,7 +1096,7 @@ ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue, ...@@ -1079,7 +1096,7 @@ ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
case FFI_TYPE_LONGDOUBLE: case FFI_TYPE_LONGDOUBLE:
if (prf + 1 < end_pfr) if (pfr + 1 < end_pfr)
{ {
avalue[i] = pfr; avalue[i] = pfr;
pfr += 2; pfr += 2;
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
Originator: <hos@tamanegi.org> 20031203 */ Originator: <hos@tamanegi.org> 20031203 */
/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */
/* { dg-options -mlong-double-128 { target powerpc64*-*-* } } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_align { typedef struct cls_struct_align {
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
Originator: From the original ffitest.c */ Originator: From the original ffitest.c */
/* { dg-do run } */ /* { dg-do run } */
/* { dg-options -mlong-double-128 { target powerpc64*-*-* } } */
#include "ffitest.h" #include "ffitest.h"
static int floating(int a, float b, double c, long double d, int e) static int floating(int a, float b, double c, long double d, int e)
...@@ -28,8 +30,6 @@ int main (void) ...@@ -28,8 +30,6 @@ int main (void)
double d; double d;
long double ld; long double ld;
signed int si2; signed int si2;
args[0] = &ffi_type_sint; args[0] = &ffi_type_sint;
values[0] = &si1; values[0] = &si1;
...@@ -41,7 +41,7 @@ int main (void) ...@@ -41,7 +41,7 @@ int main (void)
values[3] = &ld; values[3] = &ld;
args[4] = &ffi_type_sint; args[4] = &ffi_type_sint;
values[4] = &si2; values[4] = &si2;
/* Initialize the cif */ /* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 5, CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 5,
&ffi_type_sint, args) == FFI_OK); &ffi_type_sint, args) == FFI_OK);
...@@ -51,15 +51,14 @@ int main (void) ...@@ -51,15 +51,14 @@ int main (void)
d = (double)1.0/(double)3.0; d = (double)1.0/(double)3.0;
ld = 2.71828182846L; ld = 2.71828182846L;
si2 = 10; si2 = 10;
floating (si1, f, d, ld, si2); floating (si1, f, d, ld, si2);
ffi_call(&cif, FFI_FN(floating), &rint, values); ffi_call(&cif, FFI_FN(floating), &rint, values);
printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld, si2)); printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld, si2));
CHECK(rint == floating(si1, f, d, ld, si2)); CHECK(rint == floating(si1, f, d, ld, si2));
exit (0); exit (0);
} }
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
Originator: From the original ffitest.c */ Originator: From the original ffitest.c */
/* { dg-do run } */ /* { dg-do run } */
/* { dg-options -mlong-double-128 { target powerpc64*-*-* } } */
#include "ffitest.h" #include "ffitest.h"
#include "float.h" #include "float.h"
...@@ -23,14 +25,14 @@ int main (void) ...@@ -23,14 +25,14 @@ int main (void)
args[0] = &ffi_type_float; args[0] = &ffi_type_float;
values[0] = &f; values[0] = &f;
/* Initialize the cif */ /* 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); &ffi_type_longdouble, args) == FFI_OK);
f = 3.14159; f = 3.14159;
#if 1 #if 1
/* This is ifdef'd out for now. long double support under SunOS/gcc /* 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 is pretty much non-existent. You'll get the odd bus error in library
routines like printf(). */ routines like printf(). */
...@@ -38,14 +40,14 @@ int main (void) ...@@ -38,14 +40,14 @@ int main (void)
#endif #endif
ld = 666; ld = 666;
ffi_call(&cif, FFI_FN(ldblit), &ld, values); 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 /* 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 is pretty much non-existent. You'll get the odd bus error in library
routines like printf(). */ routines like printf(). */
printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON); printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON);
#endif #endif
/* These are not always the same!! Check for a reasonable delta */ /* These are not always the same!! Check for a reasonable delta */
/*@-realcompare@*/ /*@-realcompare@*/
if (ld - ldblit(f) < LDBL_EPSILON) if (ld - ldblit(f) < LDBL_EPSILON)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment