From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7868) id B24293858436; Mon, 6 Dec 2021 10:26:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B24293858436 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Takashi Yano To: newlib-cvs@sourceware.org Subject: [newlib-cygwin] ldtoa: Import gdtoa from OpenBSD. X-Act-Checkin: newlib-cygwin X-Git-Author: Takashi Yano X-Git-Refname: refs/heads/master X-Git-Oldrev: 34876c05a527a7295920979fce69cec6b4cb613c X-Git-Newrev: a4705d387f7874f9a5de3ee67861773a17691643 Message-Id: <20211206102654.B24293858436@sourceware.org> Date: Mon, 6 Dec 2021 10:26:54 +0000 (GMT) X-BeenThere: newlib-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Newlib GIT logs List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 06 Dec 2021 10:26:54 -0000 https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=a4705d387f7874f9a5de3ee67861773a17691643 commit a4705d387f7874f9a5de3ee67861773a17691643 Author: Takashi Yano Date: Wed Dec 1 06:11:32 2021 +0900 ldtoa: Import gdtoa from OpenBSD. - This patch uses gdtoa imported from OpenBSD if newlib configure option "--enable-newlib-use-gdtoa=no" is NOT specified. gdtoa provides more accurate output and faster conversion than legacy ldtoa, while it requires more heap memory. Diff: --- newlib/README | 10 + newlib/configure | 317 ++++++++------ newlib/configure.ac | 15 + newlib/libc/include/machine/ieee.h | 127 ++++++ newlib/libc/include/sys/config.h | 6 + newlib/libc/stdlib/Makefile.am | 10 +- newlib/libc/stdlib/Makefile.in | 51 ++- newlib/libc/stdlib/gdtoa-dmisc.c | 230 ++++++++++ newlib/libc/stdlib/gdtoa-gdtoa.c | 837 +++++++++++++++++++++++++++++++++++++ newlib/libc/stdlib/gdtoa-gmisc.c | 91 ++++ newlib/libc/stdlib/gdtoa-ldtoa.c | 159 +++++++ newlib/libc/stdlib/gdtoa.h | 130 +++++- newlib/libc/stdlib/gdtoaimp.h | 206 +++++++++ newlib/libc/stdlib/ldtoa.c | 6 + newlib/libc/stdlib/mprec.h | 2 +- newlib/newlib.hin | 3 + 16 files changed, 2034 insertions(+), 166 deletions(-) diff --git a/newlib/README b/newlib/README index 064c5784c..c82bf8b8c 100644 --- a/newlib/README +++ b/newlib/README @@ -352,6 +352,16 @@ One feature can be enabled by specifying `--enable-FEATURE=yes' or 64-bit integer on most systems. Disabled by default. +`--enable-newlib-use-gdtoa' + Use gdtoa rather than legacy ldtoa. gdtoa privides more accurate + output and faster conversion than legacy ldtoa, while it requires + more heap memory. gdtoa sometimes requires 16KB heap memory, so + if the platform does not have enough heap memory, consider disabling + this option. Legacy ldtoa also use heap, however, only 1KB memory + is malloc'ed. In addition, if malloc fails, it still works, with + less conversion accuracy. + Enabled by default. + `--enable-multilib' Build many library versions. Enabled by default. diff --git a/newlib/configure b/newlib/configure index ce2fb55d2..7ab6e3423 100755 --- a/newlib/configure +++ b/newlib/configure @@ -1,11 +1,9 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for newlib 4.1.0. +# Generated by GNU Autoconf 2.69 for newlib 4.1.0. # # -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software -# Foundation, Inc. +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation @@ -134,6 +132,31 @@ export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh @@ -167,7 +190,8 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi -test x\$exitcode = x0 || exit 1" +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && @@ -220,21 +244,25 @@ IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : - # We cannot yet assume a decent shell, so we have to provide a - # neutralization value for shells without unset; and this also - # works around shells that cannot unset nonexistent variables. - # Preserve -v and -x to the replacement shell. - BASH_ENV=/dev/null - ENV=/dev/null - (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV - export CONFIG_SHELL - case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; - esac - exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 fi if test x$as_have_required = xno; then : @@ -336,6 +364,14 @@ $as_echo X"$as_dir" | } # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take @@ -457,6 +493,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). @@ -491,16 +531,16 @@ if (echo >conf$$.file) 2>/dev/null; then # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. + # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' + as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -512,28 +552,8 @@ else as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -762,6 +782,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -808,6 +829,7 @@ enable_lite_exit enable_newlib_nano_formatted_io enable_newlib_retargetable_locking enable_newlib_long_time_t +enable_newlib_use_gdtoa enable_multilib enable_target_optspace enable_malloc_debugging @@ -877,6 +899,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1129,6 +1152,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1266,7 +1298,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1294,8 +1326,6 @@ target=$target_alias if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe - $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi @@ -1421,6 +1451,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -1483,6 +1514,7 @@ Optional Features: --enable-newlib-nano-formatted-io Use nano version formatted IO --enable-newlib-retargetable-locking Allow locking routines to be retargeted at link time --enable-newlib-long-time_t define time_t to long + --enable-newlib-use-gdtoa Use gdtoa rather than legacy ldtoa --enable-multilib build many library versions (default) --enable-target-optspace optimize for space --enable-malloc-debugging indicate malloc debugging requested @@ -1588,9 +1620,9 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF newlib configure 4.1.0 -generated by GNU Autoconf 2.68 +generated by GNU Autoconf 2.69 -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1666,7 +1698,7 @@ $as_echo "$ac_try_echo"; } >&5 test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext + test -x conftest$ac_exeext }; then : ac_retval=0 else @@ -1866,7 +1898,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by newlib $as_me 4.1.0, which was -generated by GNU Autoconf 2.68. Invocation command line was +generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2532,6 +2564,19 @@ else newlib_long_time_t=no fi +# Check whether --enable-newlib-use-gdtoa was given. +if test "${enable_newlib_use_gdtoa+set}" = set; then : + enableval=$enable_newlib_use_gdtoa; if test "${newlib_use_gdtoa+set}" != set; then + case "${enableval}" in + yes) newlib_use_gdtoa=yes ;; + no) newlib_use_gdtoa=no ;; + *) as_fn_error $? "bad value ${enableval} for newlib-use-gdtoa option" "$LINENO" 5 ;; + esac + fi +else + newlib_use_gdtoa=yes +fi + # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || @@ -2643,7 +2688,7 @@ case $as_dir/ in #(( # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. @@ -2812,7 +2857,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2852,7 +2897,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2903,7 +2948,7 @@ do test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do - { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ @@ -2956,7 +3001,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3296,7 +3341,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3464,7 +3509,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue @@ -3642,7 +3687,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AS="${ac_tool_prefix}as" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3682,7 +3727,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AS="as" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3734,7 +3779,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="${ac_tool_prefix}ar" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3774,7 +3819,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="ar" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3826,7 +3871,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3866,7 +3911,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3918,7 +3963,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_READELF="${ac_tool_prefix}readelf" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3958,7 +4003,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_READELF="readelf" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4146,7 +4191,7 @@ do for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue + as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in @@ -4276,7 +4321,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4322,7 +4367,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AS="${ac_tool_prefix}as" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4362,7 +4407,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AS="as" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4414,7 +4459,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4454,7 +4499,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4506,7 +4551,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4546,7 +4591,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4668,7 +4713,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4708,7 +4753,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4761,7 +4806,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4802,7 +4847,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue @@ -4860,7 +4905,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4904,7 +4949,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5350,8 +5395,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include -#include -#include +struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); @@ -5580,7 +5624,7 @@ do for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue + as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in @@ -5646,7 +5690,7 @@ do for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue + as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in @@ -5713,7 +5757,7 @@ do for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue + as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in @@ -5969,7 +6013,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6013,7 +6057,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6353,7 +6397,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6393,7 +6437,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6670,7 +6714,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="${ac_tool_prefix}ar" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6710,7 +6754,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="ar" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6775,7 +6819,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6815,7 +6859,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6874,7 +6918,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6914,7 +6958,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7504,7 +7548,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7544,7 +7588,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7596,7 +7640,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7636,7 +7680,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7688,7 +7732,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7728,7 +7772,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7780,7 +7824,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7820,7 +7864,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7872,7 +7916,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7912,7 +7956,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -11855,7 +11899,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11858 "configure" +#line 11902 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11961,7 +12005,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11964 "configure" +#line 12008 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12586,6 +12630,13 @@ _ACEOF fi +if test "${newlib_use_gdtoa}" = "yes"; then +cat >>confdefs.h <<_ACEOF +#define _WANT_USE_GDTOA 1 +_ACEOF + +fi + if test "x${iconv_encodings}" != "x" \ || test "x${iconv_to_encodings}" != "x" \ @@ -13302,16 +13353,16 @@ if (echo >conf$$.file) 2>/dev/null; then # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. + # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' + as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -13371,28 +13422,16 @@ else as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -13414,7 +13453,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # values after options handling. ac_log=" This file was extended by newlib $as_me 4.1.0, which was -generated by GNU Autoconf 2.68. Invocation command line was +generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -13480,10 +13519,10 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ newlib config.status 4.1.0 -configured by $0, generated by GNU Autoconf 2.68, +configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -13574,7 +13613,7 @@ fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then - set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' diff --git a/newlib/configure.ac b/newlib/configure.ac index 49a1b5fdd..25f6d07ed 100644 --- a/newlib/configure.ac +++ b/newlib/configure.ac @@ -259,6 +259,17 @@ AC_ARG_ENABLE(newlib-long-time_t, esac fi], [newlib_long_time_t=no])dnl +dnl Support --enable-newlib-use-gdtoa +AC_ARG_ENABLE(newlib-use-gdtoa, +[ --enable-newlib-use-gdtoa Use gdtoa rather than legacy ldtoa], +[if test "${newlib_use_gdtoa+set}" != set; then + case "${enableval}" in + yes) newlib_use_gdtoa=yes ;; + no) newlib_use_gdtoa=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for newlib-use-gdtoa option) ;; + esac + fi], [newlib_use_gdtoa=yes])dnl + NEWLIB_CONFIGURE(.) dnl We have to enable libtool after NEWLIB_CONFIGURE because if we try and @@ -537,6 +548,10 @@ if test "${newlib_long_time_t}" = "yes"; then AC_DEFINE_UNQUOTED(_WANT_USE_LONG_TIME_T) fi +if test "${newlib_use_gdtoa}" = "yes"; then +AC_DEFINE_UNQUOTED(_WANT_USE_GDTOA) +fi + dnl dnl Parse --enable-newlib-iconv-encodings option argument dnl diff --git a/newlib/libc/include/machine/ieee.h b/newlib/libc/include/machine/ieee.h new file mode 100644 index 000000000..0656909ab --- /dev/null +++ b/newlib/libc/include/machine/ieee.h @@ -0,0 +1,127 @@ +#ifndef _MACHINE_IEEE_H_ +#define _MACHINE_IEEE_H_ +#include +#include +#include +#include + +#if LDBL_MANT_DIG == 24 +#define EXT_IMPLICIT_NBIT +#define EXT_TO_ARRAY32(p, a) do { \ + (a)[0] = (p)->ext_frac; \ +} while (0) +#ifdef __IEEE_LITTLE_ENDIAN +struct ieee_ext { + uint32_t ext_frac:23; + uint32_t ext_exp:8; + uint32_t ext_sign:1; +}; +#endif +#ifdef __IEEE_BIG_ENDIAN +struct ieee_ext { +#ifndef ___IEEE_BYTES_LITTLE_ENDIAN + uint32_t ext_sign:1; + uint32_t ext_exp:8; + uint32_t ext_frac:23; +#else /* ARMEL without __VFP_FP__ */ + uint32_t ext_frac:23; + uint32_t ext_exp:8; + uint32_t ext_sign:1; +#endif +}; +#endif +#elif LDBL_MANT_DIG == 53 +#define EXT_IMPLICIT_NBIT +#define EXT_TO_ARRAY32(p, a) do { \ + (a)[0] = (p)->ext_fracl; \ + (a)[1] = (p)->ext_frach; \ +} while (0) +#ifdef __IEEE_LITTLE_ENDIAN +struct ieee_ext { + uint32_t ext_fracl; + uint32_t ext_frach:20; + uint32_t ext_exp:11; + uint32_t ext_sign:1; +}; +#endif +#ifdef __IEEE_BIG_ENDIAN +struct ieee_ext { +#ifndef ___IEEE_BYTES_LITTLE_ENDIAN + uint32_t ext_sign:1; + uint32_t ext_exp:11; + uint32_t ext_frach:20; +#else /* ARMEL without __VFP_FP__ */ + uint32_t ext_frach:20; + uint32_t ext_exp:11; + uint32_t ext_sign:1; +#endif + uint32_t ext_fracl; +}; +#endif +#elif LDBL_MANT_DIG == 64 +#define EXT_TO_ARRAY32(p, a) do { \ + (a)[0] = (p)->ext_fracl; \ + (a)[1] = (p)->ext_frach; \ +} while (0) +#ifdef __IEEE_LITTLE_ENDIAN /* for Intel CPU */ +struct ieee_ext { + uint32_t ext_fracl; + uint32_t ext_frach; + uint32_t ext_exp:15; + uint32_t ext_sign:1; + uint32_t ext_padl:16; + uint32_t ext_padh; +}; +#endif +#ifdef __IEEE_BIG_ENDIAN +struct ieee_ext { +#ifndef ___IEEE_BYTES_LITTLE_ENDIAN /* for m68k */ + uint32_t ext_sign:1; + uint32_t ext_exp:15; + uint32_t ext_pad:16; +#else /* ARM FPA10 math coprocessor */ + uint32_t ext_exp:15; + uint32_t ext_pad:16; + uint32_t ext_sign:1; +#endif + uint32_t ext_frach; + uint32_t ext_fracl; +}; +#endif +#elif LDBL_MANT_DIG == 113 +#define EXT_IMPLICIT_NBIT +#define EXT_TO_ARRAY32(p, a) do { \ + (a)[0] = (p)->ext_fracl; \ + (a)[1] = (p)->ext_fraclm; \ + (a)[2] = (p)->ext_frachm; \ + (a)[3] = (p)->ext_frach; \ +} while (0) +#ifdef __IEEE_LITTLE_ENDIAN +struct ieee_ext { + uint32_t ext_fracl; + uint32_t ext_fraclm; + uint32_t ext_frachm; + uint32_t ext_frach:16; + uint32_t ext_exp:15; + uint32_t ext_sign:1; +}; +#endif +#ifdef __IEEE_BIG_ENDIAN +struct ieee_ext { +#ifndef ___IEEE_BYTES_LITTLE_ENDIAN + uint32_t ext_sign:1; + uint32_t ext_exp:15; + uint32_t ext_frach:16; +#else /* ARMEL without __VFP_FP__ */ + uint32_t ext_frach:16; + uint32_t ext_exp:15; + uint32_t ext_sign:1; +#endif + uint32_t ext_frachm; + uint32_t ext_fraclm; + uint32_t ext_fracl; +}; +#endif +#endif + +#endif /* _MACHINE_IEEE_H_ */ diff --git a/newlib/libc/include/sys/config.h b/newlib/libc/include/sys/config.h index b9dff88ff..61a6f95d8 100644 --- a/newlib/libc/include/sys/config.h +++ b/newlib/libc/include/sys/config.h @@ -293,6 +293,12 @@ #endif #endif +#ifdef _WANT_USE_GDTOA +#ifndef _USE_GDTOA +#define _USE_GDTOA +#endif +#endif + /* If _MB_EXTENDED_CHARSETS_ALL is set, we want all of the extended charsets. The extended charsets add a few functions and a couple of tables of a few K each. */ diff --git a/newlib/libc/stdlib/Makefile.am b/newlib/libc/stdlib/Makefile.am index 357e37beb..2f46c837c 100644 --- a/newlib/libc/stdlib/Makefile.am +++ b/newlib/libc/stdlib/Makefile.am @@ -38,6 +38,10 @@ GENERAL_SOURCES = \ labs.c \ ldiv.c \ ldtoa.c \ + gdtoa-ldtoa.c \ + gdtoa-gdtoa.c \ + gdtoa-dmisc.c \ + gdtoa-gmisc.c \ malloc.c \ mblen.c \ mblen_r.c \ @@ -311,7 +315,11 @@ CHEWOUT_FILES= \ CHAPTERS = stdlib.tex $(lpfx)dtoa.$(oext): dtoa.c mprec.h -$(lpfx)ldtoa.$(oext): ldtoa.c mprec.h +$(lpfx)ldtoa.$(oext): ldtoa.c mprec.h gdtoa.h +$(lpfx)gdtoa-ldtoa.$(oext): gdtoa-ldtoa.c mprec.h gdtoaimp.h gdtoa.h +$(lpfx)gdtoa-gdtoa.$(oext): gdtoa-gdtoa.c mprec.h gdtoaimp.h gdtoa.h +$(lpfx)gdtoa-dmisc.$(oext): gdtoa-dmisc.c mprec.h gdtoaimp.h gdtoa.h +$(lpfx)gdtoa-gmisc.$(oext): gdtoa-gmisc.c mprec.h gdtoaimp.h gdtoa.h $(lpfx)ecvtbuf.$(oext): ecvtbuf.c mprec.h $(lpfx)mbtowc_r.$(oext): mbtowc_r.c mbctype.h $(lpfx)mprec.$(oext): mprec.c mprec.h diff --git a/newlib/libc/stdlib/Makefile.in b/newlib/libc/stdlib/Makefile.in index a812b6a95..7d3342a67 100644 --- a/newlib/libc/stdlib/Makefile.in +++ b/newlib/libc/stdlib/Makefile.in @@ -101,7 +101,9 @@ am__objects_2 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \ lib_a-getenv_r.$(OBJEXT) lib_a-imaxabs.$(OBJEXT) \ lib_a-imaxdiv.$(OBJEXT) lib_a-itoa.$(OBJEXT) \ lib_a-labs.$(OBJEXT) lib_a-ldiv.$(OBJEXT) \ - lib_a-ldtoa.$(OBJEXT) lib_a-malloc.$(OBJEXT) \ + lib_a-ldtoa.$(OBJEXT) lib_a-gdtoa-ldtoa.$(OBJEXT) \ + lib_a-gdtoa-gdtoa.$(OBJEXT) lib_a-gdtoa-dmisc.$(OBJEXT) \ + lib_a-gdtoa-gmisc.$(OBJEXT) lib_a-malloc.$(OBJEXT) \ lib_a-mblen.$(OBJEXT) lib_a-mblen_r.$(OBJEXT) \ lib_a-mbstowcs.$(OBJEXT) lib_a-mbstowcs_r.$(OBJEXT) \ lib_a-mbtowc.$(OBJEXT) lib_a-mbtowc_r.$(OBJEXT) \ @@ -165,6 +167,7 @@ am__objects_9 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \ div.lo dtoa.lo dtoastub.lo environ.lo envlock.lo eprintf.lo \ exit.lo gdtoa-gethex.lo gdtoa-hexnan.lo getenv.lo getenv_r.lo \ imaxabs.lo imaxdiv.lo itoa.lo labs.lo ldiv.lo ldtoa.lo \ + gdtoa-ldtoa.lo gdtoa-gdtoa.lo gdtoa-dmisc.lo gdtoa-gmisc.lo \ malloc.lo mblen.lo mblen_r.lo mbstowcs.lo mbstowcs_r.lo \ mbtowc.lo mbtowc_r.lo mlock.lo mprec.lo mstats.lo \ on_exit_args.lo quick_exit.lo rand.lo rand_r.lo random.lo \ @@ -354,6 +357,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ shared_machine_dir = @shared_machine_dir@ sharedstatedir = @sharedstatedir@ @@ -372,13 +376,14 @@ GENERAL_SOURCES = __adjust.c __atexit.c __call_atexit.c __exp10.c \ atexit.c atof.c atoff.c atoi.c atol.c calloc.c div.c dtoa.c \ dtoastub.c environ.c envlock.c eprintf.c exit.c gdtoa-gethex.c \ gdtoa-hexnan.c getenv.c getenv_r.c imaxabs.c imaxdiv.c itoa.c \ - labs.c ldiv.c ldtoa.c malloc.c mblen.c mblen_r.c mbstowcs.c \ - mbstowcs_r.c mbtowc.c mbtowc_r.c mlock.c mprec.c mstats.c \ - on_exit_args.c quick_exit.c rand.c rand_r.c random.c realloc.c \ - reallocarray.c reallocf.c sb_charsets.c strtod.c strtoimax.c \ - strtol.c strtoul.c strtoumax.c utoa.c wcstod.c wcstoimax.c \ - wcstol.c wcstoul.c wcstoumax.c wcstombs.c wcstombs_r.c \ - wctomb.c wctomb_r.c $(am__append_1) + labs.c ldiv.c ldtoa.c gdtoa-ldtoa.c gdtoa-gdtoa.c \ + gdtoa-dmisc.c gdtoa-gmisc.c malloc.c mblen.c mblen_r.c \ + mbstowcs.c mbstowcs_r.c mbtowc.c mbtowc_r.c mlock.c mprec.c \ + mstats.c on_exit_args.c quick_exit.c rand.c rand_r.c random.c \ + realloc.c reallocarray.c reallocf.c sb_charsets.c strtod.c \ + strtoimax.c strtol.c strtoul.c strtoumax.c utoa.c wcstod.c \ + wcstoimax.c wcstol.c wcstoul.c wcstoumax.c wcstombs.c \ + wcstombs_r.c wctomb.c wctomb_r.c $(am__append_1) @NEWLIB_NANO_MALLOC_FALSE@MALIGNR = malignr @NEWLIB_NANO_MALLOC_TRUE@MALIGNR = nano-malignr @NEWLIB_NANO_MALLOC_FALSE@MALLOPTR = malloptr @@ -827,6 +832,30 @@ lib_a-ldtoa.o: ldtoa.c lib_a-ldtoa.obj: ldtoa.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-ldtoa.obj `if test -f 'ldtoa.c'; then $(CYGPATH_W) 'ldtoa.c'; else $(CYGPATH_W) '$(srcdir)/ldtoa.c'; fi` +lib_a-gdtoa-ldtoa.o: gdtoa-ldtoa.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-gdtoa-ldtoa.o `test -f 'gdtoa-ldtoa.c' || echo '$(srcdir)/'`gdtoa-ldtoa.c + +lib_a-gdtoa-ldtoa.obj: gdtoa-ldtoa.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-gdtoa-ldtoa.obj `if test -f 'gdtoa-ldtoa.c'; then $(CYGPATH_W) 'gdtoa-ldtoa.c'; else $(CYGPATH_W) '$(srcdir)/gdtoa-ldtoa.c'; fi` + +lib_a-gdtoa-gdtoa.o: gdtoa-gdtoa.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-gdtoa-gdtoa.o `test -f 'gdtoa-gdtoa.c' || echo '$(srcdir)/'`gdtoa-gdtoa.c + +lib_a-gdtoa-gdtoa.obj: gdtoa-gdtoa.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-gdtoa-gdtoa.obj `if test -f 'gdtoa-gdtoa.c'; then $(CYGPATH_W) 'gdtoa-gdtoa.c'; else $(CYGPATH_W) '$(srcdir)/gdtoa-gdtoa.c'; fi` + +lib_a-gdtoa-dmisc.o: gdtoa-dmisc.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-gdtoa-dmisc.o `test -f 'gdtoa-dmisc.c' || echo '$(srcdir)/'`gdtoa-dmisc.c + +lib_a-gdtoa-dmisc.obj: gdtoa-dmisc.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-gdtoa-dmisc.obj `if test -f 'gdtoa-dmisc.c'; then $(CYGPATH_W) 'gdtoa-dmisc.c'; else $(CYGPATH_W) '$(srcdir)/gdtoa-dmisc.c'; fi` + +lib_a-gdtoa-gmisc.o: gdtoa-gmisc.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-gdtoa-gmisc.o `test -f 'gdtoa-gmisc.c' || echo '$(srcdir)/'`gdtoa-gmisc.c + +lib_a-gdtoa-gmisc.obj: gdtoa-gmisc.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-gdtoa-gmisc.obj `if test -f 'gdtoa-gmisc.c'; then $(CYGPATH_W) 'gdtoa-gmisc.c'; else $(CYGPATH_W) '$(srcdir)/gdtoa-gmisc.c'; fi` + lib_a-malloc.o: malloc.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-malloc.o `test -f 'malloc.c' || echo '$(srcdir)/'`malloc.c @@ -1610,7 +1639,11 @@ $(lpfx)$(MALLOPTR).$(oext): $(MALLOCR).c $(MALLOC_COMPILE) -DDEFINE_MALLOPT -c $(srcdir)/$(MALLOCR).c -o $@ $(lpfx)dtoa.$(oext): dtoa.c mprec.h -$(lpfx)ldtoa.$(oext): ldtoa.c mprec.h +$(lpfx)ldtoa.$(oext): ldtoa.c mprec.h gdtoa.h +$(lpfx)gdtoa-ldtoa.$(oext): gdtoa-ldtoa.c mprec.h gdtoaimp.h gdtoa.h +$(lpfx)gdtoa-gdtoa.$(oext): gdtoa-gdtoa.c mprec.h gdtoaimp.h gdtoa.h +$(lpfx)gdtoa-dmisc.$(oext): gdtoa-dmisc.c mprec.h gdtoaimp.h gdtoa.h +$(lpfx)gdtoa-gmisc.$(oext): gdtoa-gmisc.c mprec.h gdtoaimp.h gdtoa.h $(lpfx)ecvtbuf.$(oext): ecvtbuf.c mprec.h $(lpfx)mbtowc_r.$(oext): mbtowc_r.c mbctype.h $(lpfx)mprec.$(oext): mprec.c mprec.h diff --git a/newlib/libc/stdlib/gdtoa-dmisc.c b/newlib/libc/stdlib/gdtoa-dmisc.c new file mode 100644 index 000000000..332023dae --- /dev/null +++ b/newlib/libc/stdlib/gdtoa-dmisc.c @@ -0,0 +1,230 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 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 +#include + +#ifdef _USE_GDTOA +#include "gdtoaimp.h" + +#ifndef MULTIPLE_THREADS + char *dtoa_result; +#endif + + char * +#ifdef KR_headers +rv_alloc(ptr, i) struct _reent *ptr, int i; +#else +rv_alloc(struct _reent *ptr, int i) +#endif +{ + int j, k, *r; + + j = sizeof(ULong); + for(k = 0; + sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i; + j <<= 1) + k++; + r = (int*)Balloc(ptr, k); + if (r == NULL) + return ( +#ifndef MULTIPLE_THREADS + dtoa_result = +#endif + NULL); + *r = k; + return +#ifndef MULTIPLE_THREADS + dtoa_result = +#endif + (char *)(r+1); + } + + char * +#ifdef KR_headers +nrv_alloc(ptr, s, rve, n) struct _reent *ptr, char *s, **rve; int n; +#else +nrv_alloc(struct _reent *ptr, char *s, char **rve, int n) +#endif +{ + char *rv, *t; + + t = rv = rv_alloc(ptr, n); + if (t == NULL) + return (NULL); + while((*t = *s++) !=0) + t++; + if (rve) + *rve = t; + return rv; + } + +/* freedtoa(s) must be used to free values s returned by dtoa + * when MULTIPLE_THREADS is #defined. It should be used in all cases, + * but for consistency with earlier versions of dtoa, it is optional + * when MULTIPLE_THREADS is not defined. + */ + + void +#ifdef KR_headers +freedtoa(ptr, s) struct _reent *ptr, char *s; +#else +freedtoa(struct _reent *ptr, char *s) +#endif +{ + Bigint *b = (Bigint *)((int *)s - 1); + b->_maxwds = 1 << (b->_k = *(int*)b); + Bfree(ptr, b); +#ifndef MULTIPLE_THREADS + if (s == dtoa_result) + dtoa_result = 0; +#endif + } +DEF_STRONG(freedtoa); + + int +quorem +#ifdef KR_headers + (b, S) Bigint *b, *S; +#else + (Bigint *b, Bigint *S) +#endif +{ + int n; + ULong *bx, *bxe, q, *sx, *sxe; +#ifdef ULLong + ULLong borrow, carry, y, ys; +#else + ULong borrow, carry, y, ys; +#ifdef Pack_32 + ULong si, z, zs; +#endif +#endif + + n = S->_wds; +#ifdef DEBUG + /*debug*/ if (b->_wds > n) + /*debug*/ Bug("oversize b in quorem"); +#endif + if (b->_wds < n) + return 0; + sx = S->_x; + sxe = sx + --n; + bx = b->_x; + bxe = bx + n; + q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ +#ifdef DEBUG + /*debug*/ if (q > 9) + /*debug*/ Bug("oversized quotient in quorem"); +#endif + if (q) { + borrow = 0; + carry = 0; + do { +#ifdef ULLong + ys = *sx++ * (ULLong)q + carry; + carry = ys >> 32; + y = *bx - (ys & 0xffffffffUL) - borrow; + borrow = y >> 32 & 1UL; + *bx++ = y & 0xffffffffUL; +#else +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) * q + carry; + zs = (si >> 16) * q + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ * q + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } + while(sx <= sxe); + if (!*bxe) { + bx = b->_x; + while(--bxe > bx && !*bxe) + --n; + b->_wds = n; + } + } + if (cmp(b, S) >= 0) { + q++; + borrow = 0; + carry = 0; + bx = b->_x; + sx = S->_x; + do { +#ifdef ULLong + ys = *sx++ + carry; + carry = ys >> 32; + y = *bx - (ys & 0xffffffffUL) - borrow; + borrow = y >> 32 & 1UL; + *bx++ = y & 0xffffffffUL; +#else +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) + carry; + zs = (si >> 16) + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } + while(sx <= sxe); + bx = b->_x; + bxe = bx + n; + if (!*bxe) { + while(--bxe > bx && !*bxe) + --n; + b->_wds = n; + } + } + return q; + } +#endif /* _USE_GDTOA */ diff --git a/newlib/libc/stdlib/gdtoa-gdtoa.c b/newlib/libc/stdlib/gdtoa-gdtoa.c new file mode 100644 index 000000000..da2338c48 --- /dev/null +++ b/newlib/libc/stdlib/gdtoa-gdtoa.c @@ -0,0 +1,837 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998, 1999 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 +#include + +#ifdef _USE_GDTOA +#include "gdtoaimp.h" + + static Bigint * +#ifdef KR_headers +bitstob(ptr, bits, nbits, bbits) ULong *bits; +struct _reent ptr, int nbits; int *bbits; +#else +bitstob(struct _reent *ptr, ULong *bits, int nbits, int *bbits) +#endif +{ + int i, k; + Bigint *b; + ULong *be, *x, *x0; + + i = ULbits; + k = 0; + while(i < nbits) { + i <<= 1; + k++; + } +#ifndef Pack_32 + if (!k) + k = 1; +#endif + b = Balloc(ptr, k); + if (b == NULL) + return (NULL); + be = bits + ((nbits - 1) >> kshift); + x = x0 = b->_x; + do { + *x++ = *bits & ALL_ON; +#ifdef Pack_16 + *x++ = (*bits >> 16) & ALL_ON; +#endif + } while(++bits <= be); + i = x - x0; + while(!x0[--i]) + if (!i) { + b->_wds = 0; + *bbits = 0; + goto ret; + } + b->_wds = i + 1; + *bbits = i*ULbits + 32 - hi0bits(b->_x[i]); + ret: + return b; + } + +/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. + * + * Inspired by "How to Print Floating-Point Numbers Accurately" by + * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. + * + * Modifications: + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the Long + * calculation. + */ + + char * +gdtoa +#ifdef KR_headers + (ptr, fpi, be, bits, kindp, mode, ndigits, decpt, rve) + struct _reent *ptr, FPI *fpi; int be; ULong *bits; + int *kindp, mode, ndigits, *decpt; char **rve; +#else + (struct _reent *ptr, FPI *fpi, int be, ULong *bits, int *kindp, + int mode, int ndigits, int *decpt, char **rve) +#endif +{ + /* Arguments ndigits and decpt are similar to the second and third + arguments of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to 9999. + be = exponent: value = (integer represented by bits) * (2 to the power of be). + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4-9 should give the same return values as 2-3, i.e., + 4 <= mode <= 9 ==> same return as mode + 2 + (mode & 1). These modes are mainly for + debugging; often they run slower but sometimes + faster than modes 2-3. + 4,5,8,9 ==> left-to-right digit generation. + 6-9 ==> don't try fast floating-point estimate + (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + */ + + int bbits, b2, b5, be0, dig, i, ieps, ilim, ilim0, ilim1, inex; + int j, j1, k, k0, k_check, kind, leftright, m2, m5, nbits; + int rdir, s2, s5, spec_case, try_quick; + Long L; + Bigint *b, *b1, *delta, *mlo, *mhi, *mhi1, *S; + double d2, ds; + char *s, *s0; + U d, eps; + +#ifndef MULTIPLE_THREADS + if (dtoa_result) { + freedtoa(ptr, dtoa_result); + dtoa_result = 0; + } +#endif + inex = 0; + kind = *kindp &= ~STRTOG_Inexact; + switch(kind & STRTOG_Retmask) { + case STRTOG_Zero: + goto ret_zero; + case STRTOG_Normal: + case STRTOG_Denormal: + break; + case STRTOG_Infinite: + *decpt = -32768; + return nrv_alloc(ptr, "Infinity", rve, 8); + case STRTOG_NaN: + *decpt = -32768; + return nrv_alloc(ptr, "NaN", rve, 3); + default: + return 0; + } + b = bitstob(ptr, bits, nbits = fpi->nbits, &bbits); + if (b == NULL) + return (NULL); + be0 = be; + if ( (i = trailz(b)) !=0) { + rshift(b, i); + be += i; + bbits -= i; + } + if (!b->_wds) { + Bfree(ptr, b); + ret_zero: + *decpt = 1; + return nrv_alloc(ptr, "0", rve, 1); + } + + dval(d) = b2d(b, &i); + i = be + bbits - 1; + word0(d) &= Frac_mask1; + word0(d) |= Exp_11; +#ifdef IBM + if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0) + dval(d) /= 1 << j; +#endif + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 + * log10(x) = log(x) / log(10) + * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) + * log10(&d) = (i-Bias)*log(2)/log(10) + log10(d2) + * + * This suggests computing an approximation k to log10(&d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ +#ifdef IBM + i <<= 2; + i += j; +#endif + ds = (dval(d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + + /* correct assumption about exponent range */ + if ((j = i) < 0) + j = -j; + if ((j -= 1077) > 0) + ds += j * 7e-17; + + k = (int)ds; + if (ds < 0. && ds != k) + k--; /* want k = floor(ds) */ + k_check = 1; +#ifdef IBM + j = be + bbits - 1; + if ( (j1 = j & 3) !=0) + dval(d) *= 1 << j1; + word0(d) += j << Exp_shift - 2 & Exp_mask; +#else + word0(d) += (be + bbits - 1) << Exp_shift; +#endif + if (k >= 0 && k <= Ten_pmax) { + if (dval(d) < tens[k]) + k--; + k_check = 0; + } + j = bbits - i - 1; + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } + if (mode < 0 || mode > 9) + mode = 0; + try_quick = 1; + if (mode > 5) { + mode -= 4; + try_quick = 0; + } + else if (i >= -4 - Emin || i < Emin) + try_quick = 0; + leftright = 1; + ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */ + /* silence erroneous "gcc -Wall" warning. */ + switch(mode) { + case 0: + case 1: + i = (int)(nbits * .30103) + 3; + ndigits = 0; + break; + case 2: + leftright = 0; + /* no break */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* no break */ + case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + s = s0 = rv_alloc(ptr, i); + if (s == NULL) + return (NULL); + + if ( (rdir = fpi->rounding - 1) !=0) { + if (rdir < 0) + rdir = 2; + if (kind & STRTOG_Neg) + rdir = 3 - rdir; + } + + /* Now rdir = 0 ==> round near, 1 ==> round up, 2 ==> round down. */ + + if (ilim >= 0 && ilim <= Quick_max && try_quick && !rdir +#ifndef IMPRECISE_INEXACT + && k == 0 +#endif + ) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + d2 = dval(d); +#ifdef IBM + if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0) + dval(d) /= 1 << j; +#endif + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + dval(d) /= bigtens[n_bigtens-1]; + ieps++; + } + for(; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + } + else { + ds = 1.; + if ( (j1 = -k) !=0) { + dval(d) *= tens[j1 & 0xf]; + for(j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + dval(d) *= bigtens[i]; + } + } + } + if (k_check && dval(d) < 1. && ilim > 0) { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + dval(d) *= 10.; + ieps++; + } + dval(eps) = ieps*dval(d) + 7.; + word0(eps) -= (P-1)*Exp_msk1; + if (ilim == 0) { + S = mhi = 0; + dval(d) -= 5.; + if (dval(d) > dval(eps)) + goto one_digit; + if (dval(d) < -dval(eps)) + goto no_digits; + goto fast_failed; + } +#ifndef No_leftright + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + dval(eps) = ds*0.5/tens[ilim-1] - dval(eps); + for(i = 0;;) { + L = (Long)(dval(d)/ds); + dval(d) -= L*ds; + *s++ = '0' + (int)L; + if (dval(d) < dval(eps)) { + if (dval(d)) + inex = STRTOG_Inexlo; + goto ret1; + } + if (ds - dval(d) < dval(eps)) + goto bump_up; + if (++i >= ilim) + break; + dval(eps) *= 10.; + dval(d) *= 10.; + } + } + else { +#endif + /* Generate ilim digits, then fix them up. */ + dval(eps) *= tens[ilim-1]; + for(i = 1;; i++, dval(d) *= 10.) { + if ( (L = (Long)(dval(d)/ds)) !=0) + dval(d) -= L*ds; + *s++ = '0' + (int)L; + if (i == ilim) { + ds *= 0.5; + if (dval(d) > ds + dval(eps)) + goto bump_up; + else if (dval(d) < ds - dval(eps)) { + if (dval(d)) + inex = STRTOG_Inexlo; + goto clear_trailing0; + } + break; + } + } +#ifndef No_leftright + } +#endif + fast_failed: + s = s0; + dval(d) = d2; + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + if (ilim < 0 || dval(d) <= 5*ds) + goto no_digits; + goto one_digit; + } + for(i = 1;; i++, dval(d) *= 10.) { + L = dval(d) / ds; + dval(d) -= L*ds; +#ifdef Check_FLT_ROUNDS + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (dval(d) < 0) { + L--; + dval(d) += ds; + } +#endif + *s++ = '0' + (int)L; + if (dval(d) == 0.) + break; + if (i == ilim) { + if (rdir) { + if (rdir == 1) + goto bump_up; + inex = STRTOG_Inexlo; + goto ret1; + } + dval(d) += dval(d); +#ifdef ROUND_BIASED + if (dval(d) >= ds) +#else + if (dval(d) > ds || (dval(d) == ds && L & 1)) +#endif + { + bump_up: + inex = STRTOG_Inexhi; + while(*--s == '9') + if (s == s0) { + k++; + *s = '0'; + break; + } + ++*s++; + } + else { + inex = STRTOG_Inexlo; + clear_trailing0: + while(*--s == '0'){} + ++s; + } + break; + } + } + goto ret1; + } + + m2 = b2; + m5 = b5; + mhi = mlo = 0; + if (leftright) { + i = nbits - bbits; + if (be - i++ < fpi->emin && mode != 3 && mode != 5) { + /* denormal */ + i = be - fpi->emin + 1; + if (mode >= 2 && ilim > 0 && ilim < i) + goto small_ilim; + } + else if (mode >= 2) { + small_ilim: + j = ilim - 1; + if (m5 >= j) + m5 -= j; + else { + s5 += j -= m5; + b5 += j; + m5 = 0; + } + if ((i = ilim) < 0) { + m2 -= i; + i = 0; + } + } + b2 += i; + s2 += i; + mhi = i2b(ptr, 1); + if (mhi == NULL) + return (NULL); + } + if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(ptr, mhi, m5); + if (mhi == NULL) + return (NULL); + b1 = mult(ptr, mhi, b); + if (b1 == NULL) + return (NULL); + Bfree(ptr, b); + b = b1; + } + if ( (j = b5 - m5) !=0) { + b = pow5mult(ptr, b, j); + if (b == NULL) + return (NULL); + } + } + else { + b = pow5mult(ptr, b, b5); + if (b == NULL) + return (NULL); + } + } + S = i2b(ptr, 1); + if (S == NULL) + return (NULL); + if (s5 > 0) { + S = pow5mult(ptr, S, s5); + if (S == NULL) + return (NULL); + } + + /* Check for special case that d is a normalized power of 2. */ + + spec_case = 0; + if (mode < 2) { + if (bbits == 1 && be0 > fpi->emin + 1) { + /* The special case */ + b2++; + s2++; + spec_case = 1; + } + } + + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * and for all and pass them and a shift to quorem, so it + * can do shifts and ors to compute the numerator for q. + */ + i = ((s5 ? hi0bits(S->_x[S->_wds-1]) : ULbits - 1) - s2 - 4) & kmask; + m2 += i; + if ((b2 += i) > 0) { + b = lshift(ptr, b, b2); + if (b == NULL) + return (NULL); + } + if ((s2 += i) > 0) { + S = lshift(ptr, S, s2); + if (S == NULL) + return (NULL); + } + if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(ptr, b, 10, 0); /* we botched the k estimate */ + if (b == NULL) + return (NULL); + if (leftright) { + mhi = multadd(ptr, mhi, 10, 0); + if (mhi == NULL) + return (NULL); + } + ilim = ilim1; + } + } + if (ilim <= 0 && mode > 2) { + S = multadd(ptr, S,5,0); + if (S == NULL) + return (NULL); + if (ilim < 0 || cmp(b,S) <= 0) { + /* no digits, fcvt style */ + no_digits: + k = -1 - ndigits; + inex = STRTOG_Inexlo; + goto ret; + } + one_digit: + inex = STRTOG_Inexhi; + *s++ = '1'; + k++; + goto ret; + } + if (leftright) { + if (m2 > 0) { + mhi = lshift(ptr, mhi, m2); + if (mhi == NULL) + return (NULL); + } + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(ptr, mhi->_k); + if (mhi == NULL) + return (NULL); + Bcopy(mhi, mlo); + mhi = lshift(ptr, mhi, 1); + if (mhi == NULL) + return (NULL); + } + + for(i = 1;;i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(ptr, S, mhi); + if (delta == NULL) + return (NULL); + j1 = delta->_sign ? 1 : cmp(b, delta); + Bfree(ptr, delta); +#ifndef ROUND_BIASED + if (j1 == 0 && !mode && !(bits[0] & 1) && !rdir) { + if (dig == '9') + goto round_9_up; + if (j <= 0) { + if (b->_wds > 1 || b->_x[0]) + inex = STRTOG_Inexlo; + } + else { + dig++; + inex = STRTOG_Inexhi; + } + *s++ = dig; + goto ret; + } +#endif + if (j < 0 || (j == 0 && !mode +#ifndef ROUND_BIASED + && !(bits[0] & 1) +#endif + )) { + if (rdir && (b->_wds > 1 || b->_x[0])) { + if (rdir == 2) { + inex = STRTOG_Inexlo; + goto accept; + } + while (cmp(S,mhi) > 0) { + *s++ = dig; + mhi1 = multadd(ptr, mhi, 10, 0); + if (mhi1 == NULL) + return (NULL); + if (mlo == mhi) + mlo = mhi1; + mhi = mhi1; + b = multadd(ptr, b, 10, 0); + if (b == NULL) + return (NULL); + dig = quorem(b,S) + '0'; + } + if (dig++ == '9') + goto round_9_up; + inex = STRTOG_Inexhi; + goto accept; + } + if (j1 > 0) { + b = lshift(ptr, b, 1); + if (b == NULL) + return (NULL); + j1 = cmp(b, S); +#ifdef ROUND_BIASED + if (j1 >= 0 /*)*/ +#else + if ((j1 > 0 || (j1 == 0 && dig & 1)) +#endif + && dig++ == '9') + goto round_9_up; + inex = STRTOG_Inexhi; + } + if (b->_wds > 1 || b->_x[0]) + inex = STRTOG_Inexlo; + accept: + *s++ = dig; + goto ret; + } + if (j1 > 0 && rdir != 2) { + if (dig == '9') { /* possible if i == 1 */ + round_9_up: + *s++ = '9'; + inex = STRTOG_Inexhi; + goto roundoff; + } + inex = STRTOG_Inexhi; + *s++ = dig + 1; + goto ret; + } + *s++ = dig; + if (i == ilim) + break; + b = multadd(ptr, b, 10, 0); + if (b == NULL) + return (NULL); + if (mlo == mhi) { + mlo = mhi = multadd(ptr, mhi, 10, 0); + if (mlo == NULL) + return (NULL); + } + else { + mlo = multadd(ptr, mlo, 10, 0); + if (mlo == NULL) + return (NULL); + mhi = multadd(ptr, mhi, 10, 0); + if (mhi == NULL) + return (NULL); + } + } + } + else + for(i = 1;; i++) { + *s++ = dig = quorem(b,S) + '0'; + if (i >= ilim) + break; + b = multadd(ptr, b, 10, 0); + if (b == NULL) + return (NULL); + } + + /* Round off last digit */ + + if (rdir) { + if (rdir == 2 || (b->_wds <= 1 && !b->_x[0])) + goto chopzeros; + goto roundoff; + } + b = lshift(ptr, b, 1); + if (b == NULL) + return (NULL); + j = cmp(b, S); +#ifdef ROUND_BIASED + if (j >= 0) +#else + if (j > 0 || (j == 0 && dig & 1)) +#endif + { + roundoff: + inex = STRTOG_Inexhi; + while(*--s == '9') + if (s == s0) { + k++; + *s++ = '1'; + goto ret; + } + ++*s++; + } + else { + chopzeros: + if (b->_wds > 1 || b->_x[0]) + inex = STRTOG_Inexlo; + while(*--s == '0'){} + ++s; + } + ret: + Bfree(ptr, S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(ptr, mlo); + Bfree(ptr, mhi); + } + ret1: + Bfree(ptr, b); + *s = 0; + *decpt = k + 1; + if (rve) + *rve = s; + *kindp |= inex; + return s0; + } +DEF_STRONG(gdtoa); +#endif /* _USE_GDTOA */ diff --git a/newlib/libc/stdlib/gdtoa-gmisc.c b/newlib/libc/stdlib/gdtoa-gmisc.c new file mode 100644 index 000000000..40c3c2d13 --- /dev/null +++ b/newlib/libc/stdlib/gdtoa-gmisc.c @@ -0,0 +1,91 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 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 +#include + +#ifdef _USE_GDTOA +#include "gdtoaimp.h" + + void +#ifdef KR_headers +rshift(b, k) Bigint *b; int k; +#else +rshift(Bigint *b, int k) +#endif +{ + ULong *x, *x1, *xe, y; + int n; + + x = x1 = b->_x; + n = k >> kshift; + if (n < b->_wds) { + xe = x + b->_wds; + x += n; + if (k &= kmask) { + n = ULbits - k; + y = *x++ >> k; + while(x < xe) { + *x1++ = (y | (*x << n)) & ALL_ON; + y = *x++ >> k; + } + if ((*x1 = y) !=0) + x1++; + } + else + while(x < xe) + *x1++ = *x++; + } + if ((b->_wds = x1 - b->_x) == 0) + b->_x[0] = 0; + } + + int +#ifdef KR_headers +trailz(b) Bigint *b; +#else +trailz(Bigint *b) +#endif +{ + ULong L, *x, *xe; + int n = 0; + + x = b->_x; + xe = x + b->_wds; + for(n = 0; x < xe && !*x; x++) + n += ULbits; + if (x < xe) { + L = *x; + n += lo0bits(&L); + } + return n; + } +#endif /* _USE_GDTOA */ diff --git a/newlib/libc/stdlib/gdtoa-ldtoa.c b/newlib/libc/stdlib/gdtoa-ldtoa.c new file mode 100644 index 000000000..14b99042c --- /dev/null +++ b/newlib/libc/stdlib/gdtoa-ldtoa.c @@ -0,0 +1,159 @@ +/* $OpenBSD: ldtoa.c,v 1.4 2016/03/09 16:28:47 deraadt Exp $ */ +/*- + * Copyright (c) 2003 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#ifdef _USE_GDTOA +#include +#include +#include +#include +#include +#include +#include +#include "gdtoaimp.h" + +#if (LDBL_MANT_DIG > DBL_MANT_DIG) + +/* + * ldtoa() is a wrapper for gdtoa() that makes it smell like dtoa(), + * except that the floating point argument is passed by reference. + * When dtoa() is passed a NaN or infinity, it sets expt to 9999. + * However, a long double could have a valid exponent of 9999, so we + * use INT_MAX in ldtoa() instead. + */ +char * +_ldtoa_r(struct _reent *ptr, + long double ld, int mode, int ndigits, int *decpt, int *sign, char **rve) +{ + FPI fpi = { + LDBL_MANT_DIG, /* nbits */ + LDBL_MIN_EXP - LDBL_MANT_DIG, /* emin */ + LDBL_MAX_EXP - LDBL_MANT_DIG, /* emax */ + FLT_ROUNDS, /* rounding */ +#ifdef Sudden_Underflow /* unused, but correct anyway */ + 1 +#else + 0 +#endif + }; + int be, kind; + char *ret; + struct ieee_ext *p = (struct ieee_ext *)&ld; + uint32_t bits[(LDBL_MANT_DIG + 31) / 32]; + void *vbits = bits; + + _REENT_CHECK_MP (ptr); + + /* reentrancy addition to use mprec storage pool */ + if (_REENT_MP_RESULT (ptr)) { + _REENT_MP_RESULT (ptr)->_k = _REENT_MP_RESULT_K (ptr); + _REENT_MP_RESULT (ptr)->_maxwds = 1 << _REENT_MP_RESULT_K (ptr); + Bfree (ptr, _REENT_MP_RESULT (ptr)); + _REENT_MP_RESULT (ptr) = 0; + } + + /* + * gdtoa doesn't know anything about the sign of the number, so + * if the number is negative, we need to swap rounding modes of + * 2 (upwards) and 3 (downwards). + */ + *sign = p->ext_sign; + fpi.rounding ^= (fpi.rounding >> 1) & p->ext_sign; + + be = p->ext_exp - (LDBL_MAX_EXP - 1) - (LDBL_MANT_DIG - 1); + EXT_TO_ARRAY32(p, bits); + + switch (fpclassify(ld)) { + case FP_NORMAL: + kind = STRTOG_Normal; +#ifdef EXT_IMPLICIT_NBIT + bits[LDBL_MANT_DIG / 32] |= 1 << ((LDBL_MANT_DIG - 1) % 32); +#endif /* EXT_IMPLICIT_NBIT */ + break; + case FP_ZERO: + kind = STRTOG_Zero; + break; + case FP_SUBNORMAL: + kind = STRTOG_Denormal; + be++; + break; + case FP_INFINITE: + kind = STRTOG_Infinite; + break; + case FP_NAN: + kind = STRTOG_NaN; + break; + default: + abort(); + } + + ret = gdtoa(ptr, &fpi, be, vbits, &kind, mode, ndigits, decpt, rve); + if (*decpt == -32768) + *decpt = INT_MAX; + return ret; +} +DEF_STRONG(_ldtoa_r); + +#else /* (LDBL_MANT_DIG == DBL_MANT_DIG) */ + +char * +_ldtoa_r(struct _reent *ptr, + long double ld, int mode, int ndigits, int *decpt, int *sign, + char **rve) +{ + char *ret; + + ret = _dtoa_r(ptr, (double)ld, mode, ndigits, decpt, sign, rve); + if (*decpt == 9999) + *decpt = INT_MAX; + return ret; +} +DEF_STRONG(_ldtoa_r); + +#endif /* (LDBL_MANT_DIG == DBL_MANT_DIG) */ + +/* Routine used to tell if long double is NaN or Infinity or regular number. + Returns: 0 = regular number + 1 = Nan + 2 = Infinity +*/ +int +_ldcheck (long double *d) +{ + switch (fpclassify(*d)) { + case FP_NAN: + return 1; + case FP_INFINITE: + return 2; + default: + return 0; + } +} + +#endif /* _USE_GDTOA */ diff --git a/newlib/libc/stdlib/gdtoa.h b/newlib/libc/stdlib/gdtoa.h index 07506aac1..f4d2a56db 100644 --- a/newlib/libc/stdlib/gdtoa.h +++ b/newlib/libc/stdlib/gdtoa.h @@ -32,25 +32,55 @@ THIS SOFTWARE. #ifndef GDTOA_H_INCLUDED #define GDTOA_H_INCLUDED +#include /* for size_t */ +#include + +#define PROTO_NORMAL(x) +#define __BEGIN_HIDDEN_DECLS +#define __END_HIDDEN_DECLS +#define DEF_STRONG(x) + +#ifndef ULong +#define ULong __ULong +#endif + +#ifndef ANSI +#ifdef KR_headers +#define ANSI(x) () +#define Void /*nothing*/ +#else +#define ANSI(x) x +#define Void void +#endif +#endif /* ANSI */ + +#ifndef CONST +#ifdef KR_headers +#define CONST /* blank */ +#else +#define CONST const +#endif +#endif /* CONST */ enum { /* return values from strtodg */ - STRTOG_Zero = 0, - STRTOG_Normal = 1, - STRTOG_Denormal = 2, - STRTOG_Infinite = 3, - STRTOG_NaN = 4, - STRTOG_NaNbits = 5, - STRTOG_NoNumber = 6, - STRTOG_Retmask = 7, + STRTOG_Zero = 0x000, + STRTOG_Normal = 0x001, + STRTOG_Denormal = 0x002, + STRTOG_Infinite = 0x003, + STRTOG_NaN = 0x004, + STRTOG_NaNbits = 0x005, + STRTOG_NoNumber = 0x006, + STRTOG_NoMemory = 0x007, + STRTOG_Retmask = 0x00f, /* The following may be or-ed into one of the above values. */ - STRTOG_Neg = 0x08, - STRTOG_Inexlo = 0x10, - STRTOG_Inexhi = 0x20, - STRTOG_Inexact = 0x30, - STRTOG_Underflow= 0x40, - STRTOG_Overflow = 0x80 + STRTOG_Inexlo = 0x010, /* returned result rounded toward zero */ + STRTOG_Inexhi = 0x020, /* returned result rounded away from zero */ + STRTOG_Inexact = 0x030, + STRTOG_Underflow= 0x040, + STRTOG_Overflow = 0x080, + STRTOG_Neg = 0x100 /* does not affect STRTOG_Inexlo or STRTOG_Inexhi */ }; typedef struct @@ -69,6 +99,74 @@ enum { /* FPI.rounding values: same as FLT_ROUNDS */ FPI_Round_down = 3 }; -#endif /* GDTOA_H_INCLUDED */ - typedef unsigned short __UShort; +typedef struct _Bigint Bigint; + +#ifdef __cplusplus +extern "C" { +#endif + +extern char* __dtoa ANSI((struct _reent *ptr, + double d, int mode, int ndigits, int *decpt, + int *sign, char **rve)); +extern char* __gdtoa ANSI((struct _reent *ptr, + FPI *fpi, int be, ULong *bits, int *kindp, + int mode, int ndigits, int *decpt, char **rve)); +extern void __freedtoa ANSI((struct _reent *, char*)); +extern float strtof ANSI((CONST char *, char **)); +extern double strtod ANSI((CONST char *, char **)); +extern int __strtodg ANSI((CONST char*, char**, FPI*, Long*, ULong*)); +char *__hdtoa(double, const char *, int, int *, int *, char **); +char *__hldtoa(long double, const char *, int, int *, int *, char **); +char *__ldtoa(struct _reent *ptr, + long double *, int, int, int *, int *, char **); + +PROTO_NORMAL(__dtoa); +PROTO_NORMAL(__gdtoa); +PROTO_NORMAL(__freedtoa); +PROTO_NORMAL(__hdtoa); +PROTO_NORMAL(__hldtoa); +PROTO_NORMAL(__ldtoa); + +__BEGIN_HIDDEN_DECLS +extern char* __g_ddfmt ANSI((char*, double*, int, size_t)); +extern char* __g_dfmt ANSI((char*, double*, int, size_t)); +extern char* __g_ffmt ANSI((char*, float*, int, size_t)); +extern char* __g_Qfmt ANSI((char*, void*, int, size_t)); +extern char* __g_xfmt ANSI((char*, void*, int, size_t)); +extern char* __g_xLfmt ANSI((char*, void*, int, size_t)); + +extern int __strtoId ANSI((CONST char*, char**, double*, double*)); +extern int __strtoIdd ANSI((CONST char*, char**, double*, double*)); +extern int __strtoIf ANSI((CONST char*, char**, float*, float*)); +extern int __strtoIQ ANSI((CONST char*, char**, void*, void*)); +extern int __strtoIx ANSI((CONST char*, char**, void*, void*)); +extern int __strtoIxL ANSI((CONST char*, char**, void*, void*)); +extern int __strtord ANSI((CONST char*, char**, int, double*)); +extern int __strtordd ANSI((CONST char*, char**, int, double*)); +extern int __strtorf ANSI((CONST char*, char**, int, float*)); +extern int __strtorQ ANSI((CONST char*, char**, int, void*)); +extern int __strtorx ANSI((CONST char*, char**, int, void*)); +extern int __strtorxL ANSI((CONST char*, char**, int, void*)); +#if 1 +extern int __strtodI ANSI((CONST char*, char**, double*)); +extern int __strtopd ANSI((CONST char*, char**, double*)); +extern int __strtopdd ANSI((CONST char*, char**, double*)); +extern int __strtopf ANSI((CONST char*, char**, float*)); +extern int __strtopQ ANSI((CONST char*, char**, void*)); +extern int __strtopx ANSI((CONST char*, char**, void*)); +extern int __strtopxL ANSI((CONST char*, char**, void*)); +#else +#define __strtopd(s,se,x) strtord(s,se,1,x) +#define __strtopdd(s,se,x) strtordd(s,se,1,x) +#define __strtopf(s,se,x) strtorf(s,se,1,x) +#define __strtopQ(s,se,x) strtorQ(s,se,1,x) +#define __strtopx(s,se,x) strtorx(s,se,1,x) +#define __strtopxL(s,se,x) strtorxL(s,se,1,x) +#endif +__END_HIDDEN_DECLS + +#ifdef __cplusplus +} +#endif +#endif /* GDTOA_H_INCLUDED */ diff --git a/newlib/libc/stdlib/gdtoaimp.h b/newlib/libc/stdlib/gdtoaimp.h new file mode 100644 index 000000000..f2da3fc67 --- /dev/null +++ b/newlib/libc/stdlib/gdtoaimp.h @@ -0,0 +1,206 @@ +/**************************************************************** + +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. + +****************************************************************/ + +/* This is a variation on dtoa.c that converts arbitary binary + floating-point formats to and from decimal notation. It uses + double-precision arithmetic internally, so there are still + various #ifdefs that adapt the calculations to the native + double-precision arithmetic (any of IEEE, VAX D_floating, + or IBM mainframe arithmetic). + + Please send bug reports to David M. Gay (dmg at acm dot org, + with " at " changed at "@" and " dot " changed to "."). + */ + +/* On a machine with IEEE extended-precision registers, it is + * necessary to specify double-precision (53-bit) rounding precision + * before invoking strtod or dtoa. If the machine uses (the equivalent + * of) Intel 80x87 arithmetic, the call + * _control87(PC_53, MCW_PC); + * does this with many compilers. Whether this or another call is + * appropriate depends on the compiler; for this to work, it may be + * necessary to #include "float.h" or another system-dependent header + * file. + */ + +/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. + * + * This strtod returns a nearest machine number to the input decimal + * string (or sets errno to ERANGE). With IEEE arithmetic, ties are + * broken by the IEEE round-even rule. Otherwise ties are broken by + * biased rounding (add half and chop). + * + * Inspired loosely by William D. Clinger's paper "How to Read Floating + * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 112-126]. + * + * Modifications: + * + * 1. We only require IEEE, IBM, or VAX double-precision + * arithmetic (not IEEE double-extended). + * 2. We get by with floating-point arithmetic in a case that + * Clinger missed -- when we're computing d * 10^n + * for a small integer d and the integer n is not too + * much larger than 22 (the maximum integer k for which + * we can represent 10^k exactly), we may be able to + * compute (d*10^k) * 10^(e-k) with just one roundoff. + * 3. Rather than a bit-at-a-time adjustment of the binary + * result in the hard case, we use floating-point + * arithmetic to determine the adjustment to within + * one bit; only in really hard cases do we need to + * compute a second residual. + * 4. Because of 3., we don't need a large table of powers of 10 + * for ten-to-e (just some small tables, e.g. of 10^k + * for 0 <= k <= 22). + */ + +/* + * #define IEEE_8087 for IEEE-arithmetic machines where the least + * significant byte has the lowest address. + * #define IEEE_MC68k for IEEE-arithmetic machines where the most + * significant byte has the lowest address. + * #define Long int on machines with 32-bit ints and 64-bit longs. + * #define Sudden_Underflow for IEEE-format machines without gradual + * underflow (i.e., that flush to zero on underflow). + * #define IBM for IBM mainframe-style floating-point arithmetic. + * #define VAX for VAX-style floating-point arithmetic (D_floating). + * #define No_leftright to omit left-right logic in fast floating-point + * computation of dtoa and gdtoa. This will cause modes 4 and 5 to be + * treated the same as modes 2 and 3 for some inputs. + * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3. + * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines + * that use extended-precision instructions to compute rounded + * products and quotients) with IBM. + * #define ROUND_BIASED for IEEE-format with biased rounding and arithmetic + * that rounds toward +Infinity. + * #define ROUND_BIASED_without_Round_Up for IEEE-format with biased + * rounding when the underlying floating-point arithmetic uses + * unbiased rounding. This prevent using ordinary floating-point + * arithmetic when the result could be computed with one rounding error. + * #define Inaccurate_Divide for IEEE-format with correctly rounded + * products but inaccurate quotients, e.g., for Intel i860. + * #define NO_LONG_LONG on machines that do not have a "long long" + * integer type (of >= 64 bits). On such machines, you can + * #define Just_16 to store 16 bits per 32-bit Long when doing + * high-precision integer arithmetic. Whether this speeds things + * up or slows things down depends on the machine and the number + * being converted. If long long is available and the name is + * something other than "long long", #define Llong to be the name, + * and if "unsigned Llong" does not work as an unsigned version of + * Llong, #define #ULLong to be the corresponding unsigned type. + * #define KR_headers for old-style C function headers. + * #define Bad_float_h if your system lacks a float.h or if it does not + * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, + * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. + * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) + * if memory is available and otherwise does something you deem + * appropriate. If MALLOC is undefined, malloc will be invoked + * directly -- and assumed always to succeed. Similarly, if you + * want something other than the system's free() to be called to + * recycle memory acquired from MALLOC, #define FREE to be the + * name of the alternate routine. (FREE or free is only called in + * pathological cases, e.g., in a gdtoa call after a gdtoa return in + * mode 3 with thousands of digits requested.) + * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making + * memory allocations from a private pool of memory when possible. + * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, + * unless #defined to be a different length. This default length + * suffices to get rid of MALLOC calls except for unusual cases, + * such as decimal-to-binary conversion of a very long string of + * digits. When converting IEEE double precision values, the + * longest string gdtoa can return is about 751 bytes long. For + * conversions by strtod of strings of 800 digits and all gdtoa + * conversions of IEEE doubles in single-threaded executions with + * 8-byte pointers, PRIVATE_MEM >= 7400 appears to suffice; with + * 4-byte pointers, PRIVATE_MEM >= 7112 appears adequate. + * #define NO_INFNAN_CHECK if you do not wish to have INFNAN_CHECK + * #defined automatically on IEEE systems. On such systems, + * when INFNAN_CHECK is #defined, strtod checks + * for Infinity and NaN (case insensitively). + * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, + * strtodg also accepts (case insensitively) strings of the form + * NaN(x), where x is a string of hexadecimal digits (optionally + * preceded by 0x or 0X) and spaces; if there is only one string + * of hexadecimal digits, it is taken for the fraction bits of the + * resulting NaN; if there are two or more strings of hexadecimal + * digits, each string is assigned to the next available sequence + * of 32-bit words of fractions bits (starting with the most + * significant), right-aligned in each sequence. + * Unless GDTOA_NON_PEDANTIC_NANCHECK is #defined, input "NaN(...)" + * is consumed even when ... has the wrong form (in which case the + * "(...)" is consumed but ignored). + * #define MULTIPLE_THREADS if the system offers preemptively scheduled + * multiple threads. In this case, you must provide (or suitably + * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed + * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed + * in pow5mult, ensures lazy evaluation of only one copy of high + * powers of 5; omitting this lock would introduce a small + * probability of wasting memory, but would otherwise be harmless.) + * You must also invoke freedtoa(s) to free the value s returned by + * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. + * #define IMPRECISE_INEXACT if you do not care about the setting of + * the STRTOG_Inexact bits in the special case of doing IEEE double + * precision conversions (which could also be done by the strtod in + * dtoa.c). + * #define NO_HEX_FP to disable recognition of C9x's hexadecimal + * floating-point constants. + * #define -DNO_ERRNO to suppress setting errno (in strtod.c and + * strtodg.c). + * #define NO_STRING_H to use private versions of memcpy. + * On some K&R systems, it may also be necessary to + * #define DECLARE_SIZE_T in this case. + * #define USE_LOCALE to use the current locale's decimal_point value. + */ + +#ifndef GDTOAIMP_H_INCLUDED +#define GDTOAIMP_H_INCLUDED +#include "mprec.h" +#include "gdtoa.h" + +#ifndef __SINGLE_THREAD__ +#define MULTIPLE_THREADS +#endif + +#define dtoa __dtoa +#define gdtoa __gdtoa +#define freedtoa __freedtoa + +#define dtoa_result __dtoa_result_D2A +#define nrv_alloc __nrv_alloc_D2A +#define quorem __quorem_D2A +#define rshift __rshift_D2A +#define rv_alloc __rv_alloc_D2A +#define trailz __trailz_D2A + +extern char *dtoa_result; +extern char *nrv_alloc ANSI((struct _reent *, char*, char **, int)); +extern int quorem ANSI((Bigint*, Bigint*)); +extern void rshift ANSI((Bigint*, int)); +extern char *rv_alloc ANSI((struct _reent *, int)); +extern int trailz ANSI((Bigint*)); + +#endif /* GDTOAIMP_H_INCLUDED */ diff --git a/newlib/libc/stdlib/ldtoa.c b/newlib/libc/stdlib/ldtoa.c index 26c61948b..36613faad 100644 --- a/newlib/libc/stdlib/ldtoa.c +++ b/newlib/libc/stdlib/ldtoa.c @@ -2,6 +2,10 @@ * This program has been placed in the public domain. */ +#include +#include + +#ifndef _USE_GDTOA #include <_ansi.h> #include #include @@ -3900,3 +3904,5 @@ enan (short unsigned int *nan, int size) for (i = 0; i < n; i++) *nan++ = *p++; } + +#endif /* !_USE_GDTOA */ diff --git a/newlib/libc/stdlib/mprec.h b/newlib/libc/stdlib/mprec.h index a1492aa38..83de932c2 100644 --- a/newlib/libc/stdlib/mprec.h +++ b/newlib/libc/stdlib/mprec.h @@ -26,[...] [diff truncated at 100000 bytes]