From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16421 invoked by alias); 6 Nov 2007 22:47:36 -0000 Received: (qmail 16406 invoked by uid 22791); 6 Nov 2007 22:47:34 -0000 X-Spam-Check-By: sourceware.org Received: from exsmtp03.agrinet.ch (HELO exsmtp03.agrinet.ch) (81.221.254.202) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 06 Nov 2007 22:47:31 +0000 Received: from smtp.messaging.ch ([10.50.252.215]) by exsmtp03.agrinet.ch with Microsoft SMTPSVC(6.0.3790.3959); Tue, 6 Nov 2007 23:47:28 +0100 Received: from wolfram.andreas.nets ([84.73.68.225]) by smtp.messaging.ch with id 9anx1Y0014rcz700000000; Tue, 06 Nov 2007 23:47:58 +0100 X-IMP: ?? X-IMP-FROM: _________ X-IMP-AUTH_USERNAME: Message-ID: <4730EF00.5060408@pop.agri.ch> Date: Tue, 06 Nov 2007 22:47:00 -0000 From: Andreas Tobler User-Agent: Thunderbird 2.0.0.6 (Macintosh/20070728) MIME-Version: 1.0 To: GCC Patches CC: Martin Michlmayr Subject: [patch] fix pr31937 soft-float for libffi ppc 32-bit Content-Type: multipart/mixed; boundary="------------020000050803020201090004" X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2007-11/txt/msg00286.txt.bz2 This is a multi-part message in MIME format. --------------020000050803020201090004 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 749 Hi all, this patch adds soft float support for libffi-ppc 32-bit. Tested by Martin and me on a ppc-405 target. Libffi and libjava, on trunk. No negative influence on real ppc with fpu. This patch 'fixes' pr31937. The patch itself makes sure not to store float/double in the asm part. Also, the patch 'changes' the ABI to store float as UINT32 and double as UINT64. Ok for trunk? Thanks, Andreas 2007-11-06 Andreas Tobler PR libffi/31937 * src/powerpc/ffi.c (enum): Add __NO_FPRS__, handle soft-float support. (ffi_prep_args_SYSV): Handle __NO_FPRS__. (ffi_prep_cif_machdep): Likewise. (ffi_closure_helper_SYSV): Likewise. * src/powerpc/ppc_closure.S: Make sure not to store float/double on SOFT_FLOAT archs. --------------020000050803020201090004 Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0"; name="soft-float1.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="soft-float1.diff" Content-length: 4257 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 *, --------------020000050803020201090004--