From patchwork Mon Sep 22 17:11:33 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zakaria Fadli X-Patchwork-Id: 120628 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0F7AE385840B for ; Mon, 22 Sep 2025 17:13:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0F7AE385840B Authentication-Results: sourceware.org; dkim=pass (2048-bit key, secure) header.d=adacore.com header.i=@adacore.com header.a=rsa-sha256 header.s=google header.b=LMu2SjxA X-Original-To: newlib@sourceware.org Delivered-To: newlib@sourceware.org Received: from mail-wm1-x32a.google.com (mail-wm1-x32a.google.com [IPv6:2a00:1450:4864:20::32a]) by sourceware.org (Postfix) with ESMTPS id 2C7423858D38 for ; Mon, 22 Sep 2025 17:12:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2C7423858D38 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=adacore.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 2C7423858D38 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::32a ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1758561168; cv=none; b=NGDsGQBJkSytQt9KZurEiymdW5FXiPoNa8C/zdgbxVgFVNQdLCTYq0lKP1EovImnVjthZvhonzwbLI8KvqXJ8NegNlZYSJHkqfW61Yy/x55QlWzTRhs5MULVQcNR45k6lTZei/6y/QG86KvyBLR07INQNAF5qi/CJgUPVD6hH10= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1758561168; c=relaxed/simple; bh=FhMm7tCXzwb0rcZMDUSiYP1MvuU3JIRV/yrTpaYdZJ8=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=DGZqReS+8/E4WoGcPclVu4sUVL6AloC9c3Ai+mHL/9uh/nEmZJPD+tNexLvM7EDx5JtLBRzBULOmgaVdomrq4wOMsU+Xl9fobZaJacBCntPQYxzenRXgIfZBRduwp167CLJ6Ki/5UTxBmNxtqkvgW0vqPV0KCBz47moC5c4XtOI= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2C7423858D38 Received: by mail-wm1-x32a.google.com with SMTP id 5b1f17b1804b1-45f2cf99bbbso22350295e9.0 for ; Mon, 22 Sep 2025 10:12:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=adacore.com; s=google; t=1758561166; x=1759165966; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=raQzwns1IstIr2rDYH/Lj3Rv2M7npbDZuseE1qL5BIg=; b=LMu2SjxA81dUexw95X6uI50UTb0W3aT9GalDp1NKBzWH+/n1yHpuMBR4Vbj/MtwHUe xB3ln+IILvo/C/iOAPHbZybQEU8nH1d+f9ubs/ZHGdvIq3g4jPb0wnwT2w4ZAUsTcMsa I3xEJr0nS8t4mIUvwDf5HR/bN2MqiqPqyHsPOp2tSFtXsRVYf9aZ0HIJgZd2n/f+WqeF XzTqjAU0znk7mK+RbaFpOKwbBnqhyHKL44FVj+xeCZf171HgX26KyIb3HgXFgIHWO7t5 Ery/7e5TYz0qx0cdyBFV7PgbzW4DBiI21kW4+fZPNkogQK/2TZ6GrldnLBNrasfS5QyP elWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1758561166; x=1759165966; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=raQzwns1IstIr2rDYH/Lj3Rv2M7npbDZuseE1qL5BIg=; b=parsJMfsl1QBCJxypYNI6rV8cxPF23JY/8sPTaE4DcmJkU49S2ZtGdumTN6y/HRmW+ fiN7nB3zG6f/BlYvg5PkszVwG5rsfHcZblTEF1xw/LaAG7jdyj9hPpT3sMQWmSqX8LL6 8gOQPQOr2R3M9ieksSEup9fFFqe1f7TEwh/LO90uDd8NGRg6f5TWnWupjdmWb1e2UreR N0YvgBMesw+QVb8CuNU9ijG0qQL47h8Ph/6CbueZAkisJxkLqpDZK3zvZyDdU5gMKp74 HxCIVZ/rKC2gEQSbEFXtf3s6diqZXBl/yuDsFk34BFcg8BtcksnT2vwV4cX27H9KsN83 W1zQ== X-Gm-Message-State: AOJu0Yyv/5ZMaDzQkyVUX5rENFbHaHE/CTG16eYd/FCpO4uRss5rpgM2 UapoY4kk2C9VC5C4EueskiDZDSmPKnxEP7pU/vsiTDuemG0DIU2nypEto5FXn75PY5dGP6Y9t0U tqbg= X-Gm-Gg: ASbGncvPh+JgFexnUl1UbHVj1bfhOlTvjw7ld904Pv+J952zjd/TCIrl/LBVzowWBzk sS+ff+1VqDhh7ronrgqWbsWUO7GRus9P06pWGNC67uk2S6pwYbkQvE1xDabCCHLSH8Ouj7U2OhW weEq7lHygB9gAaCbfpgD6n7cfZfADQ6gNu1KB59A3n0cg/+vSWS29Hm+IUr0yqizWjBlOffCVd1 Q6XLAkP9DVM7Eg666ie3fq/86RNAGMH0FmQjGMvuHXkj0RhRm9nxBEW5RUOr1fGGnyjXq07udA0 o8iDEoEVWeOTlgvllH+5tnTpK0VZUYMfje2jv8/hKF3qFBYHYV3Bp5vv7MvbGUc9nenAs9Fo6cF i4gxWV9maJHDdheVrGdR4bnm4KIbxosM/bkJS0A== X-Google-Smtp-Source: AGHT+IGXkRFipTISgE0XOtSYFrdlhvlB95Vc6eVcOxMQaXCeBRrAWXKxuMSZ1QmLCoMauwOwflRN+g== X-Received: by 2002:a05:600c:3b11:b0:45d:d1b0:5fa2 with SMTP id 5b1f17b1804b1-467ea004642mr95589695e9.19.1758561166271; Mon, 22 Sep 2025 10:12:46 -0700 (PDT) Received: from DESKTOPfadli.adacorefr.lan ([45.147.211.82]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-46dea20f833sm32903915e9.10.2025.09.22.10.12.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Sep 2025 10:12:45 -0700 (PDT) From: Zakaria Fadli To: newlib@sourceware.org Cc: Zakaria Fadli Subject: [RFC PATCH 1/1] newlib: strtold: Import strtorQ for 128-bit long double support Date: Mon, 22 Sep 2025 19:11:33 +0200 Message-ID: <20250922171137.3137186-2-fadli@adacore.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250922171137.3137186-1-fadli@adacore.com> References: <20250922171137.3137186-1-fadli@adacore.com> MIME-Version: 1.0 X-Spam-Status: No, score=-10.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, LIKELY_SPAM_BODY, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: newlib@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Newlib mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: newlib-bounces~patchwork=sourceware.org@sourceware.org The implementation of strtorQ is imported from FreeBSD's gdtoa library (By David M. Gay) with some adaptations to fit with newlib. `strtorQ.c` enables `strtold` to perform correct parsing on targets where long double uses the IEEE754 binary128 format (113-bit mantissa), such as AArch64. Without this patch, strtold would wrongly fallback to `strtorx` which will parse into a 80-bit long double and give invalid result. * libc/stdlib/strtorQ.c: New file, adapted from FreeBSD gdtoa. * libc/stdlib/strtold.c (_strtold_impl): New helper selecting strtorx for 80-bit and strtorQ for 128-bit long double. (_strtold_r, strtold_l, strtold): Use _strtold_impl. * libc/stdlib/mprec.h (_strtorQ_l): Declare. * libc/stdlib/Makefile.inc (libc_a_SOURCES): Add strtorQ.c. * newlib/Makefile.in: Regenerate with automake Signed-off-by: Zakaria Fadli --- newlib/Makefile.in | 19 +++++ newlib/libc/stdlib/Makefile.inc | 1 + newlib/libc/stdlib/mprec.h | 2 + newlib/libc/stdlib/strtold.c | 56 +++++++------- newlib/libc/stdlib/strtorQ.c | 129 ++++++++++++++++++++++++++++++++ 5 files changed, 178 insertions(+), 29 deletions(-) create mode 100644 newlib/libc/stdlib/strtorQ.c diff --git a/newlib/Makefile.in b/newlib/Makefile.in index 9a32646ab..c1515407b 100644 --- a/newlib/Makefile.in +++ b/newlib/Makefile.in @@ -125,6 +125,7 @@ check_PROGRAMS = @HAVE_LONG_DOUBLE_TRUE@am__append_6 = \ @HAVE_LONG_DOUBLE_TRUE@ libc/stdlib/strtodg.c \ @HAVE_LONG_DOUBLE_TRUE@ libc/stdlib/strtold.c \ +@HAVE_LONG_DOUBLE_TRUE@ libc/stdlib/strtorQ.c \ @HAVE_LONG_DOUBLE_TRUE@ libc/stdlib/strtorx.c \ @HAVE_LONG_DOUBLE_TRUE@ libc/stdlib/wcstold.c @@ -1045,6 +1046,7 @@ am__dirstamp = $(am__leading_dot)dirstamp @HAVE_LONG_DOUBLE_TRUE@am__objects_2 = \ @HAVE_LONG_DOUBLE_TRUE@ libc/stdlib/libc_a-strtodg.$(OBJEXT) \ @HAVE_LONG_DOUBLE_TRUE@ libc/stdlib/libc_a-strtold.$(OBJEXT) \ +@HAVE_LONG_DOUBLE_TRUE@ libc/stdlib/libc_a-strtorQ.$(OBJEXT) \ @HAVE_LONG_DOUBLE_TRUE@ libc/stdlib/libc_a-strtorx.$(OBJEXT) \ @HAVE_LONG_DOUBLE_TRUE@ libc/stdlib/libc_a-wcstold.$(OBJEXT) am__objects_3 = libc/stdlib/libc_a-a64l.$(OBJEXT) \ @@ -5611,6 +5613,8 @@ libc/stdlib/libc_a-strtodg.$(OBJEXT): libc/stdlib/$(am__dirstamp) \ libc/stdlib/$(DEPDIR)/$(am__dirstamp) libc/stdlib/libc_a-strtold.$(OBJEXT): libc/stdlib/$(am__dirstamp) \ libc/stdlib/$(DEPDIR)/$(am__dirstamp) +libc/stdlib/libc_a-strtorQ.$(OBJEXT): libc/stdlib/$(am__dirstamp) \ + libc/stdlib/$(DEPDIR)/$(am__dirstamp) libc/stdlib/libc_a-strtorx.$(OBJEXT): libc/stdlib/$(am__dirstamp) \ libc/stdlib/$(DEPDIR)/$(am__dirstamp) libc/stdlib/libc_a-wcstold.$(OBJEXT): libc/stdlib/$(am__dirstamp) \ @@ -13652,6 +13656,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@libc/stdlib/$(DEPDIR)/libc_a-strtold.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libc/stdlib/$(DEPDIR)/libc_a-strtoll.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libc/stdlib/$(DEPDIR)/libc_a-strtoll_r.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libc/stdlib/$(DEPDIR)/libc_a-strtorQ.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libc/stdlib/$(DEPDIR)/libc_a-strtorx.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libc/stdlib/$(DEPDIR)/libc_a-strtoul.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libc/stdlib/$(DEPDIR)/libc_a-strtoull.Po@am__quote@ @@ -21559,6 +21564,20 @@ libc/stdlib/libc_a-strtold.obj: libc/stdlib/strtold.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -c -o libc/stdlib/libc_a-strtold.obj `if test -f 'libc/stdlib/strtold.c'; then $(CYGPATH_W) 'libc/stdlib/strtold.c'; else $(CYGPATH_W) '$(srcdir)/libc/stdlib/strtold.c'; fi` +libc/stdlib/libc_a-strtorQ.o: libc/stdlib/strtorQ.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -MT libc/stdlib/libc_a-strtorQ.o -MD -MP -MF libc/stdlib/$(DEPDIR)/libc_a-strtorQ.Tpo -c -o libc/stdlib/libc_a-strtorQ.o `test -f 'libc/stdlib/strtorQ.c' || echo '$(srcdir)/'`libc/stdlib/strtorQ.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libc/stdlib/$(DEPDIR)/libc_a-strtorQ.Tpo libc/stdlib/$(DEPDIR)/libc_a-strtorQ.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libc/stdlib/strtorQ.c' object='libc/stdlib/libc_a-strtorQ.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -c -o libc/stdlib/libc_a-strtorQ.o `test -f 'libc/stdlib/strtorQ.c' || echo '$(srcdir)/'`libc/stdlib/strtorQ.c + +libc/stdlib/libc_a-strtorQ.obj: libc/stdlib/strtorQ.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -MT libc/stdlib/libc_a-strtorQ.obj -MD -MP -MF libc/stdlib/$(DEPDIR)/libc_a-strtorQ.Tpo -c -o libc/stdlib/libc_a-strtorQ.obj `if test -f 'libc/stdlib/strtorQ.c'; then $(CYGPATH_W) 'libc/stdlib/strtorQ.c'; else $(CYGPATH_W) '$(srcdir)/libc/stdlib/strtorQ.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libc/stdlib/$(DEPDIR)/libc_a-strtorQ.Tpo libc/stdlib/$(DEPDIR)/libc_a-strtorQ.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libc/stdlib/strtorQ.c' object='libc/stdlib/libc_a-strtorQ.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -c -o libc/stdlib/libc_a-strtorQ.obj `if test -f 'libc/stdlib/strtorQ.c'; then $(CYGPATH_W) 'libc/stdlib/strtorQ.c'; else $(CYGPATH_W) '$(srcdir)/libc/stdlib/strtorQ.c'; fi` + libc/stdlib/libc_a-strtorx.o: libc/stdlib/strtorx.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libc_a_CPPFLAGS) $(CPPFLAGS) $(libc_a_CFLAGS) $(CFLAGS) -MT libc/stdlib/libc_a-strtorx.o -MD -MP -MF libc/stdlib/$(DEPDIR)/libc_a-strtorx.Tpo -c -o libc/stdlib/libc_a-strtorx.o `test -f 'libc/stdlib/strtorx.c' || echo '$(srcdir)/'`libc/stdlib/strtorx.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libc/stdlib/$(DEPDIR)/libc_a-strtorx.Tpo libc/stdlib/$(DEPDIR)/libc_a-strtorx.Po diff --git a/newlib/libc/stdlib/Makefile.inc b/newlib/libc/stdlib/Makefile.inc index 9812add76..6510cdfdd 100644 --- a/newlib/libc/stdlib/Makefile.inc +++ b/newlib/libc/stdlib/Makefile.inc @@ -83,6 +83,7 @@ if HAVE_LONG_DOUBLE libc_a_SOURCES += \ %D%/strtodg.c \ %D%/strtold.c \ + %D%/strtorQ.c \ %D%/strtorx.c \ %D%/wcstold.c endif # HAVE_LONG_DOUBLE diff --git a/newlib/libc/stdlib/mprec.h b/newlib/libc/stdlib/mprec.h index 83de932c2..c2d0a0ac3 100644 --- a/newlib/libc/stdlib/mprec.h +++ b/newlib/libc/stdlib/mprec.h @@ -385,6 +385,8 @@ double _strtod_l (struct _reent *ptr, const char *__restrict s00, #if defined (_HAVE_LONG_DOUBLE) && !defined (_LDBL_EQ_DBL) int _strtorx_l (struct _reent *, const char *, char **, int, void *, locale_t); +int _strtorQ_l (struct _reent *, const char *, char **, int, + void *, locale_t); int _strtodg_l (struct _reent *p, const char *s00, char **se, struct FPI *fpi, Long *exp, __ULong *bits, locale_t); diff --git a/newlib/libc/stdlib/strtold.c b/newlib/libc/stdlib/strtold.c index 6bd1c2cbb..57cc38e30 100644 --- a/newlib/libc/stdlib/strtold.c +++ b/newlib/libc/stdlib/strtold.c @@ -58,47 +58,45 @@ __flt_rounds(void) #define FLT_ROUNDS 0 #endif -long double -_strtold_r (struct _reent *ptr, const char *__restrict s00, - char **__restrict se) -{ -#ifdef _LDBL_EQ_DBL - /* On platforms where long double is as wide as double. */ - return _strtod_l (ptr, s00, se, __get_current_locale ()); -#else +/* + * The core implementation for the strtold family of functions, handling + * different long double formats. + */ +static long double +_strtold_impl(struct _reent *ptr, const char *__restrict s00, + char **__restrict se, locale_t loc) { +#if defined(_LDBL_EQ_DBL) + /* On platforms where long double is as wide as double. */ + return _strtod_l(ptr, s00, se, loc); +#elif LDBL_MANT_DIG == 64 /* For 80 bit long doubles */ long double result; - - _strtorx_l (ptr, s00, se, FLT_ROUNDS, &result, __get_current_locale ()); + _strtorx_l(ptr, s00, se, FLT_ROUNDS, &result, loc); return result; +#elif LDBL_MANT_DIG == 113 /* For 128bit long doubles */ + long double result; + _strtorQ_l(ptr, s00, se, FLT_ROUNDS, &result, loc); + return result; +#else +#warning "strtold not implemented for this long double format" + return (long double)_strtod_l(ptr, s00, se, loc); #endif } long double -strtold_l (const char *__restrict s00, char **__restrict se, locale_t loc) -{ -#ifdef _LDBL_EQ_DBL - /* On platforms where long double is as wide as double. */ - return _strtod_l (_REENT, s00, se, loc); -#else - long double result; +_strtold_r(struct _reent *ptr, const char *__restrict s00, + char **__restrict se) { + return _strtold_impl(ptr, s00, se, __get_current_locale()); +} - _strtorx_l (_REENT, s00, se, FLT_ROUNDS, &result, loc); - return result; -#endif +long double +strtold_l(const char *__restrict s00, char **__restrict se, locale_t loc) { + return _strtold_impl(_REENT, s00, se, loc); } long double strtold (const char *__restrict s00, char **__restrict se) { -#ifdef _LDBL_EQ_DBL - /* On platforms where long double is as wide as double. */ - return _strtod_l (_REENT, s00, se, __get_current_locale ()); -#else - long double result; - - _strtorx_l (_REENT, s00, se, FLT_ROUNDS, &result, __get_current_locale ()); - return result; -#endif + return _strtold_impl(_REENT, s00, se, __get_current_locale()); } #endif /* _HAVE_LONG_DOUBLE */ diff --git a/newlib/libc/stdlib/strtorQ.c b/newlib/libc/stdlib/strtorQ.c new file mode 100644 index 000000000..b3205e3b7 --- /dev/null +++ b/newlib/libc/stdlib/strtorQ.c @@ -0,0 +1,129 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include <_ansi.h> +#include +#include +#include +#include "mprec.h" +#include "gdtoa.h" + +#if defined (_HAVE_LONG_DOUBLE) && !defined (_LDBL_EQ_DBL) + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#define _3 3 +#endif +#ifdef IEEE_8087 +#define _0 3 +#define _1 2 +#define _2 1 +#define _3 0 +#endif + + void +#ifdef KR_headers +ULtoQ(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k; +#else +ULtoQ(ULong *L, ULong *bits, Long exp, int k) +#endif +{ + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = L[3] = 0; + break; + + case STRTOG_Normal: + L[_3] = bits[0]; + L[_2] = bits[1]; + L[_1] = bits[2]; + L[_0] = (bits[3] & ~0x10000) | ((exp + 0x3fff + 112) << 16); + break; + + case STRTOG_NaNbits: + L[_3] = bits[0]; + L[_2] = bits[1]; + L[_1] = bits[2]; + L[_0] = (bits[3] & ~0x10000) + | (((exp + 0x3fff + 112) << 16) | (1 << 15)); + break; + + case STRTOG_Denormal: + L[_3] = bits[0]; + L[_2] = bits[1]; + L[_1] = bits[2]; + L[_0] = bits[3]; + break; + + case STRTOG_Infinite: + L[_0] = 0x7fff0000; + L[_1] = L[_2] = L[_3] = 0; + break; + + case STRTOG_NaN: + *((long double*)L) = __builtin_nanl (""); + } + if (k & STRTOG_Neg) + L[_0] |= 0x80000000L; + } + + int +#ifdef KR_headers +_strtorQ_l(s, sp, rounding, L, locale) struct _reent *p; CONST char *s; +char **sp; int rounding; void *L; locale_t locale; +#else +_strtorQ_l(struct _reent *p, CONST char *s, char **sp, + int rounding, void *L, locale_t locale) +#endif +{ + static FPI fpi0 = { 113, 1-16383-113+1, 32766-16383-113+1, 1, SI }; + FPI *fpi, fpi1; + ULong bits[4]; + Long exp; + int k; + + fpi = &fpi0; + if (rounding != FPI_Round_near) { + fpi1 = fpi0; + fpi1.rounding = rounding; + fpi = &fpi1; + } + k = _strtodg_l(p, s, sp, fpi, &exp, bits, locale); + ULtoQ((ULong*)L, bits, exp, k); + return k; + } + +#endif /* _HAVE_LONG_DOUBLE && !_LDBL_EQ_DBL */