Index: src/powerpc/ppc_closure.S =================================================================== --- src/powerpc/ppc_closure.S (revision 129874) +++ src/powerpc/ppc_closure.S (working copy) @@ -28,6 +28,7 @@ stw %r9, 40(%r1) stw %r10,44(%r1) +#ifndef __NO_FPRS__ # next save fpr 1 to fpr 8 (aligned to 8) stfd %f1, 48(%r1) stfd %f2, 56(%r1) @@ -37,6 +38,7 @@ stfd %f6, 88(%r1) stfd %f7, 96(%r1) stfd %f8, 104(%r1) +#endif # set up registers for the routine that actually does the work # get the context pointer from the trampoline Index: src/powerpc/ffi.c =================================================================== --- src/powerpc/ffi.c (revision 129874) +++ src/powerpc/ffi.c (working copy) @@ -51,7 +51,11 @@ /* About the SYSV ABI. */ enum { NUM_GPR_ARG_REGISTERS = 8, +#ifndef __NO_FPRS__ NUM_FPR_ARG_REGISTERS = 8 +#else + NUM_FPR_ARG_REGISTERS = 0 +#endif }; enum { ASM_NEEDS_REGISTERS = 4 }; @@ -117,7 +121,9 @@ int i; ffi_type **ptr; +#ifndef __NO_FPRS__ double double_tmp; +#endif union { void **v; char **c; @@ -163,6 +169,7 @@ { switch ((*ptr)->type) { +#ifndef __NO_FPRS__ case FFI_TYPE_FLOAT: double_tmp = **p_argv.f; if (fparg_count >= NUM_FPR_ARG_REGISTERS) @@ -195,6 +202,7 @@ fparg_count++; FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); break; +#endif #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE case FFI_TYPE_LONGDOUBLE: @@ -230,6 +238,9 @@ case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: +#ifdef __NO_FPRS__ + case FFI_TYPE_DOUBLE: +#endif if (intarg_count == NUM_GPR_ARG_REGISTERS-1) intarg_count++; if (intarg_count >= NUM_GPR_ARG_REGISTERS) @@ -292,6 +303,9 @@ case FFI_TYPE_UINT32: case FFI_TYPE_SINT32: case FFI_TYPE_POINTER: +#ifdef __NO_FPRS__ + case FFI_TYPE_FLOAT: +#endif gprvalue = **p_argv.ui; putgpr: @@ -596,7 +610,9 @@ flags |= FLAG_RETURNS_64BITS; /* Fall through. */ case FFI_TYPE_FLOAT: +#ifndef __NO_FPRS__ flags |= FLAG_RETURNS_FP; +#endif break; case FFI_TYPE_UINT64: @@ -658,6 +674,7 @@ { switch ((*ptr)->type) { +#ifndef __NO_FPRS__ case FFI_TYPE_FLOAT: fparg_count++; /* floating singles are not 8-aligned on stack */ @@ -680,8 +697,12 @@ intarg_count++; break; +#endif case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: +#ifdef __NO_FPRS__ + case FFI_TYPE_DOUBLE: +#endif /* 'long long' arguments are passed as two words, but either both words must fit in registers or both go on the stack. If they go on the stack, they must @@ -922,7 +943,9 @@ long nf; /* number of floating registers already used */ long ng; /* number of general registers already used */ ffi_cif * cif; +#ifndef __NO_FPRS__ double temp; +#endif unsigned size; cif = closure->cif; @@ -994,6 +1017,9 @@ case FFI_TYPE_SINT32: case FFI_TYPE_UINT32: case FFI_TYPE_POINTER: +#ifdef __NO_FPRS__ + case FFI_TYPE_FLOAT: +#endif /* there are 8 gpr registers used to pass values */ if (ng < 8) { @@ -1029,6 +1055,9 @@ case FFI_TYPE_SINT64: case FFI_TYPE_UINT64: +#ifdef __NO_FPRS__ + case FFI_TYPE_DOUBLE: +#endif /* passing long long ints are complex, they must * be passed in suitable register pairs such as * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10) @@ -1059,6 +1088,7 @@ } break; +#ifndef __NO_FPRS__ case FFI_TYPE_FLOAT: /* unfortunately float values are stored as doubles * in the ffi_closure_SYSV code (since we don't check @@ -1106,6 +1136,7 @@ } break; +#endif #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE case FFI_TYPE_LONGDOUBLE: if (cif->abi != FFI_LINUX) @@ -1149,7 +1180,21 @@ && cif->abi != FFI_LINUX) return FFI_TYPE_STRUCT; #endif +#ifdef __NO_FPRS__ + switch (cif->rtype->type) + { + case FFI_TYPE_FLOAT: + return FFI_TYPE_UINT32; + break; + case FFI_TYPE_DOUBLE: + return FFI_TYPE_UINT64; + break; + default: + return cif->rtype->type; + } +#else return cif->rtype->type; +#endif } int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *,