From owner-svn-src-head@FreeBSD.ORG Fri May 29 13:33:45 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 304C4B79; Fri, 29 May 2015 13:33:45 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from mail109.syd.optusnet.com.au (mail109.syd.optusnet.com.au [211.29.132.80]) by mx1.freebsd.org (Postfix) with ESMTP id E96D31066; Fri, 29 May 2015 13:33:44 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from c211-30-166-197.carlnfd1.nsw.optusnet.com.au (c211-30-166-197.carlnfd1.nsw.optusnet.com.au [211.30.166.197]) by mail109.syd.optusnet.com.au (Postfix) with ESMTPS id 012F2D62170; Fri, 29 May 2015 23:13:33 +1000 (AEST) Date: Fri, 29 May 2015 23:13:33 +1000 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: Andrew Turner cc: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: Re: svn commit: r283694 - head/lib/libc/gen In-Reply-To: <201505290926.t4T9QBVE030151@svn.freebsd.org> Message-ID: <20150529221743.D1965@besplex.bde.org> References: <201505290926.t4T9QBVE030151@svn.freebsd.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.1 cv=QeFf4Krv c=1 sm=1 tr=0 a=KA6XNC2GZCFrdESI5ZmdjQ==:117 a=PO7r1zJSAAAA:8 a=kj9zAlcOel0A:10 a=JzwRw_2MAAAA:8 a=_BaMDy3rIB0_iexLCQAA:9 a=CjuIK1q_8ugA:10 X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 29 May 2015 13:33:45 -0000 On Fri, 29 May 2015, Andrew Turner wrote: > Log: > Fix __fpclassifyl when double == long double. As with r283693 this is > needed on ARM and PowerPC. > > MFC after: 1 Week > > Modified: > head/lib/libc/gen/fpclassify.c > > Modified: head/lib/libc/gen/fpclassify.c > ============================================================================== > --- head/lib/libc/gen/fpclassify.c Fri May 29 09:23:20 2015 (r283693) > +++ head/lib/libc/gen/fpclassify.c Fri May 29 09:26:10 2015 (r283694) > @@ -29,6 +29,8 @@ > > #include > > +#include > + > #include > #include > > @@ -84,10 +86,18 @@ __fpclassifyl(long double e) > return (FP_SUBNORMAL); > } > mask_nbit_l(u); /* Mask normalization bit if applicable. */ > +#if LDBL_MANT_DIG == 53 > + if (u.bits.exp == 2047) { > + if ((u.bits.manl | u.bits.manh) == 0) > + return (FP_INFINITE); > + return (FP_NAN); > + } > +#else > if (u.bits.exp == 32767) { > if ((u.bits.manl | u.bits.manh) == 0) > return (FP_INFINITE); > return (FP_NAN); > } > +#endif > return (FP_NORMAL); > } This can be written without any ifdefs by spelling 2047 and 32767 as LBDL_MUMBLE. However, I prefer explicit values, with masks spelled in hex as 0x7fff or 7ff, not as above or as (2 * LDBL_MAX_EXP - 1). However2, grepping for the usual spelling of such masks shows that the above is a wrong fix -- a style bug. All long double functions where long double is just double should be weak aliases to the double functions. This method is used for all nontrivial functions. The above code is pessimized to support the intermediate version with everything looking the same but parametrized by macros and struct layouts. bits.exp, bits.manh and bits.manl have all sorts of sizes so that they look the same, but this gives pessimal code for arches where the sizes are unnatural and the compiler can't repack to better ones. There are no examples of ifdefs for the weak aliases that apply directly here. Usually the long double version is in a file by itself and is ommitted for arches without real long doubles by not putting it in the MD Makefile. Here and for isinf*(), all the libc functions are in the same file, so ifdefs would be needed. You may also need to keep the extern __*l() functions for library compatibility. This is for functions that are only in libc as 10 year old compatibility hacks for 20 year old mistakes :-(, If the above is ifdefed, then it may as well handle the normalization bit correctly using another ifdef. There are just 3 supported cases: - 64-bit long doubles (really doubles). Normalization is implicit; there are no invalid formats and tests can ignore the normalization bit - 80-bit long doubles. Don't clobber the normalization bit, but check that it is consistent - 128-bit long doubles. Like 64-bit ones for normalization. __isnanl() seems to be broken in one more place (unless you fixed this too). libm has another extern copy of __isnanl() in s_isnanl.c. This is compiled in both the PIC and !PIC cases, while the one in libc is only compiled in the PIC case. I think this copy is even more unreachable than the one in libc. As mentioned in a previous reply, math.h has a copy of __isnanl() which is the one normally used, and it is missing most of the bugs. Bruce