From d674eb2f5c198a128ea401681e2f0937587e6369 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Mon, 26 Sep 2005 19:56:22 +0000 Subject: float1.c (value_type): New typedef. * testsuite/libffi.call/float1.c (value_type): New typedef. (CANARY): New define. (main): Check for result buffer overflow. * src/powerpc/linux64.S: Handle linux64 long double returns. * src/powerpc/ffi.c (FLAG_RETURNS_128BITS): New constant. (ffi_prep_cif_machdep): Handle linux64 long double returns. From-SVN: r104660 --- libffi/src/powerpc/ffi.c | 7 +++++++ libffi/src/powerpc/linux64.S | 6 +++++- 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'libffi/src') diff --git a/libffi/src/powerpc/ffi.c b/libffi/src/powerpc/ffi.c index cc410bc..7d8bf3a 100644 --- a/libffi/src/powerpc/ffi.c +++ b/libffi/src/powerpc/ffi.c @@ -39,6 +39,7 @@ enum { 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_ARG_NEEDS_COPY = 1 << (31- 7), FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */ @@ -543,6 +544,12 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) /* else fall through. */ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE case FFI_TYPE_LONGDOUBLE: + if (type == FFI_TYPE_LONGDOUBLE && cif->abi == FFI_LINUX64) + { + flags |= FLAG_RETURNS_128BITS; + flags |= FLAG_RETURNS_FP; + break; + } #endif intarg_count++; flags |= FLAG_RETVAL_REFERENCE; diff --git a/libffi/src/powerpc/linux64.S b/libffi/src/powerpc/linux64.S index 18423bf..25b2c4f 100644 --- a/libffi/src/powerpc/linux64.S +++ b/libffi/src/powerpc/linux64.S @@ -120,9 +120,13 @@ ffi_call_LINUX64: blr .Lfp_return_value: + bt 27, .Lfd_return_value bf 28, .Lfloat_return_value stfd %f1, 0(%r30) - stfd %f2, 8(%r30) /* It might be a long double */ + b .Ldone_return_value +.Lfd_return_value: + stfd %f1, 0(%r30) + stfd %f2, 8(%r30) b .Ldone_return_value .Lfloat_return_value: stfs %f1, 0(%r30) -- cgit v1.1