PowerPC CPU without FPU (such as the PPC405EP) doesn't pass the libffi testsuite. Most of the tests crash with an "illegal instruction" error message, even those that don't manipulate double/float. For instance, it crashes with the "cls_uint" test.
After investigating, I think the problem comes from the ppc assembly code from the libffi/src/powerpc directory that includes FPU instructions not supported by those CPU. In particular, the ppc_closure.S file contains "stfd" FPU instructions that are supposed to save FPU registers and are always executed, even if no fpu operation is to be performed.
If you don't need fpu support (as I do), a quick and dirty hack is to comment out those "stfd" instructions from the ppc_closure.S file.
I guess the right way to fix it would be to use the soft-float system when no FPU is present. But that's something I don't know how to do...
I've tried with gcc 3.4.3 and gcc 4.1.0, but I guess all versions are affected.
Notice that this bug prevents loading and running java bytecode from a native code binary compiled with gcj. I guess it relies on libffi to call the methods of the bytecode.
This java problem is what I've encountered first before investigating and finding out that it all comes from libfii.
Working on support for.
Patch is posted here:
The mentioned patch does not work properly, it only handles soft-float when no-long-double-128 is used.
Working on a better one which should support both, 'double == long double' and long double == 128.
New patch here: http://gcc.gnu.org/ml/gcc-patches/2007-11/msg01128.html
Subject: Bug 31937
Date: Sat Dec 1 21:00:04 2007
New Revision: 130559
2007-12-01 Andreas Tobler <firstname.lastname@example.org>
* src/powerpc/ffitarget.h: Introduce new ABI FFI_LINUX_SOFT_FLOAT.
Add local FFI_TYPE_UINT128 to handle soft-float long-double-128.
* src/powerpc/ffi.c: Distinguish between __NO_FPRS__ and not and
set the NUM_FPR_ARG_REGISTERS according to.
Add support for potential soft-float support under hard-float
(ffi_prep_args_SYSV): Set NUM_FPR_ARG_REGISTERS to 0 in case of
FFI_LINUX_SOFT_FLOAT, handle float, doubles and long-doubles according
to the FFI_LINUX_SOFT_FLOAT ABI.
* src/powerpc/ppc_closure.S: Make sure not to store float/double
on archs where __NO_FPRS__ is true.
Add FFI_TYPE_UINT128 support.
* src/powerpc/sysv.S: Add support for soft-float long-double-128.
Adjust copyright notice.
Implemented. Hopefully it will be of some use to others :)