From patchwork Sat Jul 6 21:25:10 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?J=C3=BCrgen_Urban?= X-Patchwork-Id: 257315 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 9ECD22C009C for ; Sun, 7 Jul 2013 07:25:27 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:message-id:from:to:cc:subject:content-type:date :in-reply-to:references; q=dns; s=default; b=vRL5/alN3Axaun6Pnji rPkpt2dFgUKu06+VL2An+lMrkbjZj7gDAOU2PZGoOdbHs05Vl7NBXjIpZCO0IGmH Sd61XyiDjwHoTKegQYubGGmBUTJ0cFMM96zu9pVBcM+04fq2r8rWHnEQ0wrhtAQd Ao9u4lkloZvTUv05oueFoHO0= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:message-id:from:to:cc:subject:content-type:date :in-reply-to:references; s=default; bh=dcZfSyBTC0BCq2oucPDtQPbhd aQ=; b=fAW5RPTW3Z9FBToiBh1+pLGMuLG4mpzdx7pxCrx0pe5Ag3X2rGJbk3nQX /FQh1t9EMhXJH/SZIfV2KAIVueVy8uSIZm1qwujCLZ3OgsgmkY+u/FChMfat3pus M1CYg/lP5jY3A3wtNWxrxcpRySSPM6Dr8kcUDnsjzNDkU9rMxE= Received: (qmail 10483 invoked by alias); 6 Jul 2013 21:25:19 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 10459 invoked by uid 89); 6 Jul 2013 21:25:14 -0000 X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, KHOP_THREADED, RCVD_IN_DNSWL_NONE, RCVD_IN_HOSTKARMA_NO, SPF_PASS, TW_MF autolearn=ham version=3.3.1 Received: from mout.gmx.net (HELO mout.gmx.net) (212.227.15.19) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Sat, 06 Jul 2013 21:25:12 +0000 Received: from 3capp-gmx-bs07.server.lan ([172.19.170.56]) by mrigmx.server.lan (mrigmx001) with ESMTP (Nemesis) id 0LnEWZ-1UH21j0BlF-00hP1j; Sat, 06 Jul 2013 23:25:10 +0200 Received: from [84.178.60.67] by 3capp-gmx-bs07.server.lan with HTTP; Sat Jul 06 23:25:10 CEST 2013 MIME-Version: 1.0 Message-ID: From: =?UTF-8?Q?=22J=C3=BCrgen_Urban=22?= To: "Richard Sandiford" Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] FPU IEEE 754 for MIPS r5900 Date: Sat, 6 Jul 2013 23:25:10 +0200 (CEST) Sensitivity: Normal In-Reply-To: <87r4gh92dy.fsf@talisman.default> References: <87zjv77ygt.fsf@talisman.default> , <87r4gh92dy.fsf@talisman.default> X-UI-Message-Type: mail X-Virus-Found: No Hello Richard, I used the SPU code in GCC as example for creating an r5900_single_format structure. The patch is attached to the e-mail. I want to submit this patch. > >> * removing the ISA_HAS_LDC1_SDC1 setting. I realise what you did > >> describes the reality of the processor, but the problem is that > >> the patch doesn't provide an alternative for 64-bit loads and > >> stores when -mfp64 is used. That combination also isn't rejected, > >> so we're likely to get an internal compiler error instead. > >> > >> This change shouldn't affect the soft-float case you describe. > >> It also shouldn't be important for the single-float code. I needed to patch ISA_HAS_LDC1_SDC1, because the GCC uses the instructions also for single float to store FPRs on the stack. To get around the missing alternative, I reject in the code the following combinations, because it would never work: -march=r5900 -mfp64 -mhard-float -march=r5900 -mdouble-float -mhard-float > >> FWIW, the Cygnus/Red Hat version of the port just stuck with the R5900 > >> behaviour and made GCC understand it (MODE_HAS_* & various other bits). > >> This code was then updated and extended for the SPU. I'd have expected > >> the support to be in reasonably good shape because of the SPU. > > > > I assume that you mean the cell processor of the PS3 and not the Sound > > Processing Unit of the PS2. > > :-) > > > The macros MODE_HAS_* in the GCC look promising. > > You've probably already seen it, but there's also spu_single_format. To be able to use it, you need to use mipsr5900el and "--with-float=single". "--with-float=hard" results in double float because of MIPS ISA III. I didn't changed the default in config.gcc. It is still soft float, because floating point doesn't behave as defined by IEEE 754. I don't see much improvement. This is the case on the PS2 and the PS3. For example inf minus inf should be NaN, but on both systems it is 0. I tested it on r5900 and the PS3 SPU. Both calculates the same result despite the MODE_HAS_* implementation. This means that there is a patch needed in the generic part (i.e. not mips) of the GCC. Currently I only provide a simple patch, so that the GCC knows the missing stuff, even if it is not correctly handled in the generic GCC part. I thought that Linux is running on SPU, but this is not the case, because it just a simple coprocessor. It seems that SPU is not used for complex floating point calculations in homebrew software. I am pretty sure that nearly nobody knows that floating point in GCC behaves this way on SPU. Best regards Jürgen Index: gcc/real.c =================================================================== --- gcc/real.c (Revision 200583) +++ gcc/real.c (Arbeitskopie) @@ -3028,6 +3028,34 @@ true }; +/* r5900 Single precision format is the same as IEEE + single precision with the following differences: + - Infinities are not supported. Instead MAX_FLOAT or MIN_FLOAT + are generated. + - NaNs are not supported. + - Denormals are not supported. + - the only supported rounding mode is trunction (towards zero). */ +const struct real_format r5900_single_format = + { + encode_ieee_single, + decode_ieee_single, + 2, + 24, + 24, + -125, + 128, + 31, + 31, + true, + true, + false, + false, + false, + true, + false, + true + }; + const struct real_format motorola_single_format = { encode_ieee_single, Index: gcc/real.h =================================================================== --- gcc/real.h (Revision 200583) +++ gcc/real.h (Arbeitskopie) @@ -303,6 +303,7 @@ /* Target formats defined in real.c. */ extern const struct real_format ieee_single_format; extern const struct real_format mips_single_format; +extern const struct real_format r5900_single_format; extern const struct real_format motorola_single_format; extern const struct real_format spu_single_format; extern const struct real_format ieee_double_format; Index: gcc/config.gcc =================================================================== --- gcc/config.gcc (Revision 200583) +++ gcc/config.gcc (Arbeitskopie) @@ -3472,7 +3475,7 @@ supported_defaults="abi arch arch_32 arch_64 float tune tune_32 tune_64 divide llsc mips-plt synci" case ${with_float} in - "" | soft | hard) + "" | soft | hard | single | double) # OK ;; *) Index: gcc/config/mips/mips.c =================================================================== --- gcc/config/mips/mips.c (Revision 200583) +++ gcc/config/mips/mips.c (Arbeitskopie) @@ -16830,6 +16830,19 @@ target_flags &= ~MASK_FLOAT64; } + if (TARGET_HARD_FLOAT_ABI && TARGET_FLOAT64 && TARGET_MIPS5900) + { + /* FPU of r5900 only supports 32 bit. */ + error ("unsupported combination: %s", "-march=r5900 -mfp64 -mhard-float"); + } + + if (TARGET_HARD_FLOAT_ABI && TARGET_DOUBLE_FLOAT && TARGET_MIPS5900) + { + /* FPU of r5900 only supports 32 bit. */ + error ("unsupported combination: %s", + "-march=r5900 -mdouble-float -mhard-float"); + } + /* End of code shared with GAS. */ /* If a -mlong* option was given, check that it matches the ABI, @@ -17139,6 +17152,11 @@ filling. Registering the pass must be done at start up. It's convenient to do it here. */ register_pass (&insert_pass_mips_machine_reorg2); + + if (TARGET_MIPS5900) + { + REAL_MODE_FORMAT (SFmode) = &r5900_single_format; + } } /* Swap the register information for registers I and I + 1, which Index: gcc/config/mips/mips.h =================================================================== --- gcc/config/mips/mips.h (Revision 200583) +++ gcc/config/mips/mips.h (Arbeitskopie) @@ -859,7 +859,9 @@ || TARGET_LOONGSON_2EF) /* ISA has LDC1 and SDC1. */ -#define ISA_HAS_LDC1_SDC1 (!ISA_MIPS1 && !TARGET_MIPS16) +#define ISA_HAS_LDC1_SDC1 (!ISA_MIPS1 \ + && !TARGET_MIPS16 \ + && !TARGET_MIPS5900) \ /* ISA has the mips4 FP condition code instructions: FP-compare to CC, branch on CC, and move (both FP and non-FP) on CC. */ @@ -989,7 +991,7 @@ /* True if trunc.w.s and trunc.w.d are real (not synthetic) instructions. Both require TARGET_HARD_FLOAT, and trunc.w.d also requires TARGET_DOUBLE_FLOAT. */ -#define ISA_HAS_TRUNC_W (!ISA_MIPS1) +#define ISA_HAS_TRUNC_W (!ISA_MIPS1 || TARGET_MIPS5900) /* ISA includes the MIPS32r2 seb and seh instructions. */ #define ISA_HAS_SEB_SEH ((ISA_MIPS32R2 \