From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from conuserg-07.nifty.com (conuserg-07.nifty.com [210.131.2.74]) by sourceware.org (Postfix) with ESMTPS id 33E20385840C for ; Wed, 1 Dec 2021 19:35:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 33E20385840C Authentication-Results: sourceware.org; dmarc=fail (p=none dis=none) header.from=nifty.ne.jp Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=nifty.ne.jp Received: from localhost.localdomain (z221123.dynamic.ppp.asahi-net.or.jp [110.4.221.123]) (authenticated) by conuserg-07.nifty.com with ESMTP id 1B1JYewJ028655; Thu, 2 Dec 2021 04:34:46 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conuserg-07.nifty.com 1B1JYewJ028655 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.ne.jp; s=dec2015msa; t=1638387287; bh=vN8+pPKkRmlK8WuwdYvN9mvMGNQVxx23t7cmsc4M2J4=; h=From:To:Cc:Subject:Date:From; b=y5xq0L6coX9X2h3rrCKn7zMZQL/WAjK7u1sATq+VM8OluLSqbxzNZK/0K2bmftkG4 UnMhL10a9xb/VF5DTsh5Px7rN4aDG018a2raMemUVTIakXN6eiDYyju7ShI41XHRum Ba2mIXN0Ww6VlHfnctrgjk/bC0dQkgGklGFPa2rt2yUEdqmKUBS32ENLfDXM183g7H Pe1xo1y0IoPjkEhsouiZ3DWBOtGAMx09Ap0XqbQZsv3vNaqMFpfEmfjRjt9fUPIn7f PNsBrHpTBjVWY0ck9jEfWy7BwNPcMcqA6BWsBNYOHAWjNzHwiGLHWT7qCPcInNNcpu IEUsoGmthv9EA== X-Nifty-SrcIP: [110.4.221.123] From: Takashi Yano To: newlib@sourceware.org Subject: [PATCH] frexpl: Support smaller long double. Date: Thu, 2 Dec 2021 04:34:34 +0900 Message-Id: <20211201193435.1266-1-takashi.yano@nifty.ne.jp> X-Mailer: git-send-email 2.33.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-10.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: newlib@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Newlib mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 01 Dec 2021 19:35:19 -0000 - Currently, frexpl() supports only the following cases. 1) LDBL_MANT_DIG == 64 or 113 2) 'long double' is equivalent to 'double' This patch add support for smaller long double, LDBL_MANT_DIG is 24 or 53. --- newlib/libm/common/frexpl.c | 78 +++++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 12 deletions(-) diff --git a/newlib/libm/common/frexpl.c b/newlib/libm/common/frexpl.c index 22c811689..8fc6b4a9c 100644 --- a/newlib/libm/common/frexpl.c +++ b/newlib/libm/common/frexpl.c @@ -33,16 +33,66 @@ POSSIBILITY OF SUCH DAMAGE. #include "local.h" /* On platforms where long double is as wide as double. */ -#if defined(_LDBL_EQ_DBL) || (LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024) +#if defined(_LDBL_EQ_DBL) long double frexpl (long double x, int *eptr) { return frexp(x, eptr); } -#endif +#else /* !_DBL_EQ_DBL */ +# if (LDBL_MANT_DIG == 24) /* 32-bit long double */ +static const double scale = 0x1p25; + +union ldbl { + long double x; + struct { +# ifdef __IEEE_LITTLE_ENDIAN /* for Intel CPU */ + __uint32_t frac:23; + __uint32_t exp:8; + __uint32_t sign:1; +# endif +# ifdef __IEEE_BIG_ENDIAN +# ifndef ___IEEE_BYTES_LITTLE_ENDIAN + __uint32_t sign:1; + __uint32_t exp:8; + __uint32_t frac:23; +# else /* ARMEL without __VFP_FP__ */ + __uint32_t frac:23; + __uint32_t exp:8; + __uint32_t sign:1; +# endif +# endif + } u32; +}; +# elif (LDBL_MANT_DIG == 53) /* 64-bit long double */ +static const double scale = 0x1p54; + +union ldbl { + long double x; + struct { +# ifdef __IEEE_LITTLE_ENDIAN /* for Intel CPU */ + __uint32_t fracl; + __uint32_t frach:20; + __uint32_t exp:11; + __uint32_t sign:1; +# endif +# ifdef __IEEE_BIG_ENDIAN + __uint32_t sign:1; + __uint32_t exp:11; + __uint32_t frach:20; +# ifndef ___IEEE_BYTES_LITTLE_ENDIAN +# else /* ARMEL without __VFP_FP__ */ + __uint32_t frach:20; + __uint32_t exp:11; + __uint32_t sign:1; +# endif + __uint32_t fracl; +# endif + } u32; +}; +# elif (LDBL_MANT_DIG == 64) /* 80-bit long double */ +static const double scale = 0x1p65; -#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 -# if (LDBL_MANT_DIG == 64) /* 80-bit long double */ union ldbl { long double x; struct { @@ -68,7 +118,9 @@ union ldbl { # endif } u32; }; -# else /* LDBL_MANT_DIG == 113, 128-bit long double */ +# elif (LDBL_MANT_DIG == 113) /* 128-bit long double */ +static const double scale = 0x1p114; + union ldbl { long double x; struct { @@ -96,9 +148,11 @@ union ldbl { # endif } u32; }; +# else +# error Unsupported long double format. # endif -static const double two114 = 0x1p114; +static const int scale_exp = LDBL_MANT_DIG + 1; long double frexpl (long double x, int *eptr) @@ -107,16 +161,16 @@ frexpl (long double x, int *eptr) u.x = x; int e = u.u32.exp; *eptr = 0; - if (e == 0x7fff || x == 0) + if (e == (LDBL_MAX_EXP*2 - 1) || x == 0) return x; /* inf,nan,0 */ if (e == 0) /* subnormal */ { - u.x *= two114; + u.x *= scale; e = u.u32.exp; - *eptr -= 114; + *eptr -= scale_exp; } - *eptr += e - 16382; - u.u32.exp = 0x3ffe; /* 0 */ + *eptr += e - (LDBL_MAX_EXP - 2); + u.u32.exp = LDBL_MAX_EXP - 2; /* -1 */ return u.x; } -#endif /* End of 80-bit or 128-bit long double */ +#endif /* !_LDBL_EQ_DBL */ -- 2.33.0